Back to Blog
Terminal window
Terminal window
February 20, 2024 6 min
Terraform Best Practices for Multi-Cloud Deployments
TerraformInfrastructure as CodeDevOpsCloud
Managing infrastructure across multiple cloud providers can quickly become complex. Here’s how I approach Terraform organization for maintainability and scalability.
Module Structure
A well-organized Terraform repository is crucial. Here’s the structure I recommend:
terraform/├── modules/│ ├── networking/│ │ ├── main.tf│ │ ├── variables.tf│ │ └── outputs.tf│ ├── compute/│ └── security/├── environments/│ ├── dev/│ ├── staging/│ └── prod/└── global/ └── iam/State Management
Remote state with locking is non-negotiable. Here’s how to configure it with S3 and DynamoDB:
terraform { backend "s3" { bucket = "my-terraform-state" key = "prod/infrastructure.tfstate" region = "us-east-1" encrypt = true dynamodb_table = "terraform-locks" }}Create the DynamoDB table for locking:
aws dynamodb create-table \ --table-name terraform-locks \ --attribute-definitions AttributeName=LockID,AttributeType=S \ --key-schema AttributeName=LockID,KeyType=HASH \ --billing-mode PAY_PER_REQUESTTesting Infrastructure
Use Terratest for automated testing of your modules. Here’s a simple example:
package test
import ( "testing" "github.com/gruntwork-io/terratest/modules/terraform" "github.com/stretchr/testify/assert")
func TestVpcModule(t *testing.T) { terraformOptions := &terraform.Options{ TerraformDir: "../modules/networking", Vars: map[string]interface{}{ "vpc_cidr": "10.0.0.0/16", "environment": "test", }, }
defer terraform.Destroy(t, terraformOptions) terraform.InitAndApply(t, terraformOptions)
vpcId := terraform.Output(t, terraformOptions, "vpc_id") assert.NotEmpty(t, vpcId)}Key Principles
- DRY (Don’t Repeat Yourself): Use modules for reusable components
- Immutable Infrastructure: Prefer replacement over modification
- Version Pinning: Always pin provider and module versions
terraform { required_version = ">= 1.5.0"
required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } }}For more on Terraform best practices, check out the official documentation.