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.
Table of contents
- Prerequisites
- Infrastructure Overview
- Step-by-Step Guide
- 1. Clone the Base Infrastructure
- 2. Setup State Backend
- 3. Create Environment-Specific .tfvars Files
- 4. Initialize and Validate Terraform
- 5. Managing State Files for Different Environments
- 6. Adding EC2 Instances
- 7. User Data Configuration
- 8. Switch Between Workspaces
- 9. Check Public IPs of All Servers
- 10. Clean Up (Destroy Infrastructure)
- 11. Delete Workspaces
- 12. DynamoDB for State Locking
- 13. Excluding DynamoDB from Terraform State
- Conclusion
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
todev.tfvars
.Create
uat.tfvars
andprod.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.
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:
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.