tfctl 1.1.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.bundle/config +3 -0
- data/.github/dependabot.yml +7 -0
- data/.github/workflows/linter.yml +14 -0
- data/.github/workflows/release.yml +37 -0
- data/.github/workflows/test.yml +23 -0
- data/.gitignore +0 -1
- data/.rubocop.yml +7 -2
- data/CHANGELOG.adoc +29 -0
- data/Makefile +4 -4
- data/README.adoc +51 -20
- data/RELEASING.adoc +13 -0
- data/bin/tfctl +4 -4
- data/docs/configuration.adoc +8 -6
- data/docs/control_tower.adoc +39 -21
- data/docs/iam_permissions.adoc +2 -2
- data/docs/project_layout.adoc +3 -3
- data/examples/control_tower/profiles/example-profile/main.tf +1 -1
- data/examples/control_tower/profiles/example-profile/variables.tf +1 -1
- data/examples/control_tower/tfctl.yaml +2 -2
- data/lib/hash.rb +2 -1
- data/lib/tfctl.rb +8 -8
- data/lib/tfctl/aws_org.rb +18 -16
- data/lib/tfctl/config.rb +4 -2
- data/lib/tfctl/executor.rb +1 -1
- data/lib/tfctl/generator.rb +12 -10
- data/lib/tfctl/logger.rb +1 -1
- data/lib/tfctl/schema.rb +1 -1
- data/lib/tfctl/version.rb +1 -1
- data/tfctl.gemspec +9 -6
- metadata +40 -16
- data/.travis.yml +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a7ca446d4435cb6780d2b8018e89c8f7b981a247d249ff3fe8083b94edd66ac
|
4
|
+
data.tar.gz: bc7f96ea1cb77fb6366453f4e268e55be5c398e939002f382223c94e09bccbf0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 777d4fd03430d1d54bcf822f3f4087c7e0c55374d69167487057201ef20132abe5de5c2b949cfa33aa1d48c346a9e0cd819db8193af5a8803dacb7d3988e526e
|
7
|
+
data.tar.gz: 5cc2a820f7930d930efc43c8eab98e9b825e6d1cf48390ca929f01b4136cdbd33509978a31e16f5f4956c458e007bc6dc759e86ee9305b4f14d21c77f267d8ab
|
data/.bundle/config
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
name: Release
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
tags:
|
6
|
+
- 'v*'
|
7
|
+
|
8
|
+
jobs:
|
9
|
+
publish:
|
10
|
+
name: Build + Publish
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
steps:
|
13
|
+
- uses: actions/checkout@v2
|
14
|
+
- name: Set up Ruby 2.6
|
15
|
+
uses: ruby/setup-ruby@v1
|
16
|
+
with:
|
17
|
+
ruby-version: 2.6
|
18
|
+
- name: Build gem
|
19
|
+
run: make pkg
|
20
|
+
- name: Publish to RubyGems
|
21
|
+
run: |
|
22
|
+
mkdir -p $HOME/.gem
|
23
|
+
touch $HOME/.gem/credentials
|
24
|
+
chmod 0600 $HOME/.gem/credentials
|
25
|
+
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
26
|
+
gem push pkg/*.gem
|
27
|
+
env:
|
28
|
+
GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
|
29
|
+
- name: Release on GitHub
|
30
|
+
uses: actions/create-release@v1
|
31
|
+
env:
|
32
|
+
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
33
|
+
with:
|
34
|
+
draft: false
|
35
|
+
prerelease: false
|
36
|
+
release_name: 'Release ${{ github.ref }}'
|
37
|
+
tag_name: '${{ github.ref }}'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
name: Tests
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ master ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ master ]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
rspec:
|
11
|
+
runs-on: ${{ matrix.os }}-latest
|
12
|
+
strategy:
|
13
|
+
fail-fast: false
|
14
|
+
matrix:
|
15
|
+
os: [ubuntu, macos]
|
16
|
+
ruby: [2.6, 2.7, 3.0]
|
17
|
+
continue-on-error: ${{ endsWith(matrix.ruby, 'head') || matrix.ruby == 'debug' }}
|
18
|
+
steps:
|
19
|
+
- uses: actions/checkout@v2
|
20
|
+
- uses: ruby/setup-ruby@v1
|
21
|
+
with:
|
22
|
+
ruby-version: ${{ matrix.ruby }}
|
23
|
+
- run: make spec
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
---
|
2
2
|
AllCops:
|
3
|
-
TargetRubyVersion: 2.
|
3
|
+
TargetRubyVersion: 2.5
|
4
4
|
DisplayCopNames: true
|
5
|
+
NewCops: enable
|
5
6
|
|
6
7
|
Layout/IndentationWidth:
|
7
8
|
Width: 4
|
@@ -45,7 +46,7 @@ Metrics/BlockLength:
|
|
45
46
|
Metrics/MethodLength:
|
46
47
|
Enabled: false
|
47
48
|
|
48
|
-
|
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/CHANGELOG.adoc
CHANGED
@@ -1,5 +1,34 @@
|
|
1
1
|
= Changelog
|
2
2
|
|
3
|
+
== 1.4.0
|
4
|
+
|
5
|
+
* feat: support yaml anchors and aliases in configuration file.
|
6
|
+
|
7
|
+
== 1.3.0
|
8
|
+
|
9
|
+
* feat: support new Terraform provider syntax
|
10
|
+
|
11
|
+
BREAKING CHANGE: The minimum supported Terraform version has been bumped to
|
12
|
+
0.12.29. If you are running an older version of Terraform you will need to
|
13
|
+
update to the latest Terraform in 0.12.x series before updating tfctl. Once
|
14
|
+
tfctl is updated you can upgrade Terraform to further versions.
|
15
|
+
|
16
|
+
== 1.2.2
|
17
|
+
* chore: reverted PR #11 - not necessary and introduced regression. See PR #13 for details.
|
18
|
+
|
19
|
+
== 1.2.1
|
20
|
+
* chore: added required Ruby version to Gemspec.
|
21
|
+
|
22
|
+
== 1.2.0
|
23
|
+
|
24
|
+
* feat: pass TF_ environment variables to terraform (PR #11).
|
25
|
+
|
26
|
+
== 1.1.1
|
27
|
+
|
28
|
+
* fix: handle empty response from Organizations API containing children (thanks @grothja)
|
29
|
+
* chore: stopped testing on EOL Rubies 2.3 and 2.4 (but should still currently work)
|
30
|
+
* chore: dependencies minimum version bump
|
31
|
+
|
3
32
|
== 1.1.0
|
4
33
|
|
5
34
|
* feat: look for configuration in `tfctl.yaml` by default.
|
data/Makefile
CHANGED
@@ -2,7 +2,8 @@
|
|
2
2
|
|
3
3
|
vendor:
|
4
4
|
$(info => Installing Ruby dependencies)
|
5
|
-
@bundle install
|
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
|
|
@@ -31,6 +32,5 @@ clean:
|
|
31
32
|
$(info => Cleaning)
|
32
33
|
@rm -rf pkg/
|
33
34
|
@rm -rf vendor/
|
34
|
-
@rm -rf .bundle
|
35
35
|
@rm -f Gemfile.lock
|
36
36
|
@rm -rf spec/reports/
|
data/README.adoc
CHANGED
@@ -20,7 +20,7 @@ endif::[]
|
|
20
20
|
|
21
21
|
= tfctl
|
22
22
|
|
23
|
-
image:https://travis-ci.
|
23
|
+
image:https://travis-ci.com/scalefactory/tfctl.svg?branch=master["Build Status", link="https://travis-ci.com/scalefactory/tfctl"]
|
24
24
|
image:https://badge.fury.io/rb/tfctl.svg["Gem Version", link="https://badge.fury.io/rb/tfctl"]
|
25
25
|
image:https://img.shields.io/badge/terraform-0.12-blue.svg["Terraform 0.12", link="https://img.shields.io/badge/terraform-0.12-blue"]
|
26
26
|
|
@@ -28,19 +28,37 @@ toc::[]
|
|
28
28
|
|
29
29
|
== Overview
|
30
30
|
|
31
|
-
|
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
|
37
|
+
accounts. It supports hierarchies of nested Organizational Units (OUs),
|
38
|
+
and helps keep your Terraform DRY.
|
38
39
|
|
39
|
-
|
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.
|
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
|
-
==
|
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,11 +105,12 @@ make install
|
|
85
105
|
|
86
106
|
== Running tfctl
|
87
107
|
|
88
|
-
|
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
|
----
|
@@ -102,7 +123,7 @@ tfctl -c CONFIG_FILE TARGET_OPTIONS -- TERRAFORM_COMMAND
|
|
102
123
|
options. See https://www.terraform.io/docs/commands/index.html[Terraform
|
103
124
|
commands] for details.
|
104
125
|
|
105
|
-
NOTE: You must have your AWS credentials configured before
|
126
|
+
NOTE: You must have your AWS credentials configured before you run `tfctl`, or run
|
106
127
|
it using an AWS credentials helper such as
|
107
128
|
https://github.com/99designs/aws-vault[aws-vault].
|
108
129
|
|
@@ -110,18 +131,21 @@ https://github.com/99designs/aws-vault[aws-vault].
|
|
110
131
|
|
111
132
|
Show help:
|
112
133
|
|
134
|
+
[source,shell]
|
113
135
|
----
|
114
136
|
tfctl -h
|
115
137
|
----
|
116
138
|
|
117
139
|
Show merged configuration:
|
118
140
|
|
141
|
+
[source,shell]
|
119
142
|
----
|
120
143
|
tfctl -s
|
121
144
|
----
|
122
145
|
|
123
146
|
List all discovered accounts:
|
124
147
|
|
148
|
+
[source,shell]
|
125
149
|
----
|
126
150
|
tfctl --all -l
|
127
151
|
----
|
@@ -129,49 +153,56 @@ tfctl --all -l
|
|
129
153
|
TIP: This can be narrowed down using targeting options and is a good way to
|
130
154
|
test what accounts match.
|
131
155
|
|
132
|
-
Run
|
156
|
+
Run `terraform init` across all accounts:
|
133
157
|
|
158
|
+
[source,shell]
|
134
159
|
----
|
135
160
|
tfctl --all -- init
|
136
161
|
----
|
137
162
|
|
138
|
-
|
163
|
+
Plan Terraform across all accounts in the `test` OU:
|
139
164
|
|
165
|
+
[source,shell]
|
140
166
|
----
|
141
167
|
tfctl -o test -- plan
|
142
168
|
----
|
143
169
|
|
144
|
-
|
170
|
+
Plan Terraform in `live` accounts, assuming that `live` is a child OU in multiple
|
145
171
|
organization units:
|
146
172
|
|
173
|
+
[source,shell]
|
147
174
|
----
|
148
175
|
tfctl -o '.*/live' -- plan
|
149
176
|
----
|
150
177
|
|
151
|
-
Run plan
|
178
|
+
Run a plan for an individual account:
|
152
179
|
|
180
|
+
[source,shell]
|
153
181
|
----
|
154
182
|
tfctl -a example-account - plan
|
155
183
|
----
|
156
184
|
|
157
|
-
|
185
|
+
Apply Terraform changes across all accounts:
|
158
186
|
|
187
|
+
[source,shell]
|
159
188
|
----
|
160
189
|
tfctl --all -- apply
|
161
190
|
----
|
162
191
|
|
163
|
-
|
192
|
+
Destroy Terraform-managed resources in all the `test` OU accounts:
|
164
193
|
|
194
|
+
[source,shell]
|
165
195
|
----
|
166
196
|
tfctl -o test -- destroy -auto-approve
|
167
197
|
----
|
168
198
|
|
169
199
|
Don't buffer the output:
|
170
200
|
|
201
|
+
[source,shell]
|
171
202
|
----
|
172
203
|
tfctl -a example-account -u -- plan
|
173
204
|
----
|
174
205
|
|
175
206
|
This will show output in real time. Usually output is buffered and displayed
|
176
|
-
after Terraform command finishes to make it more readable when running
|
177
|
-
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__)
|
4
|
+
if File.directory?("#{File.dirname(__FILE__)}/../vendor")
|
5
5
|
require 'bundler/setup'
|
6
6
|
end
|
7
7
|
require 'optparse'
|
@@ -81,8 +81,8 @@ begin
|
|
81
81
|
targetting_opts = %i[account ou all]
|
82
82
|
targets_set = []
|
83
83
|
options.each do |k, v|
|
84
|
-
if targetting_opts.include?(k)
|
85
|
-
targets_set << k.to_s
|
84
|
+
if targetting_opts.include?(k) and !v.nil?
|
85
|
+
targets_set << k.to_s
|
86
86
|
end
|
87
87
|
end
|
88
88
|
if targets_set.length > 1
|
@@ -146,7 +146,7 @@ begin
|
|
146
146
|
|
147
147
|
log.info 'Working out AWS account topology'
|
148
148
|
|
149
|
-
yaml_config = YAML.safe_load(File.read(options[:config_file]))
|
149
|
+
yaml_config = YAML.safe_load(File.read(options[:config_file]), aliases: true)
|
150
150
|
Tfctl::Schema.validate(yaml_config)
|
151
151
|
yaml_config.symbolize_names!
|
152
152
|
|
data/docs/configuration.adoc
CHANGED
@@ -24,8 +24,8 @@ toc::[]
|
|
24
24
|
|
25
25
|
== Overview
|
26
26
|
|
27
|
-
|
28
|
-
it with configuration specified in
|
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
|
|
@@ -83,14 +83,16 @@ above.
|
|
83
83
|
|
84
84
|
== Handling secrets
|
85
85
|
|
86
|
-
|
87
|
-
|
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].
|
90
92
|
|
91
93
|
== Configuration Schema
|
92
94
|
|
93
|
-
|
95
|
+
The configuration file is validated using https://json-schema.org/[JSON Schema].
|
94
96
|
|
95
97
|
The schema is defined in
|
96
98
|
https://github.com/scalefactory/tfctl/blob/master/lib/tfctl/schema.rb[lib/tfctl/schema.rb]
|
data/docs/control_tower.adoc
CHANGED
@@ -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
|
-
*
|
54
|
-
*
|
55
|
-
*
|
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
|
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
|
-
|
93
|
-
export
|
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
|
116
|
+
ParameterKey=TerraformStateBucket,ParameterValue="${STATE_BUCKET_NAME}"
|
111
117
|
----
|
112
118
|
|
113
|
-
Create a stack set instance in
|
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
|
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
|
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
|
----
|
@@ -158,7 +168,7 @@ You need to modify the following parameters:
|
|
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
|
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
186
|
tfctl -s
|
176
187
|
----
|
177
188
|
|
178
|
-
This will not make any changes but will print out
|
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
|
193
|
+
Initialise Terraform for all discovered accounts:
|
183
194
|
|
195
|
+
[source,shell]
|
184
196
|
----
|
185
197
|
tfctl --all -- init
|
186
198
|
----
|
187
199
|
|
188
200
|
Tfctl will run Terraform against all accounts in parallel.
|
189
201
|
|
190
|
-
|
202
|
+
`plan` the Terraform:
|
191
203
|
|
204
|
+
[source,shell]
|
192
205
|
----
|
193
206
|
tfctl --all -- plan
|
194
207
|
----
|
195
208
|
|
196
|
-
and apply:
|
209
|
+
and `apply` it:
|
197
210
|
|
211
|
+
[source,shell]
|
198
212
|
----
|
199
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
223
|
tfctl --all -- destroy -auto-approve
|
206
224
|
----
|
207
225
|
|
208
|
-
That's it! You can now execute
|
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.
|
data/docs/iam_permissions.adoc
CHANGED
@@ -20,7 +20,7 @@ endif::[]
|
|
20
20
|
|
21
21
|
= IAM roles
|
22
22
|
|
23
|
-
|
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.
|
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
|
data/docs/project_layout.adoc
CHANGED
@@ -50,12 +50,12 @@ The configuration data is exposed to terraform via a profile `config` variable.
|
|
50
50
|
It also defines Terraform and tfctl configuration such as state tracking and
|
51
51
|
what IAM roles to use.
|
52
52
|
|
53
|
-
By default tfctl will use `tfctl.yaml` in
|
53
|
+
By default, tfctl will use `tfctl.yaml` in its current working directory. You
|
54
54
|
can specify a different file using `-c`. Multiple configurations are supported
|
55
55
|
in the same project directory and generated data will be stored separately for
|
56
56
|
each config file in `.tfctl/`.
|
57
57
|
|
58
|
-
== profiles
|
58
|
+
== `profiles`
|
59
59
|
|
60
60
|
Profiles are re-usable collections of resources which can be applied to
|
61
61
|
accounts. They are implemented just like usual modules but provide an
|
@@ -64,6 +64,6 @@ other data sources). Profiles often compose multiple modules and provide
|
|
64
64
|
configuration data to them. This approach makes it possible to re-use standard
|
65
65
|
modules (e.g. Terraform module registry).
|
66
66
|
|
67
|
-
== modules
|
67
|
+
== `modules`
|
68
68
|
|
69
69
|
Standard Terraform modules.
|
@@ -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
|
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/
|
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.
|
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
|
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
|
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
|
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
|
-
).
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
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
|
-
|
89
|
+
ou_name = parent_name == :root ? ou.name.to_sym : "#{parent_name}/#{ou.name}".to_sym
|
89
90
|
|
90
|
-
|
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
|
4
|
-
require_relative 'error
|
3
|
+
require_relative '../hash'
|
4
|
+
require_relative 'error'
|
5
5
|
require 'yaml'
|
6
6
|
require 'json'
|
7
7
|
|
@@ -121,7 +121,9 @@ module Tfctl
|
|
121
121
|
return config unless config.key?(:exclude_accounts)
|
122
122
|
|
123
123
|
config[:accounts].each_with_index do |account, idx|
|
124
|
+
# rubocop:disable Style/IfWithBooleanLiteralBranches
|
124
125
|
config[:accounts][idx][:excluded] = config[:exclude_accounts].include?(account[:name]) ? true : false
|
126
|
+
# rubocop:enable Style/IfWithBooleanLiteralBranches
|
125
127
|
end
|
126
128
|
|
127
129
|
config
|
data/lib/tfctl/executor.rb
CHANGED
data/lib/tfctl/generator.rb
CHANGED
@@ -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)
|
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.
|
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'
|
27
|
-
'
|
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'
|
75
|
-
'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
data/lib/tfctl/schema.rb
CHANGED
data/lib/tfctl/version.rb
CHANGED
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.
|
30
|
+
spec.add_dependency 'aws-sdk-organizations', '~> 1.40'
|
29
31
|
spec.add_dependency 'json_schemer', '~> 0.2'
|
30
|
-
spec.add_dependency 'parallel', '~> 1.
|
31
|
-
spec.add_dependency 'terminal-table', '
|
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',
|
34
|
-
spec.add_development_dependency 'rspec',
|
35
|
-
spec.add_development_dependency 'rubocop',
|
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.
|
4
|
+
version: 1.4.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:
|
11
|
+
date: 2021-06-23 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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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: '
|
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: '
|
130
|
+
version: '2.2'
|
111
131
|
description:
|
112
132
|
email:
|
113
133
|
- akw@scalefactory.com
|
@@ -116,16 +136,21 @@ executables:
|
|
116
136
|
extensions: []
|
117
137
|
extra_rdoc_files: []
|
118
138
|
files:
|
139
|
+
- ".bundle/config"
|
140
|
+
- ".github/dependabot.yml"
|
141
|
+
- ".github/workflows/linter.yml"
|
142
|
+
- ".github/workflows/release.yml"
|
143
|
+
- ".github/workflows/test.yml"
|
119
144
|
- ".gitignore"
|
120
145
|
- ".rspec"
|
121
146
|
- ".rubocop.yml"
|
122
|
-
- ".travis.yml"
|
123
147
|
- CHANGELOG.adoc
|
124
148
|
- Gemfile
|
125
149
|
- Guardfile
|
126
150
|
- LICENSE
|
127
151
|
- Makefile
|
128
152
|
- README.adoc
|
153
|
+
- RELEASING.adoc
|
129
154
|
- bin/tfctl
|
130
155
|
- docs/configuration.adoc
|
131
156
|
- docs/control_tower.adoc
|
@@ -164,15 +189,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
164
189
|
requirements:
|
165
190
|
- - ">="
|
166
191
|
- !ruby/object:Gem::Version
|
167
|
-
version:
|
192
|
+
version: 2.5.0
|
168
193
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
169
194
|
requirements:
|
170
195
|
- - ">="
|
171
196
|
- !ruby/object:Gem::Version
|
172
197
|
version: '0'
|
173
198
|
requirements: []
|
174
|
-
|
175
|
-
rubygems_version: 2.7.7
|
199
|
+
rubygems_version: 3.0.3.1
|
176
200
|
signing_key:
|
177
201
|
specification_version: 4
|
178
202
|
summary: Terraform wrapper for managing multi-account AWS infrastructures
|
data/.travis.yml
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
rvm:
|
2
|
-
- 2.3
|
3
|
-
- 2.6
|
4
|
-
os: linux
|
5
|
-
language: ruby
|
6
|
-
script: make test
|
7
|
-
jobs:
|
8
|
-
include:
|
9
|
-
- stage: Gem release
|
10
|
-
rvm: 2.6
|
11
|
-
deploy:
|
12
|
-
provider: rubygems
|
13
|
-
api_key:
|
14
|
-
secure: LAVcdER+LtQ2TSUrVOY7Be1BC7GXJRD0QBt386vRM5Nld5QaD9Ow9gtN6FprzkzloI4R8BkPWqZbAT6YjC+C0AFB5HK6iPwD2bLsiF9w3ccDD+yrW99RHxiErpmYMun2PqZv0WkJ/pkEplPCKMRFv7SM7W9DMRlU7dsXc1v6IVyIb5u3A04jErS2jXXKY0ijlCDJYVo8zzYL6yUmUcXhc//3CIVnu2Miu6Qr8h7e6jMXNUWfMkwEXsFP9id4TsCz7hRY+39PkiBAknHTN5UqjjJiEOknZnHeTBcVPvi2h2xv+fFLSzVTxlxaRsVoMCShQp5D12qzhQObRJsRVQFs8Yyg9IYMyPdxssFYyUZFaAy5taWDm57uM3HTHylm/Dq3LmXTgGNxWUUkf2oh1g7R6cYZpBUQwiEPzhZQ7CoBQbGUAJmH9ZU9m+cr8kuAOUipd6BNEDvn/fIH4WJsRCNP72JGX16JBpuICvpkuNhskZT91xFlYk1pTXHOxNpbTcxUTgMHhrTqspeRXPmf6DiYGvjMb2S6kaoGqCIRIcwl0TGKuMsOMqR9SqF8gubkqHMVbSl1E7mwBn4ke8/7IGoMkWOGwUpVxqVOLBHi6zSR09RTVSbKl4oiFV3ZwmVPSxDncq54MptyJ2WCZ7dD6ht2l+VA8iGwYeIoqOpwGWxyuNI=
|
15
|
-
gem: tfctl
|
16
|
-
on:
|
17
|
-
tags: true
|
18
|
-
repo: scalefactory/tfctl
|