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
/
  • Введение
  • Уроки
  • How it works
  • База знаний
  • Шпаргалка
  • Capstone
  • Собеседование
home/terraform/lessons/tf-beginner-04-state

lesson ── terraform-beginner ── ~10 мин ── 4 шагов

State: what lives inside the terraform.tfstate file

State is the file where Terraform remembers what it created. Without state it could not tell which bucket in the cloud is "its own". In this lesson you create a resource, look at the state with your own eyes, and learn to read it with terraform state list and terraform show.

For a full explanation of what state is and why it is dangerous, see tf-state.

▶ интерактивный sandbox

Поднимется пара контейнеров: terraform 1.9 и localstack 3.8 в одной сети. В браузере откроется терминал, можно сразу terraform init. Каждый шаг проверяется автоматически. TTL 45 минут, без регистрации.

запустить sandbox →

stack ── terraform · localstack · 1 GB RAM · самоуничтожается через 45 мин простоя

Шаги

  1. 01

    Create a bucket: we need a resource in state

    ~/tf-state already has a provider.tf. Create main.tf:

    hcl
    resource "aws_s3_bucket" "demo" {
      bucket = "linuxlab-state-${random_id.suffix.hex}"
      tags = {
        Owner   = "student"
        Purpose = "learning-state"
      }
    }
    resource "random_id" "suffix" {
      byte_length = 4
    }

    Run init and apply:

    bash
    cd /home/student/tf-state
    terraform init -input=false
    terraform apply -auto-approve -input=false
    подсказка

    If apply complains about the provider: check that `provider.tf` is present and LocalStack is responding (`wait-for-localstack.sh` should have waited for it).

    ✓ The `terraform.tfstate` file is created. Terraform wrote the new bucket into it.

  2. 02

    Look at the list of resources in state

    The JSON file itself is not readable by hand. There is a handy command:

    bash
    terraform state list

    It should print:

    random_id.suffix
    aws_s3_bucket.demo

    These are the resource addresses, how you refer to them in HCL and in other commands. More on addressing in tf-references.

    подсказка

    If the output is empty: apply did not go through. Go back to step 1 and check.

    ✓ State has two resources: the bucket and random_id. Next we look at the attributes.

  3. 03

    Read all attributes of the bucket

    Run:

    bash
    terraform state show aws_s3_bucket.demo

    You will see all the attributes, the ones you set (bucket, tags), and the ones the cloud computed (arn, region, id). This is far more complete than what was in HCL, the provider fills in dozens of computed fields.

    You would see some attributes as (sensitive value) if they were marked sensitive. An S3 bucket has none of those, almost everything is open.

    подсказка

    Pay attention to `arn`: it is the global identifier of the resource in AWS, you will need it in later lessons.

    ✓ You can see arn, region, id and other attributes: everything Terraform knows.

    The same thing on OpenTofu

    OpenTofu keeps the CLI and state compatible with Terraform for the commands in this step: migration usually goes through mv .terraform .terraform.bak; tofu init -upgrade. On a first switch, though, make a backup of the state and do a run on a feature branch, the differences cluster in the newer features (variables in the backend, state encryption, OCI registry-backed modules). See tf-opentofu-parity for the full matrix.

    • → OpenTofu parity
  4. 04

    Read state in machine-readable form: with jq

    In scripts it is easier to work with JSON than to parse text:

    bash
    terraform show -json | jq '.values.root_module.resources[] | select(.address == "aws_s3_bucket.demo") | .values.tags'

    This same command is the basis of the terraform_state_resource verify type that checks the lesson steps in this course. Right now it should return a JSON object with two keys: Owner and Purpose.

    The key point: you just read state the same way Terraform itself does on every plan. No magic, plain JSON.

    подсказка

    If jq complains "invalid JSON": the state is not created yet, or the path is wrong.

    ✓ State read, tags.Purpose matched the expectation.

    What else is inside state: serial and lineage

    Besides resources, state has internal fields:

    • serial, a counter. Each apply increments it by 1. This guards against accidentally replacing the file with an older version.
    • lineage, a unique UUID of this state file, generated once at init. If you accidentally copy state from another project, the lineage will not match, and Terraform refuses to work. Do NOT edit the file by hand. Terraform checks invariants. All operations go through the terraform state commands.
    • → Terraform state

Что ты узнал

You created a bucket, saw its record in state, and read the attributes through the CLI. You understood the difference between an attribute that Terraform knows right away (bucket) and one the cloud computes after creation (arn).

команды

  • terraform state listaddresses of every resource in state
  • terraform state show <address>all attributes of a specific resource
  • terraform show -json | jq '.values.root_module.resources'the entire state in machine-readable form

концепции

  • · State: a JSON snapshot of "what Terraform thinks reality looks like"
  • · Attributes split into those set by the user and those computed by the cloud
  • · Without state Terraform would not know which resources to touch

← предыдущий

Large-scale state, breaking up the monolith

следующий →

Troubleshooting Garden: Checkov fails in the pipeline

Footer
linuxlab-
Copyright © 2026 LinuxLab. All rights reserved.
Tutorials
Pricing
About
Privacy & cookies