Jonatan Matajonmatum.com
conceptsnotesexperimentsessays
© 2026 Jonatan Mata. All rights reserved.v2.1.1
Concepts

Infrastructure as Code

Practice of defining and managing infrastructure through versioned configuration files instead of manual processes. Foundation of modern operations automation.

evergreen#devops#iac#automation#cloud

Infrastructure as Code (IaC) is treating infrastructure exactly like code: versioned in Git, reviewed in PRs, tested in CI, and applied in an automated and reproducible way.

What problem it solves

Without IaC:

  • Snowflake servers — each server is unique, manually configured, impossible to reproduce
  • Configuration drift — environments silently diverge
  • Outdated documentation — the wiki says one thing, reality is another
  • Impossible auditing — who changed what, when, why?
  • Slow disaster recovery — rebuilding manually takes hours or days

With IaC: terraform apply and the complete infrastructure is recreated in minutes.

Approaches

Declarative vs imperative

ApproachDescriptionTools
DeclarativeDescribe desired state, tool figures out how to get thereTerraform, CloudFormation, Kubernetes YAML
ImperativeDescribe steps to execute in orderBash scripts, Ansible (partially), Pulumi
# Declarative (Terraform) — "I want this"
resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"
}
# Imperative (Pulumi) — "do this"
server = aws.ec2.Instance("web",
    ami="ami-0c55b159cbfafe1f0",
    instance_type="t3.micro")

Mutable vs immutable

  • Mutable — update existing servers (Ansible, Chef, Puppet)
  • Immutable — destroy and recreate (Terraform + AMIs, containers)

Immutable infrastructure eliminates configuration drift by design.

Main tools

ToolTypeCloudLanguageState
TerraformProvisioningMulti-cloudHCLRemote state
OpenTofuProvisioningMulti-cloudHCLRemote state
PulumiProvisioningMulti-cloudTS, Python, GoManaged/self-hosted
AWS CDKProvisioningAWSTS, Python, JavaCloudFormation
CloudFormationProvisioningAWSYAML/JSONAWS-managed
AnsibleConfig mgmtAgnosticYAMLStateless
CrossplaneProvisioningMulti-cloudYAML (K8s CRDs)Kubernetes

Fundamental principles

1. Everything in Git

infra/
├── modules/
│   ├── networking/
│   ├── compute/
│   └── database/
├── environments/
│   ├── dev/
│   ├── staging/
│   └── production/
├── .github/workflows/
│   └── terraform.yml
└── README.md

2. Idempotency

Applying the same code N times produces the same result:

terraform apply   # Creates 3 instances
terraform apply   # No changes. Infrastructure is up-to-date.
terraform apply   # No changes. Infrastructure is up-to-date.

3. State management

State is the source of truth about what exists:

# Remote backend (shared across team)
terraform {
  backend "s3" {
    bucket         = "my-terraform-state"
    key            = "prod/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "terraform-locks"
    encrypt        = true
  }
}

4. Reusable modules

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "5.0.0"
 
  name = "production"
  cidr = "10.0.0.0/16"
 
  azs             = ["us-east-1a", "us-east-1b"]
  private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
  public_subnets  = ["10.0.101.0/24", "10.0.102.0/24"]
 
  enable_nat_gateway = true
}

5. Plan before apply

terraform plan    # See what will change
# + aws_instance.web (create)
# ~ aws_security_group.web (modify)
# - aws_instance.old (destroy)
 
terraform apply   # Apply after review

IaC pipeline

# .github/workflows/terraform.yml
name: Terraform
 
on:
  pull_request:
    paths: ['infra/**']
  push:
    branches: [main]
    paths: ['infra/**']
 
jobs:
  plan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: hashicorp/setup-terraform@v3
      - run: terraform init
      - run: terraform validate
      - run: terraform plan -out=plan.tfplan
      - uses: actions/upload-artifact@v4
        with:
          name: plan
          path: plan.tfplan
 
  apply:
    needs: plan
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v4
      - uses: hashicorp/setup-terraform@v3
      - uses: actions/download-artifact@v4
        with:
          name: plan
      - run: terraform apply plan.tfplan

IaC testing

LevelToolWhat it validates
Lintterraform validate, tflintSyntax and conventions
StaticCheckov, tfsec, TrivySecurity and compliance
UnitTerratest, terraform testModule logic
IntegrationTerratestTemporary real infrastructure
PolicyOPA, SentinelOrganizational policies

Anti-patterns

  • ClickOps — creating resources manually then "importing" them as a patch
  • Mega-state — all infra in a single state file. Split by domain/environment.
  • No locks — two people applying simultaneously corrupt the state
  • Hardcoded values — use variables and tfvars to parameterize
  • No plan review — applying without reviewing the plan is like merging without code review
  • Ignoring drift — not detecting manual changes that diverge from code

