Companion lab for the Medium article Terraform — Using Multiple Providers. Part of my Terraform fundamentals series — more on Medium.
How to deploy resources to multiple AWS regions (or multiple AWS accounts) from a single Terraform project using provider aliases — the canonical pattern for cross-region and multi-account infrastructure.
┌──────────────────┐ ┌──────────────────────────────────┐
│ Terraform │ │ AWS │
│ │ │ │
│ provider.aws │ ────► │ S3 bucket · us-east-1 (VA) │
│ │ │ │
│ provider.aws │ ────► │ S3 bucket · eu-west-3 (Paris) │
│ .paris (alias) │ │ │
└──────────────────┘ └──────────────────────────────────┘
One codebase, two provider instances, two regions.
| File | Purpose |
|---|---|
provider.tf |
Declares two AWS provider instances: default (us-east-1) and paris alias (eu-west-3) |
variables.tf |
Defines bucket_virginia and bucket_paris input variables |
main.tf |
Creates S3 buckets — one in each region, using provider = aws.paris on the second |
output.tf |
Outputs the regional domain names of both buckets |
backend.tf |
Configures local state backend |
- Terraform ≥ 1.5
- AWS CLI configured (
aws configure) with adefaultprofile that has access to both regions - Globally unique S3 bucket names — set
bucket_virginiaandbucket_parisviaterraform.tfvarsor-var(the defaults will collide)
# Initialize (downloads the AWS provider once, used for both aliases)
terraform init
# Preview — you should see 2 S3 buckets, one per region
terraform plan \
-var="bucket_virginia=my-unique-va-bucket-2026" \
-var="bucket_paris=my-unique-paris-bucket-2026"
# Apply
terraform apply \
-var="bucket_virginia=my-unique-va-bucket-2026" \
-var="bucket_paris=my-unique-paris-bucket-2026"
# Inspect the outputs
terraform outputExpected output: two s3.<region>.amazonaws.com domain names, one for Virginia and one for Paris.
terraform destroy \
-var="bucket_virginia=my-unique-va-bucket-2026" \
-var="bucket_paris=my-unique-paris-bucket-2026"- Provider aliases —
alias = "paris"creates a second provider instance you can reference asaws.paris provider =resource argument — attach a resource to a specific provider instance (provider = aws.paris)- Single
terraform init— downloads the provider plugin once even for multiple instances - Multi-region (and by extension, multi-account) pattern — swap regions for account credentials to manage infra across AWS accounts
- Cross-region DR — primary in
us-east-1, disaster recovery in another region - Multi-account organization — one Terraform root module managing infra across accounts via assume-role
- Mixing cloud providers —
provider.aws+provider.gcp+provider.azurermall in one module
Part of my Terraform fundamentals series:
- Previous: Managing Environments with Terraform Workspaces
- Also in series: Creating Your First Instance with Terraform
All articles on Medium.