tfctl 0.2.0 → 1.2.1

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.
@@ -1,17 +1,37 @@
1
- :toc:
2
-
3
- == Control Tower integration guide
1
+ // Settings:
2
+ :idprefix:
3
+ :idseparator: -
4
+ ifndef::env-github[:icons: font]
5
+ ifdef::env-github,env-browser[]
6
+ :toc: macro
7
+ :toclevels: 1
8
+ endif::[]
9
+ ifdef::env-github[]
10
+ :branch: master
11
+ :status:
12
+ :outfilesuffix: .adoc
13
+ :!toc-title:
14
+ :caution-caption: :fire:
15
+ :important-caption: :exclamation:
16
+ :note-caption: :paperclip:
17
+ :tip-caption: :bulb:
18
+ :warning-caption: :warning:
19
+ endif::[]
20
+
21
+ = Control Tower integration guide
4
22
 
5
23
  This guide will help you integrate Terraform with AWS Control Tower using the
6
24
  tfctl wrapper. This involves setting up resources for remote state tracking,
7
25
  necessary IAM roles and a tfctl project.
8
26
 
9
- === Overview
27
+ toc::[]
28
+
29
+ == Overview
10
30
 
11
31
  For state tracking we're going to create a dedicated `shared-services` account
12
32
  under a `mgmt` organization unit. We'll use S3 for state storage and DynamoDB
13
33
  for locking. `TerraformState` IAM role will be created for cross account
14
- access to state resources from the primary account.
34
+ access to state resources from the primary AWS account.
15
35
 
16
36
  In the primary account we'll create a `TfctlOrgAccess` role. It gives tfctl
17
37
  read only access to AWS Organizations which is used to discover accounts and
@@ -26,16 +46,17 @@ account factory and can be assumed from the primary account.
26
46
  We're going to create a `live` and `test` organization units in Control Tower
27
47
  and provision a couple of accounts for testing.
28
48
 
29
- === Prerequisites
49
+ == Prerequisites
30
50
 
31
51
  Before starting you'll need:
32
52
 
33
- * Control Tower set up in your primary account.
34
- * A user with `AdministratorAccess` privileges in primary account.
35
- * 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.
36
57
  * Terraform 0.12 or higher.
37
58
 
38
- === Configure Control Tower
59
+ == Configure Control Tower
39
60
 
40
61
  Create the following organization units in Control Tower:
41
62
 
@@ -52,30 +73,35 @@ Then provision accounts:
52
73
  NOTE: Control Tower accounts need to be provisioned one at a time. It takes
53
74
  approximately 20 mins to provision one.
54
75
 
55
- === Install tfctl
76
+ == Install tfctl
56
77
 
78
+ [source,shell]
57
79
  ----
58
80
  git clone git@github.com:scalefactory/tfctl.git
59
81
  cd tfctl/ && sudo make install
60
82
  ----
61
83
 
62
- === Set up AWS resources
84
+ == Set up AWS resources
63
85
 
64
86
  It's assumed you have configured AWS CLI access to the primary account.
65
87
 
66
88
  We'll use CloudFormation templates in `examples/bootstrap/`.
67
89
 
68
- First export configuration using environment variables making sure to change to
69
- values to suit your set up:
90
+ First export configuration using environment variables, making sure to change to
91
+ values to suit your setup:
70
92
 
93
+ [source,shell]
71
94
  ----
72
- export PRIMARY_ACCOUNT_ID=11111111
73
- 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
74
98
  export STATE_BUCKET_NAME='example-terraform-state'
99
+ export AWS_REGION=eu-west-1
75
100
  ----
76
101
 
77
102
  Create the remote state resources stack set:
78
103
 
104
+ [source,shell]
79
105
  ----
80
106
  cd examples/bootstrap/
81
107
 
@@ -87,31 +113,34 @@ aws cloudformation create-stack-set \
87
113
  --execution-role-name AWSControlTowerExecution \
