Инфраструктура как код (infrastructure as code, она же IaC) - это лекарство от такой боли. Идея простая: всё, что описывает твою инфраструктуру - серверы, сети, образы, настройки сервисов - ты держишь в текстовых файлах под контролем версий. Не кликаешь в облачной консоли, не правишь руками, а пишешь декларацию того, как должно быть, и инструмент сам приводит реальность к этому виду.
Проблема новичка в том, что инструментов IaC десятки, и на первый взгляд они делают "что-то похожее". Ansible, Packer, Kubernetes, Terraform, Chef, Puppet, Nomad, Pulumi, CloudFormation... Возникает соблазн думать, что это конкуренты и надо выбрать один. Это ошибка. На самом деле они решают разные задачи и в нормальном стеке работают вместе. Цель этого урока - разложить их по полочкам, чтобы ты понимал, где заканчивается зона ответственности каждого и почему Terraform - это про terraform yandex cloud и provisioning, а не замена всему остальному.
Пять категорий инструментов IaC
Удобнее всего делить инструменты не по брендам, а по тому, какую работу они выполняют. Получается пять категорий.
1. Самодельные скрипты (ad hoc). Это твой старый добрый bash, Python-скрипт или batch-файл. Ты просто записываешь последовательность команд, которую раньше набирал руками. Подходит для разовых задач и быстрых хаков. Минус в том, что скрипты императивны (описывают шаги, а не результат) и плохо масштабируются: если команда уже выполнялась, повторный запуск может всё сломать. Идемпотентности из коробки нет, обработку ошибок пишешь сам, читать чужой скрипт через год - удовольствие сомнительное.
Код: Выделить всё
#!/usr/bin/env bash
set -euo pipefail
apt-get update
apt-get install -y nginx
systemctl enable --now nginx
3. Шаблонизация серверов (server templating). Packer и сборка Docker-образов. Вместо того чтобы настраивать машину после запуска, ты заранее "печёшь" готовый образ (image) со всем нужным софтом внутри. Потом из этого образа поднимаешь хоть сто одинаковых машин - они стартуют уже настроенными. Это основа подхода immutable infrastructure (неизменяемая инфраструктура): не патчим работающий сервер, а пересобираем образ и катим заново. Packer делает образы виртуалок (в том числе для Yandex Cloud), Docker - образы контейнеров.
4. Оркестрация (orchestration). Kubernetes, Nomad, Amazon ECS. Когда у тебя десятки контейнеров и образов, кто-то должен решать, на какой ноде их запускать, как балансировать нагрузку, что делать при падении, как раскатывать новую версию без простоя. Этим занимается оркестратор. Kubernetes - это, по сути, операционная система для кластера: ты говоришь "хочу 5 реплик этого сервиса", а он следит, чтобы они всегда были живы.
5. Выделение ресурсов (provisioning). Вот тут и живёт Terraform, а с ним CloudFormation, Pulumi и OpenTofu (открытый форк Terraform после смены лицензии). Эти инструменты создают саму инфраструктуру в облаке или на железе: виртуальные машины, сети, подсети, диски, балансировщики, базы данных, DNS-записи. Не настройку внутри машины, а сами ресурсы как сущности у провайдера. Terraform делает это декларативно и поверх единого языка HCL для десятков провайдеров.

