tfctl 1.0.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6d47682cf9949db840c18d07b6f06907a9d36e2a75d0a5255b4c57f3603c0dbf
4
- data.tar.gz: d5a81e877943fff53e903a104249e1147a827c593430bc91c0b78d5cc467fc4b
3
+ metadata.gz: 5fe79c7d1c05d536eabd439037d74996bf35af1b72e359e34a0f52f32067fecf
4
+ data.tar.gz: 67c20fd6e27f58ce119e9c050923c80499b0054991716515f41dbbd2c4156336
5
5
  SHA512:
6
- metadata.gz: 03b7d69b7a7bbf296b0b1ab3aa8794d8b91e51559a1e2ee1d450396615aeba495b63993f84866c6fe5997d34c760da143cb66ca0cabc2a1a5a1266b701676bac
7
- data.tar.gz: f9ebdae72fd58473c3a8cc5015fd2d2e32092488218b52efa79e2d625802ccdf4447298e45497d4ec0e03583b0edbd3a31b51e92f76a5981a5f3819f9cee1e4a
6
+ metadata.gz: 693f29d4f7ddea34dfe9dbb747cf976452bdc8ff423bf63d41bc2f77f2ae05fb58ddb8b6d9a2d4c1f151749899a325b7326384e5e4128eda076d51c7c54bd8ca
7
+ data.tar.gz: a71acfa057e8a80923b7ec9c48ab2654af1fd6d73e4fa0259949d3bded769773dd3127590475266586fe48e3f5549a7f8725c111429a6ceb850389bb7fc63c01
data/.bundle/config ADDED
@@ -0,0 +1,3 @@
1
+ ---
2
+ BUNDLE_WITH: "developement"
3
+ BUNDLE_BIN: "vendor/bin"
@@ -0,0 +1,7 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: bundler
4
+ directory: "/"
5
+ schedule:
6
+ interval: daily
7
+ open-pull-requests-limit: 10
data/.gitignore CHANGED
@@ -4,7 +4,6 @@
4
4
  pkg/
5
5
  *.gem
6
6
  vendor/
7
- .bundle
8
7
  bin/bundle
9
8
  bin/htmldiff
10
9
  bin/ldiff
data/.rubocop.yml CHANGED
@@ -1,12 +1,13 @@
1
1
  ---
2
2
  AllCops:
3
- TargetRubyVersion: 2.3
3
+ TargetRubyVersion: 2.5
4
4
  DisplayCopNames: true
5
+ NewCops: enable
5
6
 
6
7
  Layout/IndentationWidth:
7
8
  Width: 4
8
9
 
9
- Layout/IndentHeredoc:
10
+ Layout/HeredocIndentation:
10
11
  Enabled: false
11
12
 
12
13
  Layout/EmptyLines:
@@ -15,7 +16,7 @@ Layout/EmptyLines:
15
16
  Layout/EmptyLinesAroundMethodBody:
16
17
  Enabled: false
17
18
 
18
- Layout/AlignHash:
19
+ Layout/HashAlignment:
19
20
  EnforcedHashRocketStyle:
20
21
  - table
21
22
  EnforcedColonStyle:
@@ -45,7 +46,7 @@ Metrics/BlockLength:
45
46
  Metrics/MethodLength:
46
47
  Enabled: false
47
48
 
48
- Metrics/LineLength:
49
+ Layout/LineLength:
49
50
  Max: 140
50
51
 
51
52
  Metrics/AbcSize:
@@ -77,3 +78,7 @@ Style/TrailingCommaInHashLiteral:
77
78
 
78
79
  Style/RedundantReturn:
79
80
  Enabled: false
81
+
82
+ # don't break older Rubies just because of style
83
+ Style/RedundantBegin:
84
+ Enabled: false
data/.travis.yml CHANGED
@@ -1,18 +1,19 @@
1
1
  rvm:
2
- - 2.3
3
- - 2.6
2
+ - 2.5
3
+ - 2.6
4
+ - 2.7
4
5
  os: linux
5
6
  language: ruby
6
7
  script: make test
7
8
  jobs:
8
9
  include:
9
- - stage: Gem release
10
- rvm: 2.6
11
- deploy:
12
- provider: rubygems
13
- api_key:
14
- secure: FKAONS7x6koN7oiEULr4ViwjlDBzbE0bCgqhXRP4DfTtlRyEymeqgrfSIqkVH7unjd0muIGrMBnFuaQVSx7648RS1Ss0QAJo32SVnzoYl1P03cijqNmbbaf1jRdA3IGmh0gV5vsXrmlHiP8gfAuC9PqQ550OzxzWUvEI8vXgSTibmKd/PoQinv5g/dq0gBFjlhSMt/k3Z9WlMmkEsAro/r/Ie2M7mItHPT65f0ga5q5SeujPQQ3Sd/l3mznh37bmnw5RZpFDYdA7jL2p0Y58XJPBU8soa3ZC5GeHyxCYVoGh6EDGAFb83ERRT6rQ7ywkOufTv1o497P7a/prSbvT6fzc+DcugXPEaglT+dUXMe36OoF907Xva4vq3xIHV2N/yrxbDM85hmMk22wEU+9wpDDzFNQnfsXNbaHG9F7gLgy0eoTRrSuJf6cPDlE8pwvn7b8cjieeqWc//ZNhSYnHYZGER4LFINWVxs68Eofmmqp2IESTcUpJ8oB4bV+bzzyobJMRobOXu2hvgCrTdr6r/PnckpAfZE/l4nVQa14f1FU//8bU3DwvNun6TX1Ujp+XNiRDUlvP2KnkBU4s5rsIkL3lCHW7r6GipSk6SOvGMTz5eySMsoWvZQBdAzk/OxcIteeWH9pdo1Hbu5x2/bwyuTRCQ9E79CKWDKlIQwCgUY0=
15
- gem: tfctl
16
- on:
17
- tags: true
18
- repo: scalefactory/tfctl
10
+ - stage: Gem release
11
+ rvm: 2.6
12
+ deploy:
13
+ provider: rubygems
14
+ api_key:
15
+ secure: LAVcdER+LtQ2TSUrVOY7Be1BC7GXJRD0QBt386vRM5Nld5QaD9Ow9gtN6FprzkzloI4R8BkPWqZbAT6YjC+C0AFB5HK6iPwD2bLsiF9w3ccDD+yrW99RHxiErpmYMun2PqZv0WkJ/pkEplPCKMRFv7SM7W9DMRlU7dsXc1v6IVyIb5u3A04jErS2jXXKY0ijlCDJYVo8zzYL6yUmUcXhc//3CIVnu2Miu6Qr8h7e6jMXNUWfMkwEXsFP9id4TsCz7hRY+39PkiBAknHTN5UqjjJiEOknZnHeTBcVPvi2h2xv+fFLSzVTxlxaRsVoMCShQp5D12qzhQObRJsRVQFs8Yyg9IYMyPdxssFYyUZFaAy5taWDm57uM3HTHylm/Dq3LmXTgGNxWUUkf2oh1g7R6cYZpBUQwiEPzhZQ7CoBQbGUAJmH9ZU9m+cr8kuAOUipd6BNEDvn/fIH4WJsRCNP72JGX16JBpuICvpkuNhskZT91xFlYk1pTXHOxNpbTcxUTgMHhrTqspeRXPmf6DiYGvjMb2S6kaoGqCIRIcwl0TGKuMsOMqR9SqF8gubkqHMVbSl1E7mwBn4ke8/7IGoMkWOGwUpVxqVOLBHi6zSR09RTVSbKl4oiFV3ZwmVPSxDncq54MptyJ2WCZ7dD6ht2l+VA8iGwYeIoqOpwGWxyuNI=
16
+ gem: tfctl
17
+ on:
18
+ tags: true
19
+ repo: scalefactory/tfctl
data/CHANGELOG.adoc CHANGED
@@ -1,5 +1,34 @@
1
1
  = Changelog
