Skip to content
CAMPUX Cloud Bootcamp
Field notes · Infrastructure as Code
What is infrastructure as code

What is Infrastructure as Code (IaC)? A plain-English guide

By Captain O7 min read

Instead of clicking through a portal to build your cloud, you write down what you want in a file and let a tool build it. That one move — infrastructure described as code — is what makes cloud environments repeatable, reviewable, and safe to rebuild.

New to cloud? CAMPUX is a free, build-first course. Start here →

Infrastructure as Code (IaC) is the practice of defining and provisioning your cloud infrastructure — networks, virtual machines, storage, databases — with declarative code and configuration files instead of clicking through a portal. Because those files live in version control, every change is repeatable, reviewable, and rebuildable, and the same file produces the same environment every time. That is the whole idea in one breath. The rest of this note is what that actually means on a real team, and the concepts most tutorials skip over.

Why this matters once more than one person touches the cloud

The first time you build something in the Azure portal, clicking feels fine. The problem shows up later. Six months on, nobody remembers whether the production storage account has soft-delete turned on, because someone toggled it by hand one afternoon and never wrote it down. Your staging environment and your production environment have quietly diverged — that gap is called configuration drift, and it is where a scary share of outages come from.

IaC fixes this by making the file the source of truth. On a real team that buys you three things you cannot get from a portal:

None of that is exotic tooling. It is the ordinary discipline of software — version control, code review, a build pipeline — pointed at your infrastructure instead of your app.

The concepts tutorials skip

Most "getting started" guides throw a template at you and move on. The ideas that actually make IaC click are three, and they are worth slowing down for.

Declarative vs imperative

An imperative approach is a list of steps: create this, then attach that, then set this flag. A shell script is imperative. A declarative approach describes the end state you want — "a storage account named X, in this region, with these settings" — and lets the tool work out how to get there. Bicep, Terraform, and ARM are declarative. You are not writing instructions; you are writing a description, and the tool computes the difference between what exists and what you asked for.

Idempotency

Idempotency is the payoff of being declarative: you can run the same file ten times and the result is identical to running it once. If the storage account already exists and matches, the tool does nothing. If someone changed it by hand, the tool changes it back. This is exactly why IaC is safe to run on a schedule and a raw provisioning script is not — run a "create" script twice and you get an error or a duplicate; apply an IaC file twice and you get the same environment, calmly.

State

To know what to create, change, or leave alone, the tool needs to know what already exists. That record is called state. This is the single biggest difference between the Azure tools, so it is worth being precise: with ARM and Bicep, Azure Resource Manager is the state — Azure already knows what is deployed, so there is no separate file to manage. With Terraform, you own a state file that Terraform maintains, and you must store it somewhere safe and shared (a storage account, typically) so your whole team works from the same picture. Losing or corrupting that state file is a genuine failure mode, and it catches people out.

A common misconception

IaC is not "just scripts." A PowerShell script that creates resources is automation, and automation is good — but it is imperative and usually not idempotent. Run it twice and it errors or duplicates. IaC's declarative, idempotent, state-aware model is what makes it something you can trust to run continuously in a pipeline, not a one-shot you babysit. If you take one thing from this note, take that distinction.

Before and after: the same job, two ways

Say you need a storage account. The portal way is a sequence of clicks nobody records; the IaC way is a few lines someone can read, review, and re-run. Here is the contrast at a glance.

Portal clicks vs a few lines of Bicep
Doing it in the portalDoing it as code
Open the portal, search "Storage accounts," click Create, fill five wizard tabs, pick options from memory, click through, wait. Write ~10 lines of Bicep describing the account, commit it, and run one deploy command.
No record of what you chose. The next person guesses or clicks around to check. The file is the record. Anyone reads it in ten seconds.
Need a second identical one for staging? Repeat every click and hope you match it. Copy the file, change the name, deploy. Identical by construction.

Describe the end state. Commit the file. Let the tool make reality match it.

The Azure IaC tools, compared

Four names come up constantly. Here is how they actually differ, so you can pick without reading four docs sites.

