linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
Intro
Lessons
Footer
linuxlab-TutorialsPricingAboutPrivacy & cookies
Copyright © 2026 LinuxLab. All rights reserved.
linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
  • Introduction
  • Lessons
  • How it works
  • Knowledge base
  • Cheat sheet
  • Capstone
  • Interview prep
home/terraform/how/tf-plan-as-artifact

how/cicd

plan as an artifact: a pipeline with review between plan and apply

Save tfplan to a file, show it to a human, apply exactly that file, and stop a different diff from sneaking through by accident. The canonical CI pattern for Terraform.

If your team has more than one person on it, or you just want to sleep at night, you have the same question: how do you make apply apply exactly what you reviewed.

The simple sequence terraform plan → "looks good" → terraform apply does not give you that guarantee. When you run apply with no arguments, it builds a new plan, runs a refresh, and if someone changed something in the cloud during those 30 seconds, the diff will be different. What you read on the screenshot and what actually got applied are two different things.

Press ▶ to see how the tfplan file closes this window of uncertainty.

step 1/6·00 · the naive way: plan + apply back to back
НАИВНЫЙ ПОТОК · БЕЗ АРТЕФАКТА И БЕЗ РЕВЬЮ$ terraform plan$ terraform apply # запустит plan заново - может быть НЕ ТЕМterraform plan-out=tfplanterraform applyapply tfplan (exact)без артефакта: apply делает СВОЙ plan, может разойтись

§ steps

  1. Locally, on your own machine:

    bash
    $ terraform plan
    # you look at the output, all good
    $ terraform apply
    # you type yes, off it goes

    What the second apply actually does: it builds the plan again, runs a refresh, and applies. Between the two plans, changes in the cloud, a provider update, or a race with another engineer could have happened. In 99% of cases the diff does not change. In 1% it changes, and you find out about it afterward. That is the window of uncertainty.

recap

Key things to remember:

  • terraform plan -out=tfplan saves the plan to a binary file. Inside it: the diff, a state snapshot, and metadata. You cannot read it by eye.
  • terraform show -json tfplan > plan.json or terraform show -no-color tfplan turns the binary into a readable form. For a PR comment, usually plain text; for a policy engine, JSON (see tf-policy-gate).
  • terraform apply tfplan does not run another refresh and does not recompute the plan. It just executes exactly what was recorded. If tfplan has gone "stale", apply fails with Saved plan is stale, and you need to generate a new one.
  • In CI you usually have two separate jobs: plan (runs on every PR, the artifact is saved) and apply (runs on merge to the main branch or manually, downloads the artifact). See tf-plan-apply-ci.
  • State access. plan -out must run against the same backend as apply. Otherwise tfplan will hold the state snapshot of one database while apply tries to write to another.
  • tfplan contains decrypted sensitive values. Store it as an artifact only in protected storage (Actions artifacts with retention, S3 with SSE-KMS). Do not push it to git.

Next: tf-oidc-aws on how CI gets access to AWS without long-lived keys.

§ dig into the knowledge base

  • tf-planterraform plan in detail
  • tf-applyterraform apply: what it changes in state
  • tf-plan-apply-ciPlan/Apply pipeline in CI
  • tf-policy-as-codePolicy gate between plan and apply
  • tf-secrets-in-stateWhat is inside tfplan: the state snapshot

§ try it hands-on

  • ›tf-production-07-plan-as-artifact- Plan-as-artifact on GitHub Actions
  • ›tf-production-08-github-actions- The full GH Actions pipeline
Footer
linuxlab-
Copyright © 2026 LinuxLab. All rights reserved.
Tutorials
Pricing
About
Privacy & cookies