Terraform Team Collaboration
Introduction
When working with Terraform in a team environment, collaboration becomes crucial for maintaining consistent, reliable infrastructure. While Terraform is powerful for individual use, it truly shines when teams collaborate effectively to manage infrastructure as code. This guide explores best practices for Terraform team collaboration, helping you transition from solo development to efficient team workflows.
Terraform team collaboration involves:
- Sharing and managing Terraform state
- Organizing code for multiple contributors
- Establishing consistent workflows and standards
- Implementing proper version control practices
- Setting up collaboration tools and processes
Let's dive into how you can set up your team for success with Terraform.
State Management in Team Environments
Remote State Storage
When working alone, local state files might suffice. In a team environment, remote state storage becomes essential.
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "prod/terraform.tfstate"
region = "us-west-2"
dynamodb_table = "terraform-locks"
encrypt = true
}
}
This configuration:
- Stores state in an S3 bucket
- Uses DynamoDB for state locking
- Encrypts the state file for security
State Locking
State locking prevents concurrent modifications that could corrupt your infrastructure state.
terraform {
backend "azurerm" {
resource_group_name = "tfstate"
storage_account_name = "tfstate1234"
container_name = "tfstate"
key = "prod.terraform.tfstate"
}
}
Output when another team member tries to apply changes simultaneously:
Error: Error locking state: Error acquiring the state lock: storage: service returned error:
StatusCode=409, ErrorCode=LeaseAlreadyPresent, ErrorMessage=There is already a lease present.
Workspace Isolation
Use workspaces to isolate different environments or team projects:
# Create and switch to a new workspace
terraform workspace new dev-feature-x
# List available workspaces
terraform workspace list
# Select a workspace
terraform workspace select dev-feature-x
Code Organization for Team Collaboration
Module Sharing
Create shared modules for common infrastructure patterns:
project-root/
├── modules/
│ ├── networking/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ └── database/
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
├── prod/
│ ├── main.tf
│ └── terraform.tfvars
└── dev/
├── main.tf
└── terraform.tfvars
Example module usage:
module "vpc" {
source = "../modules/networking"
vpc_cidr = "10.0.0.0/16"
environment = "production"
}
Repository Structure
Organize repositories to support team collaboration:
Workflow Standardization
Terraform Version Control
Use .terraform-version
files to standardize Terraform versions across team members:
# .terraform-version
1.5.4
Combined with tools like tfenv
, this ensures consistent Terraform versions.
Pre-commit Hooks
Implement pre-commit hooks to maintain code quality:
# .pre-commit-config.yaml
repos:
- repo: https://github.com/antonbabenko/pre-commit-terraform
rev: v1.77.1
hooks:
- id: terraform_fmt
- id: terraform_docs
- id: terraform_tflint
- id: terraform_validate
This configuration:
- Formats Terraform code consistently
- Updates documentation automatically
- Performs static analysis
- Validates Terraform configurations
Documentation Standards
Standardize documentation for modules:
/**
* # Networking Module
*
* This module creates a standard VPC with public and private subnets.
*
* ## Usage
* ```hcl
* module "vpc" {
* source = "./modules/networking"
* vpc_cidr = "10.0.0.0/16"
* }
* ```
*/
variable "vpc_cidr" {
description = "CIDR block for the VPC"
type = string
}
Collaborative Development Practices
Pull Request Workflow
Implement a pull request workflow for Terraform changes:
- Create a feature branch
- Make infrastructure changes
- Run
terraform plan
and commit the plan output - Open a pull request with the plan output
- Review the plan as a team
- Merge and apply changes
Example plan output to include in PR description:
Terraform will perform the following actions:
# aws_instance.example will be created
+ resource "aws_instance" "example" {
+ ami = "ami-0c55b159cbfafe1f0"
+ instance_type = "t2.micro"
+ vpc_security_group_ids = [
+ "sg-12345678",
]
# ... other attributes
}
Plan: 1 to add, 0 to change, 0 to destroy.
CI/CD Integration
Integrate Terraform with CI/CD pipelines:
# .github/workflows/terraform.yml
name: "Terraform"
on:
push:
branches: [ main ]
pull_request:
jobs:
terraform:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
- name: Terraform Format
run: terraform fmt -check
- name: Terraform Init
run: terraform init
- name: Terraform Validate
run: terraform validate
- name: Terraform Plan
run: terraform plan -no-color
if: github.event_name == 'pull_request'
Managing Secrets and Variables
Variable Hierarchy
Implement a variable hierarchy to manage environment-specific values:
project/
├── terraform.tfvars # Common variables
├── prod.tfvars # Production overrides
├── staging.tfvars # Staging overrides
└── dev.tfvars # Development overrides
Example variable file:
# terraform.tfvars - Common variables
region = "us-west-2"
instance_type = "t2.micro"
# prod.tfvars - Production overrides
instance_type = "t2.large"
high_availability = true
Secret Management
Use secure methods to manage sensitive variables:
# Using environment variables
provider "aws" {
region = var.region
access_key = var.aws_access_key
secret_key = var.aws_secret_key
}
# Export secrets as environment variables
export TF_VAR_aws_access_key="AKIAIOSFODNN7EXAMPLE"
export TF_VAR_aws_secret_key="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
Real-world Team Collaboration Example
Let's walk through a complete example of how a team might collaborate on a Terraform project.
Project Structure
terraform-project/
├── .github/
│ └── workflows/
│ └── terraform.yml
├── modules/
│ ├── networking/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ └── webserver/
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
├── environments/
│ ├── dev/
│ │ ├── main.tf
│ │ └── terraform.tfvars
│ └── prod/
│ ├── main.tf
│ └── terraform.tfvars
└── README.md
Workflow Example
-
New Feature Development
Developer creates a new branch for a feature:
bashgit checkout -b feature/add-load-balancer
-
Module Development
Create a new load balancer module:
hcl# modules/load_balancer/main.tf
resource "aws_lb" "example" {
name = var.lb_name
internal = var.internal
load_balancer_type = "application"
security_groups = var.security_groups
subnets = var.subnets
enable_deletion_protection = var.environment == "prod" ? true : false
tags = {
Environment = var.environment
Project = var.project_name
}
} -
Module Usage
Update the environment configuration:
hcl# environments/dev/main.tf
module "vpc" {
source = "../../modules/networking"
vpc_cidr = "10.0.0.0/16"
environment = "dev"
}
module "load_balancer" {
source = "../../modules/load_balancer"
lb_name = "dev-lb"
internal = false
security_groups = [module.vpc.security_group_id]
subnets = module.vpc.public_subnets
environment = "dev"
project_name = "example-project"
} -
Local Testing
bashcd environments/dev
terraform init
terraform plan -
Pull Request
bashgit add .
git commit -m "Add load balancer module and implement in dev environment"
git push origin feature/add-load-balancer
# Create PR through GitHub interface -
CI Process
The CI pipeline automatically runs:
- Terraform format check
- Terraform init
- Terraform validate
- Terraform plan
-
Code Review
Team members review:
- The module implementation
- The plan output
- Security considerations
- Compliance with team standards
-
Approval and Merge
After approval, the PR is merged to main.
-
Deployment
bashcd environments/dev
terraform apply
Summary
Effective Terraform team collaboration requires:
- Remote State Management: Implement remote state storage with locking to prevent conflicts.
- Code Organization: Structure your code with modules and consistent repository organization.
- Workflow Standardization: Establish consistent practices for versioning, formatting, and documentation.
- Collaboration Tools: Use pull requests, code reviews, and CI/CD pipelines.
- Security Practices: Implement secure methods for managing secrets and sensitive data.
By following these practices, your team can work together efficiently on Terraform projects, reducing conflicts and maintaining infrastructure consistency across environments.
Additional Resources
- Terraform Registry - Discover and use pre-built modules
- Terraform Cloud - Managed service for Terraform state and workflows
- Atlantis - Terraform pull request automation
- Terragrunt - Thin wrapper for Terraform that provides extra tools for working with multiple Terraform modules
Exercises
- Set up a remote state backend for your Terraform project using S3 or another provider.
- Create a reusable module for a common infrastructure component your team uses.
- Implement a GitHub Actions workflow for Terraform validation and planning.
- Practice a pull request workflow with a team member, including code review of Terraform changes.
- Configure workspace isolation for different environments in your Terraform project.
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)