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
- Letting both Terraform and a separate automation script manage the same field "just to be safe" - this guarantees drift, not safety.
- Assuming "multi-cloud" means write-once-run-anywhere HCL; provider-specific arguments and behavior still differ even though the workflow (init/plan/apply) stays the same.
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/terraformand choose slugtf-dependency-ordering; the lab runs real Terraform against the offline FakeCloud provider.