linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
Intro
Lessons
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Уроки
  • How it works
  • База знаний
  • Шпаргалка
  • Capstone
  • Собеседование
home/terraform/lessons/tf-beginner-05-update

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

Update: меняем атрибут, видим diff

В реальной работе HCL меняется постоянно: добавили тег, поправили имя, поменяли class у БД. Terraform должен понимать, что изменилось, и применить нужный набор API-вызовов, без удаления-создания всего подряд.

В этом уроке создадим бакет, поменяем у него теги и увидим как plan показывает diff. Узнаем разницу между «обновить» (update-in-place) и «пересоздать» (-/+ replacement).

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

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

запустить sandbox →

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

Шаги

  1. 01

    Создай начальный бакет с одним тегом

    Создай файл main.tf:

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

    Запусти:

    bash
    cd /home/student/tf-update
    terraform init -input=false
    terraform apply -auto-approve -input=false

    После apply state знает бакет с одним тегом Owner.

    подсказка

    Если что-то падает: проверь init. И что LocalStack живой.

    ✓ Бакет создан с тегом Owner=student. Теперь добавим второй тег.

  2. 02

    Добавь второй тег в HCL

    Открой main.tf и поменяй блок tags:

    hcl
    tags = {
      Owner       = "student"
      Environment = "learning"
    }

    Теперь сделай plan без apply, увидишь diff:

    bash
    terraform plan

    В выводе будет блок типа:

      ~ resource "aws_s3_bucket" "demo" {
          ~ tags = {
                "Owner" = "student"
              + "Environment" = "learning"
            }
        }
      Plan: 0 to add, 1 to change, 0 to destroy.

    Знак ~ рядом с resource = «обновить в месте». Никакого пересоздания. Внутри: + "Environment" = новый тег добавится. Owner без знака

    • не меняется.

    См. tf-plan про значения знаков.

    подсказка

    Если plan показал `-/+ resource ...`: значит, ты поменял что-то, что нельзя обновить без replacement. Откати и поменяй только tags.

    ✓ Plan показал ~ change. Применим: обновится без пересоздания.

  3. 03

    Применить изменение

    bash
    terraform apply -auto-approve

    Apply покажет:

    aws_s3_bucket.demo: Modifying...
    aws_s3_bucket.demo: Modifications complete after Xs
    Apply complete! Resources: 0 added, 1 changed, 0 destroyed.

    Ключевое: 0 destroyed, 1 changed. Бакет не пересоздавался. AWS-провайдер просто отправил PutBucketTagging API-запрос. Объекты внутри (если бы были) остались на месте.

    Это и есть update-in-place. Ваша задача, структурировать HCL так, чтобы большинство изменений шли по этому пути.

    подсказка

    Если получаешь destroy: значит, кроме tags поменялось что-то ещё. Проверь главные поля (bucket, etc): они не должны меняться.

    ✓ Тег обновлён в месте, бакет тот же.

    То же самое на OpenTofu

    OpenTofu держит CLI и state совместимыми с Terraform по командам этого шага: миграция обычно проходит через mv .terraform .terraform.bak; tofu init -upgrade. Но при первом переходе сделай backup state и прогон на feature-branch - расхождения концентрируются в новых фичах (variables в backend, state-encryption, OCI registry-backed модули). См. tf-opentofu-parity для полной матрицы.

    • → OpenTofu parity
  4. 04

    Повторный plan: чистый

    Главный инвариант Terraform: после apply повторный plan = «No changes». Если показывает изменения, что-то не так (drift или ignore_changes пропустил что-то).

    Проверим:

    bash
    terraform plan -detailed-exitcode
    echo "exit: $?"

    Должно быть exit: 0. Если бы там было 2, значит, есть несогласованность.

    -detailed-exitcode важен для CI: можно автоматически алертить при drift'е.

    подсказка

    Если plan показывает «No changes» в человекочитаемом тексте: значит, всё ОК, exit будет 0.

    ✓ Plan чистый. Invariant соблюдён: state == HCL.

    Когда apply делает destroy + create (-/+)

    Некоторые атрибуты ресурса нельзя поменять без пересоздания. Например, availability_zone у EC2-инстанса, instance_class у части RDS-инстансов, bucket у S3-бакета, если меняешь имя бакета, AWS не умеет «переименовать», только создать новый и снести старый. Terraform покажет это в plan'е как -/+. Будь осторожен: данные пересоздаваемого ресурса теряются.

    • → lifecycle блок
    • → terraform plan

Что ты узнал

Ты увидел четыре типа изменений в plan: + создать, ~ обновить в месте, -/+ пересоздать, и финальное No changes после apply. Это базовая грамматика чтения plan'ов.

команды

  • terraform planпоказать diff между HCL и state
  • terraform apply -auto-approveприменить план
  • terraform plan -detailed-exitcodeexit 0 = чисто, 2 = есть изменения

концепции

  • · + = создать, ~ = обновить в месте, -/+ = пересоздать, - = удалить
  • · После apply повторный plan должен быть чистым: это инвариант
  • · Не все атрибуты можно обновить: некоторые требуют пересоздания

← предыдущий

Blue-green миграция legacy в Terraform

следующий →

Troubleshooting Garden: модуль протух, провайдер обновился

Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки