Skip to content

Latest commit

 

History

History
229 lines (167 loc) · 5.99 KB

control_tower.adoc

File metadata and controls

229 lines (167 loc) · 5.99 KB

Control Tower integration guide

This guide will help you integrate Terraform with AWS Control Tower using the tfctl wrapper. This involves setting up resources for remote state tracking, necessary IAM roles and a tfctl project.

Overview

For state tracking we’re going to create a dedicated shared-services account under a mgmt organization unit. We’ll use S3 for state storage and DynamoDB for locking. TerraformState IAM role will be created for cross account access to state resources from the primary AWS account.

In the primary account we’ll create a TfctlOrgAccess role. It gives tfctl read only access to AWS Organizations which is used to discover accounts and the organization unit structure.

We’ll use CloudFormation stacks and stack-sets to bootstrap these resources.

For executing Terraform in spoke accounts we’ll use the AWSControlTowerExecution role which is automatically created by Control Tower account factory and can be assumed from the primary account.

We’re going to create a live and test organization units in Control Tower and provision a couple of accounts for testing.

Prerequisites

Before starting you’ll need:

  • An AWS account that is part of an Organization.

  • Control Tower set up in your primary AWS account.

  • A user with AdministratorAccess privileges in your primary AWS account.

  • AWS CLI tools installed on your local machine.

  • Terraform 0.12 or higher.

Configure Control Tower

Create the following organization units in Control Tower:

  • mgmt

  • live

  • test

Then provision accounts:

  • In mgmt OU create an account called mgmt-shared-services

  • In live create live-example1

  • In test create test-example1

📎
Control Tower accounts need to be provisioned one at a time. It takes approximately 20 mins to provision one.

Install tfctl

git clone git@github.com:scalefactory/tfctl.git
cd tfctl/ && sudo make install

Set up AWS resources

It’s assumed you have configured AWS CLI access to the primary account.

We’ll use CloudFormation templates in examples/bootstrap/.

First export configuration using environment variables, making sure to change to values to suit your setup:

# Change these to match your setup
export PRIMARY_ACCOUNT_ID=123456789012
export SHARED_SERVICES_ACCOUNT_ID=345678901234
export STATE_BUCKET_NAME='example-terraform-state'
export AWS_REGION=eu-west-1

Create the remote state resources stack set:

cd examples/bootstrap/

aws cloudformation create-stack-set \
    --stack-set-name TerraformState \
    --template-body file://terraform-state.template \
    --description "Resources for managing Terraform state" \
    --capabilities CAPABILITY_NAMED_IAM CAPABILITY_IAM \
    --execution-role-name AWSControlTowerExecution \
    --administration-role-arn arn:aws:iam::${PRIMARY_ACCOUNT_ID}:role/service-role/AWSControlTowerStackSetRole \
    --parameters ParameterKey=PrimaryAccountId,ParameterValue=${PRIMARY_ACCOUNT_ID} \
    ParameterKey=TerraformStateBucket,ParameterValue="${STATE_BUCKET_NAME}"

Create a stack set instance in your shared services account:

aws cloudformation create-stack-instances \
    --stack-set-name TerraformState \
    --accounts ${SHARED_SERVICES_ACCOUNT_ID} \
    --regions ${AWS_REGION}

Check status:

aws cloudformation describe-stack-instance \
    --stack-set-name TerraformState \
    --stack-instance-account ${SHARED_SERVICES_ACCOUNT_ID} \
    --stack-instance-region ${AWS_REGION}
📎
Initial status will be OUTDATED, it should change to CURRENT once deployed.

Deploy the TfctlOrgAccess IAM role stack:

aws cloudformation create-stack \
    --stack-name TfctlOrgAccess \
    --template-body file://tfctl-org-access.template \
    --capabilities CAPABILITY_NAMED_IAM CAPABILITY_IAM \
    --parameters ParameterKey=PrimaryAccountId,ParameterValue=${PRIMARY_ACCOUNT_ID}

Check status:

aws cloudformation describe-stacks --stack-name TfctlOrgAccess
📎
Successful status should read: CREATE_COMPLETE.

Configure tfctl

Copy the example project directory examples/control_tower somewhere convenient and edit tfctl.yaml.

You need to modify the following parameters:

  • tf_state_bucket - set to $STATE_BUCKET_NAME

  • tf_state_role_arn - set shared services account ID

  • tfctl_role_arn - set primary account ID

  • primary_account - set the primary account name. You can find it through AWS Organizations in the console.

💡
You should keep your project directory under version control.

Deploy example tfctl profile

The example profile will create an S3 bucket in accounts under test, live and mgmt OUs.

📎
Run tfctl commands from the root of you project directory.

First, dump the configuration to verify everything works:

tfctl -s

This will not make any changes but will print out YAML containing the final, merged configuration data. It should contain a list of discovered accounts and their configuration.

Initialise Terraform for all discovered accounts:

tfctl --all -- init

Tfctl will run Terraform against all accounts in parallel.

plan the Terraform:

tfctl --all -- plan

and apply it:

tfctl --all -- apply

Clean up

To destroy created resources, run:

tfctl --all -- destroy -auto-approve

That’s it! You can now execute Terraform across your Control Tower estate.

💡
Your project directory should be under version control excluding the .tfctl directory which is automatically generated.