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-garden-02-state-drift

lesson ── terraform-garden ── ~20 мин ── 5 шагов

Troubleshooting Garden: state и облако разъехались

Сценарий: ты ушёл в отпуск, вернулся, кто-то «срочно поправил руками». Бакет в state, versioning=Enabled. Бакет в облаке, versioning=Suspended. Плюс рядом завёлся ещё один бакет, которого Terraform не знает.

Твоя задача, увидеть оба drift'а, решить как с каждым поступить (вернуть, импортировать, оставить), и привести plan к чистому виду.

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

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

запустить sandbox →

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

Шаги

  1. 01

    Покажи drift через refresh-only

    bash
    cd /home/student/tf-garden
    terraform plan -refresh-only 2>&1 | tee /tmp/drift.log

    Должна вылезти строка вида:

    ~ aws_s3_bucket_versioning.data
      ~ versioning_configuration { status = "Enabled" -> "Suspended" }

    Это и есть drift №1: state считает versioning Enabled, реальность показывает Suspended. Сам бакет тоже на месте, это просто настройка.

    ✓ Drift №1 виден. Теперь, orphan bucket.

  2. 02

    Найди orphan-bucket в облаке

    Terraform не знает про второй бакет, для него «его не существует». Но через AWS CLI напрямую он виден:

    bash
    aws --endpoint-url=http://localstack:4566 s3 ls | tee /tmp/buckets.log

    Ты увидишь оба бакета: garden-drift-data (этот в state) и garden-drift-orphan (этот orphan).

    Это не drift в строгом смысле, это unmanaged resource. Terraform про него не знает, и plan его не покажет.

    ✓ Orphan виден. Теперь, стратегии.

  3. 03

    Вернуть versioning к HCL: apply

    Решение по drift №1: предполагаем что в HCL правда (Enabled). Кто-то ошибся и убрал versioning, возвращаем.

    bash
    terraform apply -auto-approve

    Terraform увидит что в облаке Suspended, а должно быть Enabled, и вернёт. После, plan должен быть чистым по versioning.

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

    Если exit 2, где-то ещё drift; если 0, versioning починен.

    ✓ Versioning вернулся в Enabled. Drift №1 закрыт.

  4. 04

    Импортировать orphan-bucket в state

    Decision: orphan-бакет нужный, кто-то завёл его руками для логов, но забыл добавить в HCL. Подтянем в Terraform: добавь HCL и import-блок.

    Добавь в main.tf:

    hcl
    resource "aws_s3_bucket" "orphan" {
      bucket = "garden-drift-orphan"
    }
    import {
      to = aws_s3_bucket.orphan
      id = "garden-drift-orphan"
    }

    Запусти:

    bash
    terraform plan
    terraform apply -auto-approve

    Import-блок (TF 1.5+) декларативно затащит существующий бакет в state. После apply plan становится чистым.

    Подробнее, tf-state-import.

    ✓ Orphan заимпортирован. Теперь под управлением Terraform.

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

    OpenTofu поддерживает import-блок начиная с 1.6, синтаксис идентичен. В матричных CI можно гонять оба бок-о-бок и сравнивать state-файлы они совместимы. См. tf-opentofu-parity.

    • → terraform import
    • → OpenTofu parity
    • → Drift detection
  5. 05

    Финал: plan должен быть чистым

    bash
    terraform plan -detailed-exitcode

    Exit 0, state и облако совпадают, plan ничего не предлагает.

    Если exit 2, что-то ещё в дрифте, посмотри -refresh-only и пройди шаги ещё раз.

    ✓ Plan чистый. Drift и orphan закрыты.

Что ты узнал

Drift ловится через terraform plan -refresh-only, через -detailed-exitcode в CI, через scheduled-pipeline. Reconcile через apply (вернуть), import (принять новый ресурс), removed (декларативно убрать из state без destroy).

команды

  • terraform plan -refresh-onlyпосмотреть drift не строя план изменений
  • terraform apply -refresh-onlyобновить state из облака, не меняя инфру
  • terraform plan -detailed-exitcodeexit 2 = есть drift; для scheduled-pipeline

концепции

  • · Не каждый drift надо лечить apply'ем, кто-то мог поправить намеренно
  • · Orphan resource, либо import, либо игнор; никогда destroy «потому что не моё»
  • · Versioning S3, Suspended ≠ удалено; данные на месте, новые версии не пишутся

← предыдущий

Переменные: убираем хардкод

следующий →

Модуль из Terraform Registry

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