Infrastructure as Code with Terraform: Concepts and Multi-Cloud Workflows
Infrastructure as Code (IaC) is the practice of defining infrastructure — servers, networks, DNS records, databases, SaaS configuration — in machine-readable files that you version, review, and apply automatically, instead of clicking through consoles or running one-off commands. Terraform is HashiCorp's IaC tool: you describe the desired end state in HCL (HashiCorp Configuration Language), and Terraform works out what to create, change, or destroy to reach it. Because Terraform talks to every platform through plugins called providers, one workflow — write, plan, apply — manages AWS, Azure, Google Cloud, on-premises systems, and hundreds of other services. The Terraform Associate 004 exam opens with exactly this material: what IaC is, the advantages of IaC patterns, and how Terraform handles multi-cloud, hybrid-cloud, and service-agnostic workflows. This lesson covers all three sub-objectives, plus the declarative-versus-imperative distinction the exam loves to probe.
On this page7 sections
- What Infrastructure as Code is
- The advantages of IaC patterns
- Declarative versus imperative: how Terraform thinks
- One workflow, many providers: how Terraform manages multi-cloud
- Hybrid cloud and service-agnostic workflows
- Terraform versus configuration management tools
- Exam traps: keeping the concepts straight
- Define Infrastructure as Code and explain how it differs from manual provisioning
- List the advantages of IaC patterns: versioning, repeatability, automation, reduced human error, and self-service
- Distinguish declarative configuration from imperative scripting, and explain why Terraform is declarative
- Explain how Terraform runs one workflow across multiple clouds through providers
- Describe what multi-cloud, hybrid-cloud, and service-agnostic mean in Terraform terms
- Position Terraform against configuration management tools such as Ansible, Chef, and Puppet
What Infrastructure as Code is
Infrastructure as Code means you define infrastructure in configuration files rather than building it by hand. The files are the source of truth: they describe what should exist, they live in version control alongside application code, and a tool — Terraform — reads them and makes reality match. Provisioning stops being a sequence of console clicks that nobody can reproduce and becomes an artifact you can review, test, and re-run.
Terraform configurations are written in HCL, a human-readable declarative language (JSON is also accepted). The core unit is the resource block, which declares one infrastructure object. This is a complete, valid resource:
resource "aws_instance" "web" {
ami = "ami-0c02fb55956c7d316"
instance_type = "t3.micro"
tags = {
Name = "web-server"
}
}Read it as: an EC2 instance, known inside this configuration as aws_instance.web, with that AMI, that size, and that tag. Nothing here says how to create the instance — no API calls, no ordering, no retry logic. That is Terraform's job. You commit the file, run terraform plan to preview the change, and terraform apply to execute it.
The exam definition to hold onto: IaC manages infrastructure through machine-readable definition files, giving infrastructure the same lifecycle as software — written, versioned, reviewed, and deployed.
The advantages of IaC patterns
IaC patterns deliver five advantages the exam expects you to name: versioning, repeatability, automation, reduced human error, and self-service. Each one is a direct consequence of infrastructure being code.
| Concern | Manual provisioning | Infrastructure as Code |
|---|---|---|
| Change history | Undocumented console clicks; no audit trail | Every change is a commit — diff, blame, revert |
| Reproducing environments | Hand-rebuilt from memory or wiki notes; environments drift apart | Re-apply the same configuration to get an identical stack (dev, staging, prod) |
| Speed | Limited by how fast a human can click | Runs unattended in CI/CD pipelines; large stacks provision in minutes |
| Human error | Typos and skipped steps are invisible until something breaks | Changes are previewed with a plan and peer-reviewed before apply |
| Access model | An ops team is the bottleneck for every request | Teams self-serve from approved, reusable configurations and modules |
Two of these deserve emphasis. Repeatability rests on idempotency: applying the same configuration twice produces the same result, and a second apply with no changes does nothing. Reduced human error comes from the review loop — a Terraform plan shows exactly what will change before anything happens, which no console workflow offers.
Declarative versus imperative: how Terraform thinks
Terraform is declarative: you describe the desired end state, and Terraform computes the steps to reach it. An imperative approach — a bash script full of aws ec2 run-instances calls, for example — instead specifies the exact commands to run, in order, and it is your job to handle what already exists, what failed halfway, and what order dependencies require.
The difference shows up the second time you run something. Run an imperative creation script twice and you get two servers, or an error. Run terraform apply twice and the second run reports no changes, because Terraform compares your configuration against recorded state and only acts on the difference. Declaring count = 5 for a resource means five instances exist — whether Terraform must create five, create two more, or destroy one to get there is derived, not scripted.
Declarative also means ordering is inferred. When one resource references another's attribute, Terraform builds a dependency graph and creates, updates, or destroys resources in the correct order — and parallelizes wherever the graph allows. In an imperative script, you hand-author that ordering and it silently breaks when the topology changes.
Exam trigger words: "describes the end state" and "what, not how" point at declarative; "step-by-step", "sequence of commands", and "specifies how" point at imperative. Terraform, CloudFormation, and Kubernetes manifests are declarative; shell scripts and raw CLI or SDK calls are imperative.
One workflow, many providers: how Terraform manages multi-cloud
Terraform manages multi-cloud by separating the workflow from the platform. Terraform core knows how to parse configuration, build a dependency graph, plan, and apply — but it makes no cloud API calls itself. Everything platform-specific lives in providers, plugins that translate resource blocks into API calls: the aws provider knows EC2 and S3, the google provider knows Compute Engine, the azurerm provider knows Azure Resource Manager.
Because of that split, resources from different clouds can sit in one configuration and flow through one plan and one apply:
resource "aws_instance" "api" {
ami = "ami-0c02fb55956c7d316"
instance_type = "t3.micro"
}
resource "google_compute_instance" "worker" {
name = "worker-1"
machine_type = "e2-small"
zone = "us-central1-a"
boot_disk {
initialize_params {
image = "debian-cloud/debian-12"
}
}
network_interface {
network = "default"
}
}Same language, same commands, same state management — one team skill set covers every platform. That is the operational win of multi-cloud Terraform: you avoid one tool per cloud (CloudFormation for AWS, ARM/Bicep for Azure, Deployment Manager for Google) and you can spread workloads across providers for resilience or best-of-breed services without splitting your workflow.
Know the limit, because the exam tests it: Terraform makes the workflow cloud-agnostic, not the configuration. An aws_instance cannot be pointed at Azure; moving clouds means writing that cloud's resources.
Hybrid cloud and service-agnostic workflows
Hybrid cloud in Terraform terms means one configuration and one workflow spanning public cloud and on-premises infrastructure. The provider model makes this uneventful: a vsphere provider manages VMware VMs in your data center while the aws provider manages the cloud half, and both land in the same dependency graph, the same plan output, and the same state.
Service-agnostic pushes the idea past infrastructure entirely. A provider is just a bridge to an API, so Terraform manages anything with a provider: Kubernetes objects, GitHub repositories and teams, Datadog monitors, Cloudflare DNS, PagerDuty schedules, Vault policies. The Terraform Registry hosts thousands of providers, and utility providers such as random and tls do not call any external API at all:
resource "random_pet" "suffix" {
length = 2
}
resource "aws_s3_bucket" "artifacts" {
bucket = "artifacts-${random_pet.suffix.id}"
}Notice the cross-provider reference: the bucket name interpolates an attribute of a random resource. Terraform's dependency graph spans providers, so it creates the pet name first, then the bucket — no manual sequencing.
For the exam, map the three phrases to one mechanism: multi-cloud (several public clouds), hybrid cloud (cloud plus on-premises), and service-agnostic (any API — DNS, monitoring, source control) all work because Terraform core is platform-neutral and providers carry all platform knowledge.
Terraform versus configuration management tools
Terraform is a provisioning tool: it creates, modifies, and destroys infrastructure — the servers, networks, load balancers, and managed services themselves. Configuration management tools such as Ansible, Chef, Puppet, and SaltStack work one layer up: they install packages, edit files, and manage services on machines that already exist. The exam expects you to place each tool on the right layer, not to crown a winner.
The philosophical split is mutability. Configuration management leans mutable: the same long-lived server is updated in place, patch after patch, which risks configuration drift between supposedly identical machines. Terraform leans immutable: when a change cannot be made in place (changing an EC2 instance's AMI, for example), Terraform replaces the resource — destroys the old one and creates a new one from the current definition, so every server is born from code and drift has nowhere to accumulate.
The tools are complementary, and real pipelines chain them: Terraform provisions the VM, then Ansible configures the software on it (or Terraform bakes the pairing in by provisioning from a pre-built machine image). Both Terraform and the major configuration management tools are declarative and idempotent — the distinction the exam wants is what they manage, not how they express it.
Trigger words: "provisions infrastructure lifecycle" and "immutable" point at Terraform; "installs software on existing servers", "in-place", and "mutable" point at configuration management.
Exam traps: keeping the concepts straight
The traps in this domain are near-miss statements — each one almost true, wrong in one word. Slow down on these:
- "Terraform configurations are portable across clouds." False. The workflow is cloud-agnostic; resource blocks are provider-specific.
aws_instancenever becomes an Azure VM. - "Terraform is imperative because you run commands like apply." False. Running a CLI does not make a tool imperative — the configuration declares end state, and Terraform derives the steps.
- "IaC eliminates human error." Too strong. IaC reduces error through previewed plans, peer review, and repeatable runs. Absolutes in answer options are usually wrong.
- "Terraform replaces Ansible." False. Provisioning and configuration management are different layers; they complement each other.
- "Multi-cloud requires separate state or separate tools per cloud." False as a requirement — one configuration can hold multiple providers, one plan covers them all, and cross-provider references work.
Also keep the advantage list ready as recall: versioning, repeatability (idempotency), automation, reduced human error, self-service. Scenario questions describe a symptom — "environments drift apart between dev and prod", "no audit trail of who changed the firewall" — and ask which IaC advantage addresses it. Match drift to repeatability, audit to versioning, bottlenecked ops teams to self-service, and console typos to reduced human error via plan review.
Tip. Expect definition and best-description questions: which statement best describes IaC, which options are advantages of IaC patterns (versioning, repeatability, automation, reduced human error, self-service often appear as a pick-multiple), and whether Terraform is declarative or imperative. Multi-cloud questions probe the workflow-versus-configuration distinction — watch for wrong answers claiming resource blocks are portable between clouds. Trigger words: "desired end state" (declarative), "cloud-agnostic workflow" (providers), "installs software on existing servers" (configuration management, not Terraform).
- IaC defines infrastructure in machine-readable, version-controlled files — the definition files are the source of truth, not the console
- The advantages of IaC patterns: versioning, repeatability, automation, reduced human error, and self-service
- Terraform is declarative: you state the desired end state and Terraform computes the create/change/destroy steps and their order
- Applying the same configuration twice is safe — idempotency means a no-change apply does nothing
- One workflow (write, plan, apply) spans multi-cloud, hybrid cloud, and any API with a provider, because all platform knowledge lives in provider plugins
- The workflow is cloud-agnostic but the configuration is not — resource types are provider-specific and do not port between clouds
- Terraform provisions infrastructure lifecycle (immutable, replace-on-change); Ansible, Chef, and Puppet manage software on existing servers — complementary, not competing
Frequently asked questions
What is Infrastructure as Code in simple terms?
Infrastructure as Code means defining your servers, networks, and services in configuration files instead of creating them manually in a console. A tool like Terraform reads the files and makes real infrastructure match them. Because the files are code, you can version them in Git, review changes before they happen, and re-run them to rebuild identical environments.
Is Terraform declarative or imperative?
Terraform is declarative. You write configuration that describes the desired end state — five instances, one bucket, these tags — and Terraform compares it with recorded state, computes the difference, and executes only the changes needed, in dependency order. You never script the individual API calls or their sequence, which is what an imperative approach (like a shell script of CLI commands) would require.
Can Terraform manage more than one cloud at the same time?
Yes. A single Terraform configuration can declare resources from multiple providers — AWS, Azure, Google Cloud, plus on-premises platforms like vSphere — and one terraform plan and apply covers them all. Terraform core is platform-neutral; each provider plugin translates its resource blocks into that platform's API calls, and resources can even reference attributes across providers.
Does multi-cloud Terraform mean I can move the same configuration from AWS to Azure?
No. Terraform makes the workflow portable, not the configuration. Resource types are provider-specific — an aws_instance is an EC2 instance and cannot become an Azure VM. Moving to another cloud means rewriting resources with that cloud's provider (for example azurerm_linux_virtual_machine), though your skills, workflow, and tooling carry over unchanged. The exam tests this distinction directly.
What is the difference between Terraform and Ansible?
Terraform is a provisioning tool: it creates, changes, and destroys infrastructure itself — VMs, networks, managed services — and favors immutable infrastructure, replacing resources rather than patching them. Ansible is a configuration management tool: it installs packages, edits files, and manages services on machines that already exist, typically in place. Teams commonly use both: Terraform provisions the server, Ansible configures the software on it.
Sign up free to mark lessons complete, bookmark topics and track your exam readiness.