88
114
  --administration-role-arn arn:aws:iam::${PRIMARY_ACCOUNT_ID}:role/service-role/AWSControlTowerStackSetRole \
89
115
  --parameters ParameterKey=PrimaryAccountId,ParameterValue=${PRIMARY_ACCOUNT_ID} \
90
- ParameterKey=TerraformStateBucket,ParameterValue=${STATE_BUCKET_NAME}
116
+ ParameterKey=TerraformStateBucket,ParameterValue="${STATE_BUCKET_NAME}"
91
117
  ----
92
118
 
93
- Create a stack set instance in you shared services account:
119
+ Create a stack set instance in your shared services account:
94
120
 
121
+ [source,shell]
95
122
  ----
96
123
  aws cloudformation create-stack-instances \
97
124
  --stack-set-name TerraformState \
98
125
  --accounts ${SHARED_SERVICES_ACCOUNT_ID} \
99
- --regions eu-west-1
126
+ --regions ${AWS_REGION}
100
127
  ----
101
128
 
102
129
  Check status:
103
130
 
131
+ [source,shell]
104
132
  ----
105
133
  aws cloudformation describe-stack-instance \
106
134
  --stack-set-name TerraformState \
107
135
  --stack-instance-account ${SHARED_SERVICES_ACCOUNT_ID} \
108
- --stack-instance-region eu-west-1
136
+ --stack-instance-region ${AWS_REGION}
109
137
  ----
110
138
 
111
139
  NOTE: Initial status will be `OUTDATED`, it should change to `CURRENT` once deployed.
112
140
 
113
- Deploy `TfctlOrgAccess` IAM role stack:
141
+ Deploy the `TfctlOrgAccess` IAM role stack:
114
142
 
143
+ [source,shell]
115
144
  ----
116
145
  aws cloudformation create-stack \
117
146
  --stack-name TfctlOrgAccess \
@@ -122,70 +151,79 @@ aws cloudformation create-stack \
122
151
 
123
152
  Check status:
124
153
 
154
+ [source,shell]
125
155
  ----
126
156
  aws cloudformation describe-stacks --stack-name TfctlOrgAccess
127
157
  ----
128
158
 
129
159
  NOTE: Successful status should read: `CREATE_COMPLETE`.
130
160
 
131
- === Configure tfctl
161
+ == Configure tfctl
132
162
 
133
163
  Copy the example project directory `examples/control_tower` somewhere convenient
134
- and edit `conf/example.yaml`.
164
+ and edit `tfctl.yaml`.
135
165
 
136
166
  You need to modify the following parameters:
137
167
 
138
168
  * `tf_state_bucket` - set to `$STATE_BUCKET_NAME`
139
169
  * `tf_state_role_arn` - set shared services account ID
140
170
  * `tfctl_role_arn` - set primary account ID
