2.1 What Infrastructure as Code Is

Key Takeaways

  • Infrastructure as Code manages infrastructure with versioned configuration files rather than a GUI or one-off console clicks.
  • Terraform is a declarative provisioning tool: you describe desired end state in HCL, and Terraform records real objects in a state file.
  • HCL (HashiCorp Configuration Language) is the native syntax of the Terraform language used in `.tf` files.
  • Configuration management of already-running guests is not the same job as Terraform provisioning.
  • Click-ops and ticket queues do not produce reusable desired state; committing and applying `.tf` files does.
Last updated: August 2026

2.1 What Infrastructure as Code Is

Quick Answer: Infrastructure as Code (IaC) is the practice of defining infrastructure in versioned, machine-readable configuration files instead of clicking through cloud consoles or filing tickets. Terraform is HashiCorp's IaC provisioning tool: you declare desired state in HCL, and Terraform records real resources in a state file so the same workflow can create, change, and destroy that infrastructure.

HashiCorp's published definition is practical, not philosophical. IaC tools let you manage infrastructure with configuration files rather than a graphical user interface, so you can build, change, and manage environments in a safe, consistent, and repeatable way by defining resource configurations that you can version, reuse, and share. Terraform Associate (004) objective 1a tests whether you can apply that definition: tell IaC apart from click-ops, ticket queues, and guest-level configuration management, and recognize that Terraform is a provisioning engine that records state.

Why this objective matters on Terraform Associate (004)

Later objectives assume this mental model. State (2d, 6a–6d), the write–plan–apply workflow (3a–3f), providers (2a–2c), and HCP Terraform collaboration (8a–8d) all rest on one idea: desired infrastructure lives in files, Terraform compares those files to recorded state, and only then talks to an API. If you still think "IaC" means "we keep a wiki of CLI commands," you will miss questions about why .tf files, state, and plans exist.

The product version on the current exam is Terraform 1.12. Terraform Community Edition, HCP Terraform, and Terraform Enterprise all speak the same Terraform language. Objective 1a is edition-agnostic: IaC is the practice; Terraform is one tool that implements it.

Click-ops and ticket-driven provisioning versus versioned configuration

Click-ops

Click-ops is the unofficial name for building infrastructure by pointing and clicking in a vendor console. An engineer opens the AWS, Azure, or Google Cloud console, creates a VPC, draws a security group, launches a virtual machine, and pastes a public IP into chat. The next engineer cannot see why that security group allows 0.0.0.0/0, cannot replay the same environment in another region, and cannot tell whether last Tuesday's "quick fix" is still in production.

Ticket-driven provisioning

Ticket-driven provisioning is the older operations pattern. A developer files a request ("need two medium VMs and a load balancer"). A central team eventually clicks or scripts the change. The ticket may become the only record. Delivery is slow, standards depend on who picked up the ticket, and the resulting servers become snowflakes—unique, hand-tuned, and hard to rebuild.

Versioned configuration

Versioned configuration replaces both habits. Desired infrastructure is written in files (in Terraform, usually *.tf), committed to a version control system such as Git, and reviewed like application code. A pull request can show that someone added an ingress rule or doubled instance count. The approved files—not a console session—are what Terraform applies.

ApproachHow change happensWhat you can reviewTypical failure mode
Click-opsHuman clicks in a cloud consoleScreenshots, maybe an audit logSnowflake environments; unreproducible production
Ticket-drivenRequest queue, then a human or one-off scriptTicket text, not executable desired stateLong lead time; tribal knowledge
IaC with TerraformCommit HCL, plan, then applyDiff of .tf files plus an execution planProcess and state mistakes (still possible—see 1b)

Declarative desired state versus imperative scripts

Imperative scripts

An imperative approach lists steps: create the VPC, then the subnet, then the route table, then the instance, then attach the interface. Bash, Python plus a cloud SDK, or a long Azure CLI script are typical. The author is responsible for order, retries, and "already exists" logic. Run the script twice and you may create duplicates or fail halfway through.

Declarative desired state

A declarative approach describes the desired end state. You do not tell Terraform "first call CreateVpc, then CreateSubnet." You declare that a VPC with this CIDR and a subnet in that VPC should exist. Terraform's configuration language is declarative: it describes an intended goal rather than the steps to reach that goal. Terraform then builds a resource graph, calculates implicit dependencies (the subnet references the VPC id), and creates, updates, or destroys resources in a safe order. Independent resources can proceed in parallel.

That is why file and block order in a Terraform configuration is generally not the execution order. Relationships between resources, not the order you typed the blocks, drive the plan. You do not write step-by-step API instructions because Terraform handles the underlying logic.

Terraform as a provisioning tool that records state

Terraform is HashiCorp's infrastructure as code tool. Official docs describe it as a way to define both cloud and on-prem resources in human-readable configuration files, then use a consistent workflow to provision and manage that infrastructure throughout its lifecycle. It can manage low-level objects (compute, storage, networking) and high-level ones (DNS records, SaaS features).

Provisioning is the job: create, change, and destroy infrastructure objects through their APIs. Terraform talks to those APIs through providers—plugins listed on the Terraform Registry, including AWS, Azure, Google Cloud, Kubernetes, Helm, GitHub, Datadog, and thousands more.

