TLDR: This blog post explores Terraform workspaces, explaining their purpose, how to create and switch between them, and demonstrating their practical application in managing multiple environments without duplicating code. It emphasizes the importance of workspaces in maintaining separate state files for different environments, thus preventing conflicts and simplifying infrastructure management.
In this blog post, we will delve into the concept of Terraform workspaces, a powerful feature that allows developers to manage multiple environments efficiently. This is part of the Terraform Zero to Hero series, and today we will cover what workspaces are, why they are essential, and how to implement them in your projects.
create s3+ec2 |
modular approach → to re-use the code block by different development team |
but for diff stage environment → dev,stage, pre-prod, prod → we would not able to maintain diff state file → state file will be overridden |
Terraform workspaces → each stage will have separate folder → dev folder, stage folder, pre-prod folder, prod folder → each folder will have there own state file → dev folder → state file, stage folder → state file …. → this solves state file overridden issue |
commands |
terraform workspace new <workspace_name> |
terraform workspace new dev |
terraform workspace new stage |
terraform workspace new prod |
tree → terraform.tfstate.d → dev,stage,prod |
terraform workspace select <workspace_name> |
terraform workspace select dev |
terraform workspace show → display current work space → dev |
terraform init |
terraform plan |
terraform apply |
tree → terraform.tfstate.d → dev[terraform.tfstate],stage,prod |
create seperte tfvars for all stages → prod.tfvars,dev.tfvars,stage.tfvars → instated of single terraform.tfvars |
terraform workspace select prod |
terraform apply -var-file=prod.tfvars |
so selected workspace is prod , also select prod.tfvars → t2.xlarge type of instance is created |
lookup [module] + map [variable]→ dynamically apply variables according to selected workspace → single terraform.tfvars |
terraform workspace select prod |
terraform apply |
so selected workspace is prod → t2.xlarge type of instance is created |
// Day6/module/ec2_instance/main.tf
provider "aws" {
region = "us-east-1"
}
variable "ami" {
description = "This is AMI for the instance"
}
variable "instance_type" {
description = "This is the instance type, for example: t2.micro"
}
resource "aws_instance" "example" {
ami = var.ami
instance_type = var.instance_type
}
// Day6/main.tf
provider "aws" {
region = "us-east-1"
}
variable "ami" {
description = "value"
}
variable "instance_type" {
description = "value"
type = map(string)
default = {
"dev" = "t2.micro"
"stage" = "t2.medium"
"prod" = "t2.xlarge"
}
}
module "ec2_instance" {
source = "./modules/ec2_instance"
ami = var.ami
instance_type = lookup(var.instance_type, terraform.workspace, "t2.micro")
}
// Day6/terraform.tfvars
ami = "ami-053b0d53c279acc90"
What are Terraform Workspaces?
Terraform workspaces are a way to manage different environments (like development, staging, and production) within a single Terraform configuration. They allow you to maintain separate state files for each environment, preventing conflicts and simplifying infrastructure management.
The Problem Workspaces Solve
Consider a scenario where a development team needs to set up an EC2 instance and an S3 bucket on AWS. Instead of creating separate Terraform configurations for each environment, workspaces enable you to write a single configuration that can be reused across multiple environments. This approach not only saves time but also reduces the risk of errors that can occur when managing multiple configurations.
Creating and Managing Workspaces
Creating Workspaces
To create a new workspace, you can use the following command:
terraform workspace new <workspace_name>
For example, to create a workspace for development, you would run:
terraform workspace new dev
This command creates a new directory for the state files associated with the dev
workspace.
Switching Between Workspaces
To switch between workspaces, use the command:
terraform workspace select <workspace_name>
For instance, to switch to the staging workspace, you would run:
terraform workspace select stage
You can check your current workspace with:
terraform workspace show
Practical Demonstration
Now, let's see how to set up Terraform workspaces in a practical scenario. We will create a simple Terraform module for an EC2 instance and demonstrate how to use workspaces to manage different environments.
Step 1: Setting Up the Module
First, create a folder for your module and define the EC2 instance configuration in a main.tf
file. Here’s a basic example:
provider "aws" {
region = "us-east-1"
}
resource "aws_instance" "example" {
ami = var.ami
instance_type = var.instance_type
}
variable "ami" {}
variable "instance_type" {}
Step 2: Using the Module
Next, in your main project directory, create a main.tf
file that uses this module. You can specify the instance type based on the workspace:
module "ec2_instance" {
source = "./modules/ec2_instance"
ami = var.ami
instance_type = lookup(var.instance_types, terraform.workspace, "t2.micro")
}
variable "ami" {}
variable "instance_types" {
type = map(string)
default = {
dev = "t2.micro"
stage = "t2.medium"
prod = "t2.xlarge"
}
}
Step 3: Initializing and Applying the Configuration
After setting up your configuration, initialize Terraform:
tf init
Then, create the workspaces for each environment:
terraform workspace new dev
terraform workspace new stage
terraform workspace new prod
Now, switch to the dev
workspace and apply the configuration:
terraform workspace select dev
terraform apply
Repeat the process for the stage
and prod
workspaces, switching to each and applying the configuration. Each workspace will maintain its own state file, ensuring that changes in one environment do not affect the others.
Conclusion
Terraform workspaces are an essential tool for managing multiple environments within a single Terraform project. By using workspaces, you can avoid duplicating code, maintain separate state files, and streamline your infrastructure management process. This approach is particularly beneficial for DevOps engineers who need to manage complex configurations across various environments.
As you continue to work with Terraform, remember to leverage workspaces to enhance your workflow and reduce the risk of errors. Happy coding!