141
- * `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.
142
172
 
143
173
  TIP: You should keep your project directory under version control.
144
174
 
145
- === Deploy example tfctl profile
175
+ == Deploy example tfctl profile
146
176
 
147
177
  The example profile will create an S3 bucket in accounts under `test`, `live`
148
178
  and `mgmt` OUs.
149
179
 
150
180
  NOTE: Run tfctl commands from the root of you project directory.
151
181
 
152
- First dump the configuration to verify everything works:
182
+ First, dump the configuration to verify everything works:
153
183
 
184
+ [source,shell]
154
185
  ----
155
- tfctl -c conf/example.yaml -s
186
+ tfctl -s
156
187
  ----
157
188
 
158
- 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,
159
190
  merged configuration data. It should contain a list of discovered accounts and
160
191
  their configuration.
161
192
 
162
- Initialise terraform for all discovered accounts:
193
+ Initialise Terraform for all discovered accounts:
163
194
 
195
+ [source,shell]
164
196
  ----
165
- tfctl -c conf/example.yaml --all -- init
197
+ tfctl --all -- init
166
198
  ----
167
199
 
168
200
  Tfctl will run Terraform against all accounts in parallel.
169
201
 
170
- Run plan:
202
+ `plan` the Terraform:
171
203
 
204
+ [source,shell]
172
205
  ----
173
- tfctl -c conf/example.yaml --all -- plan
206
+ tfctl --all -- plan
174
207
  ----
175
208
 
176
- and apply:
209
+ and `apply` it:
177
210
 
211
+ [source,shell]
178
212
  ----
179
- tfctl -c conf/example.yaml --all -- apply
213
+ tfctl --all -- apply
180
214
  ----
181
215
 
182
- To destroy created resources run:
183
216
 
217
+ == Clean up
218
+
219
+ To destroy created resources, run:
220
+
221
+ [source,shell]
184
222
  ----
185
- tfctl -c conf/example.yaml --all -- destroy -auto-approve
223
+ tfctl --all -- destroy -auto-approve
186
224
  ----
187
225
 
188
- 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.
189
227
 
190
228
  TIP: Your project directory should be under version control excluding the
191
229
  `.tfctl` directory which is automatically generated.
@@ -1,9 +1,31 @@
1
- == Creating and deploying a tfctl profile
1
+ // Settings:
2
+ :idprefix:
3
+ :idseparator: -
4
+ ifndef::env-github[:icons: font]
5
+ ifdef::env-github,env-browser[]
6
+ :toc: macro
7
+ :toclevels: 1
8
+ endif::[]
9
+ ifdef::env-github[]
10
+ :branch: master
11
+ :status:
12
+ :outfilesuffix: .adoc
13
+ :!toc-title:
14
+ :caution-caption: :fire:
15
+ :important-caption: :exclamation:
16
+ :note-caption: :paperclip:
17
+ :tip-caption: :bulb:
18
+ :warning-caption: :warning:
19
+ endif::[]
20
+
21
+ = Creating and deploying a tfctl profile
2
22
 
3
23
  This guide will show you how to create a tfctl profile, declare some resources
4
24
  in it and deploy it to to a group of accounts in an organization unit.
5
25
 
6
- === Create a new profile
26
+ toc::[]
27
+
28
+ == Create a new profile
7
29
 
8
30
  In your tfctl project directory create a new profile:
9
31
 
@@ -59,7 +81,7 @@ profile. Tfctl configuration can be accessed using this variable. This It
59
81
  includes an array of all discovered accounts as well their parameters from
60
82
  tfctl config file.
61
83
 
62
- 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
63
85
  yaml format. This exact data is available in the `config` variable in your
64
86
  profile.
65
87
 
@@ -87,7 +109,7 @@ resource "aws_s3_bucket" "example" {
87
109
  This will create an S3 bucket with a name containing the current account name
88
110
  (which will vary depending on which account it's deployed to).
89
111
 
90
- === Assign profile to accounts
112
+ == Assign profile to accounts
91
113
 
92
114
  Before you can deploy the new profile you need to tell `tfctl` which accounts
93
115
  to deploy it to.
@@ -102,7 +124,7 @@ You have few options here:
102
124
  For the sake of this example we're going to deploy our bucket to all accounts
103
125
  in `test` OU.
104
126
 
105
- In tfctl config file add the profile to the `test` OU:
127
+ In `tfctl.yaml` add the profile to the `test` OU:
106
128
 
107
129
  [source, yaml]
108
130
  ----
@@ -113,13 +135,13 @@ organization_units:
113
135
  ----
114
136
 
115
137
 
116
- === Plan
138
+ == Plan
117
139
 
118
140
  To see what would happen when the change is applied run:
119
141
 
120
142
  ----
121
- tfctl -c conf/example.yaml -o test -- init
122
- tfctl -c conf/example.yaml -o test -- plan
143
+ tfctl -o test -- init
144
+ tfctl -o test -- plan
123
145
  ----
124
146
 
125
147
  This will run `terraform init` to initialise terraform and then `terraform
