- Write configuration: define resources and desired state in
.tffiles (HCL). - Initialize the workspace: download provider plugins and configure the backend.
- Plan changes: generate an execution plan that previews changes.
- Apply changes: execute the plan to change real infrastructure.
- Destroy (optional): remove infrastructure created by Terraform.
Always review a
terraform plan output (or plan file) before running terraform apply. Plans are your primary safety check to avoid unintended changes.- Use version control (Git) for all Terraform code. Treat
.tffiles as the canonical source of truth. - Prefer remote state backends (e.g., S3 with DynamoDB locking, Terraform Cloud/Enterprise) for team collaboration and state locking.
- Use
terraform plan -out=plan.tfplanthenterraform apply "plan.tfplan"to guarantee the apply exactly matches the reviewed plan. - Protect secrets: avoid committing plaintext secrets. Use environment variables, secret managers, or encrypted variables in CI/CD.
- Write configuration
- Create
.tffiles to declare providers, resources, variables, outputs, and modules. - Use modules to encapsulate reusable infrastructure patterns.
- Keep environment-specific values out of code; pass them via variables, variable files (
-var-file), or a workspace-specific backend. - Example:
- Initialize the workspace (
terraform init)
- Downloads provider plugins and modules.
- Configures the backend (local or remote).
- Useful flags:
-backend-config=FILEto supply backend configuration.-reconfigureto ignore existing backend configuration and reinitialize.
- Example:
- Plan changes (
terraform plan)
- Produces an execution plan showing what will be created, changed, or destroyed.
- Common flags:
-out=plan.tfplanto save the plan for later apply.-var='key=value'or-var-file=prod.tfvarsto inject variables.-refresh=true|falseto control state refresh.
- Best practice: always run
terraform planand review the diff before applying.
- Apply changes (
terraform apply)
- Apply can accept a saved plan file or run a fresh plan interactively.
- Typical usage:
- Prefer using saved plan files in automated pipelines to ensure reproducibility.
- Destroy (
terraform destroy)
- Safely tear down infrastructure that Terraform manages.
- Use with caution; consider
-targetor manual safeguards if you only want to remove specific resources.
- State is critical: it maps your Terraform configuration to real resources.
- Use remote backends for team environments:
- S3 + DynamoDB (AWS) for state storage + locking
- Terraform Cloud or Terraform Enterprise for integrated state, locking, runs, and policy
- Encrypt state at rest and limit access.
- Avoid manual edits to state; use
terraform statesubcommands only when necessary.
- Use separate workspaces (or separate backends/states) per environment (dev, staging, prod).
- Common pattern: separate IaC repos or directories for distinct lifecycles; or use variable files and CI/CD pipelines that target specific backends.
- Prefer distinct state per environment rather than relying on a single workspace to hold multiple unrelated resources.
- Create pipelines that:
- Run
terraform fmtandterraform validate - Run
terraform plan -out=plan.tfplanand publish plan output for review - On approval, run
terraform apply plan.tfplan(non-interactive)
- Run
- Store backend secrets and provider credentials in the CI secret store.
- Lock and version provider/plugins by using the
required_providersblock andterraform lockfile.
| Command | Purpose | Example |
|---|---|---|
terraform init | Initialize directory, download providers, configure backend | terraform init -backend-config="bucket=team-state" |
terraform plan | Preview changes without applying | terraform plan -out=plan.tfplan -var-file=prod.tfvars |
terraform apply | Apply changes to reach desired state | terraform apply "plan.tfplan" |
terraform destroy | Remove managed infrastructure | terraform destroy -auto-approve |
terraform fmt | Reformat HCL files | terraform fmt -recursive |
terraform validate | Validate configuration syntax | terraform validate |
Sensitive data can end up in Terraform state. Do not store secrets in plaintext variables that are committed to version control. Use secure secret management and encrypted backends.
- Terraform CLI docs: https://www.terraform.io/cli
- Terraform State: https://www.terraform.io/language/state
- Terraform Backends: https://www.terraform.io/language/settings/backends
- Terraform Cloud: https://www.terraform.io/cloud
- We’ll next walk through an example repository: initialize a backend, write a small module, run a plan, and apply safely in a CI pipeline. You’ll get hands-on practice with state locking, plan-review workflow, and best practices for team collaboration.