The main IaC tools on Azure
ToolLanguageStateBest for
ARM templates JSON (verbose, native to Azure) Managed by Azure Resource Manager — no separate file Azure-only teams that need the raw native format; increasingly a compile target rather than something you hand-write.
Bicep Bicep DSL — clean, readable; compiles to ARM Managed by Azure Resource Manager — no separate file Azure-only teams who want ARM's power without the JSON pain. The default choice on modern Azure.
Terraform HCL (HashiCorp Configuration Language) Its own state file you store and manage Multi-cloud or hybrid teams; one language and workflow across Azure, AWS, GCP, and more.
Pulumi / Ansible Pulumi: real languages (Python, TypeScript). Ansible: YAML playbooks Pulumi: state like Terraform. Ansible: largely stateless, config-focused Pulumi for teams who want IaC in a language they already know; Ansible for configuration management and provisioning of servers.

The short version: if you are all-in on Azure, learn Bicep. If you touch more than one cloud, learn Terraform. Everything else is a variation on those two ideas, and once you understand declarative, idempotency, and state, switching between them is mostly syntax.

What it actually looks like

Enough description — here is real IaC. This Bicep file creates a storage account. Read it top to bottom; it says what it is:

// storage.bicep — a locally-redundant storage account
param location string = resourceGroup().location
param storageName string

resource stg 'Microsoft.Storage/storageAccounts@2023-01-01' = {
  name: storageName
  location: location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
  properties: {
    minimumTlsVersion: 'TLS1_2'
    allowBlobPublicAccess: false
  }
}

Deploy it with one command — az deployment group create --template-file storage.bicep --parameters storageName=campuxdata01 — and Azure builds exactly that. Run it again and nothing changes, because the account already matches. Change allowBlobPublicAccess to a new value, commit the diff, re-deploy, and only that one property updates. That is the entire loop: edit the description, apply, reality follows.

The Terraform version of the same thing is a handful of HCL lines in a resource "azurerm_storage_account" block — different keywords, identical idea. If Bicep makes sense, Terraform will too.

Where to go from here

You now have the mental model: IaC is describing infrastructure declaratively in versioned files, so the cloud becomes repeatable, reviewable, and rebuildable. The concepts that make it real are declarative thinking, idempotency, and state — get those and the tools are just syntax. The next honest step is to write one file that creates one resource and deploy it twice, so you feel idempotency with your own hands rather than reading about it.

Questions people also ask

What problem does Infrastructure as Code solve?

IaC solves configuration drift, unrepeatable environments, and infrastructure changes that nobody reviewed. When your infrastructure lives in versioned files, every environment is built the same way, every change goes through code review and version history, and you can rebuild or replicate an environment on demand instead of remembering which buttons you clicked in the portal last quarter.

What is the difference between ARM, Bicep, and Terraform?

ARM templates are Azure's native JSON format — powerful but verbose. Bicep is a cleaner Azure-only language that compiles down to ARM, with no separate state file because Azure Resource Manager tracks state for you. Terraform is a third-party tool that works across Azure, AWS, and many other providers using its own HCL language and its own state file that you must store and manage. Pick Bicep if you are Azure-only, Terraform if you are multi-cloud.

Is Infrastructure as Code hard to learn?

The syntax is easy — a Bicep or Terraform file that creates a storage account is a dozen readable lines. The genuinely new ideas are declarative thinking (you describe the end state, not the steps), idempotency (running the same file twice is safe), and state (how the tool knows what already exists). Grasp those three concepts and the tools follow quickly.

Is Infrastructure as Code just scripting?

No. A shell or PowerShell script is imperative — it runs commands step by step and will fail or duplicate resources if you run it twice. IaC is usually declarative: you describe the infrastructure you want, and the tool figures out what to create, change, or leave alone to reach that state. That difference — idempotency — is why IaC is safe to run repeatedly and a raw provisioning script is not.

Further reading — the Microsoft docs
Your next class · free
You've read the idea. Class 1 — What is Cloud? is where you build it, hands-on — no account needed.Start Class 1 →
Captain O
Founder & instructor · CAMPUX Cloud Engineering Bootcamp
Part of the 100 Days of Azure path. Next note: What is an ARM template? →