Yusuke Hatanaka

March 5, 2021

Using terraform workspace in multi account environment

In the modern age, a network infrastructure is frequently written down to the code.
To use terraform is the one option to achieve them, also I use on a daily.

These days, we are forced to construct several network environment on the cloud which are always in used by developing, testing and providing services to the world. We always hope that each environment should be the same construction and reflected from the one code base in order to avoid some problems due to difference between environments in advance. We can get through the such concern to use terraform workspace. 
Here is an example of using terraform aws provider.

Prerequisite:
  • create IAM role in each AWS account corresponding to the environment you want construct. These roles are used by terraform, thus you must give it decent policy similar like an administrator.
  • create IAM role (or user) which is able to assume roles created above, and make it to be able to use by terraform executor like you (or some CI environment).

Initialize the project:
$ terraform init
$ terraform workspace new production
$ terraform workspace new sandbox

Add provider setting like below:
$ cat provider.tf
variable "role_arn" {
  default = {
    sandbox    = "arn:aws:iam::123456789012:role/terraform"
    production = "arn:aws:iam::987654321098:role/terraform"
  }
}

provider "aws" {
  region = "ap-northeast-1"
  assume_role {
    role_arn = var.role_arn[terraform.workspace]
  }
}

Make some resource definition:
$ cat s3.tf
locals {
  my_bucket = {
    production = {
      bucket = "bucket"
    }
    sandbox = {
      bucket = "sandbox-bucket"
    }
  }
}

resource "aws_s3_bucket" "my_bucket" { bucket = local.my_bucket[terraform.workspace].bucket }

Create resource to each environment:
$ terraform workspace select sandbox
$ terraform apply
$ terraform workspace select production
$ terraform apply

that's it.

When you apply those workaround I showed up above to your existing environment, why not import production environment first, then apply it to another. To import existing environment to the code using terraform is bit tough thing, but I bet you'll find out the comfort after whole systems imported maybe.

About Yusuke Hatanaka

I'm working as a software engineer in Japan. I like reading, watching basketball game, and fishing. 
Not only the fact oriented but also intuition.