Skip to content
Pipelines and Pizza 🍕
Go back

Infrastructure as Code: What, Why, and How

6 min read

Building on the Git and Ansible foundations, this week we explore Infrastructure as Code (IaC) — the philosophy, the benefits, and the tools to make infrastructure repeatable, reliable, and version-controlled.

What Is Infrastructure as Code?

Infrastructure as Code (IaC) is the practice of managing and provisioning your IT infrastructure—everything from servers and networks to databases and firewalls—using code and automation, rather than manual setup. Think of it as treating your infrastructure like software: you write scripts to spin up your environments, version control your changes, and let tools do the heavy lifting. This means faster deployments, fewer errors, and the power to recreate entire systems on demand.

Key idea: Treat your infrastructure the same way you treat application code.

Example from AzureRM Terraform provider:

resource "azurerm_resource_group" "example" {
  name     = "example-resources"
  location = "West Europe"
}

resource "azurerm_virtual_network" "example" {
  name                = "example-network"
  address_space       = ["10.0.0.0/16"]
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
}

resource "azurerm_subnet" "example" {
  name                 = "internal"
  resource_group_name  = azurerm_resource_group.example.name
  virtual_network_name = azurerm_virtual_network.example.name
  address_prefixes     = ["10.0.2.0/24"]
}

resource "azurerm_linux_virtual_machine" "example" {
  name                = "example-machine"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location
  size                = "Standard_F2"
  admin_username      = "adminuser"
  # ... additional config
}

This snippet creates a basic linux vm in azure — without clicking inside the portal.


Why IaC Matters

Benefits:

  • Repeatability: Run the same config in dev, staging, and prod.
  • Versioning: Track changes over time in Git history.
  • Speed: Deploy infrastructure in minutes, not hours.
  • Collaboration: Share config like any other code.
  • Disaster Recovery: Rebuild environments from scratch.

Without IaC, teams rely on manual steps and tribal knowledge — a recipe for drift and outages.


Declarative vs. Imperative Approaches

When managing cloud resources, you have two main philosophies: declarative and imperative.

  • Declarative (What): You describe your desired end state—what you want to exist—and let a tool figure out how to make it reality. Tools like Terraform and AWS CloudFormation excel here.

    resource "azurerm_resource_group" "rg" {
      name     = "my-rg"
      location = "East US"
    }

    After you’ve written your configuration:

    terraform apply

    And when it’s time to clean up:

    terraform destroy
  • Imperative (How): You write out a series of step-by-step commands telling the system how to reach your goal.

    az group create --name my-rg --location "East US"
    # ... later ...
    az group delete --name my-rg --yes --no-wait

Bottom line: Declarative IaC tools like Terraform are like handing the chef your pizza order and letting them handle the details, while imperative scripting is you in the kitchen—kneading the dough, adding the toppings, and hoping you don’t forget a step.


Core Principles of IaC

  1. Idempotence: Your infrastructure code should be safe to run again and again, always bringing the system to the same expected state.

  2. Version Control: Treat your infrastructure scripts just like application code—store them in Git.

  3. Automation: Remove humans from the critical path. Infrastructure changes should be automated from start to finish.

  4. Testing: Never just “hope it works.” Use tools and processes to validate your IaC before pushing it to production.

  5. Modularity: Break your infrastructure into reusable building blocks, such as Terraform modules or Ansible roles.


ToolLanguageMulti-cloudConfig MgmtEase
TerraformHCLYesNoHigh
AnsibleYAMLYesYesHigh
PulumiJS/Py/GoYesNoMedium
CloudFormationJSON/YAMLNoNoMedium
ARM TemplatesJSONNoNoLow

IaC in DevOps Pipelines

Infrastructure as Code integrates seamlessly into your CI/CD workflows:

  1. Commit IaC changes to Git.
  2. Trigger automated validation and testing in your pipeline.
  3. Apply infrastructure changes in staging, then production.

Example: Using GitHub Actions to Deploy with Terraform

jobs:
  plan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: hashicorp/setup-terraform@v3
      - run: terraform init
      - run: terraform plan -out=tfplan
      - uses: actions/upload-artifact@v4
        with:
          name: tfplan
          path: tfplan

  apply:
    needs: plan
    runs-on: ubuntu-latest
    environment: production  # Requires manual approval
    steps:
      - uses: actions/checkout@v4
      - uses: hashicorp/setup-terraform@v3
      - run: terraform init
      - uses: actions/download-artifact@v4
        with:
          name: tfplan
      - run: terraform apply tfplan

Note: Never use terraform apply -auto-approve in CI without a plan step and approval gate. The pattern above plans on every push, then requires manual approval before applying.


Common Pitfalls

  • Manual Changes in Production: Making changes directly on live infrastructure causes “configuration drift.”
  • Not Using Modules: Skipping modules leads to repeated code and maintenance headaches.
  • Ignoring State Files: Tools like Terraform rely on state files. Always secure and back them up.
  • Skipping Reviews: Infrastructure code deserves peer review—always use pull requests.

Hands-On Lab

Goal: Create an Azure Resource Group with Terraform.

  1. Install Terraform.
  2. Create main.tf:
provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "rg" {
  name     = "my-rg"
  location = "East US"
}
  1. Run:
terraform init
terraform plan
terraform apply
  1. Review the plan output, type yes to confirm, then verify in Azure Portal.

Q&A

Q: Should I store secrets in IaC code? A: No — use a secrets manager or environment variables. Never commit passwords, tokens, or keys to Git.

Q: Can IaC replace all manual ops? A: Not always — but aim for 100% automation where possible. The goal is that manual changes are the exception, not the norm.


Final Thoughts

IaC isn’t just a technical practice — it’s a mindset shift. When your infrastructure is code, it gets all the benefits of software development: version control, peer review, automated testing, and repeatable deployments. Start small (a single resource group in Terraform), get comfortable with the workflow, and expand from there.

In the next post, we’ll go deeper into Terraform specifically — providers, resources, and how state management works under the hood.

Happy automating!