2
2
 
3
+ == 1.3.0
4
+
5
+ * feat: support new Terraform provider syntax
6
+
7
+ BREAKING CHANGE: The minimum supported Terraform version has been bumped to
8
+ 0.12.29. If you are running an older version of Terraform you will need to
9
+ update to the latest Terraform in 0.12.x series before updating tfctl. Once
10
+ tfctl is updated you can upgrade Terraform to further versions.
11
+
12
+ == 1.2.2
13
+ * chore: reverted PR #11 - not necessary and introduced regression. See PR #13 for details.
14
+
15
+ == 1.2.1
16
+ * chore: added required Ruby version to Gemspec.
17
+
18
+ == 1.2.0
19
+
20
+ * feat: pass TF_ environment variables to terraform (PR #11).
21
+
22
+ == 1.1.1
23
+
24
+ * fix: handle empty response from Organizations API containing children (thanks @grothja)
25
+ * chore: stopped testing on EOL Rubies 2.3 and 2.4 (but should still currently work)
26
+ * chore: dependencies minimum version bump
27
+
28
+ == 1.1.0
29
+
30
+ * feat: look for configuration in `tfctl.yaml` by default.
31
+
3
32
  == 1.0.0
4
33
 
5
34
  * feat(config): JSON schema config validation
data/Makefile CHANGED
@@ -2,7 +2,8 @@
2
2
 
3
3
  vendor:
4
4
  $(info => Installing Ruby dependencies)
5
- @bundle install --path vendor --with developement --binstubs=vendor/bin
5
+ @bundle install
6
+ @bundle binstubs --all --path vendor/bin
6
7
 
7
8
  test: vendor rubocop spec
8
9
 
@@ -10,11 +11,11 @@ guard: vendor
10
11
  $(info => Starting guard)
11
12
  @bundle exec guard
12
13
 
13
- rubocop:
14
+ rubocop: vendor
14
15
  $(info => Running rubocop)
15
16
  @vendor/bin/rubocop
16
17
 
17
- spec:
18
+ spec: vendor
18
19
  $(info => Running spec tests)
19
20
  @vendor/bin/rspec
20
21
 
data/README.adoc CHANGED
@@ -28,19 +28,37 @@ toc::[]
28
28
 
29
29
  == Overview
30
30
 
31
- Tfctl is a small Terraform wrapper for working with multi-account AWS
31
+ `tfctl` is a small Terraform wrapper for working with multi-account AWS
32
32
  infrastructures where new accounts may be created dynamically and on-demand.
33
33
 
34
- It discovers accounts by reading the AWS Organizations API and can assign
34
+ It discovers accounts by reading the AWS Organizations API, and can assign
35
35
  Terraform resources to multiple accounts based on the organization hierarchy.
36
36
  Resources can be assigned globally, based on organization unit or to individual
37
- accounts. It supports nested OU hierarchies and helps keep your Terraform DRY.
37
+ accounts. It supports hierarchies of nested Organizational Units (OUs),
38
+ and helps keep your Terraform DRY.
38
39
 
39
- Tfctl was originally developed to integrate Terraform with
40
+ The Scale Factory originally created tfctl to integrate Terraform with
40
41
  https://aws.amazon.com/solutions/aws-landing-zone/[AWS Landing Zone] and
41
42
  https://aws.amazon.com/controltower/[Control Tower] but should work with most
42
43
  other ways of managing accounts in AWS Organizations.
43
44
 
45
+ == Project status
46
+
47
+ `tfctl` is an open source project published by The Scale Factory.
48
+
49
+ We currently consider this project to be maintained but we don't actively
50
+ develop new features. We keep it security patched and ready for use in
51
+ production environments.
52
+
53
+ We’ll take a look at any issues or PRs you open and get back to you as soon as
54
+ we can. We don’t offer any formal SLA, but we’ll be checking on this project
55
+ periodically.
56
+
57
+ If your issue is urgent, you can flag it as such, and we’ll attempt to triage
58
+ appropriately, but we have paying customers who also have demands on our time.
59
+ If your business depends on this project and you have an urgent problem, then
60
+ you can talk to our sales team about paying us to support you.
61
+
44
62
  == Features
45
63
 
46
64
  * Discovers AWS accounts automatically.
@@ -56,8 +74,8 @@ other ways of managing accounts in AWS Organizations.
56
74
 
57
75
  == Requirements
58
76
 
59
- * Terraform >= 0.12
60
- * Ruby >= 2.3
77
+ * Terraform >= 0.12.29
78
+ * Ruby >= 2.5
61
79
  * Accounts managed in AWS Organizations (by Landing Zone, Control Tower, some
62
80
  other means)
63
81
 
@@ -65,17 +83,19 @@ other ways of managing accounts in AWS Organizations.
65
83
 
66
84
  To install the latest release from RubyGems run:
67
85
 
86
+ [source,shell]
68
87
  ----
69
88
  gem install tfctl
70
89
  ----
71
90
 
72
- Alternatively you can build and install from this repo with:
91
+ Alternatively, you can build and install from this repo with:
73
92
 
93
+ [source,shell]
74
94
  ----
75
95
  make install
76
96
  ----
77
97
 
78
- == Docs
98
+ == Documentation
79
99
 
80
100
  * https://github.com/scalefactory/tfctl/tree/master/docs/control_tower.adoc[Control Tower quick start guide]
81
101
  * https://github.com/scalefactory/tfctl/tree/master/docs/project_layout.adoc[Project layout]
@@ -85,23 +105,25 @@ make install
85
105
 
86
106
  == Running tfctl
87
107
 
88
- tfctl should be run from the root of the project directory. It will generate
89
- Terraform configuration in `.tfctl/`.
108
+ You should run `tfctl` from the root of your project directory. It will generate
109
+ Terraform configuration in `.tfctl/` (add this to your `.gitignore`).
90
110
 
91
111
  Anatomy of a tfctl command:
92
112
 
113
+ [source,shell]
93
114
  ----
94
115
  tfctl -c CONFIG_FILE TARGET_OPTIONS -- TERRAFORM_COMMAND
95
116
  ----
96
117
 
97
- * `-c` specifies which tfctl config file to use (usually in `conf/`)
118
+ * `-c` specifies which tfctl config file to use (defaults to `tfctl.yaml` in
119
+ current working directory if not set)
98
120
  * `TARGET_OPTIONS` specifies which accounts to target. This could be an individual
99
121
  account, a group of accounts in an organizational unit or all accounts.
100
122
  * `TERRAFORM_COMMAND` will be passed to `terraform` along with any
101
123
  options. See https://www.terraform.io/docs/commands/index.html[Terraform
102
124
  commands] for details.
