Infrastructure as Code
Infrastructure as code (IaC) means defining and managing cloud resources – servers, networks, databases, load balancers, DNS records – in machine-readable configuration files that you version-control, review, and deploy the same way you deploy application code. It eliminates manual click-ops, makes infrastructure reproducible across environments, and turns infrastructure changes into auditable events with a full history.
The IaC Deployment Pipeline
Policy-as-code (OPA/Sentinel) gates infrastructure changes before they reach terraform apply — shift-left for infra.
Terraform, by HashiCorp, is the most widely adopted IaC tool. Its declarative HCL syntax describes the desired state of your infrastructure, and the Terraform engine calculates and applies the diff. The registry of community providers covers every major cloud and most SaaS platforms, so you can manage AWS VPCs, Cloudflare DNS records, GitHub repository settings, and Datadog monitors in the same codebase. OpenTofu is the open-source fork maintained by the Linux Foundation following HashiCorp’s licence change, and it has gained rapid adoption as a drop-in Terraform-compatible alternative. Pulumi takes a different approach: you write infrastructure definitions in TypeScript, Python, Go, or Java, which gives you the full power of a programming language – loops, conditionals, functions, and testing frameworks – for infrastructure code. For AWS-only shops, the AWS CDK (Cloud Development Kit) follows the same programming-language model against CloudFormation.
The operational patterns around IaC have matured into clear best practices. State management is critical in Terraform: remote state in S3 with DynamoDB locking (or Terraform Cloud) prevents concurrent modifications from corrupting your state file. Module composition – breaking infrastructure into reusable modules for networking, compute, and databases – keeps configurations manageable as they grow. Policy as code tools like Open Policy Agent (OPA) and HashiCorp Sentinel enforce guardrails (no public S3 buckets, required tags, approved instance types) automatically in CI before any change is applied. Drift detection – continuously checking whether deployed infrastructure matches the declared state – is a newer capability that catches manual changes before they cause incidents.
Frequently Asked Questions
What is the difference between Terraform and CloudFormation?
CloudFormation is AWS-specific and manages infrastructure using JSON or YAML templates. Terraform is cloud-agnostic and supports hundreds of providers through a plugin ecosystem, which makes it the standard choice when you use multiple cloud providers or want to manage non-AWS resources alongside your AWS infrastructure. CloudFormation has tighter AWS integration and handles some AWS-specific scenarios better.
How do you manage secrets in infrastructure as code?
You should never store secrets in plain text in IaC files. The standard approach is to reference secrets from a secrets manager (AWS Secrets Manager, HashiCorp Vault, or Azure Key Vault) in your Terraform code and let the runtime inject values. For CI/CD pipelines, secrets are stored in the pipeline platform (GitHub Actions secrets, GitLab CI variables) and injected as environment variables.
What is drift detection and why does it matter?
Drift is when the actual state of your infrastructure differs from what your IaC declares – usually because someone made a manual change in the cloud console. Drift detection tools periodically compare the live state against your declared configuration and alert you to differences. Catching drift early prevents incidents where someone assumes the IaC is the source of truth but the infrastructure has already changed underneath it.
Should you use Terraform or Pulumi for new projects?
Terraform (or OpenTofu) is the safer default if your team already knows it or if you need the widest provider support. Choose Pulumi when your infrastructure logic is complex enough that a real programming language would simplify it significantly – for example, generating dozens of similar resources dynamically or writing unit tests for infrastructure modules. Both are mature tools with active communities.
