Terraform Workspace

Set up workspace

$ terraform workspace new dev
Created and switched to workspace "dev"!

$ terraform workspace new prod
Created and switched to workspace "prod"!

$ terraform workspace list
  default  <------------------ Note default workspace which is always present.
* dev      <================== Asterisk indicates current workspace
  prod
  testing123

$ terraform workspace select prod
Switched to workspace "prod".

$ terraform workspace show
prod


$ terraform workspace select dev
Switched to workspace "dev".

Terraform code to use workspace

setup.tf

# Export key and secret credentials first.
# Create new workspace with 'terraform workspace new dev|prod'
# See all workspaces with 'terraform workspace list'
# Select workspace with 'terraform select dev|prod'
# run as -> $ terraform apply
 
 
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "3.74.1"
    }
  }
 
  # Use AWS s3 and dynamo for state files
  backend "s3" {
    region         = "eu-west-2"
    bucket         = "ajs-vpc-ec2-statefiles"
    key            = "tsg/plan-apply.tfstate"
    dynamodb_table = "ajs-tsg-plan-apply-lockfiles"
  }
 
}
 
provider "aws" {
    region = "eu-west-2"
  }

parameter-store.tf

resource "aws_ssm_parameter" "environment" {
  name = format("%s_%s", "environment", terraform.workspace)
  type = "String"
  description = "Environment, eg. Production / Development"
  tags = {
    email = "andrew.2.stringer@bt.com",
    builtBy = "terraform"
  }
  value = terraform.workspace
}
 
variable "ami_instance_type" {
  type = map    # Note! TF variable type lower case
  default = {
    "prod"   = "t2.large"
    "dev"   = "t2.nano"
  }
}
 
resource "aws_ssm_parameter" "ami_to_use" {
  name  = format("%s_%s", "ami_to_use", terraform.workspace)
  type  = "String"   # NOTE! Quotes + Capital - AWS resource Type
  value = var.ami_instance_type[terraform.workspace]
}

network.tf

resource "aws_vpc" "main" {
  cidr_block       = "10.0.0.0/16"
  instance_tenancy = "default"
 
  tags = {
    Name = format("%s_%s", "vpc", terraform.workspace)
 
  }
}

Using Workspace to create prod and dev environments with the same code

You will need to create a prod and dev workspace first. Depending on which workspace you run the terraform apply from, an appropriate instance size will be selected for EC2 and an appropriately named VPC will be created.

Note:- No changes needed to the actual terraform code to create two environments in one account but with different resources.

setup.tf

# Export key and secret credentials first.
# run as -> $ terraform apply
 
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "3.74.1"
    }
  }
 
  # Use AWS s3 and dynamo for state files
  backend "s3" {
    region         = "eu-west-2"
    bucket         = "tfworkspace-statefiles"
    key            = "tsg/plan-apply.tfstate"
    dynamodb_table = "tsg-plan-apply-lockfiles"
  }
 
}
 
provider "aws" {
    region = "eu-west-2"
  }

parameter-store.tf

resource "aws_ssm_parameter" "environment" {
  name = format("%s_%s", "environment", terraform.workspace)
  type = "String"
  description = "Environment, eg. Production / Development"
  tags = {
    email = "andrew.2.stringer@bt.com",
    builtBy = "terraform"
  }
  value = terraform.workspace
}
 
variable "ami_instance_type" {
  type = map    # Note! TF variable type lower case
  default = {
    "prod"   = "t2.large"
    "dev"   = "t2.nano"
  }
}
 
resource "aws_ssm_parameter" "ami_to_use" {
  name  = format("%s_%s", "ami_to_use", terraform.workspace)
  type  = "String"   # NOTE! Quotes + Capital - AWS resource Type
  value = var.ami_instance_type[terraform.workspace]
}

network.tf

resource "aws_vpc" "main" {
  cidr_block       = "10.0.0.0/16"
  instance_tenancy = "default"
 
  tags = {
    Name = format("%s_%s", "vpc", terraform.workspace)
 
  }
}
 
terraform/terraform-workspace.txt · Last modified: 12/01/2023 10:44 by andrew