Infrastructure as Code
Terraform, CloudFormation, Pulumi, Bicep; state management, modules
Infrastructure as Code (IaC) treats infrastructure configuration as version-controlled, reviewable, testable source code. Terraform (by HashiCorp, now OpenTofu as open-source fork) is cloud-agnostic and uses HCL; AWS CloudFormation and AWS CDK are AWS-native; Azure Bicep is a DSL that compiles to ARM templates; and Pulumi uses general-purpose languages (TypeScript, Python, Go). IaC enables drift detection, reproducible environments, and disaster recovery through automated recreation.
Key Points
- Terraform state files contain all resource metadata — store in a remote backend (S3 + DynamoDB lock, Terraform Cloud, Azure Storage) to enable team collaboration and prevent state corruption.
- Terraform plan/apply workflow: `terraform plan` produces a diff (no changes made); `terraform apply` executes — always review the plan in CI before applying to production.
- Terraform modules are the unit of reuse — publish to a private Terraform registry or use the public Terraform Registry; pin module versions with `source = "module@1.2.3"`.
- CloudFormation StackSets deploy a single template to multiple AWS accounts and regions via AWS Organizations — the canonical pattern for multi-account baseline controls.
- AWS CDK (Cloud Development Kit) synthesizes CloudFormation templates from TypeScript/Python — enabling IDE auto-complete, unit testing with `aws-cdk-lib/assertions`, and construct libraries.
- Bicep is a first-class Azure IaC language; `az bicep build` compiles to ARM JSON — supports deployment stacks for lifecycle management of resource groups.
- Pulumi stores state in Pulumi Cloud or self-hosted backends; uses real programming language constructs (loops, conditionals, functions) rather than DSL workarounds.
- IaC policy enforcement: use Sentinel (Terraform Enterprise), OPA/Conftest, or cfn-guard to validate templates against organisational policies before deployment.
Terraform: S3 bucket with versioning and KMS encryption — idiomatic resource composition
# Terraform example: S3 bucket with versioning + encryption
resource "aws_s3_bucket" "app_data" {
bucket = "${var.env}-app-data-${data.aws_caller_identity.current.account_id}"
tags = var.common_tags
}
resource "aws_s3_bucket_versioning" "app_data" {
bucket = aws_s3_bucket.app_data.id
versioning_configuration { status = "Enabled" }
}
resource "aws_s3_bucket_server_side_encryption_configuration" "app_data" {
bucket = aws_s3_bucket.app_data.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "aws:kms"
kms_master_key_id = aws_kms_key.s3_key.arn
}
}
}Real-World Example
Mercado Libre manages 1,400+ AWS accounts using Terraform with Atlantis (GitOps PR-based automation), running `terraform plan` on every pull request and requiring two engineer approvals before `terraform apply` is triggered.