AWS Control Tower Account Factory for Terraform AFT Deep Dive

AWS Control Tower Account Factory for Terraform enables organizations to provision and customize AWS accounts with governance and repeatability. The module automates account creation and post-provisioning customization inside an AWS Control Tower landing zone using Terraform workflows.

AWS Control Tower Account Factory for Terraform is a Terraform module that makes it easy to create and customize new accounts that comply with your organization's security guidelines. AFT defines a pipeline for automated and consistent creation of AWS Control Tower accounts, giving you the benefits of Terraform's workflow and Control Tower's governance features. AWS maintains this module.

The tutorial guides you through the one-time steps required to deploy AFT to create the pipeline for account creation. Then, you will to use AFT to create and customize your Control Tower accounts. In this tutorial, you will deploy the AFT module, review the support account customization options, and learn about the components of AFT and its workflow.

This tutorial assumes that you are familiar with the standard Terraform workflow. If you are new to Terraform, complete the Get Started tutorials first.

Prerequisites and Environment Requirements

For this tutorial, you will need:

  • Terraform v0.15+ installed locally configured with credentials for the non-root user with AdministratorAccess
  • an AWS account, with credentials for a non-root user with the AdministratorAccess policy attached. Some steps can take up to 30 minutes, so make sure your credentials have a long enough duration

Prerequisites before you start for a typical AFT account provisioning run are:

  • You should have an AWS Control Tower environment deployed and available. Follow the getting started guide if you need to launch AWS Control Tower.
  • You should have an AFT deployed on a dedicated AFT Management account. Follow the guide on this post to set up AFT.
  • A new root email address for a new vended AWS account that you’ll submit through AFT.
  • A new or existing Organizational Units (OU) governed by AWS Control Tower, which is needed as part of new account request parameter in AFT.
  • Integrated development environment (IDE) with Git, Terraform, and AWS Command Line Interface (AWS CLI) installed

AFT follows a GitOps model and sets up a Terraform pipeline to provision and customize AWS accounts in AWS Control Tower. You create an account request in Terraform and commit to the repository that triggers the AFT workflow for Account Factory. After Account Factory execution is complete, AFT runs additional customization steps automatically.

Prerequisite Description
Terraform version v0.15+ installed locally
AWS credentials Non-root user with AdministratorAccess
Control Tower landing zone Deployed and available
AFT Management account Dedicated account with AFT deployed
Account root email New root email address for vended account
Organizational Unit New or existing OU governed by Control Tower
Tooling IDE with Git, Terraform, AWS CLI

AFT Architecture and Repositories

AFT uses four separate repositories to manage this entire workflow.

The repositories and their functions are:

  • aft-account-request
    • handles placing or updating account requests
  • aft-account-customizations
    • holds account level Terraform customizations
  • aft-global-customizations
    • applies customizations to all accounts managed by AFT
  • aft-account-provisioning-customizations
    • state machine for provisioning customizations

AWS Control Tower Account Factory for Terraform follows a GitOps model to automate the processes of account provisioning and account updating in AWS Control Tower. You'll create an account request Terraform file, which provides the necessary input that triggers the AFT workflow for account provisioning.

For more information on AFT, see Overview of AWS Control Tower Account Factory for Terraform

This guide is intended for administrators of AWS Control Tower environments who wish to set up Account Factory for Terraform in their environment. It describes how to set up an Account Factory for Terraform environment with a new, dedicated AFT management account. This guide follows the deployment steps outlined in Deploy AWS Control Tower Account Factory for Terraform.

Repository Purpose
aft-account-request Place or update account requests via Terraform
aft-account-customizations Per-account category customizations, e.g., SANDBOX, PRODUCTION
aft-global-customizations Cross-account customizations applied to all managed accounts
aft-account-provisioning-customizations Provisioning customization state machine

Customers use AWS Control Tower Account Factory to create a new AWS account or enroll existing AWS accounts in their AWS Organizations. Customers launch Account Factory from the AWS Control Tower console or via AWS Service Catalog API. We hear from customers that they want to manage their AWS accounts in the same way that they manage their AWS infrastructure using Terraform. We launched AWS Control Tower Account Factory for Terraform at re:Invent 2021, a new Terraform module to provision and customize AWS accounts using Terraform. In this post, we’ll walk you through the steps to deploy a new AWS account using AFT, and then we’ll show you how to customize the account created via AFT.

Deployment Steps for AFT Environment

Five steps are required to configure and launch your AFT environment.

Step 1: Launch your AWS Control Tower landing zone

Before launching AFT, you must have a working AWS Control Tower landing zone in your AWS account. You will configure and launch AFT from the AWS Control Tower management account.

Step 2: Create a new organizational unit for AFT (recommended)

We recommend that you create a separate OU in your AWS Organization, where you will deploy the AFT management account. Create an OU through your AWS Control Tower management account

Step 3: Deploy AFT module to management account

Step 4: Configure repositories and pipelines

Step 5: Validate pipeline execution

Initializing AFT with Terraform

The value for Account should match your ctmanagementaccount_id input variable.

$ aws sts get-caller-identity { "UserId": "AAAA….", "Account": "CONTROL TOWER MANAGEMENT ACCOUNT ID", "Arn": "arn:aws:iam::ACCOUNT_ID:user/USER" }

Initialize the configuration to install the AWS provider and download the AFT module.

