IaC: зачем и принципы, декларативность и идемпотентность
↑ Этап 6 · Infrastructure as Code: Ansible, Terraform
Зачем это на собесе
Базовые принципы 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-модули (в большинстве), SQL | Bash-скрипты, 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
- Всё в Git: код инфраструктуры, ревью через PR, история, защита веток.
- Единый источник истины: изменения только через код (запрет ручных правок; «drift detection»).
- Идемпотентность и повторяемость; безопасный повторный запуск.
- Модульность и переиспользование: модули/роли/шаблоны; DRY без чрезмерной абстракции.
- Параметризация окружений (переменные, inventory, workspaces): один код — разные значения.
- Секреты вне кода: Vault, SOPS, облачные менеджеры,
ansible-vault; не в Git и не в state-файлах открыто. - Тестирование и валидация: линтеры (
tflint,ansible-lint,yamllint),terraform validate/plan,checkov/tfsec, Molecule/Testinfra, preview-окружения. - План перед применением (
terraform plan,ansible --check --diff) и ревью изменений. - Минимальные права у автоматизации (service accounts, роли на окружение).
- Автоматизация в CI/CD: plan на PR, apply после merge с подтверждением на prod.
- Наблюдаемость и аудит: кто и что применил, журнал изменений.
- Документация и стандарты: соглашения по именованию, тегам, структуре репозитория.
- Малые изменения, частые применения; защита от удаления критичных ресурсов (
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 создаёт сети).
Вопросы с ответами
Чем декларативный подход отличается от императивного?
Декларативный описывает желаемое состояние, а инструмент сам вычисляет и выполняет необходимые изменения; императивный задаёт шаги. Декларативный проще повторять и коррекировать дрейф.
Что такое идемпотентность и почему она важна?
Повторное выполнение не меняет результат, если система уже в целевом состоянии. Это позволяет безопасно перезапускать конфигурацию, исправлять дрейф и восстанавливаться после частичных сбоев.
В чём разница между Terraform и Ansible?
Terraform декларативно создаёт и изменяет облачные ресурсы, хранит state; Ansible настраивает ОС и приложения на хостах по SSH (агентless) без хранения состояния. Часто используются вместе.