
Terraform by HashiCorp is a powerful tool for managing infrastructure as code (IaC). One of its standout features is the concept of workspaces, which allow for managing multiple environments (e.g., development, UAT, production) within a single configuration. This capability is particularly useful in CI/CD and DevOps workflows, enabling streamlined deployments across various environments. In this blog, we’ll explore Terraform workspaces in-depth, including practical examples and a use case involving a GitLab AutoDevOps pipeline for deploying to development, UAT, and production environments.
What are Terraform Workspaces?
Terraform workspaces provide a mechanism to manage multiple states and configurations within a single Terraform configuration directory. Each workspace has its own state file, allowing you to deploy the same configuration to different environments without overwriting state data. This makes workspaces ideal for separating environments like development, staging, and production.
Benefits of Using Terraform Workspaces
- Isolation: Each workspace has its own state file, ensuring that changes in one environment do not affect others.
- Consistency: Using the same configuration for multiple environments ensures consistency in infrastructure deployments.
- Scalability: Easily scale your infrastructure across multiple environments without duplicating configuration files.
Implementing Workspaces
Let’s start by creating and managing workspaces with Terraform.
Example: Creating Workspaces
# Initialize Terraform (if not already initialized)
terraform init
# Create new workspaces
terraform workspace new dev
terraform workspace new uat
terraform workspace new prod
# Select a workspace
terraform workspace select dev
Example: Using Workspace-Specific Variables
You can define environment-specific variables by referencing the current workspace in your configuration.
variable "environment" {
description = "The current environment"
type = string
default = terraform.workspace
}
resource "aws_s3_bucket" "example" {
bucket = "my-app-${var.environment}-bucket"
acl = "private"
}
In this example, the S3 bucket name is dynamically generated based on the current workspace, ensuring each environment has a unique bucket.
Use Case: CI/CD Pipeline with GitLab AutoDevOps
Let’s implement a CI/CD pipeline using GitLab AutoDevOps to deploy Terraform configurations to development, UAT, and production environments.
GitLab CI/CD Configuration
Create a .gitlab-ci.yml
file to define the pipeline stages and jobs for each environment.
stages:
- validate
- plan
- apply
variables:
TF_VERSION: "1.0.0"
TF_ROOT: ${CI_PROJECT_DIR}/terraform
cache:
paths:
- .terraform
before_script:
- terraform --version
- terraform init -backend-config="bucket=my-terraform-state-bucket"
validate:
stage: validate
script:
- terraform validate
.plan_template: &plan_definition
stage: plan
script:
- terraform workspace select ${ENVIRONMENT}
- terraform plan -out=planfile
artifacts:
paths:
- planfile
.apply_template: &apply_definition
stage: apply
script:
- terraform workspace select ${ENVIRONMENT}
- terraform apply -auto-approve planfile
plan:dev:
<<: *plan_definition
variables:
ENVIRONMENT: dev
plan:uat:
<<: *plan_definition
variables:
ENVIRONMENT: uat
plan:prod:
<<: *plan_definition
variables:
ENVIRONMENT: prod
apply:dev:
<<: *apply_definition
when: manual
variables:
ENVIRONMENT: dev
apply:uat:
<<: *apply_definition
when: manual
variables:
ENVIRONMENT: uat
apply:prod:
<<: *apply_definition
when: manual
variables:
ENVIRONMENT: prod
Explanation
- Stages: The pipeline is divided into three stages:
validate
,plan
, andapply
. - Variables: The
TF_VERSION
andTF_ROOT
variables define the Terraform version and root directory. - Cache: Caching the
.terraform
directory speeds up the pipeline by reusing downloaded provider plugins. - before_script: Common setup commands, including initializing Terraform with the backend configuration.
- validate: Validates the Terraform configuration.
- plan_template: A reusable template for the
plan
stage, selecting the appropriate workspace and generating a plan file. - apply_template: A reusable template for the
apply
stage, applying the plan file to the selected workspace. - plan: Defines the
plan
jobs fordev
,uat
, andprod
environments, using theplan_template
. - apply: Defines the
apply
jobs fordev
,uat
, andprod
environments, using theapply_template
and setting them tomanual
to ensure controlled deployments.
Terraform workspaces offer a powerful way to manage multiple environments within a single configuration, enhancing the efficiency and scalability of your infrastructure deployments. By integrating workspaces into a GitLab AutoDevOps pipeline, you can streamline your CI/CD workflows, ensuring consistent and isolated deployments across development, UAT, and production environments.
Using the example provided, you can set up a robust pipeline that automates the deployment process, reduces manual errors, and maintains consistency across environments. Embrace Terraform workspaces and CI/CD best practices to take your infrastructure management to the next level. Happy coding!