Terraform is not only a config compiler. It records state. After an apply, a state file maps your configuration addresses (for example aws_instance.web) to real remote objects (instance ids, IPs, ARNs). HashiCorp calls that state a source of truth for the environment Terraform manages. On the next plan, Terraform refreshes that picture, compares it to your current .tf files, and proposes only the delta.

The core workflow you will live with for the rest of this guide is:

  1. Write — author HCL that declares resources, often across more than one provider.
  2. Plan — Terraform describes what it will create, update, or destroy based on existing infrastructure and your configuration.
  3. Apply — after approval, Terraform performs those operations in dependency order.

terraform init installs the provider plugins a working directory needs before plan and apply can run. Objective 1a only requires you to know that this workflow exists and that state is how Terraform remembers what it already provisioned.

HashiCorp Configuration Language (HCL)

The native syntax of the Terraform language is defined in terms of HCL (HashiCorp Configuration Language), the same family of syntax used by other HashiCorp products. You do not need the full HCL specification for the Associate exam, but you must recognize that operators write Terraform language in .tf files. A JSON syntax also exists for generated configs; humans normally write native HCL.

The language has a small surface:

  • Blocks configure objects (resource, variable, provider, and others). A block has a type, optional labels, and a body in { }.
  • Arguments assign a name to a value (ami = "ami-0abc123"). HCL documentation often says "attribute"; Terraform docs prefer "argument" because resources also expose read-only attributes such as id.
  • Expressions compute values, including references such as aws_vpc.main.id.

A tiny declarative example:

resource "aws_instance" "web" {
  ami           = "ami-0abc123"
  instance_type = "t3.micro"
}

This does not say "call RunInstances now." It says a resource of type aws_instance named web should exist with those arguments. Terraform decides whether to create, update, or leave it alone by comparing configuration to state. The first label (aws_instance) is the provider resource type; the second (web) is the local name you chose.

What IaC is not

Provisioning versus configuration management

IaC as Terraform practices it is not the same job as configuration management of already-running guests. HashiCorp is explicit: tools such as Chef and Puppet install and manage software on a machine that already exists. Terraform is not a configuration management tool. It focuses on the higher-level abstraction—the datacenter and associated services—and lets existing guest tooling do what it is good at.

That distinction is an exam favorite.

  • Provisioning / IaC (Terraform): Does the VPC, VM, load balancer, DNS record, or SaaS project exist with the declared attributes?
  • Configuration management (Chef, Puppet, Ansible, and similar): Once a guest exists, which packages, users, and files should be on the disk?

You can combine them. Terraform can set cloud-init (or an equivalent bootstrap) so a newly created instance registers with your configuration management system on first boot. That handoff does not turn Terraform into Chef. If a question describes patching packages on a long-lived VM, you are no longer in Terraform's primary job.

IaC is also not "we automated one click with a recorded macro," and it is not "we keep a shared spreadsheet of instance ids." Without versioned desired state and a tool that can reconcile that state, you still have click-ops with extra documentation.

Worked scenario: SSH into consoles versus committing .tf files

Scenario. A platform team launches "just one" staging cluster from the Azure portal whenever a feature branch needs a demo. Engineers RDP or SSH to tweak network security groups, resize disks, and install a hotfix. Six months later, production and staging disagree, nobody can rebuild staging after a subscription cleanup, and a security review cannot list every public IP.

IaC response. The team writes Terraform configuration that declares the resource group, virtual network, security groups, and virtual machines. They commit the .tf files. A reviewer sees the security-group rule in the pull request, not in a forgotten portal blade. terraform plan shows creates before anyone touches Azure. terraform apply provisions the cluster and writes instance ids into state. When the subscription is wiped, they apply again and get a new cluster that matches the files—not a memory of last quarter's clicks.

The exam will dress this story in AWS, GCP, VMware, or a SaaS vendor. The contrast is the same: consoles and SSH sessions do not produce a reusable desired state; committed configuration plus recorded state does.

Exam traps for objective 1a

  • IaC is not a cloud. Terraform does not replace AWS or vSphere; it drives their APIs.
  • Declarative is not "no state." Desired state lives in HCL; recorded state lives in the state file. Both are required.
  • HCL is the language, Terraform is the engine. Writing a .tf file does nothing until init / plan / apply run.
  • Provisioning is not guest config. Installing nginx on an existing VM is configuration management unless you are replacing the machine (or its image) through Terraform.
  • Tickets are not IaC. A well-written request is still not executable desired state.

Official starting points: What is Terraform?, What is Infrastructure as Code with Terraform?, and Terraform vs. Chef, Puppet, etc..

Loading diagram...
IaC with Terraform: write, plan, apply, and state
Test Your Knowledge

On Terraform Associate (004), what is Infrastructure as Code?

A
B
C
D
Test Your Knowledge

How does Terraform's declarative model differ from imperative scripts?

A
B
C
D
Test Your Knowledge

A team SSHes into cloud consoles to create virtual machines and later cannot reproduce the environment. Which IaC change addresses the problem?

A
B
C
D