Ручное тестирование Terraform и очистка ресурсов

Рейтинг: 78.5% · 14 голосов
Подробный курс по Terraform и OpenTofu на примерах Yandex Cloud: ресурсы и провайдеры, состояние и бэкенды, модули, циклы и условия HCL, секреты и Lockbox, тестирование, CI/CD и командная работа. С актуализацией на 2026 (Terraform 1.3-1.10, OpenTofu).
Ответить
Аватара пользователя
Vlad_DevOps
Сообщения: 47
Зарегистрирован: 11 май 2026, 05:31

Ручное тестирование Terraform и очистка ресурсов

Сообщение Vlad_DevOps »

Оглавление курса (47)
  1. Что такое инфраструктура как код и зачем она нужна
  2. Категории инструментов IaC: чем отличаются Ansible, Packer, Kubernetes и Terraform
  3. Чем Terraform отличается от Ansible, Pulumi и CloudFormation
  4. Как работает Terraform под капотом и кто такой OpenTofu
  5. Установка Terraform и OpenTofu, подготовка Yandex Cloud
  6. Первый ресурс: разворачиваем виртуальную машину в Yandex Cloud
  7. Веб-сервер на ВМ: метаданные, user-data и группы безопасности
  8. Переменные ввода и выходные значения в Terraform
  9. Кластер ВМ: группа экземпляров Yandex Compute Instance Group
  10. Балансировщик нагрузки: Application Load Balancer в Yandex Cloud
  11. Состояние Terraform: что такое tfstate и чем опасен локальный файл
  12. Удалённое хранилище состояния: бэкенд на Yandex Object Storage
  13. Изоляция состояния: рабочие области против раскладки по папкам
  14. Источники данных и terraform_remote_state: связываем компоненты
  15. Модули Terraform: переиспользуем инфраструктуру
  16. Входные, локальные и выходные переменные модуля
  17. Версионирование модулей и подводные камни
  18. Циклы в Terraform: параметр count
  19. Циклы в Terraform: for_each по множествам и картам
  20. Выражения for и строковые директивы
  21. Условная логика: count-трюк, for_each и директива if
  22. Встроенные функции, типы и выражения HCL
  23. Развёртывание без простоя: create_before_destroy
  24. Подводные камни Terraform и рефакторинг с блоком moved
  25. Управление секретами: основы и типы
  26. Инструменты управления секретами: Yandex Lockbox, Vault, SOPS
  27. Аутентификация провайдера и секреты: сервисные аккаунты и OIDC
  28. Секреты в ресурсах и состоянии, ephemeral-значения
  29. Провайдеры Terraform: установка, версии, required_providers
  30. Несколько копий одного провайдера: alias и мультизона
  31. Несколько провайдеров и аккаунтов: configuration_aliases
  32. Terraform, Docker и Kubernetes: Managed Kubernetes в Yandex Cloud
  33. Код Terraform промышленного уровня: почему это долго
  34. Мелкие компонуемые модули вместо монолита
  35. Тестируемые модули и проверки: validation, precondition, postcondition
  36. Версионирование, публикация модулей и Terragrunt
  37. Ручное тестирование Terraform и очистка ресурсов (вы здесь)
  38. Автоматические тесты на Terratest: модульные тесты
  39. Интеграционные и сквозные тесты, пирамида тестирования
  40. Нативный terraform test и статический анализ
  41. Внедрение Terraform в команде: процессы и культура
  42. Конвейер развёртывания прикладного кода
  43. Конвейер инфраструктурного кода и золотое правило Terraform
  44. Стиль, ревью и CI/CD-инструменты: Atlantis, TACOS, policy as code
  45. Что нового в Terraform 1.3-1.10: моды, импорт, провайдер-функции, Stacks
  46. OpenTofu в 2026: чем живёт форк и как мигрировать
  47. Сертификация HashiCorp Terraform Associate и карьера