@@ -161,9 +183,9 @@ what went wrong.
161
183
  tfctl will generate a plan file automatically and use it with `apply` in the
162
184
  next step.
163
185
 
164
- === Apply
186
+ == Apply
165
187
 
166
188
  Once you're happy with the plan, apply it.
167
189
  ----
168
- tfctl -c conf/example.yaml -o test -- apply
190
+ tfctl -o test -- apply
169
191
  ----
@@ -1,6 +1,26 @@
1
- == IAM roles
1
+ // Settings:
2
+ :idprefix:
3
+ :idseparator: -
4
+ ifndef::env-github[:icons: font]
5
+ ifdef::env-github,env-browser[]
6
+ :toc: macro
7
+ :toclevels: 1
8
+ endif::[]
9
+ ifdef::env-github[]
10
+ :branch: master
11
+ :status:
12
+ :outfilesuffix: .adoc
13
+ :!toc-title:
14
+ :caution-caption: :fire:
15
+ :important-caption: :exclamation:
16
+ :note-caption: :paperclip:
17
+ :tip-caption: :bulb:
18
+ :warning-caption: :warning:
19
+ endif::[]
2
20
 
3
- Tfctl usually requires three IAM roles to be configured:
21
+ = IAM roles
22
+
23
+ `tfctl` usually requires three IAM roles to be configured:
4
24
 
5
25
  * `TfctlRole` - read only access to AWS Organizations set up in the primary account.
6
26
  * `TerraformStateRole` - access to remote state resources (S3, DynamoDB) in the
@@ -8,7 +28,7 @@ Tfctl usually requires three IAM roles to be configured:
8
28
  * `TerraformExecutionRole` - configured in all spoke accounts and used for executing Terraform.
9
29
 
10
30
  The user executing tfctl needs permission to assume all three roles cross
11
- account. Tfctl will assume roles automatically for you.
31
+ account. Once these are configured, tfctl automatically assumes roles for you.
12
32
 
13
33
  It's possible to configure different Terraform execution roles in different
14
34
  spoke accounts based on OU or account names. This can be used to restrict
@@ -1,10 +1,29 @@
1
- == Project layout
1
+ // Settings:
2
+ :idprefix:
3
+ :idseparator: -
4
+ ifndef::env-github[:icons: font]
5
+ ifdef::env-github,env-browser[]
6
+ :toc: macro
7
+ :toclevels: 1
8
+ endif::[]
9
+ ifdef::env-github[]
10
+ :branch: master
11
+ :status:
12
+ :outfilesuffix: .adoc
13
+ :!toc-title:
14
+ :caution-caption: :fire:
15
+ :important-caption: :exclamation:
16
+ :note-caption: :paperclip:
17
+ :tip-caption: :bulb:
18
+ :warning-caption: :warning:
19
+ endif::[]
20
+
21
+ = Project layout
2
22
 
3
23
  Example project structure
4
24
  ----
5
25
  project_dir/
6
- ├── conf
7
- │   └── example.yaml
26
+ ├── tfctl.conf
8
27
  ├── modules
9
28
  │   └── s3-bucket
10
29
  │   ├── main.tf
@@ -16,7 +35,9 @@ project_dir/
16
35
  └── variables.tf
17
36
  ----
18
37
 
19
- === tfctl configuration file
38
+ toc::[]
39
+
40
+ == tfctl configuration file
20
41
 
21
42
  Assigns Terraform profiles and configuration to accounts based on:
22
43
 
@@ -29,7 +50,12 @@ The configuration data is exposed to terraform via a profile `config` variable.
29
50
  It also defines Terraform and tfctl configuration such as state tracking and
30
51
  what IAM roles to use.
31
52
 
