A while ago I walked some of my colleagues at work through the basics of using Hashicorp Terraform with AWS to deploy and maintain resources. I am a very big supporter of using infrastructure as Code and blog about AWS CDK, Terraform, ansible and any other means to achieve that goal.
I thought I would write this guide along with an accompanying Youtube Video to show how improvements with AWS Control Tower API Integrations allow you to actually create a landing zone without using the Console using Terraform. The Code for this is located in my Terraform 101 repo (aussiecloudguy/terraform101) which also has some other samples of Terraform use with the AWS Provider (Refer to my other AWS Terraform guide).
With this guide you might hopefully get to understand the steps to automate the provisioning of AWS Multi-Account Landing zones based on AWS Control Tower in a region of your choice.
AWS have a really good guide on how to set up Control Tower using APIs (Ref: Get started with AWS Control Tower using APIs - AWS Control Tower) and I have simply taken that guide and converted it to use with Terraform.
I am not going to step by step how the AWS Provider and authentication works with Terraform as I have a basic Terraform Blog on this site covering that but I will outline that the Requirements you need here:
- An AWS Management Account to host the Control Tower Organization.
- An IAM User with Administrative Access in that Account
- AWS Credentials for that account for use with Terraform
Following the Readme in my terraform-controltower folder you will see that you fill in the variables for email addresses for each of the newly requested accounts and some other details.
The Sample Terraform is an end to end code and it performs the following required actions automatically:
1. Creates an AWS Organization in the Management Account that is provisioned already
2. Create the defined roles required by AWS Control Tower and attaches the policies (as per the linked documentation)
3. Creates a Logging and Audit Account using defined email addresses that need to be supplied
4. Create a basic AWS Landing Zone.
The end result is a Control Tower Instance.
I will be adding more samples and blogs in coming weeks to cover things like provisioning new Accounts using AWS Control Tower AFT (Account Factory For Terraform) as well as also how to add things like guard rails and customisations to the landing zone after deployment.
Stage 1 - Create AWS Organization for the Landing Zone
In order to create member accounts you need to set up an AWS Organizations Org. If you try to create a child account through CLI or terraform otherwise it will fail. You can create an organization from the console but my terraform sample includes creating that inside the Terraform deployment. The code looks like this

I was a bit silly in my initial testing of this code and tried to just do the account creates and landing zone set ups. That failed obviously. I then amended my sample to add the above code in (which creates an AWS Org, enables Cloudtrail and Config for the Org and uses "All Features"). All Features is the default now but I still included it as a defined value in the code.
Stage 2 - Create AWS Accounts for the Landing Zone
The AWS API documented method of Control Tower requires that the AWS accounts for auditing and logging exist. The AWS guide uses AWS CLI to provision them. I have them provisioned using terraform code with the email address and name stored as a variable. It kinds looks like this in code

I think one of the main differences between doing this from code and console is that the console deployment can create the accounts for you. But in the background it is really just using code/api to run the account creations before it does everything else.
After the deployment runs it will enroll these existing accounts into the AWS Control Tower environment and manage them.
You will see in the above snippet a depends_on field. Those who are versed in IaC including users of AWS CDK will understand that this is to show that the Account Creations have a dependency. In this case they require the AWS Organization to be created first.
Stage 3 - Create the Roles
AWS Control Tower needs a number of Service Roles with defined permissions to allow deployment to complete. These are documented in the API Guides and Control Tower guides along with the permissions they require.
All of this is automated in the terraform stack including the creation of the roles, the required trust documents and defined managed policies or inline policies.
An Example of the Terraform code is below

Stage 4 Create Landing Zone
The Landing Zone creation is the same as it is for regular api based deployments. It uses a defined manifest file that references the Logging, and Auditing accounts, defines the Governed regions using a variable from the vars.tf file, creates the 2 defined Organizational Units and enrolls the accounts within it.
In my Sample I have set defined retentions for Cloudtrail and Config but these can also be variablized.
Note: It is usually best practice to provide a AWS KMS Customer Managed Key for Control Tower. This is going to be included in my next update to this code. It was not included now because there are cost implications and I am not sure how easy it is to clean it up in the terraform stack. Encryption Keys can be specified for Landing Zones either AT LAUNCH time or AFTER

The launch process of the landing zone is estimated to take up to 60 minutes. The time in practice that it will take depends very much on how many Regions are being Governed and in a small footprint (like my lab) it can realistically take only 20-25 minutes.
At the end of it you will see this.

Very soon I will add a few more blogs and code samples to add things like AWS Backup, Control Tower Guardrails, etc.
I have put the video on Youtube to help run through it: Launching an AWS Control Tower Landing Zone with Terraform
I hope you found this useful. And as I said the sample code located inside my public github repo is here: terraform101/aws/aws-terraform-controltower-sample at main · aussiecloudguy/terraform101
Feel free to drop any comments or questions on this and I will happily respond when I can.
Add comment
Comments