Organizations often struggle with how to structure their cloud footprint across different business units, budgets, and cost centers. While putting everything into a single shared AWS account might seem simpler at first, it quickly creates operational bottlenecks.

Adopting a multi-account AWS architecture provides several critical advantages:

  • Eliminating Resource & Rate Limit Competition: Shared accounts mean teams compete for the same regional AWS service quotas (e.g., EC2 vCPU limits, VPC endpoints) and risk hitting AWS API rate limits (throttling) during peak deployments or automated CI/CD runs.
  • Preventing Configuration Collisions: Isolating teams into dedicated accounts eliminates cross-team configuration issues—such as overlapping IAM policies, naming collisions on shared resources (like S3 buckets or Security Groups), or accidental modifications to another team’s infrastructure.
  • Simplified Cost Allocation: Tracking costs at the AWS account level is far cleaner than untangling complex tag-based chargeback models across shared environments.
  • Environment Isolation & Reduced Blast Radius: Keeping Development, Staging, and Production in separate accounts ensures that a misconfiguration or security event in a non-prod environment cannot impact production workloads.

Automating account creation at scale requires robust orchestration. One solution I’ve implemented is Account Factory for Terraform (AFT)—an open-source framework built by AWS.

AFT adopts a GitOps approach: a developer simply commits a new account request Terraform file to a repository. This triggers an event-driven pipeline that provisions the account via the AWS Control Tower API.

From there, AFT manages:

  • AWS Organization enrollment
  • Service Catalog association
  • Post-provisioning account customizations

For advanced workflows, AFT supports extra account customization through supplemental Terraform manifests or AWS Lambda functions invoked directly by AFT Step Functions state machines.

A major advantage of AFT is how it breaks down state management. Rather than lumping hundreds of accounts into a single massive state file, each provisioned target account is managed by three distinct, isolated state files:

  1. account-customization-state
    Sets up the account-level CodePipeline infrastructure that drives global and specific customizations.
  2. global-customizations-state
    Tracks baseline Terraform code applied to all accounts in the organization (stored in the aft-global-customizations repo).
  3. account-customizations-state
    Tracks Terraform code applied only to this specific account (stored under /terraform/<account_name> in the aft-account-customizations repo).

Managing accounts this way drastically reduces the number of resources in any single state file, minimizing the blast radius if an apply fails.

Prior to adopting AFT, I experienced the pain of using a single monolithic Terraform state file to manage global resources across dozens of accounts. State refreshes were painfully slow, and routine terraform apply executions regularly stretched to 30 minutes or more. Splitting state by account and customization layer restores speed and safety to the deployment pipeline.

AFT is installed into a dedicated AFT Management Account inside your AWS Organization. This account hosts the core orchestration engines—the pipelines, Step Functions state machines, IAM roles, EventBridge rules, and logs.

The AFT Management account uses cross-account IAM roles to execute actions across the environment:

  • Main Control Tower Account: Orchestrates SSO, OU movements, and account baseline enrollment.
  • Target Account: Provisions environment-specific resources like VPCs, S3 buckets, and application IAM roles.

If you’re currently managing a growing AWS footprint manually or wrestling with monolithic Terraform state files for account provisioning, AFT is worth a close look. It bridges the gap between Control Tower’s governance and Terraform’s IaC workflow seamlessly.

AFT Architecture

Reference:

https://github.com/aws-ia/terraform-aws-control_tower_account_factory