Представь ситуацию. Ты дописал модуль, прогнал terraform apply прямо на знакомом проекте, вроде все поднялось. А через неделю приходит счет от облака, и там лишние пару тысяч рублей за виртуалку, которую ты поднял "на минуточку проверить" и забыл прибить. Знакомо? Если нет - значит, ты еще не дошел до этого этапа, но дойдешь. Этот урок про то, как тестировать инфраструктуру как код руками, не теряя при этом ни прод, ни деньги.

Мы пока не трогаем автотесты (Terratest, проверки в CI - это отдельная большая тема). Сегодня - дисциплина ручной проверки: подними, проверь, снеси. Звучит просто, но именно на "снеси" спотыкается большинство.

Зачем вообще тестировать инфра-код руками

Terraform - это инфраструктура как код, и слово "код" тут не для красоты. Код имеет свойство содержать ошибки. Опечатка в имени подсети, неправильный CIDR, забытый атрибут, провайдер, который молча создал ресурс не там - все это всплывает только когда ты реально вызываешь terraform plan и apply против живого облака.

Ручной тест отвечает на простые вопросы:
  • Применяется ли конфигурация вообще, без ошибок валидации и API?
  • Получается ли в итоге то, что ты задумал - сеть со связностью, виртуалка с доступом, бакет с правами?
  • Корректно ли все это удаляется обратно? (да, destroy тоже надо тестировать)
  • Идемпотентен ли код - если прогнать apply дважды, второй раз показывает "No changes"?
Последний пункт недооценивают. Если повторный terraform plan apply показывает изменения там, где ты ничего не менял, значит, в коде что-то описано не так, как облако это реально хранит. Это будущий источник "дрейфа" и ночных сюрпризов.

Изображение

Почему песочница, а не прод

Главное правило: тестовое окружение должно быть физически изолировано от боевого. Не "та же инфраструктура, только осторожненько", а отдельная песочница, где не страшно сломать вообще все.

В Yandex Cloud для этого есть удобная иерархия: организация - облако (cloud) - каталог (folder). Каталог - это и есть твоя естественная граница изоляции. Заводишь отдельный folder под тесты, например с именем sandbox или dev-playground, и работаешь только в нем. Если что-то пойдет не так, ты сносишь ресурсы только внутри этого каталога и прод даже не заметит.

Почему именно отдельный каталог, а не отдельный state в том же:
  • Права (IAM) выдаются на каталог. Можно дать тестовому сервисному аккаунту доступ только к песочнице - и он физически не дотянется до прода.
  • Биллинг и квоты видно отдельно. Легко понять, сколько жрет именно тестирование.
  • Случайный terraform destroy в песочнице не превратится в катастрофу.
Вот минимальный каркас провайдера под тестовый каталог. Обрати внимание - folder_id отдельный, и токены/ключи берутся из переменных окружения, а не хардкодятся:

Код: Выделить всё

terraform {
  required_providers {
    yandex = {
      source  = "yandex-cloud/yandex"
    }
  }
}

provider "yandex" {
  zone      = "ru-central1-a"
  folder_id = var.sandbox_folder_id
}

variable "sandbox_folder_id" {
  type        = string
  description = "ID тестового каталога - НИКОГДА не прод"
}
Идентификацию (token или service_account_key_file) удобно прокидывать через переменные окружения YC_TOKEN или авторизацией yc-cli, чтобы ключи не лежали в коде и не утекли в git.

Цикл ручного теста: apply, проверка, destroy

Полный круг выглядит так. Создаем минимальную, но осмысленную инфраструктуру - сеть, подсеть и виртуалку с тегами, по которым потом легко найти все тестовое:

Код: Выделить всё

resource "yandex_vpc_network" "test" {
  name   = "tf-test-net"
  labels = {
    env     = "sandbox"
    owner   = "ivan"
    cleanup = "auto"
  }
}