103
125
 
104
- NOTE: You must have your AWS credentials configured before running tfctl or run
126
+ NOTE: You must have your AWS credentials configured before you run `tfctl`, or run
105
127
  it using an AWS credentials helper such as
106
128
  https://github.com/99designs/aws-vault[aws-vault].
107
129
 
@@ -109,68 +131,78 @@ https://github.com/99designs/aws-vault[aws-vault].
109
131
 
110
132
  Show help:
111
133
 
134
+ [source,shell]
112
135
  ----
113
136
  tfctl -h
114
137
  ----
115
138
 
116
139
  Show merged configuration:
117
140
 
141
+ [source,shell]
118
142
  ----
119
- tfctl -c conf/example.yaml -s
143
+ tfctl -s
120
144
  ----
121
145
 
122
146
  List all discovered accounts:
123
147
 
148
+ [source,shell]
124
149
  ----
125
- tfctl -c conf/example.yaml --all -l
150
+ tfctl --all -l
126
151
  ----
127
152
 
128
153
  TIP: This can be narrowed down using targeting options and is a good way to
129
154
  test what accounts match.
130
155
 
131
- Run Terraform init across all accounts:
156
+ Run `terraform init` across all accounts:
132
157
 
158
+ [source,shell]
133
159
  ----
134
- tfctl -c conf/example.yaml --all -- init
160
+ tfctl --all -- init
135
161
  ----
136
162
 
137
- Run plan in `test` OU accounts:
163
+ Plan Terraform across all accounts in the `test` OU:
138
164
 
165
+ [source,shell]
139
166
  ----
140
- tfctl -c conf/example.yaml -o test -- plan
167
+ tfctl -o test -- plan
141
168
  ----
142
169
 
143
- Run plan in `live` accounts assuming that `live` is a child OU in multiple
170
+ Plan Terraform in `live` accounts, assuming that `live` is a child OU in multiple
144
171
  organization units:
145
172
 
173
+ [source,shell]
146
174
  ----
147
- tfctl -c conf/example.yaml -o '.*/live' -- plan
175
+ tfctl -o '.*/live' -- plan
148
176
  ----
149
177
 
150
- Run plan in an individual account:
178
+ Run a plan for an individual account:
151
179
 
180
+ [source,shell]
152
181
  ----
153
- tfctl -c conf/example.yaml -a example-account - plan
182
+ tfctl -a example-account - plan
154
183
  ----
155
184
 
156
- Run apply in all accounts:
185
+ Apply Terraform changes across all accounts:
157
186
 
187
+ [source,shell]
158
188
  ----
159
- tfctl -c conf/example.yaml --all -- apply
189
+ tfctl --all -- apply
160
190
  ----
161
191
 
162
- Run destroy in `test` OU accounts:
192
+ Destroy Terraform-managed resources in all the `test` OU accounts:
163
193
 
194
+ [source,shell]
164
195
  ----
165
- tfctl -c conf/example.yaml -o test -- destroy -auto-approve
196
+ tfctl -o test -- destroy -auto-approve
166
197
  ----
167
198
 
168
199
  Don't buffer the output:
169
200
 
201
+ [source,shell]
170
202
  ----
171
- tfctl -c conf/example.yaml -a example-account -u -- plan
203
+ tfctl -a example-account -u -- plan
172
204
  ----
173
205
 
174
206
  This will show output in real time. Usually output is buffered and displayed
175
- after Terraform command finishes to make it more readable when running across
176
- multiple accounts in parallel.
207
+ after the Terraform command finishes, to make it more readable when running
208
+ across multiple accounts in parallel.
data/RELEASING.adoc ADDED
@@ -0,0 +1,13 @@
1
+ = Releasing
2
+
3
+ This document is aimed at `tfctl` maintainers and describes the process of
4
+ releasing a new gem version.
5
+
6
+ == Process
7
+
8
+ * Smoke test in SF test accounts: https://github.com/scalefactory/tfctl-test
9
+ * Bump version in `lib/tfctl/version.rb`
10
+ * Update `CHANGELOG.adoc`
11
+ * Commit
12
+ * Create a new GitHub release and version tag using format: vX.X.X
13
+ * TravisCI will build and release the gem automatically: https://travis-ci.org/github/scalefactory/tfctl
data/bin/tfctl CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- if File.directory?(File.dirname(__FILE__) + '/../vendor')
4
+ if File.directory?("#{File.dirname(__FILE__)}/../vendor")
5
5
  require 'bundler/setup'
6
6
  end
7
7
  require 'optparse'
