Orchestrating AWS Multi-Account Governance with Terraform and Control Tower

The complexity of managing a multi-account AWS environment has grown exponentially in recent years. Organizations moving away from single-account silos to adopt a shared-responsibility model face significant challenges in maintaining security compliance, cost governance, and architectural consistency across dozens or even hundreds of accounts. AWS Control Tower was introduced to address these challenges by automating the setup and governance of a multi-account AWS environment. However, the initial setup and ongoing management of this landing zone have traditionally relied heavily on the AWS Management Console. While effective for small-scale deployments, manual console operations do not scale for large enterprises requiring infrastructure as code (IaC) rigor. Integrating Terraform with AWS Control Tower, particularly through the Account Factory for Terraform (AFT) module, provides a robust solution that combines the automated governance of Control Tower with the deterministic, version-controlled workflows of Terraform. This integration allows teams to define, deploy, and manage security guardrails, organizational units, and account provisioning through code, ensuring that every account in the landing zone adheres to the organization's security guidelines from the moment it is created.

Architecture of the Integrated Ecosystem

AWS Control Tower is not a standalone service but an orchestrator that leverages several other AWS services to build a secure landing zone. It builds on AWS Organizations to manage account structure, AWS Service Catalog for provisioning standard resources, and AWS Config for continuous compliance monitoring. When integrated with Terraform, the system creates a layered architecture where Terraform handles the declarative definition of the infrastructure, while Control Tower enforces the runtime policies.

The core components of this integrated ecosystem include the Landing Zone, which represents the overall multi-account environment structure; Organizational Units (OUs), which group accounts with shared policies; and Guardrails, which are preventive and detective controls implemented as Service Control Policies (SCPs) and Config rules. Additionally, the architecture includes specific account types such as the Log Archive Account for centralized logging and the Audit Account for security and compliance auditing. A typical structure places a Management Account at the root, branching out into specific OUs like Security, Sandbox, and Workloads. The Security OU contains the Log Archive and Audit accounts, while the Workloads OU houses production and staging environments.

Component Function Terraform Integration Role
Landing Zone Overall multi-account environment structure Defined via Control Tower API via Terraform resources
Organizational Units Groups of accounts with shared policies Managed via aws_organizations_organizational_unit resources
Guardrails Preventive and detective controls (SCPs/Config) Managed via aws_controltower_control resources
Account Factory Automated account provisioning Triggered via AFT workflow or direct API
Log Archive Account Centralized logging Provisioned automatically by Control Tower
Audit Account Security and compliance auditing Provisioned automatically by Control Tower

This structure ensures that when users perform any action in any account within the landing zone, that action is subject to the controls governing the specific OU. For example, a production OU might have a strict "disallow internet access" control, while a development sandbox OU might allow broader access. Terraform allows these distinctions to be codified, reviewed, and tested before deployment.

Account Factory for Terraform (AFT)

One of the most significant advancements in managing Control Tower via Terraform is the AWS Control Tower Account Factory for Terraform (AFT). AFT is a Terraform module maintained by AWS that makes it easy to create and customize new accounts that comply with organizational security guidelines. AFT defines a pipeline for automated and consistent creation of AWS Control Tower accounts, giving administrators the benefits of Terraform's workflow and Control Tower's governance features.

AFT operates on a GitOps model. Instead of manually creating accounts or running ad-hoc scripts, administrators create an account request Terraform file. This file serves as the input that triggers the AFT workflow. The workflow is a series of automated steps that handle account provisioning, base configuration, and customizations. AFT supports multiple deployment backends, including HashiCorp Terraform Cloud (HCP Terraform), Terraform Enterprise, and the Terraform Community Edition. This flexibility allows organizations to use their existing CI/CD pipelines and state management strategies.

The workflow initiated by an account request includes an account provisioning stage and an account customization stage. After the account provisioning stage is complete, AFT automatically runs a series of steps before the account customizations stage begins. This ensures that the base governance controls are applied before any specific customizations are executed, preventing the introduction of non-compliant configurations early in the lifecycle.

