Skip to main content
Terraform beginner Lesson 2 of 11

Terraform Workflow (init → validate → plan → apply)

Learn the Terraform command workflow and what each step guarantees. Includes practical copy/paste examples.

Terraform workflow is all about moving from configurationcheckschange previewreal changes.

Learning outcomes

After this tutorial you’ll be able to:

  • run the standard Terraform commands in the correct order
  • interpret what plan is telling you
  • avoid common “why is it changing?” surprises

1) What the Terraform commands do

terraform init

Downloads and sets up dependencies:

  • providers (e.g., hashicorp/aws)
  • modules you reference
  • backend configuration for remote state (if configured)
terraform init

terraform validate

Validates that your configuration is internally consistent.

terraform validate

Typical results:

  • ✅ “Success! The configuration is valid.”
  • ❌ errors like missing variables, invalid types, malformed HCL

terraform plan

Creates an execution plan: what Terraform intends to change.

terraform plan

You can also save the plan to apply the exact same changes later:

terraform plan -out=tfplan

terraform apply

Applies changes to reach the desired state.

Apply from a saved plan:

terraform apply tfplan

Or apply directly (re-plans as it goes):

terraform apply

2) A minimal runnable example

Create these files in a folder (example: ./terraform-workflow/).

main.tf

terraform {
  required_version = ">= 1.6.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = var.aws_region
}

resource "aws_s3_bucket" "example" {
  bucket = "my-unique-bucket-name-12345" # change me (must be globally unique)
}

variables.tf

variable "aws_region" {
  type    = string
  default = "us-east-1"
}

outputs.tf

output "bucket_name" {
  value = aws_s3_bucket.example.bucket
}

Run it

terraform init
terraform validate
terraform plan
terraform apply

3) Interpreting terraform plan

The plan output generally shows things like:

  • Plan: X to add, Y to change, Z to destroy
  • per-resource diffs in ~ (change) and -/+ (replace)

Replacement vs in-place change

  • ~ means Terraform can update the resource in-place
  • -/+ means Terraform must destroy and re-create it (often because a ForceNew argument changed)

4) Best practices for safe workflow

  • Always run plan before apply (or save plan to tfplan).
  • Use a consistent workflow in CI: init → validate → plan.
  • Keep sensitive values out of .tf files (use variables + environment variables/secrets).

5) Cleanup

When done:

terraform destroy

This uses the current state to remove resources.

Frequently Asked Questions

Why does Terraform need `init`?
`terraform init` downloads providers/modules, initializes the working directory, and prepares Terraform to plan/apply.
What’s the difference between `validate` and `plan`?
`terraform validate` checks internal consistency of your configuration (syntax + basic checks). `terraform plan` computes the actual changes against the current state.