@@ -22,7 +22,7 @@ options = {
22
22
  ou: nil,
23
23
  all: nil,
24
24
  show_config: false,
25
- config_file: nil,
25
+ config_file: 'tfctl.yaml',
26
26
  unbuffered: false,
27
27
  debug: false,
28
28
  use_cache: false,
@@ -68,10 +68,6 @@ begin
68
68
 
69
69
  # Validate CLI arguments
70
70
 
71
- if options[:config_file].nil?
72
- raise OptionParser::MissingArgument, '--config-file'
73
- end
74
-
75
71
  unless File.exist? options[:config_file]
76
72
  raise OptionParser::InvalidOption,
77
73
  "Config file not found in: #{options[:config_file]}"
@@ -85,8 +81,8 @@ begin
85
81
  targetting_opts = %i[account ou all]
86
82
  targets_set = []
87
83
  options.each do |k, v|
88
- if targetting_opts.include?(k)
89
- targets_set << k.to_s unless v.nil?
84
+ if targetting_opts.include?(k) and !v.nil?
85
+ targets_set << k.to_s
90
86
  end
91
87
  end
92
88
  if targets_set.length > 1
@@ -104,7 +100,7 @@ end
104
100
 
105
101
 
106
102
 
107
- # Generates configuration and runs Terraform commands for a target account.
103
+ # Execute terraform in target accounts
108
104
  def run_account(config, account, options, tf_argv, log)
109
105
 
110
106
  # Skip excluded accounts
@@ -145,6 +141,7 @@ begin
145
141
  log.info 'tfctl running'
146
142
 
147
143
  config_name = File.basename(options[:config_file]).chomp('.yaml')
144
+ config_name = 'default' if config_name == 'tfctl'
148
145
  log.info "Using config: #{config_name}"
149
146
 
150
147
  log.info 'Working out AWS account topology'
@@ -24,8 +24,8 @@ toc::[]
24
24
 
25
25
  == Overview
26
26
 
27
- Tfctl retrieves initial account configuration from AWS Organizations and merges
28
- it with configuration specified in a yaml file.
27
+ `tfctl` retrieves initial account configuration from AWS Organizations and merges
28
+ it with configuration specified in YAML format (`tfctl.yaml` by default).
29
29
 
30
30
  The configuration is merged in the following order:
31
31
 
@@ -68,9 +68,9 @@ organization_units:
68
68
 
69
69
  This will result in all three profiles deployed to accounts in `team` OU.
70
70
 
71
- TIP: You can display the fully merged configuration by running `tfctl -c
72
- conf/CONFIG_FILE.yaml -s`. It's safe to run as it doesn't make any changes to
73
- AWS resources. It's a good way to test your configuration.
71
+ TIP: You can display the fully merged configuration by running `tfctl -s`.
72
+ It's safe to run as it doesn't make any changes to AWS resources. It's a good
73
+ way to test your configuration.
74
74
 
75
75
  == Defining arbitrary data
76
76
 
@@ -83,7 +83,17 @@ above.
83
83
 
84
84
  == Handling secrets
85
85
 
86
- No secrets should be committed into Terraform or tfctl configuration. Use AWS
87
- Secrets Manager instead and retrieve in Terraform profiles using
86
+ CAUTION: Do not commit secrets into your Terraform or tfctl configuration.
87
+
88
+ Instead, use AWS Secrets Manager and retrieve secrets in Terraform profiles using
89
+ the
88
90
  https://www.terraform.io/docs/providers/aws/d/secretsmanager_secret.html[secrets
89
- manager data source]
91
+ manager data source].
92
+
93
+ == Configuration Schema
94
+
95
+ The configuration file is validated using https://json-schema.org/[JSON Schema].
96
+
97
+ The schema is defined in
98
+ https://github.com/scalefactory/tfctl/blob/master/lib/tfctl/schema.rb[lib/tfctl/schema.rb]
99
+ and is a good place to look up all available options.
@@ -31,7 +31,7 @@ toc::[]
31
31
  For state tracking we're going to create a dedicated `shared-services` account
32
32
  under a `mgmt` organization unit. We'll use S3 for state storage and DynamoDB
33
33
  for locking. `TerraformState` IAM role will be created for cross account
34
- access to state resources from the primary account.
34
+ access to state resources from the primary AWS account.
35
35
 
36
36
  In the primary account we'll create a `TfctlOrgAccess` role. It gives tfctl
37
37
  read only access to AWS Organizations which is used to discover accounts and
@@ -50,9 +50,10 @@ and provision a couple of accounts for testing.
50
50
 
51
51
  Before starting you'll need:
52
52
 
53
- * Control Tower set up in your primary account.
54
- * A user with `AdministratorAccess` privileges in primary account.
55
- * AWS CLI tools installed on your machine.
53
+ * An AWS account that is part of an Organization.
54
+ * Control Tower set up in your primary AWS account.
55
+ * A user with `AdministratorAccess` privileges in your primary AWS account.
56
+ * AWS CLI tools installed on your local machine.
56
57
  * Terraform 0.12 or higher.
57
58
 
58
59
  == Configure Control Tower
@@ -74,6 +75,7 @@ approximately 20 mins to provision one.
74
75
 
75
76
  == Install tfctl
76
77
 
78
+ [source,shell]
77
79
  ----
78
80
  git clone git@github.com:scalefactory/tfctl.git
79
81
  cd tfctl/ && sudo make install
@@ -85,17 +87,21 @@ It's assumed you have configured AWS CLI access to the primary account.
85
87
 
86
88
  We'll use CloudFormation templates in `examples/bootstrap/`.
87
89
 
88
- First export configuration using environment variables making sure to change to
89
- values to suit your set up:
90
+ First export configuration using environment variables, making sure to change to
91
+ values to suit your setup:
90
92
 
93
+ [source,shell]
91
94
  ----
92
- export PRIMARY_ACCOUNT_ID=11111111
93
- export SHARED_SERVICES_ACCOUNT_ID=22222222
95
+ # Change these to match your setup
96
+ export PRIMARY_ACCOUNT_ID=123456789012
97
+ export SHARED_SERVICES_ACCOUNT_ID=345678901234
94
98
  export STATE_BUCKET_NAME='example-terraform-state'
99
+ export AWS_REGION=eu-west-1
95
100
  ----
96
101
 
97
102
  Create the remote state resources stack set:
98
103
 
104
+ [source,shell]
99
105
  ----
100
106
  cd examples/bootstrap/