resource "yandex_vpc_subnet" "test" {
  name           = "tf-test-subnet"
  zone           = "ru-central1-a"
  network_id     = yandex_vpc_network.test.id
  v4_cidr_blocks = ["10.10.0.0/24"]
}

resource "yandex_compute_instance" "test" {
  name        = "tf-test-vm"
  platform_id = "standard-v3"
  zone        = "ru-central1-a"

  resources {
    cores  = 2
    memory = 2
  }

  boot_disk {
    initialize_params {
      image_id = "fd8..."  # подставь актуальный image_id из YC
      size     = 10
    }
  }

  network_interface {
    subnet_id = yandex_vpc_subnet.test.id
    nat       = true
  }

  labels = {
    env     = "sandbox"
    cleanup = "auto"
  }
}
Дальше - сама дисциплина прогона:

Код: Выделить всё

# 1. Что вообще будет создано - читаем глазами
terraform plan

# 2. Создаем
terraform apply

# 3. Проверяем работоспособность руками:
#    - пингуем внешний IP виртуалки
#    - ssh-имся внутрь
#    - дергаем нужный сервис
ping <внешний_IP>
ssh user@<внешний_IP>

# 4. Прогон на идемпотентность - должно быть No changes
terraform apply

# 5. Сносим ВСЕ, что подняли
terraform destroy
Шаг 5 - не опциональный. Это часть теста, а не уборка после него. Пока ты не убедился, что destroy сносит ресурсы чисто и без зависших зависимостей (а в сетях это частая боль - подсеть не удаляется, пока к ней что-то привязано), тест не пройден.

Проблема забытых ресурсов и денег

Главный враг тут - человеческая память. Ты создал три тестовых стенда за день, два снес, про третий забыл. Виртуалка с публичным IP и диском тихо капает деньги, пока ты про нее не вспомнишь в момент прихода счета.

Что с этим делать системно:

1. Лейблы и теги на всем. Заметил, я везде вешал labels с env=sandbox и cleanup=auto. Это не для красоты - это твой будущий фильтр. В любой момент можно через yc-cli найти все, что помечено как тестовое:

Код: Выделить всё

yc compute instance list --folder-id <sandbox_folder_id> \
  --format json | jq '.[] | select(.labels.cleanup == "auto") | .name'
2. Инструменты массовой зачистки. В мире AWS есть популярный cloud-nuke, который сносит вообще все в аккаунте по фильтру. Для Yandex Cloud прямого аналога такого же уровня нет, но логика та же: скрипт, который проходит по каталогу и удаляет ресурсы по лейблу или по всему folder. Простейший вариант на yc-cli:

Код: Выделить всё

#!/bin/bash
# Снести все виртуалки с меткой cleanup=auto в песочнице
FOLDER="<sandbox_folder_id>"
for id in $(yc compute instance list --folder-id "$FOLDER" \
    --format json | jq -r '.[] | select(.labels.cleanup=="auto") | .id'); do
  echo "Удаляю инстанс $id"
  yc compute instance delete "$id"
done
Но честно: если ты создавал инфраструктуру через Terraform, основной инструмент очистки - это сам terraform destroy. Скрипты-нюкеры нужны для подбора "мусора", который остался вне state - ручные эксперименты, ресурсы из удаленного кода, артефакты упавших apply.

3. Отдельный каталог как естественный нюкер. Если вся песочница - это один folder и в нем нет ничего ценного, можно просто периодически выгребать его целиком. Это самый надежный способ не платить за забытое.

4. Бюджеты и алерты в биллинге. Поставь в YC оповещение на сумму по тестовому каталогу. Условные 500 рублей в месяц на песочницу - и если порог пробит, тебе прилетит письмо раньше, чем счет.

Кстати, все то же применимо и к OpenTofu - это форк Terraform, команды plan, apply, destroy и работа со state идентичны, так что вся дисциплина переносится один в один.

