Инфраструктура как код: Terraform и управление конфигурациями
Зачем нужна инфраструктура как код в DevOps-цепочке
В предыдущих статьях курса мы выстроили базовую линию DevOps:
DevOps-мышление требует быстрых и безопасных изменений.
Linux, сети и Git дают базовые навыки диагностики и управления изменениями.
CI/CD автоматизирует сборку, тестирование и доставку.
Контейнеризация стандартизирует упаковку и запуск.Но остается критический вопрос: как создавать и менять сами окружения (сети, кластеры, базы, балансировщики, права доступа) так же контролируемо, как код приложения.
Инфраструктура как код (IaC, Infrastructure as Code) — подход, при котором инфраструктура описывается декларативно в файлах, хранится в Git, проходит ревью и применяется автоматически (или полуавтоматически) через пайплайны.
!Где IaC находится в общем DevOps-цикле
Основные принципы IaC
Чтобы IaC действительно работал, важны не столько инструменты, сколько принципы.
Декларативность: вы описываете желаемое состояние (например, “нужна сеть и 3 виртуальные машины”), а инструмент сам определяет, что создать или изменить.
Воспроизводимость: одно и то же описание должно приводить к одному и тому же результату.
Версионирование в Git: инфраструктура меняется через коммиты, pull/merge request и ревью.
Автоматизация применения: изменения применяются через пайплайн, а не вручную в консоли.
Минимум ручных правок: если что-то изменили в инфраструктуре, это должно быть отражено в IaC, иначе появится расхождение.Ключевой эффект IaC — инфраструктура становится частью “продукта”, а не набором ручных настроек.
Terraform: что это и почему он так популярен
Terraform — инструмент для описания и применения инфраструктуры как кода. Он работает через провайдеры (providers), которые умеют управлять ресурсами конкретных платформ: облака, DNS, Kubernetes, базы данных как сервис, GitHub и т.д.
Официальные источники:
Terraform Documentation
Terraform Language
Terraform ProvidersБазовые термины Terraform
Provider (провайдер) — плагин для работы с API платформы.
Resource (ресурс) — то, чем Terraform управляет (виртуальная машина, сеть, DNS-запись).
Data source (источник данных) — чтение уже существующих данных (например, получить ID готовой сети).
Module (модуль) — переиспользуемый набор ресурсов с входами и выходами.
State (состояние) — файл (или удаленное хранилище), где Terraform хранит соответствие “ресурс в реальности ↔ ресурс в коде”.Типовой рабочий цикл Terraform
Terraform построен вокруг предсказуемого процесса.
terraform init
terraform fmt и terraform validate
terraform plan
terraform applyСмысл шагов:
init скачивает провайдеры и настраивает backend (хранилище state).
fmt приводит код к стандартному форматированию.
validate проверяет базовую корректность конфигурации.
plan показывает, что изменится, но ничего не меняет.
apply применяет изменения.Практика для DevOps: plan удобно запускать в CI на каждый merge request, а apply — только после ревью и подтверждения.
Минимальный пример Terraform-конфигурации
Ниже пример, который показывает структуру HCL-конфигурации: провайдер, переменные и ресурс. Пример намеренно абстрактный, потому что реальные ресурсы зависят от выбранной платформы.
Что здесь важно:
variable задает входной параметр конфигурации.
output публикует результат (удобно для CI/CD или для следующих модулей).Для реальной инфраструктуры добавляются provider и resource блоки конкретной платформы.
Terraform state: почему без него нельзя
Terraform должен понимать, какие объекты в реальности соответствуют ресурсам в коде. Для этого он хранит state.
Что обычно хранится в state:
идентификаторы ресурсов в платформе (например, ID сети/инстанса),
часть атрибутов ресурса, которые нужны для вычисления изменений,
зависимости между ресурсами.Ключевое следствие: state — чувствительная часть системы, потому что там могут оказаться значения, которые не должны быть публичными.
Локальный state против удаленного
Если state лежит локально на ноутбуке, командная работа быстро ломается: разные люди получают разные “истины”. Поэтому в командах используют удаленный backend.
Удаленный backend решает несколько задач:
общий state для всей команды,
блокировки (locking), чтобы два человека не применили изменения одновременно,
аудит и управляемость.Популярные варианты:
Terraform Cloud/Enterprise,
S3 + DynamoDB для блокировок (в AWS-практиках),
аналоги в других облаках.Официальная документация по backends:
Terraform Backends!Зачем нужен state и почему он должен быть общим
Модули Terraform: как не утонуть в копипасте
По мере роста инфраструктуры возникает повторяемость: сети, базовые политики, стандартные компоненты. Модули позволяют упаковать “шаблон инфраструктуры” и переиспользовать его.
Практический смысл модулей:
снизить копипасту,
стандартизировать инфраструктуру,
скрыть сложность за простым интерфейсом (variables/outputs).Официальная документация:
Terraform ModulesРекомендация по стилю: модуль должен иметь понятные входы (переменные) и выходы, а внутри — реализовывать детали.
Окружения: dev, staging, production без хаоса
Окружения обычно отличаются:
размерами (меньше ресурсов в staging),
настройками доступов,
доменами, сертификатами,
иногда даже регионом.Главная цель — чтобы staging был максимально похож на production, но дешевле и безопаснее.
Практический подход для Terraform:
держать разный state для разных окружений,
использовать разные значения переменных,
применять изменения по отдельным пайплайнам.Terraform предлагает механизм workspaces, но в реальных командах часто выбирают более явную структуру репозитория (например, отдельные директории на окружение), чтобы было сложнее ошибиться и “применить не туда”.
Документация:
Terraform WorkspacesУправление конфигурациями: где заканчивается Terraform и начинается Ansible
Terraform отлично подходит для создания инфраструктурных ресурсов. Но на практике нужно еще и настраивать то, что внутри:
пакеты,
конфиги сервисов,
пользователи и права,
параметры ОС,
раскладка файлов.Для этого используют управление конфигурациями (configuration management). Один из популярных инструментов — Ansible.
Официальные источники:
Ansible DocumentationВ чем разница на практике
| Задача | Terraform | Ansible |
|---|---|---|
| Создать сеть, балансировщик, ВМ, managed-сервис | Да | Обычно нет |
| Описать связи ресурсов и зависимости | Да | Ограниченно |
| Настроить пакеты и конфиги внутри серверов | Ограниченно | Да |
| Работать через SSH на уже созданных хостах | Не основной сценарий | Да |
Упрощенная ментальная модель:
Terraform отвечает за “что создать в платформе”.
Ansible отвечает за “как настроить хост после создания”.Типовые комбинации
Terraform создает инфраструктуру (сети, ВМ, security groups), затем Ansible настраивает ПО на ВМ.
Terraform создает кластер Kubernetes и сопутствующие ресурсы, а приложение ставится в кластер через Helm/манифесты.
Вместо настройки серверов используют “запеченные образы” (image baking): образ собирается заранее (например, Packer), а Terraform лишь запускает готовые образы.Выбор зависит от платформы и зрелости процессов, но общий DevOps-принцип один: меньше ручных действий, больше воспроизводимости.
Секреты и чувствительные данные в IaC
В IaC постоянно встречаются секреты: токены, пароли, ключи. Ошибки здесь особенно опасны.
Правила, которые стоит принять как базовые:
не хранить секреты в репозитории,
не передавать секреты через открытые параметры командной строки,
хранить секреты в специализированных системах (например, Vault или секрет-хранилища облаков),
помнить, что Terraform state может содержать значения атрибутов, включая чувствительные.Terraform умеет помечать значения как sensitive, чтобы они не выводились в консоль, но это не гарантирует, что значение не окажется в state.
Документация:
Sensitive Data in TerraformIaC в CI/CD: как сделать изменения инфраструктуры управляемыми
Практика, которая хорошо ложится на DevOps-мышление из первых статей курса:
Изменение IaC идет через merge request.
CI запускает terraform fmt и terraform validate.
CI запускает terraform plan и публикует план как артефакт или комментарий.
После ревью и approval выполняется terraform apply (часто вручную подтверждаемым шагом пайплайна для production).Это дает:
прозрачность изменений,
повторяемость,
контроль доступа,
меньший риск “случайных кликов” в облачной консоли.Дополнительно полезные практики:
разделять права: пайплайн для plan может иметь более узкие права, чем пайплайн для apply,
логировать, кто и когда применил изменения,
периодически делать drift detection (проверять, что реальность не разошлась с описанием).Типичные ошибки и рабочие практики
Ошибки
“Правки в консоли, потому что быстрее” и забыли перенести в IaC.
Один общий state на все окружения.
Секреты в Git или секреты, утекшие в логи CI.
Отсутствие ревью на изменения инфраструктуры.
Слишком большие изменения одним коммитом, которые сложно проверить.Практики
маленькие изменения и частые применения,
обязательный plan перед apply,
удаленный backend со lock,
модульность и стандартизация,
разделение окружений,
принцип наименьших привилегий для учеток Terraform и CI.Что дальше в курсе
Теперь у нас есть полный “скелет” DevOps-поставки:
Git как источник правды,
CI/CD как механизм автоматизации,
Docker/Kubernetes как стандартный runtime,
Terraform и управление конфигурациями как способ воспроизводимо создавать окружения.Следующий логичный шаг — собрать это в единый практический процесс: от коммита до деплоя в Kubernetes, где инфраструктура и приложение развиваются согласованно, а наблюдаемость подтверждает качество изменений.