Mastering Terraform Workspaces

In today’s blog post, we will learn terraform workspaces. In particular, how to list, create, switch, show, delete workspaces, how to use workspaces in terraform withe example and workspaces best practices.

What Is Terraform Workspaces?

A Terraform workspace provides a way to manage multiple distinct instances of a single Terraform configuration within the same working directory. Each workspace has its own independent state file, which tracks the resources managed by that specific instance of your configuration. This isolation of state helps in managing different environments.

Why Use Terraform Workspaces?

Many users wonder if they should use separate directories for each environment or use Terraform workspaces. The answer depends on the nature of the differences between your environments.

Terraform workspaces are particularly useful when your environments share the same basic infrastructure layout but have minor differences. These differences might include:

  • Varying resource sizes: For example, a development environment might use smaller instance types compared to a production environment.
  • Different database sizes or configurations: You might need a larger database for production.
  • Feature flags or minor configuration changes: Enabling or disabling certain features based on the environment.

The key benefit of using workspaces in these scenarios is code reusability. You maintain a single set of Terraform configuration files, reducing code duplication and making updates easier. When you switch between workspaces, Terraform automatically uses the corresponding state file, ensuring that operations are applied to the correct environment.

However, it is important to note that workspaces are generally not recommended for environments with major differences, such as:

  • Different cloud regions: If your production environment is in us-east-1 and staging is in eu-west-1, separate directories or alternative patterns might be more suitable.
  • Distinct networking setups: Complex and fundamentally different network architectures across environments.
  • Unique security policies or access controls: When strict isolation of credentials and access is required, separate root modules or approaches like Terragrunt might be preferred.

In summary, use workspaces when your environments are largely similar, requiring only parameter variations. For significantly diverse environments, consider a modular approach with separate root directories.

Common Terraform Workspace Commands

Terraform provides a straightforward set of commands to manage workspaces.

Initializing a Workspace

Before you can create or select workspaces, you need to initialize your Terraform directory.

# Initializes a Terraform working directory
terraform init

This command performs backend initialization, downloads necessary plugins, and prepares your directory for Terraform operations.

Listing Workspaces

To see all available workspaces for your current configuration, use the list command.

# Lists all existing workspaces
terraform workspace list

The output will show a list of workspaces, with an asterisk (*) indicating the currently selected workspace. By default, Terraform starts with a default workspace.

Creating a New Workspace

You can create a new workspace using the new command.

# Creates a new workspace named 'staging'
terraform workspace new staging

After creation, Terraform automatically switches to the newly created workspace. If you were to run terraform plan immediately after, it would operate on a new, empty state specific to the staging workspace.

Switching Workspaces

To switch between existing workspaces, use the select command.

# Switches to the 'production' workspace
terraform workspace select production

This command changes the active workspace, meaning all subsequent terraform plan and terraform apply operations will interact with the state file associated with the selected workspace.

Showing the Current Workspace

If you are unsure which workspace is currently active, you can use the show command.

# Shows the name of the current workspace
terraform workspace show

This will simply print the name of the active workspace to your console.

Deleting a Workspace

To remove a workspace, use the delete command.

# Deletes the 'dev' workspace
terraform workspace delete dev

Important Note: Deleting a workspace does not destroy the infrastructure managed by that workspace. It only removes the workspace’s state file. You should always run terraform destroy in a workspace before deleting it if you intend to tear down the associated resources.

Using Workspaces in Your Configuration

You can make your Terraform configuration behave differently based on the active workspace using the terraform.workspace interpolation syntax. This variable contains the name of the current workspace.

Here is an example demonstrating how to use terraform.workspace to adjust resource properties:

# main.tf

# Define a variable for instance type, with different defaults based on workspace
variable "instance_type" {
  description = "The EC2 instance type."
  type        = string
  default     = "t2.micro" # Default for 'default' workspace or general use
}

# Define an EC2 instance resource
resource "aws_instance" "example" {
  # Select AMI based on your region and requirements
  ami           = "ami-0xxxxxxxxxxxxxx" 
  instance_type = var.instance_type # Use the variable for instance type

  tags = {
    Name        = "${terraform.workspace}-example-instance" # Tag instance with workspace name
    Environment = terraform.workspace # Another tag for environment
  }

  # Conditional scaling: if it's the 'production' workspace, create 2 instances; otherwise, 1
  count = terraform.workspace == "production" ? 2 : 1 
}

# Output the instance ID
output "instance_id" {
  description = "The ID of the EC2 instance."
  value       = aws_instance.example[0].id # Access the first instance in the count
}

Explanation of the code:

  • The instance_type variable has a default value. You could override this in your terraform.tfvars or command line arguments for specific workspaces if needed.
  • The tags block uses terraform.workspace to dynamically name and tag the instances, making it easy to identify resources belonging to a specific environment in your cloud provider console.
  • The count argument shows conditional resource creation. If the current workspace is “production”, it will create two instances; otherwise, it will create one. This is a common pattern for scaling resources differently across environments.

Best Practices and Considerations

While powerful, it is important to use Terraform workspaces wisely and follow best practices:

  • Remote State: Always use a remote backend (like S3, Azure Blob Storage, or Terraform Cloud) to store your Terraform state. This is essential for collaboration and prevents accidental loss or corruption of your state file. Workspaces work by creating separate state files within the remote backend.
  • State Locking: Ensure your backend supports state locking to prevent concurrent operations that could lead to inconsistencies or corruption of your state files.
  • Version Control: Always keep your Terraform configuration files in a version control system like Git. This allows you to track changes, revert to previous versions, and collaborate effectively.
  • Variable Management: While terraform.workspace is useful for simple variations, for more complex environment-specific configurations, consider using .tfvars files with environment-specific values. For example, dev.tfvars, staging.tfvars, prod.tfvars, and then load them with terraform apply -var-file=dev.tfvars.
  • Avoid Over-reliance: For major architectural differences or entirely separate resource sets across environments, creating separate root modules in distinct directories often provides better isolation and clarity than relying solely on workspaces. Tools like Terragrunt can also help manage multiple environments with reduced code duplication.
  • Naming Conventions: Establish clear naming conventions for your workspaces (e.g., dev, staging, production, feature-branch-xyz) to avoid confusion.

Conclusion

Terraform workspaces offer a valuable mechanism for managing multiple environments with minimal differences using a single set of Terraform configuration files. By understanding their purpose, basic concepts, commands, and applying best practices, you can effectively streamline your infrastructure provisioning workflows and maintain a clean, reusable codebase. Remember to assess whether workspaces are the right fit for your specific environment management needs, or if a more isolated, directory-based approach would be more suitable.

Author

Debjeet Bhowmik

Experienced Cloud & DevOps Engineer with hands-on experience in AWS, GCP, Terraform, Ansible, ELK, Docker, Git, GitLab, Python, PowerShell, Shell, and theoretical knowledge on Azure, Kubernetes & Jenkins. In my free time, I write blogs on ckdbtech.com

Leave a Comment