Где проходят границы и почему это важно
Главная путаница новичков - смешивать provisioning и configuration management. Разберём на примере.
Terraform может создать виртуальную машину в Yandex Cloud: выделить ей CPU, память, диск, подключить к сети, назначить публичный IP. Но Terraform по своей природе не предназначен для того, чтобы внутри этой машины ставить пакеты и крутить конфиги. Да, через cloud-init или provisioner что-то закинуть можно, но это костыль, а не его работа. Настройка внутренностей машины - это зона Ansible.
И наоборот: Ansible умеет подключиться к серверу и навести там порядок, но он не создаёт сам сервер в облаке и не рисует тебе сеть с нуля так удобно, как это делает Terraform со своим terraform state и графом зависимостей. Каждый инструмент силён в своей нише.
Запомни формулу: Packer печёт образ - Terraform поднимает инфраструктуру - Ansible донастраивает - Kubernetes оркеструет нагрузку. Это не конкуренты, это конвейер.
Ещё одна важная ось - декларативность против императивности и наличие управления состоянием. Terraform декларативен и ведёт terraform state - файл, где он помнит, что уже создал. Благодаря этому он умеет показать заранее, что изменится (terraform plan), и аккуратно применить (terraform apply), удаляя то, что больше не нужно. Bash-скрипт так не умеет в принципе: он не знает, что было до него.
Как это выглядит в реальном стеке
Возьмём типичный сценарий выкатки веб-приложения в Yandex Cloud и пройдём по нему.
Сначала Packer собирает образ виртуалки с предустановленным Docker и нужными зависимостями. Дальше в дело вступает Terraform: он описывает облачную инфраструктуру декларативно. Вот минимальный, но рабочий по смыслу фрагмент HCL на провайдере Yandex Cloud - сеть, подсеть и виртуалка из нашего образа.
Код: Выделить всё
terraform {
required_providers {
yandex = {
source = "yandex-cloud/yandex"
}
}
}
provider "yandex" {
zone = "ru-central1-a"
}
resource "yandex_vpc_network" "app" {
name = "app-network"
}
resource "yandex_vpc_subnet" "app" {
name = "app-subnet"
zone = "ru-central1-a"
network_id = yandex_vpc_network.app.id
v4_cidr_blocks = ["10.0.1.0/24"]
}
resource "yandex_compute_instance" "web" {
name = "web-1"
platform_id = "standard-v3"
zone = "ru-central1-a"
resources {
cores = 2
memory = 2
}
boot_disk {
initialize_params {
image_id = "fd80mrhj8fl2oe87o4e1"
}
}
network_interface {
subnet_id = yandex_vpc_subnet.app.id
nat = true
}
}
После того как Terraform поднял машины, к ним подключается Ansible и доводит до ума то, что не зашили в образ: секреты, специфичные конфиги, регистрацию в мониторинге. А если приложение контейнеризовано и его много - сверху работает Kubernetes, раскидывая поды по нодам, которые, кстати, тоже создаются Terraform-ом.
Типичные грабли
- "Зачем Terraform, если есть Ansible (или наоборот)". Это разные слои. Ansible не создаёт облачную инфру удобно, Terraform не настраивает внутренности машин. Пытаться делать всё одним - больно.
- Настраивать ОС через Terraform provisioner. Соблазн велик, но provisioner в Terraform - это аварийный выход, а не инструмент конфигурации. Для настройки бери Ansible или cloud-init.
- Игнорировать terraform state. Новички часто не понимают, откуда Terraform "знает" про созданные ресурсы. Из state-файла. Потеряешь его или поправишь руками в облаке мимо Terraform - получишь рассинхрон и сюрпризы при следующем apply.
- Считать k8s заменой провижинингу. Kubernetes оркеструет контейнеры, но сам кластер, ноды, сети под ним кто-то должен создать. Обычно - тот же Terraform.
Руками писать код пока не нужно, задача - уложить картину в голове.
- Выпиши свой текущий или воображаемый проект и распиши, какой его кусок относится к каждой из пяти категорий: скрипты, конфиг-менеджмент, шаблонизация, оркестрация, провижининг.
- Для одного сервиса нарисуй на бумаге конвейер: что печёт образ, что поднимает инфру, что донастраивает, что оркеструет.
- Открой документацию провайдера Yandex Cloud для Terraform и найди ресурс yandex_compute_instance - просто посмотри, какие у него есть атрибуты. Привыкай искать атрибуты в доке, а не выдумывать.
- К какой из пяти категорий относится Terraform и в чём её суть?
- Чем provisioning отличается от configuration management на конкретном примере?
- Почему Terraform и Ansible - это дополнение друг к другу, а не конкуренты?
- Зачем Terraform нужен terraform state и что будет, если поправить ресурс в облаке мимо него?
Инструменты IaC делятся на пять категорий: самодельные скрипты, управление конфигурацией, шаблонизация серверов, оркестрация и выделение ресурсов. Terraform (как и OpenTofu, Pulumi, CloudFormation) - это категория provisioning: он декларативно создаёт саму инфраструктуру в облаке, ведёт terraform state, показывает изменения через plan и применяет через apply. Он не заменяет Ansible, Packer или Kubernetes - он работает с ними в одном конвейере: Packer печёт образ, Terraform поднимает инфру, Ansible донастраивает, k8s оркеструет. Понимаешь границы категорий - перестаёшь спорить "что лучше" и начинаешь собирать стек правильно.