Multi-cloud · Automation

Terraform: plan, state and safe changes

Terraform is a blueprint plus a notebook. Learn how to review a change, protect state and test without opening a cloud bill.

1. A provider-free practice lab

Install Terraform from HashiCorp’s official instructions. Windows users can use PowerShell; Linux users use a terminal. Create a new empty project directory with your file manager and open your terminal there. Do not reuse cloud-lab state.

The following Terraform 1.6+ recipe uses built-in terraform_data, a value tracked in state—not a VM or actual cloud service. It needs no cloud account or external provider.

2. Inspect the plan before applying

PowerShell or Linux · prepare and review
terraform version
terraform init
terraform fmt -check
terraform validate
terraform plan -out=lesson.tfplan

Init prepares the directory. Validate checks structure. Plan proposes changes by comparing configuration and state. Expect only terraform_data.lesson to be added. Read addresses and actions even in a tiny lab.

PowerShell or Linux · apply only the reviewed plan
terraform apply lesson.tfplan
terraform output
terraform state list
terraform plan
Saved plans apply without another approval prompt. Stop before apply if you have not reviewed it. Recreate a plan after relevant configuration or environment changes. The final plan should show no changes.

3. Change one tracked value

PowerShell or Linux · review a local update
terraform plan -var="lab_message=My second Contoso message" -out=change.tfplan
terraform apply change.tfplan
terraform output

Expect an input update, not a cloud-server replacement. A command-line override is temporary: a later plan without it returns to the default. For persistent non-secret settings, edit the default or use a private terraform.tfvars file. Never put passwords into shell history.

Real infrastructure has replacement rules. A changed image or immutable setting may destroy and recreate a server. prevent_destroy is not a backup or universal lock; removing configuration may remove its protection. Review the provider’s actual behavior.

4. Write a plan-only test

Save message.tftest.hcl alongside main.tf. This run explicitly uses plan rather than apply.

PowerShell or Linux · validate the expected input
terraform test

The assertion checks a planned input, not a live service. Tests using apply can create billable resources; inspect every test and module first. This specific lesson uses only a built-in state value.

Reference: Terraform tests and terraform_data.

5. Protect the notebook

State maps resource addresses to real objects and can contain secrets. Sensitive output flags hide some display; they do not encrypt state. Saved plans can also hold private data. Never commit them or paste them into public issues.

When providers are used, retain .terraform.lock.hcl to record selected versions and checksums. Deleting state does not delete infrastructure. For teams, choose a supported remote backend with restricted access, encryption, recovery and backend-appropriate locking. Confirm locking instead of assuming every backend has it.

Do not force-unlock a run unless it has stopped and you have explicit authority. Keep module boundaries small, pin reviewed versions, and separate environment state deliberately. A workspace name alone does not isolate cloud accounts or permissions.

Reference: sensitive data in state.

6. Handoff and cleanup

Terraform owns infrastructure; Ansible owns OS configuration. Pass approved output addresses to a private inventory and verify host identity. Prefer explicit reviewed pipeline stages over hidden local-exec scripts. Start with our AWS infrastructure recipe when you are ready for cloud resources.

PowerShell or Linux · remove only this local practice resource
terraform state list
terraform plan -destroy -out=cleanup.tfplan
terraform apply cleanup.tfplan
terraform state list

Expect only terraform_data.lesson to be removed. Do not run destruction from another project or state file. Keep source and remove generated plans with your file manager. No cloud charges were created.