Типичные грабли
  • Тестируешь на проде "по-быстрому". Классика. Один неудачный destroy с не тем -target, и ты объясняешь команде, куда делась боевая база.
  • Забыл, что terraform destroy сносит только то, что в текущем state. Ресурсы, созданные вне Terraform или из другого workspace, останутся жить и капать деньгами.
  • Не проверил идемпотентность. Apply прошел, но повторный показывает changes - значит, дрейф уже заложен в код.
  • Публичный IP и внешний диск остались после destroy. Бывает, когда они вынесены в отдельный ресурс с lifecycle prevent_destroy или просто не попали в зависимость.
  • Лейблы написал, а фильтровать по ним забыл. Метки без процесса поиска - просто украшение.
Мини-лаба

Сделай руками, без этого урок не усвоится:
  • Заведи в Yandex Cloud отдельный каталог под песочницу. Настрой провайдера на его folder_id.
  • Опиши сеть, подсеть и одну виртуалку с лейблами env=sandbox и cleanup=auto.
  • Прогони terraform plan, прочитай вывод. Затем apply.
  • Проверь, что виртуалка живая - зайди по ssh.
  • Прогони apply еще раз. Убедись, что видишь "No changes" - это идемпотентность.
  • Напиши однострочник на yc-cli, который выводит все ресурсы с меткой cleanup=auto.
  • Сделай terraform destroy. Проверь в консоли облака, что не осталось ни диска, ни IP.
Контрольные вопросы
  • Почему отдельный каталог (folder) в Yandex Cloud лучше для тестов, чем отдельный state в том же каталоге, что и прод?
  • Что проверяет повторный прогон terraform apply сразу после первого и почему "No changes" - это хорошо?
  • Какие тестовые ресурсы terraform destroy НЕ удалит и откуда они берутся?
  • Зачем вешать лейблы env и cleanup на ресурсы, если у тебя и так есть terraform destroy?
Итог: что запомнить

Ручной тест Terraform - это не "запустил apply и ушел". Это полный цикл: plan, apply, проверка работоспособности, проверка идемпотентности, destroy. Прод не трогаем никогда - под тесты заводим изолированную песочницу, в Yandex Cloud это отдельный каталог. Лейблы env и cleanup плюс биллинг-алерты - твоя страховка от забытых ресурсов и неожиданных счетов. И главное правило, которое стоит вытатуировать: что подняли в тесте - то и снесли. Дисциплина destroy экономит больше нервов и денег, чем любой умный скрипт.
👍5 ❤️3 🔥2 😄 🤔1
Аватара пользователя
Redtop43
Сообщения: 2
Зарегистрирован: 22 май 2026, 10:35

Re: Ручное тестирование Terraform и очистка ресурсов

Сообщение Redtop43 »

Спасибо, прям про меня - забыл инстанс на выходные, прилетел счет. Теперь буду вешать cleanup=auto на все подряд. А лейблы как-то можно задним числом на уже созданную виртуалку добавить или только пересоздавать?
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
darkdruid
Сообщения: 1
Зарегистрирован: 13 май 2026, 03:45

Re: Ручное тестирование Terraform и очистка ресурсов

Сообщение darkdruid »

Не догнал момент с идемпотентностью. Если второй apply показывает changes хотя я ничего не менял - это всегда баг в коде или бывает что облако само что-то докрутило и так нормально?
👍 ❤️1 🔥 😄 🤔1
Ответить
← Предыдущая глава
Версионирование, публикация модулей и Terragrunt
Следующая глава →
Автоматические тесты на Terratest: модульные тесты

Все главы курса «Terraform: инфраструктура как код на Yandex Cloud»

Поделиться темой: ✈ Telegram VK
Похожие запросы: terraform yandex cloud с чего начать новичкукак установить terraform и opentofu на linuxчто такое terraform state и tfstate простыми словамиудаленный backend terraform на object storage yandex cloudчто такое инфраструктура как код iac простыми словамиterraform plan и apply что делают и чем отличаются

Вернуться в «Terraform: инфраструктура как код на Yandex Cloud»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость