Terraform in the IaC Landscape

Scenario: A team already uses a cloud-native templating tool and a configuration-management tool, then argues in a meeting that only one automation tool should be allowed to survive.

Once you understand Terraform is declarative, the next question is: declarative about what? Terraform's job is resource lifecycle - creating, updating, and destroying discrete objects that a provider's API understands: a server, a DNS record, a certificate, a database instance. It does this the same way regardless of which company built the underlying service, because it talks to each service through a provider (a plugin you'll meet properly in Module 3) rather than having cloud knowledge baked into its core.

This is different from two other common tool categories you'll encounter on a real team. Cloud-native templating tools (each cloud vendor's own JSON/YAML format) can expose that vendor's newest features slightly sooner, but only work for that one vendor. Configuration-management tools (Ansible, Chef, Puppet) excel at changing software inside a machine that already exists - installing packages, editing config files, restarting services - which is a different job from deciding whether the machine should exist at all.

A healthy team draws a boundary: Terraform usually owns whether an object exists and how it's wired to other objects; something else (a prebuilt machine image, a first-boot script, Ansible, or Kubernetes) owns what runs inside it. "Multi-cloud" for Terraform means one consistent workflow across providers - it does NOT mean every cloud exposes identical concepts; a fakecloud_server and a real cloud's virtual machine still have provider-specific quirks underneath the shared Terraform syntax.

Analogy: Terraform is a general contractor coordinating specialist trades on a job site. The contractor does not pretend plumbing and electrical work are the same job - it hands each piece of work to the right specialist (provider) and keeps the overall schedule (the dependency graph) consistent.

A worked configuration

resource "fakecloud_server" "api" {
  name       = "api-01"
  network_id = fakecloud_network.app.id
}

resource "fakecloud_certificate" "edge" {
  common_name = "api.example.test"
}

A useful rule of thumb for production: one system should be authoritative for any given field on any given object. If Terraform manages a server's tags, and a separate console automation also edits those tags, the two will fight forever - Terraform will keep trying to revert the automation's changes back to what the .tf file says, and the automation will keep re-applying its own values. This endless back-and-forth is called drift, and you'll spend an entire module on it later in this track. For now, the fix is organizational: pick exactly one tool per field, and write down the handoff so the next engineer doesn't reintroduce the conflict.

Common mistakes in production

Goal: Treat the plan as a change contract: understand every create, update, replacement, and destroy before approving it. Reinforce this lesson in the tf-dependency-ordering Terraform lab. Open /labs/terraform and choose slug tf-dependency-ordering; the lab runs real Terraform against the offline FakeCloud provider.