Setting Up an Enterprise-Grade Terraform Workflow

Terraform is a powerful infrastructure-as-code (IaC) tool that enables consistent, repeatable, and reliable management of cloud resources. When building Terraform projects at an enterprise scale, structuring your repository correctly is crucial. A well-organized Terraform project simplifies development, fosters collaboration, enhances maintainability, and ensures security best practices. In this comprehensive guide, we'll establish a clear, modular, and highly maintainable Terraform project structure suitable for enterprises. We’ll deeply explore each component to ensure clarity and facilitate smooth implementation.
Recommended Directory Structure
Detailed Explanation of Structure
1. environments/
Separates Terraform configurations by deployment stages:
dev/: Lightweight for rapid development.
stage/: Mirrors production for testing.
prod/: Optimized for production-grade deployments.
Each environment contains:
main.tf
: Infrastructure module definitions.terraform.tfvars
: Environment-specific variables.backend.tf
: Terraform state management configurations.
2. modules/
Understanding Modules in Terraform
Terraform modules encapsulate reusable infrastructure components, making your Terraform configurations modular, organized, and maintainable. Modules simplify the management of infrastructure, prevent repetitive code, and enable standardization across different environments.
Components of a Terraform Module
Each module typically contains:
main.tf: Defines core resources and their relationships.
variables.tf: Defines inputs (parameters) that can be customized when calling the module.
outputs.tf: Specifies outputs, enabling modules to expose resource attributes that other configurations can reference.
README.md: Detailed documentation and usage examples for the module.
Example Module: VPC Module
main.tf
resource "aws_vpc" "main" {
cidr_block = var.vpc_cidr
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "main-vpc"
}
}
variables.tf
variable "vpc_cidr" {
description = "CIDR block for the VPC"
type = string
}
outputs.tf
output "vpc_id" {
description = "The ID of the created VPC"
value = aws_vpc.main.id
}
Calling Modules
Modules are invoked from your environment configurations (environments/dev/main.tf
):
module "vpc" {
source = "../../modules/vpc"
vpc_cidr = var.vpc_cidr
}
Here:
source
specifies the relative path to the module.vpc_cidr
is an input variable passed to the module, defined in your environment's variables.
Module Outputs and Dependencies
Module outputs allow seamless integration and dependency management:
module "ecs" {
source = "../../modules/ecs"
cluster_name = var.ecs_cluster_name
vpc_id = module.vpc.vpc_id
}
This example uses vpc_id
output from the VPC module as input to the ECS module.Each module:
3. scripts/
Utility scripts to enhance workflow automation:
deploy.sh
: Streamlines deployment with confirmation steps.A Sample deploy script is as follows
#!/bin/bash set -e ENVIRONMENT=$1 if [[ -z "$ENVIRONMENT" ]]; then echo "Usage: ./deploy.sh <environment>" echo "Example: ./deploy.sh dev" exit 1 fi WORKING_DIR="./environments/$ENVIRONMENT" if [[ ! -d "$WORKING_DIR" ]]; then echo "Error: Environment '$ENVIRONMENT' does not exist in $WORKING_DIR" exit 1 fi echo "============================" echo "Terraform Deployment Script" echo "Environment: $ENVIRONMENT" echo "Working Dir: $WORKING_DIR" echo "============================" cd "$WORKING_DIR" echo "Initializing Terraform..." terraform init echo "Validating Terraform code..." terraform validate echo "Running Terraform Plan..." terraform plan -var-file="terraform.tfvars" echo "" read -p "Do you want to apply these changes? (yes/no): " CONFIRM if [[ "$CONFIRM" == "yes" ]]; then echo "Applying Terraform changes..." terraform apply -auto-approve -var-file="terraform.tfvars" echo "Terraform apply complete." else echo "Aborted by user." exit 0 fi
same way we can write script for destroy
destroy.sh
: Safely destroys environments.validate.sh
: Runs format checks and validation plans.
4. Automated GitHub Actions Workflow
File location: .github/workflows/terraform-ci.yml
name: Terraform CI/CD
on:
push:
branches:
- main
- develop
- feature/*
pull_request:
branches:
- main
- develop
jobs:
terraform:
runs-on: ubuntu-latest
strategy:
matrix:
environment: [dev, stage, prod]
steps:
- uses: actions/checkout@v4
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: '1.10.0'
- name: Terraform Init
working-directory: ./environments/${{ matrix.environment }}
run: terraform init
- name: Terraform Validate
working-directory: ./environments/${{ matrix.environment }}
run: terraform validate
- name: Terraform Plan
working-directory: ./environments/${{ matrix.environment }}
run: terraform plan -var-file="terraform.tfvars"
- name: Terraform Apply
if: (github.ref == 'refs/heads/main' && matrix.environment == 'prod') ||
(github.ref == 'refs/heads/develop' && matrix.environment == 'stage') ||
(startsWith(github.ref, 'refs/heads/feature/') && matrix.environment == 'dev')
working-directory: ./environments/${{ matrix.environment }}
run: terraform apply -auto-approve -var-file="terraform.tfvars"
5. Detailed Branching Strategy
Main: Production deployments.
Develop: Stage deployments and integration.
Feature branches (
feature/*
): Development and testing in dev.
6. Terraform Workflow Summary
terraform init
terraform plan -var-file="terraform.tfvars"
terraform apply -var-file="terraform.tfvars"
terraform destroy -var-file="terraform.tfvars"
7. .gitignore
Protects sensitive state files:
.terraform/
*.tfstate
*.tfstate.backup
*.tfvars
*.log
8. terraform.tfvars.example
Example variable definitions to guide configuration.
aws_region = "us-west-2"
vpc_cidr = "10.0.0.0/16"
ecs_cluster_name = "example-cluster"
9. README.md
Write a Comprehensive documentation covering setup, usage, troubleshooting, and contributions which makes more easy to guide new engineers onboarding.
Conclusion
A meticulously structured enterprise-grade Terraform repository ensures scalability, maintainability, and security. Detailed documentation, clear module separation, and robust automation through GitHub Actions significantly streamline the management of cloud infrastructure, improving operational efficiency and DevOps productivity.
Subscribe to my newsletter
Read articles from aditya narra directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
