Video Thumbnail for Lesson
7.2: Using Terraform Workspaces

Using Terraform Workspaces to Manage Environments

In this lesson, we will demonstrate how to use Terraform Workspaces to manage multiple environments for our sample web application.

We will create two environments, production and staging, and deploy the web application to both environments.

Defining the Root Module

  1. Create a new directory called workspace. This directory will contain the main.tf file for the Terraform workspace implementation.

  2. Inside the main.tf file, set up the backend and providers, as we did in previous examples.

terraform {
  # Assumes s3 bucket and dynamo DB table already set up
  # See /code/03-basics/aws-backend
  backend "s3" {
    bucket         = "devops-directive-tf-state"
    key            = "07-managing-multiple-environments/workspaces/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "terraform-state-locking"
    encrypt        = true
  }

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.0"
    }
  }
}
  1. Add a variable for the sensitive password value.
variable "db_pass" {
  description = "password for database"
  type        = string
  sensitive   = true
}
  1. Make use of the workspace's name for postfixing certain resources, such as the S3 bucket, to avoid naming conflicts.
locals {
  environment_name = terraform.workspace
}

resource "aws_s3_bucket" "bucket" {
  bucket = "web-app-data-${local.environment_name}"
}
  1. Populate all the input variables for the module so it knows how to provision the environment.
module "web_app" {
  source = "../../06-organization-and-modules/web-app-module"

  # Input Variables
  bucket_prefix    = "web-app-data-${local.environment_name}"
  domain           = "devopsdeployed.com"
  environment_name = local.environment_name
  instance_type    = "t2.micro"
  create_dns_zone  = terraform.workspace == "production" ? true : false
  db_name          = "${local.environment_name}mydb"
  db_user          = "foo"
  db_pass          = var.db_pass
}
  1. Use conditionals to determine whether to provision the DNS zone or use an existing one based on the environment (production or staging).
  ...
  create_dns_zone  = terraform.workspace == "production" ? true : false
  ...

Creating Production and Staging Environments

  1. Initialize Terraform using terraform init.

  2. Create a new environment called "production" using the command terraform workspace new production. To verify the creation, use terraform workspace list.

  3. Deploy the environment using terraform apply. Pass the sensitive database password during runtime.

  4. Once the production environment is created, create another environment called "staging" using terraform workspace new staging.

  5. Deploy the staging environment using terraform apply. Pass the sensitive database password during runtime.

  6. As a result, two copies of the web application will be running, one at MY_DOMAIN.com (production) and the other at staging.MY_DOMAIN.com (staging).

Two web applications

Cleanup

To avoid incurring additional costs by leaving the infrastructure running, you can destroy destroy both environments using the terraform destroy command.

You will need ot switch to each environment using the terraform workspace select WORKSPACE_NAME followed by terraform destroy

In this lesson, we demonstrated how to use Terraform Workspaces to manage multiple environments for our sample web application.

We created two environments, production and staging, and deployed the web application to both environments, all from the same codebase.