Tracing and Observability

A critical feature of AFT is account customization request tracing. Every time an account customization request is submitted, AFT generates a unique tracing token. This token passes through an AFT customizations AWS Step Functions state machine, which logs the token as part of its execution. This observability capability is vital for debugging and auditing. Administrators can use Amazon CloudWatch Logs insights queries to search timestamp ranges and retrieve the request token, allowing them to track the entire lifecycle of a customization request. This level of detail is essential for organizations that require strict audit trails for compliance purposes.

Managing Controls with Terraform

While AFT handles the creation of accounts, the ongoing management of security controls is achieved through the aws_controltower_control resource in the Terraform AWS Provider. A control, also known as a guardrail, is a high-level rule that provides ongoing governance for the overall AWS Control Tower environment. Controls apply to an entire organizational unit, and the control affects every AWS account within that OU.

Controls are categorized according to their behavior. Preventive controls are designed to prevent actions from occurring. These are implemented with service control policies (SCPs) or resource control policies (RCPs) in AWS Organizations. The status of a preventive control is either enforced or not enabled. Detective controls, on the other hand, monitor resources for compliance and can trigger notifications if specific security-related events occur. Proactive controls take active steps to remediate non-compliance.

When using Terraform to deploy controls, it is crucial to use the correct control identifiers. Previous versions of deployment patterns used regional identifiers, which are now considered legacy. The current standard requires the use of global identifiers. The format for these global identifiers is arn:<PARTITION>:controlcatalog:::control/<CONTROL_CATALOG_OPAQUE_ID>. In most cases, the value for <PARTITION> is aws. Using global identifiers helps manage controls more effectively and expands the number of controls that can be used across the organization.

Example: Enforcing Security Controls

The following code block demonstrates how to enable strongly recommended and elective controls on specific OUs using Terraform. This example focuses on the Workloads OU and a production OU.

```hcl

Enable strongly recommended and elective controls on the Workloads OU

resource "awscontroltowercontrol" "disallowpublics3" {
controlidentifier = "arn:aws:controlcatalog:::control/AWS-GRS3ACCOUNTLEVELPUBLICACCESSBLOCKSPERIODIC"
targetidentifier = awsorganizationsorganizationalunit.workloads.arn
}

resource "awscontroltowercontrol" "rootaccountmfa" {
controlidentifier = "arn:aws:controlcatalog:::control/AWS-GRROOTACCOUNTMFAENABLED"
target
identifier = awsorganizationsorganizational_unit.workloads.arn
}

resource "awscontroltowercontrol" "disallowinternetaccess" {
controlidentifier = "arn:aws:controlcatalog:::control/AWS-GRDISALLOWVPCINTERNETACCESS"
target
identifier = awsorganizationsorganizational_unit.production.arn
}

resource "awscontroltowercontrol" "requireencryption" {
control
identifier = "arn:aws:controlcatalog:::control/AWS-GRENCRYPTEDVOLUMES"
targetidentifier = awsorganizationsorganizationalunit.workloads.arn
}

resource "awscontroltowercontrol" "ebsoptimizedinstance" {
controlidentifier = "arn:aws:controlcatalog:::control/AWS-GREBSOPTIMIZEDINSTANCE"
targetidentifier = awsorganizationsorganizationalunit.workloads.arn
}
```

In this example, the disallow_public_s3 control ensures that S3 buckets do not have public access, which is a common vector for data breaches. The root_account_mfa control mandates multi-factor authentication for the root user, a fundamental security practice. The disallow_internet_access control is applied specifically to the production OU, preventing VPCs from having direct internet access, thereby forcing traffic through bastion hosts or NAT gateways. Finally, the require_encryption control enforces encryption on Elastic Block Store (EBS) volumes, ensuring data at rest is protected.

Deployment Prerequisites and Workflow

