Cloud Foundations
Managing Multiple AWS Accounts with OpenTofu/Terraform
Manage multiple AWS accounts with OpenTofu/Terraform, from super simple to leveraging AWS Control Tower AFT.
When you start working across multiple AWS accounts, state layout, authentication, and account vending decisions matter almost immediately. The more accounts you add, the more expensive it becomes to keep changing those patterns later.
This article covers a few practical ways to manage multiple AWS accounts with OpenTofu or Terraform, from simple provider aliasing through to AWS Organizations and AWS Control Tower Account Factory for Terraform (AFT).
Single State File Approach
If you are comfortable keeping resources in one central state file, the simplest model is multiple AWS provider aliases in the same configuration:
provider "aws" {
alias = "dev"
# credentials or assume_role config
}
provider "aws" {
alias = "test"
# credentials or assume_role config
}
resource "aws_instance" "example" {
provider = aws.dev
# ...
}
This works well for smaller estates and can be straightforward to operate, but it also means one state file spans multiple accounts. That becomes harder to govern as the estate grows.
Separate State Files Per Account
For production estates, separate state per account is usually the safer model. It reduces blast radius, limits accidental cross-account change, and makes permissions easier to scope.
In AWS that often means:
- An S3 bucket in each account for backend storage.
- A DynamoDB table for state locking.
- Backend configuration supplied by the pipeline or wrapper script.
For example:
terraform init -backend-config="bucket=project-<envname>"
That allows the same configuration to target different accounts while keeping state separated cleanly.
Managing AWS Account Authentication
There are a few sensible ways to handle credentials and account selection.
AWS Profiles
For local work, AWS profiles are often enough:
provider "aws" {
region = "eu-west-1"
profile = var.aws_profile
}
You can pass the profile through local environment variables or wrapper scripts, which keeps the provider configuration simple.
Assume Role from a Shared Identity
In pipelines, assuming a role into the target account is usually cleaner than storing long-lived credentials per account. It gives you a predictable access pattern and keeps account selection outside the IaC itself.
Workspaces
Workspaces can still be useful, but usually for environment or deployment shape inside a given account rather than as the primary account selection mechanism. In most cases it is clearer to choose the target account in the pipeline and use workspaces more sparingly.
Leveraging AWS Organizations and AFT
As the estate grows, AWS Organizations becomes the right control surface for organising accounts into OUs, applying service control policies, and keeping billing and governance centralised.
From an IaC perspective, that usually means using AWS provider resources for:
- organisational units
- accounts
- service control policies
- cross-account roles
If you are using AWS Control Tower, Account Factory for Terraform (AFT) can take that further by standardising account vending and post-provisioning changes through a managed pipeline. Sources: Provision accounts within AWS Control Tower, Deploy AWS Control Tower Account Factory for Terraform.
Where AFT Fits
AFT is useful when:
- new accounts need to be created regularly
- baseline controls need to be applied consistently
- account provisioning should be reviewed and tracked as code
It gives platform teams a more structured route for scaling the account estate without relying on manual account creation.
Pipeline Integration and Best Practices
- Choose the target account in the pipeline rather than hard-coding it in configuration.
- Keep state separated for production-sensitive accounts.
- Scope IAM permissions with least privilege.
- Standardise backend naming and locking patterns.
- Treat account vending and organisation structure as part of the platform, not an afterthought.
Conclusion
Managing multiple AWS accounts with OpenTofu or Terraform is less about one perfect pattern and more about choosing the right level of separation for the stage you are at. A smaller estate may be fine with centralised state and provider aliases. A larger one usually benefits from separate state, clearer role assumption, AWS Organizations, and eventually AFT or another structured account-vending model.