What Is Infrastructure as Code (IaC)?

Infrastructure as Code turns manual infrastructure management into repeatable, version-controlled automation. Explore Terraform, Ansible, Docker, Kubernetes, and the role each plays in modern DevOps.

Nowadays, we constantly hear terms like Infrastructure as Code, provisioning, configuration management, deployment, and orchestration. Most engineers have a rough idea of what these mean, but understanding of how the different tools fit together in a real software delivery process can be confusing.

Let's break it down.

The problem Infrastructure as Code Solves

Before cloud platforms and automation tools became common, deploying an application was a highly manual process.

A system administrator would typically:

  • Create or provision servers
  • Configure networking and firewalls
  • Set up route tables and load balancers
  • Install operating systems and required software
  • Install databases
  • Configure programming language runtimes
  • Deploy application files
  • Monitor and maintain everything manually

This approach worked, but it came with significant drawbacks:

  • High operational costs
  • Slow delivery cycles
  • Human error
  • Inconsistent environments
  • Difficult disaster recovery

And that's only the initial setup.

Once the application was running, teams still had to:

  • Deploy new releases
  • Upgrade software versions
  • Perform database backups
  • Recover failed services
  • Scale infrastructure
  • Replace failed servers

If multiple environments existed (development, staging, production), every change had to be repeated across all of them.

As systems grew larger, manual infrastructure management became unsustainable.

Enter Infrastructure as Code

Infrastructure as Code (IaC) is the practice of managing and provisioning infrastructure through code rather than manual processes.

Instead of documenting setup steps in a wiki and asking someone (or Claude) to execute them, we describe the desired infrastructure in configuration files that can be versioned, reviewed, tested, and executed automatically.

This brings many of the same benefits software development gets from source code:

  • Version control
  • Code reviews
  • Repeatability
  • Automation
  • Consistency across environments
  • Faster recovery from failures

Infrastructure becomes something that can be recreated on demand rather than manually maintained.

The Main Categories of Infrastructure Automation

Although people often use "Infrastructure as Code" as a catch-all term, there are actually several categories of tools involved.

1. Infrastructure Provisioning

Provisioning tools create and manage infrastructure resources.

Examples:

  • Virtual machines
  • Kubernetes clusters
  • Networks
  • Load balancers
  • Databases
  • Storage buckets
  • DNS records

Typical tools:

  • Terraform
  • AWS CloudFormation
  • Azure Resource Manager (ARM)
  • Google Cloud Deployment Manager

Example:

resource "aws_instance" "app" {
ami = "ami-123456"
instance_type = "t3.micro"
}

This configuration declares that an EC2 instance should exist.

2. Configuration Management

Once infrastructure exists, it often needs additional software installed and configured.

Examples:

  • Installing Nginx
  • Installing PostgreSQL
  • Creating users
  • Managing configuration files
  • Updating packages
  • Starting services

Typical tools:

  • Ansible
  • Puppet
  • Chef
  • Salt

Example:

- name: Install Nginx
apt:
name: nginx
state: present

These tools focus on bringing servers into a desired state.

3. Application Deployment

After infrastructure is provisioned and configured, applications need to be deployed.

Examples:

  • Deploying a Node.js service
  • Releasing a Docker image
  • Running database migrations
  • Performing blue-green deployments

Typical tools:

  • GitHub Actions
  • GitLab CI/CD
  • Jenkins
  • ArgoCD
  • Spinnaker

These tools automate the delivery of application code into running environments.

Where Docker Fits

Docker is often mentioned alongside Infrastructure as Code, but Docker itself is not an IaC tool.

Instead, Docker helps package an application together with its dependencies.

A Dockerfile describes:

  • Required runtime
  • Installed packages
  • Environment configuration
  • Startup commands

Example:

FROM node:22
WORKDIR /app
COPY . .
RUN npm install
CMD ["nmp", "start"]

Because the application environment is defined in code, Docker reduces the amount of server configuration required and makes deployments more predictable.

In modern systems, Docker often replaces large portions of traditional configuration management.

Why Multiple Tools Are Often Used Together

No single tool solves every infrastructure problem.

A common production setup might look like:

Terraform -> provisions infrastructure

Ansible -> configures servers

Docker -> packages applications

GitHub Actions -> builds and deploys releases

Kubernetes -> runs and orchestrates containers

Each tool specializes in a different part of the software delivery lifecycle.

Declarative vs Procedural Approaches

Infrastructure tools generally follow one of two approaches.

Procedural (Imperative)

You specify how to achieve the desired result.

Example:

  1. Create a server
  2. Install software
  3. Create another server
  4. Configure networking
  5. Update the load balancer

The exact sequence matters.

Declarative

You specify what the final state should look like.

Example:

  • There should be 2 application servers
  • A load balancer should route traffic to them
  • PostgreSQL should exist

The tool determines the steps required to reach that state.

Most modern IaC tools, including Terraform and CloudFormation, are primarily declarative.

Mutable vs Immutable Infrastructure

Another important concept is how infrastructure changes over time.

Mutable Infrastructure

Existing infrastructure can be modified after creation.

Examples:

  • Install additional software
  • Update configurations
  • Change server settings

This is the traditional approach used by many configuration management tools.

Immutable Infrastructure

Existing infrastructure is never modified.

Instead:

  1. Create new infrastructure with updated configuration
  2. Redirect traffic
  3. Remove old infrastructure

For example, rather than logging into a server and upgrading an application, you build a new machine image or container image and deploy it.

Immutable infrastructure generally improves consistency, reduces configuration drift, and simplifies rollbacks.

Agent-Based vs Agentless Tolls

Infrastucture tools also differ in how they communicate with managed systems.

Agent-based

A small program (agent) runs on each managed machine.

Examples:

  • Puppet
  • Salt
  • Chef

Advantages:

  • Continuous enforcement of configuration
  • Better visibility into managed systems

Disadvantages:

  • Additional software to maintain

Agentless

No software is installed on managed machines.

The tool communicates remotely, often via SSH or APIs.

Example:

  • Ansible

Advantages:

  • Simpler setup
  • Lower operational overhead

Disadvantages:

  • Configuration is typically applied only when automation runs

Final Thoughts

Infrastructure as Code is not a single tool – it is a way of managing infrastructure through version-controlled, repeatable automation.

Terraform, CloudFormation, Ansible, Docker, Kubernetes, and CI/CD systems all solve different parts of the infrastructure lifecycle. Understanding where each tool fits is often more important than mastering any individual tool.

The ultimate goal is simple: make infrastructure predictable, reproducible, and scalable while reducing manual work and human error.


Related posts

  • The 4 Core Challenges of Web System Design

    Excerpt Every large-scale web application faces the same challenges: handling more users, managing growing amounts of data, maintaining low latency, and ensuring consistency. Learn the architectural patterns used to solve them.

← Back to blog