Deploying AFT and managing Control Tower via Terraform requires specific prerequisites. First, Terraform version 0.15 or later (with version 1.5 recommended for current control identifier support) must be installed locally and configured with credentials for a non-root user with AdministratorAccess policy. Second, an AWS account with credentials for a non-root user with the AdministratorAccess policy attached is required. Because some steps in the provisioning process can take up to 30 minutes, it is essential that the credentials have a long enough duration to avoid session expiration during the deployment.

The deployment of AFT follows a structured set of steps. The first step is to launch the AWS Control Tower landing zone. Before launching AFT, a working AWS Control Tower landing zone must exist in the AWS account. AFT is configured and launched from the AWS Control Tower management account.

The second step is to create a new organizational unit for AFT. It is recommended to create a separate OU in the AWS Organization where the AFT management account will be deployed. This separation ensures that the infrastructure managing the other accounts is isolated and follows its own security policies. The AFT management account is the entity that holds the Terraform state and executes the provisioning logic for other accounts.

Requirement Specification/Version
Terraform Version v0.15+ (v1.5+ recommended)
Terraform AWS Provider v4.67+
AWS Control Tower Version v3.2 or later
User Permissions AdministratorAccess (Non-root)
Credential Duration Long enough for 30+ minute operations

The use of a dedicated AFT management account is a best practice that enhances security. By isolating the AFT infrastructure, organizations can apply stricter controls to the account that has the power to create and modify other accounts. This containment strategy limits the blast radius if a compromise occurs.

Best Practices for Scalability

Integrating Terraform with Control Tower is not just about automating the initial setup; it is about establishing a scalable governance model. One key best practice is to version the Terraform code in a Git repository. Each change to the landing zone, whether it is a new control or a new account, should be committed and pushed to trigger the pipeline. For AFT, this means using a simple git push command to initiate account creation. This GitOps approach provides a complete audit trail of changes, linking infrastructure changes to specific code commits and pull requests.

Another best practice is to use modules for repetitive tasks. While AFT provides a comprehensive module for account creation, organizations can further abstract their customizations by creating their own Terraform modules for standard application architectures. This ensures that when a new account is created, it not only receives the base governance controls but also any standard infrastructure required by the organization, such as VPCs, subnets, and IAM roles.

Furthermore, organizations should regularly review the status of their controls. Terraform can be used to read the state of controls and verify that they are enabled as expected. This can be integrated into CI/CD pipelines to provide feedback if a control is disabled or modified outside of the expected workflow. By treating the security posture of the landing zone as code, organizations can achieve a level of consistency and auditability that is difficult to attain with manual management.

Conclusion

The integration of Terraform with AWS Control Tower represents a mature approach to managing multi-account AWS environments. By leveraging the Account Factory for Terraform (AFT) and the aws_controltower_control resource, organizations can move from a manual, console-centric operation to a fully automated, code-driven governance model. AFT provides a streamlined pipeline for account provisioning that respects the governance rules defined by Control Tower, while the use of global control identifiers ensures that the latest and most comprehensive set of security controls can be applied across the organization.

The shift to this model requires adherence to specific prerequisites, including the use of recent versions of Terraform and the AWS Provider, as well as the establishment of a dedicated AFT management account. The benefits of this approach include enhanced scalability, improved auditability through GitOps and tracing tokens, and the ability to enforce complex security policies consistently across all accounts. As organizations continue to expand their AWS footprints, the ability to govern these environments through infrastructure as code becomes not just a technical preference, but a business necessity. The combination of Control Tower's governance capabilities and Terraform's automation power provides a robust foundation for secure, compliant, and scalable cloud operations.

Sources

  1. HashiCorp Terraform Tutorials: AWS Control Tower AFT
  2. AWS Documentation: Overview of AWS Control Tower Account Factory for Terraform
  3. OneUptime Blog: Create Control Tower with Terraform
  4. AWS Prescriptive Guidance: Deploy and manage AWS Control Tower controls by using Terraform
  5. GitHub: aws-ia/terraform-aws-controltoweraccount_factory

Related Posts