Что такое инфраструктура как код

Инфраструктура как код (IaC) — это практика, где серверы, сети и базы данных описаны текстовыми файлами в репозитории, а не создаются вручную мышкой в облачной консоли.

Если вы не можете пересоздать всю инфраструктуру одной командой из git — у вас нет инфраструктуры, у вас есть набор хрупких артефактов, которые однажды кто-то случайно удалит.

Представьте, что вам нужно поднять три одинаковых окружения: dev, staging и prod. Вручную через веб-консоль это означает десятки кликов, и каждый раз вы что-то забудете — то тег, то правило файрвола, то размер диска. Через месяц никто уже не помнит, почему prod отличается от staging. Это называется configuration drift — расползание конфигурации.

IaC решает проблему радикально: вся инфраструктура становится текстом, который лежит в git рядом с кодом приложения. Его можно ревьюить в pull request, откатывать, копировать и переиспользовать. Сервер перестаёт быть «снежинкой» (уникальным и неповторимым) и становится воспроизводимым артефактом.

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

Есть два способа описать инфраструктуру. Императивный — это список шагов: «создай сервер, потом подключи диск, потом открой порт». Так работают bash-скрипты. Проблема: если скрипт упал на середине, состояние неизвестно, а повторный запуск может сломать уже созданное.

Декларативный подход (его использует Terraform) описывает не шаги, а результат: «должен быть один сервер t2.micro с открытым портом 443». Инструмент сам вычисляет, что нужно сделать, чтобы реальность совпала с описанием. Если сервер уже есть — он ничего не делает. Это свойство называется идемпотентностью: повторный запуск с тем же описанием не меняет ничего.

ИМПЕРАТИВНО (как)            ДЕКЛАРАТИВНО (что)
-----------------           ------------------
1. create_server()          desired = {
2. attach_disk()              servers: 1,
3. open_port(443)             disk: "20gb",
4. if error: ???              port: 443
                            }
шаги, состояние              результат, движок
неизвестно                   сам находит разницу

Как работает под капотом

Декларативный движок всегда работает по одной формуле: он сравнивает желаемое состояние (ваш код) с текущим (что реально существует) и вычисляет diff — набор изменений. Именно так Terraform строит план. Давайте смоделируем эту логику на чистом Python — это и есть сердце любого IaC-инструмента.

def plan(desired, current):
    # что создать, изменить, удалить
    to_create = {k: v for k, v in desired.items() if k not in current}
    to_delete = {k: v for k, v in current.items() if k not in desired}
    to_update = {k: (current[k], desired[k])
                 for k in desired if k in current and current[k] != desired[k]}
    return to_create, to_update, to_delete

desired = {"web": "t2.micro", "db": "t3.small", "cache": "t2.nano"}
current = {"web": "t2.micro", "db": "t3.micro"}  # db мельче, cache нет

c, u, d = plan(desired, current)
print("+ создать:", c)
print("~ изменить:", u)
print("- удалить:", d)

«Попробуй сам ▶» — запустите. Видите? Движок сам понял: cache надо создать, db изменить (t3.micro → t3.small), а web трогать не нужно. Идемпотентность в действии: совпадающие ресурсы остаются нетронутыми.

Частые ошибки

  • Мышка в консоли «на минуточку». Один ручной клик в обход кода — и появляется дрифт. Реальность больше не совпадает с git.
  • Путать IaC с bash-скриптами. Скрипт императивен и не идемпотентен. Повторный запуск ломает то, что уже создано.
  • Не хранить код в git. Файлы .tf на ноутбуке одного инженера — это не IaC, а бомба замедленного действия.

Best practices

  • Вся инфраструктура — в git, изменения только через pull request с ревью.
  • Никаких ручных правок в консоли облака: правьте код, прогоняйте инструмент.
  • Думайте результатами, а не шагами: «должно быть так», а не «сделай это, потом то».

Разбор глубже

Стоит чётче развести три понятия, которые новички часто смешивают: скрипт, конфигурация управления (configuration management) и provisioning. Скрипт на bash императивен и одноразов. Инструменты вроде Ansible или Chef отлично настраивают внутренности уже существующего сервера — пакеты, конфиги, сервисы. А Terraform занимается provisioning — он создаёт сами серверы, сети и балансировщики, то есть провижинит саму платформу. Эти инструменты не конкуренты, а соседи: Terraform поднимает сервер, Ansible его настраивает.

Ещё одно важное свойство декларативного IaC — конвергентность. Сколько бы раз вы ни запускали apply, система сходится к одному и тому же описанному состоянию. Это резко упрощает восстановление после сбоев: упал дата-центр — вы запускаете тот же код в другом регионе и получаете идентичную копию. Инфраструктура перестаёт быть уникальной ценностью, которую страшно потерять, и становится воспроизводимой функцией от кода в git. Именно поэтому говорят, что серверы должны быть «скотом, а не питомцами»: любой можно заменить, потому что описание лежит в репозитории.

Итог: IaC превращает инфраструктуру в воспроизводимый, ревьюируемый код. Terraform — декларативный, идемпотентный инструмент, который сам вычисляет diff между желаемым и текущим. Дальше мы разберём, как именно он это делает.

Проверьте себя
1. Чем декларативный подход отличается от императивного?
AДекларативный быстрее работает
BДекларативный описывает желаемый результат, а движок сам вычисляет шаги
CИмперативный нельзя хранить в git
DРазницы нет, это синонимы
2. Что такое идемпотентность в контексте IaC?
AПовторный запуск с тем же описанием ничего не меняет
BВозможность отката изменений
CШифрование state-файла
DПараллельное создание ресурсов