Cloud and infrastructure as code
Terraform plan and apply
The Terraform loop. Write resources, read the plan, then apply it. Learn the building blocks and the plan symbols that flag replacements.
Terraform works in two steps. plan compares your .tf files with what Terraform knows about the real world, and prints the changes it would make. apply makes those changes through cloud APIs. The plan is the safety check, and most of the skill is reading it.
Concept
Before you start. You should know what infrastructure as code is and what drift means. See why infrastructure as code.
The building blocks
| Construct | Role |
|---|---|
| Provider | A plugin that talks to one API, such as AWS, GCP or Kubernetes |
| Resource | Something Terraform creates and owns, such as aws_s3_bucket |
| Data source | A read-only lookup of something that already exists |
| Variable | An input, such as var.environment |
| Output | A value shown to humans, other modules or CI |
| Local | A named expression reused inside one module |
Walking through a small project
This file creates a bucket and turns on versioning for it.
provider "aws" {
region = "us-east-1"
}
resource "aws_s3_bucket" "assets" {
bucket = "acme-prod-assets-eu"
}
resource "aws_s3_bucket_versioning" "assets" {
bucket = aws_s3_bucket.assets.id
versioning_configuration {
status = "Enabled"
}
}The second resource refers to aws_s3_bucket.assets.id. Terraform reads that reference and creates the bucket first. The workflow is always the same:
terraform init # download providers, set up the backend
terraform plan # compute and show the diff
terraform apply # make the changesWith these files, plan ends with a summary like this:
Plan: 2 to add, 0 to change, 0 to destroy.Reading the plan
+means create.~means update in place.-means destroy.-/+means replace: destroy, then create. Terraform does this when an attribute is "force-new" and cannot change in place. Changing an EC2 AMI is one example.
A replacement on a database is the most important thing to catch in review. The old instance is deleted and a new, empty one is created, unless you restore data.
Tip
Run terraform plan -out=tfplan, then terraform apply tfplan. The apply then does exactly what you reviewed. Without a saved plan, the apply builds a new plan against a world that may have changed.
Common mistakes
- Skimming the summary line. Read every
-and-/+line, not only the count. - Applying without a saved plan. You may apply changes nobody reviewed.
- Running
applyon a laptop against production. Run it from CI with approval instead. See safe changes.
Check yourself
- A plan shows
-/+on an RDS instance. What happens? Answer: Terraform deletes the database and creates a new one. Stop and check for a snapshot and a restore plan. - Why save the plan with
-out? Answer: the apply runs exactly the changes you reviewed, not a fresh plan against a world that may have changed.
Key takeaways
planshows the diff.applymakes it real.- Read
-and-/+lines on stateful resources first. - Apply a saved plan, ideally from CI.
- Next, state explains how Terraform knows what it already created.
Further learning
His longer Terraform introduction covers providers, plan and apply, and state in one sitting.
Related
Infrastructure as code with Terraform
Declaring infrastructure in code — providers, state, plans, modules, environments and the habits that keep apply safe.
Terraform state and locking
The state file maps your code to real resources. Keep it in a remote backend with locking, and treat import, move and remove as production surgery.
Safe Terraform changes
Run plans in CI, check policy before apply, and guard stateful resources in the config. Force-new changes need extra care because they can replace data.