101
107
 
@@ -107,31 +113,34 @@ aws cloudformation create-stack-set \
107
113
  --execution-role-name AWSControlTowerExecution \
108
114
  --administration-role-arn arn:aws:iam::${PRIMARY_ACCOUNT_ID}:role/service-role/AWSControlTowerStackSetRole \
109
115
  --parameters ParameterKey=PrimaryAccountId,ParameterValue=${PRIMARY_ACCOUNT_ID} \
110
- ParameterKey=TerraformStateBucket,ParameterValue=${STATE_BUCKET_NAME}
116
+ ParameterKey=TerraformStateBucket,ParameterValue="${STATE_BUCKET_NAME}"
111
117
  ----
112
118
 
113
- Create a stack set instance in you shared services account:
119
+ Create a stack set instance in your shared services account:
114
120
 
121
+ [source,shell]
115
122
  ----
116
123
  aws cloudformation create-stack-instances \
117
124
  --stack-set-name TerraformState \
118
125
  --accounts ${SHARED_SERVICES_ACCOUNT_ID} \
119
- --regions eu-west-1
126
+ --regions ${AWS_REGION}
120
127
  ----
121
128
 
122
129
  Check status:
123
130
 
131
+ [source,shell]
124
132
  ----
125
133
  aws cloudformation describe-stack-instance \
126
134
  --stack-set-name TerraformState \
127
135
  --stack-instance-account ${SHARED_SERVICES_ACCOUNT_ID} \
128
- --stack-instance-region eu-west-1
136
+ --stack-instance-region ${AWS_REGION}
129
137
  ----
130
138
 
131
139
  NOTE: Initial status will be `OUTDATED`, it should change to `CURRENT` once deployed.
132
140
 
133
- Deploy `TfctlOrgAccess` IAM role stack:
141
+ Deploy the `TfctlOrgAccess` IAM role stack:
134
142
 
143
+ [source,shell]
135
144
  ----
136
145
  aws cloudformation create-stack \
137
146
  --stack-name TfctlOrgAccess \
@@ -142,6 +151,7 @@ aws cloudformation create-stack \
142
151
 
143
152
  Check status:
144
153
 
154
+ [source,shell]
145
155
  ----
146
156
  aws cloudformation describe-stacks --stack-name TfctlOrgAccess
147
157
  ----
@@ -151,14 +161,14 @@ NOTE: Successful status should read: `CREATE_COMPLETE`.
151
161
  == Configure tfctl
152
162
 
153
163
  Copy the example project directory `examples/control_tower` somewhere convenient
154
- and edit `conf/example.yaml`.
164
+ and edit `tfctl.yaml`.
155
165
 
156
166
  You need to modify the following parameters:
157
167
 
158
168
  * `tf_state_bucket` - set to `$STATE_BUCKET_NAME`
159
169
  * `tf_state_role_arn` - set shared services account ID
160
170
  * `tfctl_role_arn` - set primary account ID
161
- * `primary_account` - set the primary account name. You can find it in AWS Organizations.
171
+ * `primary_account` - set the primary account name. You can find it through AWS Organizations in the console.
162
172
 
163
173
  TIP: You should keep your project directory under version control.
164
174
 
@@ -169,43 +179,51 @@ and `mgmt` OUs.
169
179
 
170
180
  NOTE: Run tfctl commands from the root of you project directory.
171
181
 
172
- First dump the configuration to verify everything works:
182
+ First, dump the configuration to verify everything works:
173
183
 
184
+ [source,shell]
174
185
  ----
175
- tfctl -c conf/example.yaml -s
186
+ tfctl -s
176
187
  ----
177
188
 
178
- This will not make any changes but will print out a yaml containing the final,
189
+ This will not make any changes but will print out YAML containing the final,
179
190
  merged configuration data. It should contain a list of discovered accounts and
180
191
  their configuration.
181
192
 
182
- Initialise terraform for all discovered accounts:
193
+ Initialise Terraform for all discovered accounts:
183
194
 
195
+ [source,shell]
184
196
  ----
185
- tfctl -c conf/example.yaml --all -- init
197
+ tfctl --all -- init
186
198
  ----
187
199
 
188
200
  Tfctl will run Terraform against all accounts in parallel.
189
201
 
190
- Run plan:
202
+ `plan` the Terraform:
191
203
 
204
+ [source,shell]
192
205
  ----
193
- tfctl -c conf/example.yaml --all -- plan
206
+ tfctl --all -- plan
194
207
  ----
195
208
 
196
- and apply:
209
+ and `apply` it:
197
210
 
211
+ [source,shell]
198
212
  ----
199
- tfctl -c conf/example.yaml --all -- apply
213
+ tfctl --all -- apply
200
214
  ----
201
215
 
202
- To destroy created resources run:
203
216
 
217
+ == Clean up
218
+
219
+ To destroy created resources, run:
220
+
221
+ [source,shell]
204
222
  ----
205
- tfctl -c conf/example.yaml --all -- destroy -auto-approve
223
+ tfctl --all -- destroy -auto-approve
206
224
  ----
207
225
 
208
- That's it! You can now execute terraform across your Control Tower estate.
226
+ That's it! You can now execute Terraform across your Control Tower estate.
209
227
 
210
228
  TIP: Your project directory should be under version control excluding the
211
229
  `.tfctl` directory which is automatically generated.
@@ -81,7 +81,7 @@ profile. Tfctl configuration can be accessed using this variable. This It
81
81
  includes an array of all discovered accounts as well their parameters from
82
82
  tfctl config file.
83
83
 
84
- TIP: You can run `tfctl -c conf/CONFIG_FILE.yaml -s` to show the config data in
84
+ TIP: You can run `tfctl -s` to show the config data in
85
85
  yaml format. This exact data is available in the `config` variable in your
86
86
  profile.
87
87
 
@@ -124,7 +124,7 @@ You have few options here:
124
124
  For the sake of this example we're going to deploy our bucket to all accounts
125
125
  in `test` OU.
126
126
 
127
- In tfctl config file add the profile to the `test` OU:
127
+ In `tfctl.yaml` add the profile to the `test` OU:
128
128
 
129
129
  [source, yaml]
130
130
  ----
@@ -140,8 +140,8 @@ organization_units:
140
140
  To see what would happen when the change is applied run:
141
141
 
142
142
  ----
