IaC: зачем и принципы, декларативность и идемпотентность

↑ Этап 6 · Infrastructure as Code: Ansible, Terraform

По желанию~6 мин чтенияУровень: middle

Зачем это на собесе

Базовые принципы IaC определяют, как вы управляете серверами и облаком: декларативность, идемпотентность, неизменяемая инфраструктура.

Что такое IaC

Infrastructure as Code — описание инфраструктуры (серверы, сети, БД, права, конфигурации) в коде и файлах в репозитории, а не ручными действиями в консолях и по SSH.

Проблемы ручного управления: «снежинки» (серверы, отличающиеся друг от друга), дрейф конфигурации (configuration drift), невоспроизводимость, отсутствие истории изменений и ревью, «знание в голове», долгое восстановление, ошибки при масштабировании.

Что даёт IaC: воспроизводимость (то же окружение по запросу), версионирование и аудит (Git, PR, ревью), автоматизация (CI/CD для инфраструктуры), согласованность окружений (dev ≈ stage ≈ prod), быстрое восстановление (DR), документация как код, возможность тестирования.

Два уровня

УровеньЗадачаИнструменты
Provisioning (создание ресурсов)сети, ВМ, кластеры, БД, DNS, IAM, бакетыTerraform/OpenTofu, Pulumi, CloudFormation, Bicep, Crossplane, Cluster API
Configuration management (настройка ОС и ПО)пакеты, конфиги, сервисы, пользователи, деплойAnsible, Puppet, Chef, Salt
Образыпредсобранные образы ВМ/контейнеровPacker, Docker, Nix
Оркестрация приложенийдекларативные манифестыKubernetes, Helm, Kustomize, GitOps (ArgoCD/Flux)

Инструменты дополняют друг друга: Terraform создаёт ВМ и сеть → Ansible настраивает ОС и запускает compose/сервисы → Kubernetes запускает приложения.

Декларативный и императивный подход

ДекларативныйИмперативный
Описаниежелаемое состояние («должно быть 3 ВМ типа X»)последовательность шагов («создай ВМ, затем…»)
Инструмент вычисляетразницу между текущим и желаемым, план действийничего: выполняется как написано
Повторный запускбезопасен, приводит к тому же результатуможет дублировать/ломать
ПримерыTerraform, Kubernetes, Ansible-модули (в большинстве), SQLBash-скрипты, aws cli, kubectl create

Декларативный подход предпочтителен; императивные куски допустимы, если оформлены идемпотентно.

Идемпотентность

Операция идемпотентна, если многократное выполнение приводит к тому же результату, что и однократное: запуск, когда система уже в нужном состоянии, ничего не меняет.

# не идемпотентно
echo "export PATH=..." >> ~/.bashrc       # каждый запуск добавляет строку
useradd deploy                             # второй запуск — ошибка
 
# идемпотентно
grep -q 'export PATH' ~/.bashrc || echo '...' >> ~/.bashrc
id deploy || useradd deploy
# Ansible: идемпотентные модули; changed=0 при повторном запуске
- name: Пользователь deploy
  ansible.builtin.user: { name: deploy, groups: docker, append: true }
- name: Строка в файле
  ansible.builtin.lineinfile: { path: /etc/sysctl.conf, line: "vm.swappiness=10" }

Где нужна: повторный запуск после сбоя, безопасный CI, коррекция дрейфа, масштабирование. Признаки нарушения: command/shell без creates/changed_when, добавление в файлы без проверки, создание ресурсов с уникальными именами при каждом запуске.

Mutable и Immutable инфраструктура

  • Mutable: серверы живут долго, обновляются «на месте» (apt upgrade, правка конфигов) → накопление дрейфа;
  • Immutable: серверы/образы не изменяются; для обновления собирается новый образ/ВМ и заменяется старый (Packer, AMI, контейнеры, Talos). Плюсы: предсказуемость, простой откат, отсутствие «снежинок». Минусы: время сборки образа, управление состоянием (данные — вне образа).

Принцип «pets vs cattle»: серверы — «скот» (заменяемые, безымянные), а не «питомцы» (уникальные, выхаживаемые).

Принципы хорошего IaC

  1. Всё в Git: код инфраструктуры, ревью через PR, история, защита веток.
  2. Единый источник истины: изменения только через код (запрет ручных правок; «drift detection»).
  3. Идемпотентность и повторяемость; безопасный повторный запуск.
  4. Модульность и переиспользование: модули/роли/шаблоны; DRY без чрезмерной абстракции.
  5. Параметризация окружений (переменные, inventory, workspaces): один код — разные значения.
  6. Секреты вне кода: Vault, SOPS, облачные менеджеры, ansible-vault; не в Git и не в state-файлах открыто.
  7. Тестирование и валидация: линтеры (tflint, ansible-lint, yamllint), terraform validate/plan, checkov/tfsec, Molecule/Testinfra, preview-окружения.
  8. План перед применением (terraform plan, ansible --check --diff) и ревью изменений.
  9. Минимальные права у автоматизации (service accounts, роли на окружение).
  10. Автоматизация в CI/CD: plan на PR, apply после merge с подтверждением на prod.
  11. Наблюдаемость и аудит: кто и что применил, журнал изменений.
  12. Документация и стандарты: соглашения по именованию, тегам, структуре репозитория.
  13. Малые изменения, частые применения; защита от удаления критичных ресурсов (prevent_destroy).

Состояние (state)

Декларативные инструменты (Terraform) хранят state — соответствие между кодом и реальными ресурсами. Состояние надо защищать (удалённый backend с блокировкой, шифрование, бэкапы). Ansible «без состояния»: запрашивает фактическое состояние у хоста на каждом запуске (агентless, по SSH).

GitOps

Состояние инфраструктуры/приложений описано в Git, а агент (ArgoCD, Flux) в кластере непрерывно приводит реальность к репозиторию (pull-модель); откат = git revert; дрейф автоматически исправляется.

Дрейф (drift)

Расхождение между кодом и реальностью из-за ручных изменений, аварийных правок, сторонних процессов. Способы: запрет прав на ручные изменения, регулярный terraform plan по расписанию (drift detection), ansible --check в CI, политики, аудит-логи облака, импорт ручных ресурсов в код (terraform import).

Антипаттерны

  • правки «вручную на проде» без отражения в коде;
  • огромные монолитные конфигурации без модулей и окружений;
  • секреты в репозитории и в переменных без защиты;
  • копипаста для окружений вместо параметризации;
  • один общий state на всё (риск, блокировки);
  • отсутствие plan/ревью, автоматический apply на prod без контроля;
  • смешение ответственности инструментов (Terraform настраивает ПО, Ansible создаёт сети).

Вопросы с ответами