
Darwin Martin
Principal Software Engineer

Architecting Terraform for Multi-Cloud: The Separate Runs Pattern
Intro: Why Separate Terraform Runs Matter
Writing one script to rule all clouds might sound like a DevOps dream—but in reality, maintaining a single Terraform config with logic to switch between AWS, Azure, and GCP can create more problems than it solves. In this post, I introduce the Separate Runs Pattern for structuring Terraform code across multiple clouds.
What is the Separate Runs Pattern?
We avoid multi-provider coupling by giving each cloud its own isolated Terraform root configuration:
terraform-multi-cloud/
├── aws/
├── azure/
├── gcp/
└── modules/
Each directory contains its own state, variables, and provider setup, but calls shared modules to reduce code duplication.
Benefits of This Architecture
- Isolated State: Fewer chances for accidental cross-cloud destruction.
- Cleaner Pipelines: Each cloud deploys independently.
- Scoped Credentials: Least-privilege access per environment.
- Developer Autonomy: Teams own their cloud configurations without collisions.
Example: The AWS Root Config
provider "aws" {
region = var.region
}
module "compute" {
source = "../modules/compute"
name = "aws-instance"
region = var.region
instance_type = var.instance_type
ami = var.ami
}
Using the Pattern
To deploy, just navigate to the cloud you want and run Terraform:
cd aws
terraform init
terraform apply
Later:
cd ../gcp
terraform init
terraform apply
Conclusion
If you're scaling Terraform across clouds, the Separate Runs Pattern keeps things maintainable, secure, and flexible. Combine isolation with shared modules and you'll build multi-cloud systems that are easier to test, extend, and trust.