This repository demonstrates how to set up and manage multiple identical environments (Dev, UAT, and Prod) using Terraform Workspaces. Each environment will have 3 servers with unique naming conventions. The state management for each environment is handled separately using Terraform's state backend in S3 with DynamoDB for state locking.
- Terraform installed on your local machine.
- AWS CLI configured with proper permissions.
- S3 bucket for state backend.
- DynamoDB table for state file locking.
You will be deploying three environments:
- Dev: 3 Servers
- UAT: 3 Servers
- Prod: 3 Servers
Each environment will have its own Terraform .tfvars file to manage configuration differences like naming conventions.
Clone the base Terraform infrastructure and make the necessary changes to create multiple environments.
Create an S3 bucket to store Terraform state files and configure it as a backend in your main.tf. Ensure that the bucket is set up before proceeding.
- Rename the existing
terraform.tfvarstodev.tfvars. - Create
uat.tfvarsandprod.tfvarswith environment-specific changes (like naming conventions for servers).
terraform init
terraform validate
terraform fmtDeploy the infrastructure for each environment using the appropriate .tfvars file.
terraform apply -var-file=dev.tfvarsterraform workspace new uat
terraform apply -var-file=uat.tfvarsterraform workspace new prod
terraform apply -var-file=prod.tfvarsEach 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 prodEach workspace will create a separate folder in the S3 bucket to store the respective environment’s state file.
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"
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.htmlTo switch between environments, use the terraform workspace commands:
terraform workspace select dev
terraform plan -var-file=dev.tfvars
terraform apply -var-file=dev.tfvarsRepeat the process for UAT and Prod environments by selecting their respective workspaces.
After deployment, verify the public IP addresses of the servers in each environment.
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.tfvarsOnce the environments are destroyed, delete the workspaces:
terraform workspace delete dev
terraform workspace delete uat
terraform workspace delete prodTo avoid state file conflicts, implement state locking using DynamoDB.
-
Create a
dynamodb.tffile:resource "aws_dynamodb_table" "terraform_locks" { name = "terraform-state-lock" billing_mode = "PAY_PER_REQUEST" hash_key = "LockID" attribute { name = "LockID" type = "S" } }
-
Apply the DynamoDB configuration:
terraform apply
-
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 = "terraform-state-lock" }
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_locksOnce all the files are ready, push them to your GitHub repository:
git init
git add .
git commit -m "Initial commit for Terraform multi-environment setup"
git remote add origin https://github.com/your-username/terraform-multi-env.git
git push -u origin main- Clone the repository onto your local machine or remote instance:
git clone https://github.com/your-username/terraform-multi-env.git
- Run the Terraform commands to deploy the infrastructure:
terraform init terraform plan -var-file=dev.tfvars terraform apply -var-file=dev.tfvars
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.