32
- === 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`
33
59
 
34
60
  Profiles are re-usable collections of resources which can be applied to
35
61
  accounts. They are implemented just like usual modules but provide an
@@ -38,6 +64,6 @@ other data sources). Profiles often compose multiple modules and provide
38
64
  configuration data to them. This approach makes it possible to re-use standard
39
65
  modules (e.g. Terraform module registry).
40
66
 
41
- === modules
67
+ == `modules`
42
68
 
43
69
  Standard Terraform modules.
@@ -12,8 +12,6 @@
12
12
  # Terraform configuration
13
13
  #
14
14
 
15
- # State management
16
-
17
15
  tf_state_bucket: 'CHANGEME'
18
16
  tf_state_dynamodb_table: 'terraform-lock'
19
17
  tf_state_region: 'eu-west-1'
@@ -26,47 +24,57 @@ aws_provider_version: '>= 2.14'
26
24
  tfctl_role_arn: 'arn:aws:iam::PRIMARY_ACCOUNT_ID:role/TfctlRole'
27
25
 
28
26
  #
29
- # Organization configuration
27
+ # Data
28
+ #
29
+ # Here you can add arbitrary data which will be accessible from Terraform
30
+ # profiles. Data can also be defined per account in the organization sections
31
+ # below.
30
32
  #
33
+ # data:
34
+ # my_parameter: some_value
31
35
 
36
+ #
37
+ # Organization configuration
38
+ #
39
+ # Assign resources and data to accounts based on the organization structure.
40
+ #
32
41
  # IMPORTANT: Removing a Terraform profile here will remove all of it's
33
- # associated resources in AWS!
34
-
35
- # Name of the primary account.
36
- primary_account: CHANGEME
42
+ # associated resources during next apply!
37
43
 
38
- # Configuration to apply in all accounts
44
+ # Configuration to apply to all accounts
39
45
  organization_root:
40
-
41
46
  # Role assumed by Terraform for execution in each account
42
47
  tf_execution_role: 'AWSControlTowerExecution'
43
48
  region: 'eu-west-1'
44
- # Bucket name used by example profile it will be prefixed with the target
45
- # account number for uniqueness across accounts.
46
- example_bucket_name: 'tfctl-example-bucket'
49
+ data:
50
+ # Bucket name used by example profile it will be prefixed with the target
51
+ # account number for uniqueness across accounts.
52
+ example_bucket_name: 'tfctl-example-bucket'
47
53
  # Assign example-profile to all accounts in managed OUs
48
54
  profiles:
49
55
  - example-profile
50
56
 
51
57
  # Configuration to apply to accounts in Organization Units
52
- # Units not listed here will be ignored
58
+ # OU's not listed here will be ignored.
53
59
  organization_units:
54
- # Uncomment if you want to include Core OU accounts
55
- # Core: {}
60
+ # Core: {} # Uncomment if you want to include Core OU accounts
56
61
  live: {}
57
62
  test: {}
58
63
  mgmt:
59
- # Override the example bucket name in mgmt OU accounts
60
- example_bucket_name: 'tfctl-ou-override-example'
64
+ data:
65
+ # Override the example bucket name in mgmt OU accounts
66
+ example_bucket_name: 'tfctl-ou-override-example'
61
67
 
62
68
  # Configuration to apply to individual accounts
63
69
  account_overrides:
64
70
  test-example1:
65
- # Override the bucket name in a specific account
66
- example_bucket_name: 'tfctl-account-override-example'
71
+ data:
72
+ # Override the bucket name in a specific account
73
+ example_bucket_name: 'tfctl-account-override-example'
67
74
 
68
75
 
69
- # Exclude individual accounts from Terraform runs.
70
- #exclude_accounts:
71
- # - Audit
72
- # - 'Log archive'
76
+ # Exclude individual accounts from Terraform runs
77
+ #
78
+ # exclude_accounts:
79
+ # - Audit
80
+ # - 'Log archive'