Terraform Archive Provider - Create ZIP and TAR Files
Use the Terraform archive provider to create ZIP files for Lambda functions, Cloud Functions, and deployments. archive_file data source with source_dir and...
Terraform
Learn how to structure Terraform projects for teams. File organization, module layout, environment separation, naming conventions, and monorepo vs multi-repo.
Separate files by purpose (main.tf, variables.tf, outputs.tf), use modules for reusable components, and split environments with separate directories or workspaces. Keep each root module focused on one concern (network, compute, database).
project/
├── main.tf # Resources
├── variables.tf # Input variable declarations
├── outputs.tf # Output value declarations
├── locals.tf # Local value computations
├── providers.tf # Provider configuration
├── versions.tf # Required versions
├── terraform.tfvars # Variable values (don't commit secrets)
└── README.mdinfrastructure/
├── main.tf
├── variables.tf
├── outputs.tf
├── providers.tf
├── terraform.tfvars
└── modules/
└── vpc/
├── main.tf
├── variables.tf
└── outputs.tfinfrastructure/
├── modules/
│ ├── networking/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ ├── compute/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ └── database/
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
├── environments/
│ ├── dev/
│ │ ├── main.tf # Calls modules
│ │ ├── variables.tf
│ │ ├── terraform.tfvars
│ │ └── backend.tf
│ ├── staging/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ ├── terraform.tfvars
│ │ └── backend.tf
│ └── prod/
│ ├── main.tf
│ ├── variables.tf
│ ├── terraform.tfvars
│ └── backend.tf
└── README.mdinfrastructure/
├── modules/ # Shared modules
│ ├── vpc/
│ ├── eks-cluster/
│ ├── rds-postgres/
│ └── monitoring/
├── live/ # Deployed infrastructure
│ ├── production/
│ │ ├── networking/ # Separate state per component
│ │ │ ├── main.tf
│ │ │ └── backend.tf # s3://state/prod/networking
│ │ ├── cluster/
│ │ │ ├── main.tf
│ │ │ └── backend.tf # s3://state/prod/cluster
│ │ └── database/
│ │ ├── main.tf
│ │ └── backend.tf # s3://state/prod/database
│ └── staging/
│ ├── networking/
│ ├── cluster/
│ └── database/
└── README.md# modules/vpc/main.tf
resource "aws_vpc" "this" {
cidr_block = var.cidr_block
enable_dns_hostnames = true
tags = merge(var.tags, { Name = var.name })
}
resource "aws_subnet" "public" {
count = length(var.public_subnets)
vpc_id = aws_vpc.this.id
cidr_block = var.public_subnets[count.index]
availability_zone = var.azs[count.index]
tags = merge(var.tags, { Name = "${var.name}-public-${count.index}" })
}
# modules/vpc/variables.tf
variable "name" { type = string }
variable "cidr_block" { type = string }
variable "public_subnets" { type = list(string) }
variable "azs" { type = list(string) }
variable "tags" { type = map(string) default = {} }
# modules/vpc/outputs.tf
output "vpc_id" { value = aws_vpc.this.id }
output "subnet_ids" { value = aws_subnet.public[*].id }# environments/dev/main.tf
module "network" {
source = "../../modules/vpc"
name = "dev-vpc"
cidr_block = "10.0.0.0/16"
public_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
azs = ["us-east-1a", "us-east-1b"]
tags = { Environment = "dev" }
}| Item | Convention | Example |
|---|---|---|
| Resources | snake_case | aws_instance.web_server |
| Variables | snake_case | var.instance_type |
| Outputs | snake_case | output "vpc_id" |
| Modules | kebab-case (dirs) | modules/eks-cluster/ |
| Files | snake_case or purpose | main.tf, variables.tf |
| Tags | PascalCase (AWS) | Name, Environment |
cd environments/prod && terraform apply
cd environments/dev && terraform applyterraform workspace new dev
terraform workspace new prod
terraform workspace select prod
terraform apply -var-file="prod.tfvars"Start simple (single directory), grow into modules when you reuse patterns, and separate environments with directories for production workloads. Split state by component (network, compute, database) so changes to one don't risk another. Use consistent naming and always include README.md.
Use the Terraform archive provider to create ZIP files for Lambda functions, Cloud Functions, and deployments. archive_file data source with source_dir and...
Automate Terraform with Azure DevOps Pipelines. YAML pipelines, service connections, environment approvals, and Azure backend state configuration.
Automate Terraform with GitHub Actions. Plan on PR, apply on merge, OIDC authentication, environment protection, and drift detection workflows.
Automate Terraform with GitLab CI/CD. Plan on merge requests, apply on main, remote state with HTTP backend, and environment-specific pipelines.