Terraform Day 04 : Terraform Workspaces for Multi-Environment Infrastructure

Terraform Day 04 : Terraform Workspaces for Multi-Environment Infrastructure

This Blog demonstrates how to set up and manage multiple identical environments (Dev, UAT, and Prod) using Terraform Workspaces.

Prerequisites

  • Terraform installed on your local machine.

  • AWS CLI configured with proper permissions.

  • S3 bucket for state backend.

  • DynamoDB table for state file locking.

Infrastructure Overview

You will be deploying three environments:

  • Dev: 1 Server

  • UAT: 1 Server

  • Prod: 1 Server

Each environment will have its own Terraform .tfvars file to manage configuration differences like naming conventions.

Step-by-Step Guide

1. Clone the Base Infrastructure

Clone the base Terraform infrastructure and make the necessary changes to create multiple environments.
https://github.com/imkiran13/Mastering-Terraform.git

2. Setup State Backend

Create an S3 bucket to store Terraform state files and enable versioning if someone deletes state file we can take backup of it, configure it as a backend in your main.tf. Ensure that the bucket is set up before proceeding.

3. Create Environment-Specific .tfvars Files

  • Rename the existing terraform.tfvars to dev.tfvars.

  • Create uat.tfvars and prod.tfvars with environment-specific changes (like naming conventions for servers).

4. Initialize and Validate Terraform

terraform init
terraform validate
terraform fmt

5. Managing State Files for Different Environments

Each environment requires a separate state file. If you use the same state backend without separating the state files, Terraform will attempt to apply changes across environments.

To manage state files for different environments, use Terraform workspaces:

terraform workspace new dev
terraform workspace new uat
terraform workspace new prod

Each workspace will create a separate folder in the S3 bucket to store the respective environment’s state file

Check S3 bucket you will see all workspaces environments

6. Adding EC2 Instances

Modify the ec2.tf file to add the EC2 instance configurations:

  • Use different AMI IDs for each environment.

  • Example of setting the server name:

      server_name = "${var.env}-Server-1"
    

7. User Data Configuration

Add user data to the EC2 instances to update the web server’s index page:

#!/bin/bash
echo "Hello from ${var.env}" > /var/www/html/index.nginx-debian.html

8. Switch Between Workspaces

To switch between environments, use the terraform workspace commands:

terraform workspace select dev
terraform plan -var-file=dev.tfvars
terraform apply --auto-approve -var-file=dev.tfvars

Repeat the process for UAT and Prod environments by selecting their respective workspaces.

9. Check Public IPs of All Servers

After deployment, verify the public IP addresses of the servers in each environment.

10. Clean Up (Destroy Infrastructure)

To destroy resources from each environment:

terraform workspace select prod
terraform destroy -var-file=prod.tfvars

terraform workspace select dev
terraform destroy -var-file=dev.tfvars

terraform workspace select uat
terraform destroy -var-file=uat.tfvars

11. Delete Workspaces

Once the environments are destroyed, delete the workspaces:

terraform workspace delete dev
terraform workspace delete uat
terraform workspace delete prod

12. DynamoDB for State Locking

To avoid state file conflicts, implement state locking using DynamoDB.

  1. Create a dynamodb.tf file:

     resource "aws_dynamodb_table" "terraform_locks" {
       name         = "dynamodb-state-lock"
       billing_mode = "PAY_PER_REQUEST"
       hash_key     = "LockID"
    
       attribute {
         name = "LockID"
         type = "S"
       }
     }
    

    2.Add the DynamoDB state locking configuration to your backend in main.tf:

     backend "s3" {
       bucket         = "your-s3-bucket"
       key            = "path/to/terraform.tfstate"
       region         = "us-west-2"
       dynamodb_table = "dynamodb-state-lock"
     }
    

3.Apply the DynamoDB configuration:

  1.  terraform apply --auto-approve
    

13. Excluding DynamoDB from Terraform State

If you wish to manage DynamoDB outside of Terraform to prevent it from being destroyed, remove it from the state file:

terraform state rm aws_dynamodb_table.terraform_locks

Conclusion

This project demonstrates how to manage multiple identical environments (Dev, UAT, Prod) using Terraform Workspaces, S3 for state management, and DynamoDB for state locking. Be sure to separate your environments' state files to avoid conflicts and manage infrastructure more effectively.

Feel free to explore, modify, and extend this setup for your own infrastructure needs.