$ terraform init Initializing modules... Initializing the backend... Initializing provider plugins... - Reusing previous version of hashicorp/local from the dependency lock file - Reusing previous version of hashicorp/archive from the dependency lock file - Reusing previous version of hashicorp/random from the dependency lock file - Reusing previous version of hashicorp/time from the dependency lock file - Reusing previous version of hashicorp/aws from the dependency lock file - Using previously-installed hashicorp/random v3.1.0 - Using previously-installed hashicorp/time v0.7.2 - Using previously-installed hashicorp/aws v3.66.0 - Using previously-installed hashicorp/local v2.1.0 - Using previously-installed hashicorp/archive v2.2.0 Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see any changes that are required for your infrastructure. All Terraform commands should now work. If you ever set or change modules or backend configuration for Terraform, rerun this command to reinitialize your working directory

Account Request Workflow

To create and update the AWS account using AFT, use the aft-account-request Terraform module. Provide the mandatory input, such as account root email address and the OU. Each time that you add or modify the account request, the Terraform file is committed to the repository and will trigger the AFT pipeline.

From the IDE terminal, run the following command to copy the example account customization. Replace the placeholder AWS_REGION value with your Control Tower home region.

Updating to this repository triggers the account request pipeline.

Navigate to CodePipeline and confirm that your ct-aft-account-request pipeline status is Succeeded. It may take a few minutes for the pipeline to complete. So far, we only populate the boilerplate without yet submitting a real account request. In the next section, we’ll submit a new account request.

Provision new account

Now we’ll provision a new AWS account via AFT using the SANDOX customization that we configured earlier.

From your IDE, navigate to the aft-account-request/terraform directory. Create a new file, and give it a name account-requests.tf

Add the following Terraform code and replace the placeholder {{PLACEHOLDER NAME}} with your own value, for example for the account email, name, OU, and SSO

Account Level Customization Options

Open the main.tf file on the aft-account-customizations/SANDBOX/terraform directory. This is a Terraform configuration which sets a monthly budget of $100 on the account that you’re creating with this customization.

Open the api_helpers directory, which is where you add bash/python script to further customize your account.

To add additional account level customization, create a new directory following the same structure. You specify the accountcustomizationname when creating a new account request, and AFT applies all of the Terraform configurations specified in the specific customization directory.

To use custom variables in your Terraform configuration, you pass the customfields value during the account request. These custom fields will be available as the AWS Systems Manager (SSM) Parameter Store in the vended AWS account under path /aft/account-request/custom-fields/{field-name}. In your Terraform configuration, you can retrieve these custom fields using data source. We’ll discuss in depth about customfields in a later section.

We add Terraform customization in the aft-global-customizations repository to apply Amazon S3 Block public access for all accounts managed by AFT. We also add Terraform customization in aft-account-customizations for two categories: PRODUCTION and SANDBOX. For PRODUCTION, we add a custom guardrail using an AWS Config Rule to check if VPC Flow Logs is enabled. In SANDBOX customization, we add Terraform configuration to setup monthly AWS Budget. Inside the account request, we specify whether or not to use PRODUCTION or SANDBOX category for account-level customization.

From the IDE terminal, run the following command

Global Customizations

You can apply customizations to all of the accounts managed by AFT. For example, in this post, we’ll configure Amazon S3 Block Public Access to block public access to every Amazon Simple Storage Service (Amazon S3) bucket in all of the accounts managed by AFT.

After the pipeline has completed successfully, navigate to Step Functions and locate the aft-account-provisioning-customizations state machine.

Customization Scope Example
Global S3 Block Public Access for all accounts
Account category PRODUCTION AWS Config Rule for VPC Flow Logs enabled
Account category SANDBOX Monthly AWS Budget of $100

Workflow Summary

AFT follows a GitOps model and sets up a Terraform pipeline to provision and customize AWS accounts in AWS Control Tower. You create an account request in Terraform and commit to the repository that triggers the AFT workflow for Account Factory. After Account Factory execution is complete, AFT runs additional customization steps automatically.

The workflow stages are:

  • Account request commit triggers CodePipeline ct-aft-account-request
  • Account Factory provisions the account in AWS Organizations and Control Tower
  • AFT runs account level customizations based on accountcustomizationname
  • AFT runs global customizations for all managed accounts
  • State machine aft-account-provisioning-customizations tracks completion

Conclusion

AWS Control Tower Account Factory for Terraform provides a repeatable, GitOps driven method to create and customize AWS accounts that comply with organizational security guidelines. Deployment begins with a working Control Tower landing zone and a dedicated AFT management account, followed by creation of a recommended Organizational Unit for AFT isolation. Terraform initialization against the management account establishes provider dependencies and downloads the AFT module maintained by AWS.

Once the pipeline is deployed, account requests are managed through the aft-account-request repository using the AFT Terraform module. Each commit triggers CodePipeline execution and subsequent Account Factory provisioning. Customizations are separated into account level and global repositories, allowing teams to define SANDBOX configurations such as monthly budgets, PRODUCTION guardrails such as VPC Flow Logs checks, and global controls such as S3 Block Public Access. Custom fields passed during the account request are surfaced as SSM Parameter Store values in the vended account, enabling dynamic Terraform data sources.

The architecture requires Terraform v0.15+, AdministratorAccess credentials for a non-root user, a long-lived credential session for steps that may take up to 30 minutes, and an IDE with Git, Terraform, and AWS CLI. With these prerequisites satisfied, AFT delivers consistent, auditable, and automated account creation integrated with AWS Control Tower governance.

Sources

  1. HashiCorp Developer Terraform AWS Control Tower AFT
  2. AWS Blog Deploy and Customize AWS Accounts using Account Factory for Terraform
  3. GitHub terraform-aws-controltoweraccount_factory

Related Posts