Skip to main content

Core Commands — From Blueprint to Building

The builder has written a blueprint (an .tf file in HCL). Now the contractor needs to build from it. Terraform's core commands are the steps that turn notation into real infrastructure — and, crucially, they let you preview everything before anything changes.

Providers — Hiring the Contractors​

Terraform itself doesn't build anything. Providers are the plugins that talk to a real cloud — each one is a specialized contractor company (AWS, Azure, GCP, GitHub, and thousands more).

Declare the AWS provider
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}

provider "aws" {
region = "eu-west-1"
}

The required_providers block pins which company and version to use. The provider "aws" block sets its settings, like the region where the colony will be built.

Resources and Data Sources​

Resources — things Terraform creates and manages​

resource "aws_s3_bucket" "archive" {
bucket = "campus-library-archive"
}

Terraform will create this bucket, remember it, and track every future change to it.

Data sources — things that already exist, that you want to read​

data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"]

filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-*-amd64-server-*"]
}
}

A data source reads information about existing infrastructure (like "what's the latest Ubuntu AMI?") without managing it. Reference it as data.aws_ami.ubuntu.id.

Remember

Resource = "build and manage this." Data source = "just tell me about that." If Terraform created it, it's a resource; if it merely reads it, it's a data source.

The Lifecycle — Commands in Order​

terraform init
terraform fmt
terraform validate
terraform plan
terraform apply

1 · terraform init — the first contractor meeting​

Downloads the provider plugins and sets up the working directory. Run it once when you start, and again when you change providers.

terraform init
Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 5.0"...
- Installing hashicorp/aws v5.x.x...
Terraform has been successfully initialized!

It also creates terraform.lock.hcl — the dependency lock file that pins exact provider versions so the whole team uses identical contractors.

2 · terraform fmt — tidy the blueprint​

Reformats your .tf files to the standard style (indentation, spacing). No logic changes — just neatness.

terraform fmt

3 · terraform validate — check the blueprint for errors​

Checks syntax and internal consistency without touching any cloud. The builder's proofread.

terraform validate
Success! The configuration is valid.

4 · terraform plan — show what will happen​

The magic step. Terraform compares the blueprint against reality (via state) and prints exactly what it would create, change, or delete. It changes nothing.

terraform plan
Plan: 1 to add, 0 to change, 0 to destroy.

You can save a plan to a file and apply exactly that plan later:

terraform plan -out plan.tfplan
Careful

A plan that says "0 to destroy" is what you expect for new infrastructure. If a plan unexpectedly lists things to destroy, read it carefully before applying — see the Troubleshooting desk.

5 · terraform apply — build it​

Executes the plan and creates, updates, or deletes resources. By default it re-plans and asks for confirmation.

terraform apply
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.

Enter a value: yes

aws_s3_bucket.archive: Creating...
aws_s3_bucket.archive: Creation complete after 2s

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

To skip the prompt (used in scripts and CI):

terraform apply -auto-approve

Inspecting What You Built​

terraform show # full view of state + outputs
terraform output # just the declared outputs
terraform output archive_arn # one specific output
terraform console # interactive shell for expressions
terraform graph # dependency graph as DOT (visualizable)
terraform output
archive_arn = "arn:aws:s3:::campus-library-archive"

Refreshing — Checking Reality​

If someone changed infrastructure outside Terraform (drift), update state to match reality without changing anything:

terraform apply -refresh-only

Destroy — Demolition Day​

Tears down everything the configuration created — the reverse of apply.

terraform destroy
Destroy complete! Resources: 1 destroyed.
Careful

destroy removes real infrastructure and costs. In practice, team destroys run only in temporary environments — the permanent colony usually lives forever.

Command Cheat Sheet​

CommandWhat it doesWhen to use
terraform initDownloads providers, sets up backendFirst time, or when providers change
terraform fmtReformats files to standard styleBefore validate, on every save
terraform validateChecks config for errors (no cloud access)Before plan, in CI
terraform planShows what would change; changes nothingAlways before apply
terraform applyCreates/updates/deletes resourcesAfter reviewing a plan
terraform apply -auto-approveApplies without the promptScripts and CI
terraform apply -refresh-onlyUpdates state to match realityAfter external changes
terraform destroyDeletes everything in the configCleaning up
terraform showDisplays state and outputsInspecting
terraform outputPrints declared outputsReading results
terraform consoleInteractive expression playgroundExperimenting
terraform graphExports the dependency graphVisualizing

Next, understand the quiet hero behind all of this: the site register — Terraform state.