Notice:
This post is older than 5 years – the content might be outdated.
Terraform is a great tool to spin up environments on AWS—or in other clouds. But when it comes to a multi account environment there might be a gap. This article offers different solutions to bypass this with some kind of Makefile magic.
Requirements
Let’s define requirements we’ve met in some customer projects before we try and conquer them:
Solutions
With these requirements in mind, there are several solutions.
Keep separate subdirectories
Terraform Workspaces
Where possible, it’s recommended to use a single backend configuration for all environments and use the terraform workspace command to switch between workspaces.
Account isolation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# cat main.tf terraform { backend "s3" { bucket = "my-tf-remote-state" region = "eu-central-1" key = "webtier/terraform.tfstate" encrypt = true dynamodb_table = "my-tf-remote-state-lock" } } provider "aws" { region = "eu-central-1" } |
- most obvious: the AWS account to use which can be addressed with the configuration parameter
- backend configuration while initializing the terraform project: the -backend-config flag supports config parameter like bucket and dynamodb_table.
1 2 3 |
# terraform init -backend-config="bucket="my-tf-remote-state-dev" -backend-config="dynamodb_table=my-tf-remote-state-lock-dev" -backend-config="key=webtier-dev/terraform.tfstate" # terraform plan -var aws-account=aws-dev |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# make plan env=aws-dev (..) AWS_PROFILE=aws-dev terraform init -backend-config="bucket=825df6bc4eef-state" -backend-config="dynamodb_table=825df6bc4eef-state-lock" -backend-config="key=terraform-multi-account/terraform.tfstate" # cat .env.aws-dev account_id=123456 ec2_node_type="t2.micro" # cat .env.aws-prod account_id=12345678910 ec2_node_type="t2.large" ec2_volume_size="10"% # cat main.tf variable "ec2_node_type" {} resource "aws_launch_configuration" "ec2_instance" { name_prefix = "ec2-" image_id = "${var.ec2_ami}" instance_type = "${var.ec2_node_type}" (...) |
Alternative
Take a look at the stuff Terragrunt does. It might be worth a try.