Choosing a Better Tool
Scenario: Every apply SSHs to servers to install packages, making infrastructure changes slow and dependent on a live package repository.
Bake machine images for immutable server contents; use cloud-init for first-boot bootstrap; use Ansible or another configuration manager for ongoing host convergence; use Kubernetes or a deployment platform for applications; use provider resources for API objects; use CI for notifications and artifact publication. Terraform should pass identifiers and endpoints across boundaries, not absorb every operational step.
Analogy: A city planner creates roads and parcels; restaurant managers run kitchens. Giving one office every job creates neither clarity nor resilience.
A worked configuration
# Terraform creates infrastructure and publishes a narrow handoff.
output "inventory" {
value = { for k, v in fakecloud_server.node : k => v.address }
}
The production test is failure ownership: which system can detect drift, retry safely, report status, and roll back the action? Put the work where those lifecycle capabilities exist.
Note: Treat the plan as a change contract: understand every create, update, replacement, and destroy before approving it.
Goal: Reinforce this lesson in the tf-first-apply Terraform lab. Open/labs/terraformand choose slugtf-first-apply; the lab runs real Terraform against the offline FakeCloud provider.