Why it matters

Without IaC, infrastructure is tacit knowledge that lives in the head of whoever configured it. With IaC, every change is traceable, reviewable, and reproducible. It is the foundation on which practices like GitOps, automated disaster recovery, and self-service infrastructure are built.

References

  • Infrastructure as Code, 2nd Edition — Kief Morris, 2020. The definitive book on IaC.
  • Terraform: Up & Running, 3rd Edition — Yevgeniy Brikman, 2022. Practical Terraform guide with real patterns.
  • The Twelve-Factor App — Adam Wiggins, 2011. Cloud-native application principles that complement IaC.
  • Terraform Best Practices — Anton Babenko, 2024. Community best practices guide.
  • Pulumi Documentation — Pulumi, 2024. Official documentation for the imperative alternative.

Related content

  • DevOps

    Culture and set of practices that unify development (Dev) and operations (Ops) to deliver software with greater speed, quality, and reliability. It's not a role — it's a way of working.

  • DevOps Practices

    Set of technical and cultural practices that implement DevOps principles — from Infrastructure as Code to blameless post-mortems. The "how" behind the philosophy.

  • CI/CD

    Continuous Integration and Continuous Delivery/Deployment — practices that automate code integration, testing, and delivery to production. Foundation of modern software engineering.

  • Serverless

    Cloud computing model where the provider manages infrastructure automatically, allowing code execution without provisioning or managing servers, paying only for actual usage.

  • Cost Optimization

    Practices and strategies to minimize cloud spending without sacrificing performance, including right-sizing, reservations, spot instances, and eliminating idle resources.

  • From Prototype to Production: A Serverless Second Brain on AWS

    Architecture design for scaling a personal second brain to a production system with AWS serverless — from the current prototype to specialized use cases in legal, research, and community building.

  • Building a Second Brain in Public

    Chronicle of building a second brain with a knowledge graph, bilingual pipeline, and agent endpoints — in days, not weeks, and what that teaches about the gap between theory and working systems.

  • Terraform Docker Example

    Reusable Terraform modules for managing Docker containers and AWS ECS Fargate, with progressive examples and local testing with LocalStack.

  • Terraform AWS Serverless Modules

    Collection of 13 Terraform modules published on the Terraform Registry for deploying serverless architectures on AWS, with 12 examples covering basic ECS to full-stack CRUD with DynamoDB and AgentCore with MCP.

  • Serverless Second Brain

    Production-ready serverless backend for a personal knowledge graph — DynamoDB, Lambda, Bedrock, MCP, Step Functions. The implementation of the architecture described in the 'From Prototype to Production' essay.

  • PR Auto-Approver

    Serverless GitHub App that auto-approves pull requests after CI passes, with optional AI code review via Amazon Bedrock. Five repositories: TypeScript/Probot app, AWS Terraform module (Lambda + API Gateway + Secrets Manager + SQS DLQ), GitHub Terraform module (webhooks), deployment infra, and test repo.

  • Content Agent with Strands and Bedrock

    Three-agent system that automates the bilingual MDX content lifecycle: deterministic QA auditing, surgical fixes, and full upgrades — all orchestrated with Strands Agents, Claude Sonnet 4 on Amazon Bedrock, and GitHub Actions with a diamond workflow pattern.

  • Terraform

    HashiCorp's Infrastructure as Code tool that enables defining, provisioning, and managing multi-cloud infrastructure through declarative HCL files.

  • Self-Service Infrastructure

    Model where development teams can provision and manage infrastructure autonomously through automated interfaces, without depending on operations tickets.

  • Policy as Code

    Practice of defining security, compliance, and governance policies as versioned, executable code, automating their verification in CI/CD pipelines.

  • OpenTofu

    Open source fork of Terraform maintained by the Linux Foundation. Compatible with HCL and Terraform providers, created in response to HashiCorp's license change to BSL 1.1.

  • Helm

    Package manager for Kubernetes that simplifies installation and management of complex applications through reusable and configurable charts.

  • GitOps

    Operational practice using Git as single source of truth for infrastructure and configuration, with automatic reconciliation between desired and actual state.

  • AWS SAM

    AWS open-source framework for building serverless applications with simplified CloudFormation syntax, CLI for local development, and integrated deployment.

  • AWS S3

    AWS object storage service with 99.999999999% durability, unlimited scalability, and multiple storage classes for cost optimization.

  • AWS IAM

    AWS identity and access management service controlling who can do what in your account, with granular policies based on the principle of least privilege.

  • AWS CloudFormation

    AWS native service for defining and provisioning infrastructure as code using YAML or JSON templates, with state management and automatic rollback.

  • AWS CDK

    AWS infrastructure as code framework that allows defining cloud resources using programming languages like TypeScript, Python, or Java, generating CloudFormation.

Concepts