143
- tfctl -c conf/example.yaml -o test -- init
144
- tfctl -c conf/example.yaml -o test -- plan
143
+ tfctl -o test -- init
144
+ tfctl -o test -- plan
145
145
  ----
146
146
 
147
147
  This will run `terraform init` to initialise terraform and then `terraform
@@ -187,5 +187,5 @@ next step.
187
187
 
188
188
  Once you're happy with the plan, apply it.
189
189
  ----
190
- tfctl -c conf/example.yaml -o test -- apply
190
+ tfctl -o test -- apply
191
191
  ----
@@ -20,7 +20,7 @@ endif::[]
20
20
 
21
21
  = IAM roles
22
22
 
23
- Tfctl usually requires three IAM roles to be configured:
23
+ `tfctl` usually requires three IAM roles to be configured:
24
24
 
25
25
  * `TfctlRole` - read only access to AWS Organizations set up in the primary account.
26
26
  * `TerraformStateRole` - access to remote state resources (S3, DynamoDB) in the
@@ -28,7 +28,7 @@ Tfctl usually requires three IAM roles to be configured:
28
28
  * `TerraformExecutionRole` - configured in all spoke accounts and used for executing Terraform.
29
29
 
30
30
  The user executing tfctl needs permission to assume all three roles cross
31
- account. Tfctl will assume roles automatically for you.
31
+ account. Once these are configured, tfctl automatically assumes roles for you.
32
32
 
33
33
  It's possible to configure different Terraform execution roles in different
34
34
  spoke accounts based on OU or account names. This can be used to restrict
@@ -23,8 +23,7 @@ endif::[]
23
23
  Example project structure
24
24
  ----
25
25
  project_dir/
26
- ├── conf
27
- │   └── example.yaml
26
+ ├── tfctl.conf
28
27
  ├── modules
29
28
  │   └── s3-bucket
30
29
  │   ├── main.tf
@@ -51,7 +50,12 @@ The configuration data is exposed to terraform via a profile `config` variable.
51
50
  It also defines Terraform and tfctl configuration such as state tracking and
52
51
  what IAM roles to use.
53
52
 
54
- == profiles
53
+ By default, tfctl will use `tfctl.yaml` in its current working directory. You
54
+ can specify a different file using `-c`. Multiple configurations are supported
55
+ in the same project directory and generated data will be stored separately for
56
+ each config file in `.tfctl/`.
57
+
58
+ == `profiles`
55
59
 
56
60
  Profiles are re-usable collections of resources which can be applied to
57
61
  accounts. They are implemented just like usual modules but provide an
@@ -60,6 +64,6 @@ other data sources). Profiles often compose multiple modules and provide
60
64
  configuration data to them. This approach makes it possible to re-use standard
61
65
  modules (e.g. Terraform module registry).
62
66
 
63
- == modules
67
+ == `modules`
64
68
 
65
69
  Standard Terraform modules.
@@ -1,4 +1,4 @@
1
1
  module "bucket" {
2
2
  source = "../../modules/s3-bucket"
3
- name = "${local.account_id}-${local.account["example_bucket_name"]}"
3
+ name = "${local.account_id}-${local.account["data"]["example_bucket_name"]}"
4
4
  }
@@ -7,6 +7,6 @@ variable "config" {
7
7
  locals {
8
8
  config = jsondecode(var.config)
9
9
  account_id = "${data.aws_caller_identity.current.account_id}"
10
- # get current account configuration from tfctl config
10
+ # get account configuration from tfctl config
11
11
  account = [ for account in local.config["accounts"]: account if account["id"] == local.account_id ][0]
12
12
  }
@@ -5,7 +5,7 @@
5
5
  # create final configuration used by tfctl. You can view the merged
6
6
  # configuration by running:
7
7
  #
8
- # tfctl -c conf/example.yaml -s
8
+ # tfctl -c conf/tfctl.yaml -s
9
9
  #
10
10
 
11
11
  #
@@ -17,7 +17,7 @@ tf_state_dynamodb_table: 'terraform-lock'
17
17
  tf_state_region: 'eu-west-1'
18
18
  # Role for accessing state resources
19
19
  tf_state_role_arn: 'arn:aws:iam::SHARED_SERVICES_ACCOUNT_ID:role/TerraformStateRole'
20
- tf_required_version: '>= 0.12.0'
20
+ tf_required_version: '>= 0.12.29'
21
21
  aws_provider_version: '>= 2.14'
22
22
  # Role used by tfctl to retrieve data from AWS Organizations
23
23
  # Has to be set up in the primary org account
data/lib/hash.rb CHANGED
@@ -18,13 +18,14 @@ class Hash
18
18
  merge(second.to_h, &merger)
19
19
  end
20
20
 
21
- # Copied from ruby 2.6 Psych for 2.3 compatibility.
22
21
  def symbolize_names!(result = self)
23
22
  case result
24
23
  when Hash
24
+ # rubocop:disable Style/HashEachMethods
25
25
  result.keys.each do |key|
26
26
  result[key.to_sym] = symbolize_names!(result.delete(key))
27
27
  end
28
+ # rubocop:enable Style/HashEachMethods
28
29
  when Array
29
30
  result.map! { |r| symbolize_names!(r) }
30
31
  end
data/lib/tfctl.rb CHANGED
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'tfctl/aws_org.rb'
4
- require_relative 'tfctl/config.rb'
5
- require_relative 'tfctl/error.rb'
6
- require_relative 'tfctl/executor.rb'
7
- require_relative 'tfctl/generator.rb'
8
- require_relative 'tfctl/logger.rb'
9
- require_relative 'tfctl/schema.rb'
10
- require_relative 'tfctl/version.rb'
3
+ require_relative 'tfctl/aws_org'
4
+ require_relative 'tfctl/config'
5
+ require_relative 'tfctl/error'
6
+ require_relative 'tfctl/executor'
7
+ require_relative 'tfctl/generator'
8
+ require_relative 'tfctl/logger'
9
+ require_relative 'tfctl/schema'
10
+ require_relative 'tfctl/version'
data/lib/tfctl/aws_org.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'error.rb'
3
+ require_relative 'error'
4
4
  require 'aws-sdk-organizations'
5
5
 
6
6
  module Tfctl
@@ -71,23 +71,25 @@ module Tfctl
71
71
  @aws_org_client.list_children(
72
72
  child_type: 'ORGANIZATIONAL_UNIT',
73
73
  parent_id: parent_id,
74
- ).children.each do |child|
75
-
76
- begin
77
- ou = @aws_org_client.describe_organizational_unit(
78
- organizational_unit_id: child.id,
79
- ).organizational_unit
80
- rescue Aws::Organizations::Errors::TooManyRequestsException
81
- # FIXME: - use logger
82
- puts 'AWS Organizations: too many requests. Retrying in 5 secs.'
83
- sleep 5
84
- retries += 1
85
- retry if retries < 10
86
- end
74
+ ).each do |resp|
75
+ resp.children.each do |child|
76
+
77
+ begin
78
+ ou = @aws_org_client.describe_organizational_unit(
79
+ organizational_unit_id: child.id,
80
+ ).organizational_unit
81
+ rescue Aws::Organizations::Errors::TooManyRequestsException
82
+ # FIXME: - use logger
83
+ puts 'AWS Organizations: too many requests. Retrying in 5 secs.'
84
+ sleep 5
85
+ retries += 1
86
+ retry if retries < 10
87
+ end
87
88
 
88
- ou_name = parent_name == :root ? ou.name.to_sym : "#{parent_name}/#{ou.name}".to_sym
89
+ ou_name = parent_name == :root ? ou.name.to_sym : "#{parent_name}/#{ou.name}".to_sym
89
90
 
90
- output[ou_name] = ou.id
91
+ output[ou_name] = ou.id
92
+ end
91
93
  end
92
94
  output
93
95
  end
data/lib/tfctl/config.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../hash.rb'
4
- require_relative 'error.rb'
3
+ require_relative '../hash'
4
+ require_relative 'error'
5
5
  require 'yaml'
6
6
  require 'json'
7
7
 
@@ -48,7 +48,7 @@ module Tfctl
48
48
  @config.to_json
49
49
  end
50
50
 
51
- # Filters accounts by account property
51
+ # Filters accounts by an account property
52
52
  def find_accounts(property_name, property_value)
53
53
  output =[]
54
54
  @config[:accounts].each do |account|
@@ -88,7 +88,6 @@ module Tfctl
88
88
 
89
89
  # Retrieves AWS Organizations data and merges it with data from yaml config.
90
90
  def load_config(config_name, yaml_config, aws_org_config)
91
-
92
91
  # AWS Organizations data
93
92
  config = aws_org_config
94
93
  # Merge organization sections from yaml file
@@ -122,7 +121,9 @@ module Tfctl
122
121
  return config unless config.key?(:exclude_accounts)
123
122
 
124
123
  config[:accounts].each_with_index do |account, idx|
124
+ # rubocop:disable Style/IfWithBooleanLiteralBranches
125
125
  config[:accounts][idx][:excluded] = config[:exclude_accounts].include?(account[:name]) ? true : false
126
+ # rubocop:enable Style/IfWithBooleanLiteralBranches
126
127
  end
127
128
 
128
129
  config
@@ -3,7 +3,7 @@
3
3
  require 'open3'
4
4
  require 'fileutils'
5
5
  require 'shellwords'
6
- require_relative 'error.rb'
6
+ require_relative 'error'
7
7
 
8
8
  module Tfctl
9
9
  module Executor
@@ -10,21 +10,27 @@ module Tfctl
10
10
 
11
11
  def write_json_block(path, block)
12
12
  File.open(path, 'w') do |f|
13
- f.write(JSON.pretty_generate(block) + "\n")
13
+ f.write("#{JSON.pretty_generate(block)}\n")
14
14
  end
15
15
  end
16
16
 
17
17
  def make(account:, config:)
18
18
  target_dir = "#{PROJECT_ROOT}/.tfctl/#{config[:config_name]}/#{account[:name]}"
19
- tf_version = config.fetch(:tf_required_version, '>= 0.12.0')
19
+ tf_version = config.fetch(:tf_required_version, '>= 0.12.29')
20
20
  aws_provider_version = config.fetch(:aws_provider_version, '>= 2.14')
21
21
 
22
22
  FileUtils.mkdir_p target_dir
23
23
 
24
24
  terraform_block = {
25
25
  'terraform' => {
26
- 'required_version' => tf_version,
27
- 'backend' => {
26
+ 'required_version' => tf_version,
27
+ 'required_providers' => {
28
+ 'aws' => {
29
+ 'source' => 'hashicorp/aws',
30
+ 'version' => aws_provider_version,
31
+ },
32
+ },
33
+ 'backend' => {
28
34
  's3' => {
29
35
  'bucket' => config[:tf_state_bucket],
30
36
  'key' => "#{account[:name]}/tfstate",
@@ -41,7 +47,6 @@ module Tfctl
41
47
  provider_block = {
42
48
  'provider' => {
43
49
  'aws' => {
44
- 'version' => aws_provider_version,
45
50
  'region' => account[:region],
46
51
  'assume_role' => {
47
52
  'role_arn' => "arn:aws:iam::#{account[:id]}:role/#{account[:tf_execution_role]}",
@@ -71,11 +76,8 @@ module Tfctl
71
76
  profile_block = {
72
77
  'module' => {
73
78
  profile => {
74
- 'source' => "../../../profiles/#{profile}",
75
- 'config' => '${var.config}',
76
- 'providers' => {
77
- 'aws' => 'aws',
78
- },
79
+ 'source' => "../../../profiles/#{profile}",
80
+ 'config' => '${var.config}',
79
81
  },
80
82
  },
81
83
  }
data/lib/tfctl/logger.rb CHANGED
@@ -6,7 +6,7 @@ module Tfctl
6
6
  class Logger
7
7
 
8
8
  def initialize(log_level)
9
- @outlog = ::Logger.new(STDOUT)
9
+ @outlog = ::Logger.new($stdout)
10
10
 
11
11
  self.level = log_level
12
12
 
data/lib/tfctl/schema.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'json_schemer'
4
- require_relative 'error.rb'
4
+ require_relative 'error'
5
5
 
6
6
  # Config validator using JSON schema
7
7
 
@@ -29,7 +29,7 @@ module Tfctl
29
29
  def main_schema
30
30
  iam_arn_pattern = 'arn:aws:iam:[a-z\-0-9]*:[0-9]{12}:[a-zA-Z\/+@=.,]*'
31
31
 
32
- # rubocop:disable Layout/AlignHash
32
+ # rubocop:disable Layout/HashAlignment
33
33
  {
34
34
  'type' => 'object',
35
35
  'properties' => {
@@ -61,7 +61,7 @@ module Tfctl
61
61
  ],
62
62
  'additionalProperties' => false,
63
63
  }
64
- # rubocop:enable Layout/AlignHash
64
+ # rubocop:enable Layout/HashAlignment
65
65
  end
66
66
 
67
67
  def org_schema
data/lib/tfctl/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tfctl
4
- VERSION = '1.0.0'
4
+ VERSION = '1.3.0'
5
5
  end
data/tfctl.gemspec CHANGED
@@ -23,14 +23,17 @@ Gem::Specification.new do |spec|
23
23
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
24
24
  spec.require_paths = ['lib']
25
25
 
26
+ spec.required_ruby_version = '>= 2.5.0'
27
+
26
28
  # Think when adding new dependencies. Is it really necessary?
27
29
  # "The things you own end up owning you" etc.
28
- spec.add_dependency 'aws-sdk-organizations', '~> 1.13'
30
+ spec.add_dependency 'aws-sdk-organizations', '~> 1.40'
29
31
  spec.add_dependency 'json_schemer', '~> 0.2'
30
- spec.add_dependency 'parallel', '~> 1.17'
31
- spec.add_dependency 'terminal-table', '~> 1.8'
32
+ spec.add_dependency 'parallel', '~> 1.19'
33
+ spec.add_dependency 'terminal-table', '>= 1.8', '< 4.0'
32
34
 
33
- spec.add_development_dependency 'guard-rspec', '~> 4.7'
34
- spec.add_development_dependency 'rspec', '~> 3.8'
35
- spec.add_development_dependency 'rubocop', '~> 0.76'
35
+ spec.add_development_dependency 'guard-rspec', '~> 4.7'
36
+ spec.add_development_dependency 'rspec', '~> 3.9'
37
+ spec.add_development_dependency 'rubocop', '~> 1.3'
38
+ spec.add_development_dependency 'rubocop-rspec', '~> 2.2'
36
39
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tfctl
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Wasilczuk
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-14 00:00:00.000000000 Z
11
+ date: 2021-05-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-organizations
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.13'
19
+ version: '1.40'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.13'
26
+ version: '1.40'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: json_schemer
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -44,28 +44,34 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '1.17'
47
+ version: '1.19'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '1.17'
54
+ version: '1.19'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: terminal-table
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '1.8'
62
+ - - "<"
63
+ - !ruby/object:Gem::Version
64
+ version: '4.0'
62
65
  type: :runtime
63
66
  prerelease: false
64
67
  version_requirements: !ruby/object:Gem::Requirement
65
68
  requirements:
66
- - - "~>"
69
+ - - ">="
67
70
  - !ruby/object:Gem::Version
68
71
  version: '1.8'
72
+ - - "<"
73
+ - !ruby/object:Gem::Version
74
+ version: '4.0'
69
75
  - !ruby/object:Gem::Dependency
70
76
  name: guard-rspec
71
77
  requirement: !ruby/object:Gem::Requirement
@@ -86,28 +92,42 @@ dependencies:
86
92
  requirements:
87
93
  - - "~>"
88
94
  - !ruby/object:Gem::Version
89
- version: '3.8'
95
+ version: '3.9'
90
96
  type: :development
91
97
  prerelease: false
92
98
  version_requirements: !ruby/object:Gem::Requirement
93
99
  requirements:
94
100
  - - "~>"
95
101
  - !ruby/object:Gem::Version
96
- version: '3.8'
102
+ version: '3.9'
97
103
  - !ruby/object:Gem::Dependency
98
104
  name: rubocop
99
105
  requirement: !ruby/object:Gem::Requirement
100
106
  requirements:
101
107
  - - "~>"
102
108
  - !ruby/object:Gem::Version
103
- version: '0.76'
109
+ version: '1.3'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '1.3'
117
+ - !ruby/object:Gem::Dependency
118
+ name: rubocop-rspec
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: '2.2'
104
124
  type: :development
105
125
  prerelease: false
106
126
  version_requirements: !ruby/object:Gem::Requirement
107
127
  requirements:
108
128
  - - "~>"
109
129
  - !ruby/object:Gem::Version
110
- version: '0.76'
130
+ version: '2.2'
111
131
  description:
112
132
  email:
113
133
  - akw@scalefactory.com
@@ -116,6 +136,8 @@ executables:
116
136
  extensions: []
117
137
  extra_rdoc_files: []
118
138
  files:
139
+ - ".bundle/config"
140
+ - ".github/dependabot.yml"
119
141
  - ".gitignore"
120
142
  - ".rspec"
121
143
  - ".rubocop.yml"
@@ -126,6 +148,7 @@ files:
126
148
  - LICENSE
127
149
  - Makefile
128
150
  - README.adoc
151
+ - RELEASING.adoc
129
152
  - bin/tfctl
130
153
  - docs/configuration.adoc
131
154
  - docs/control_tower.adoc
@@ -135,12 +158,12 @@ files:
135
158
  - examples/bootstrap/terraform-exec-role.template
136
159
  - examples/bootstrap/terraform-state.template
137
160
  - examples/bootstrap/tfctl-org-access.template
138
- - examples/control_tower/conf/example.yaml
139
161
  - examples/control_tower/modules/s3-bucket/main.tf
140
162
  - examples/control_tower/modules/s3-bucket/variables.tf
141
163
  - examples/control_tower/profiles/example-profile/data.tf
142
164
  - examples/control_tower/profiles/example-profile/main.tf
143
165
  - examples/control_tower/profiles/example-profile/variables.tf
166
+ - examples/control_tower/tfctl.yaml
144
167
  - lib/hash.rb
145
168
  - lib/tfctl.rb
146
169
  - lib/tfctl/aws_org.rb
@@ -164,15 +187,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
164
187
  requirements:
165
188
  - - ">="
166
189
  - !ruby/object:Gem::Version
167
- version: '0'
190
+ version: 2.5.0
168
191
  required_rubygems_version: !ruby/object:Gem::Requirement
169
192
  requirements:
170
193
  - - ">="
171
194
  - !ruby/object:Gem::Version
172
195
  version: '0'
173
196
  requirements: []
174
- rubyforge_project:
175
- rubygems_version: 2.7.7
197
+ rubygems_version: 3.0.8
176
198
  signing_key:
177
199
  specification_version: 4
178
200
  summary: Terraform wrapper for managing multi-account AWS infrastructures