Infrastructure as Code: управление инфраструктурой код с помощью Terraform, Pulumi, Ansible
Мы часто видим, как terraform apply зависает на aws_db_instance.main: Still modifying... — и никто не знает, безопасно ли его прервать. Потому что state хранится локально в terraform.tfstate, последние три инженера работали с ним по очереди, а сейчас двое запустили apply одновременно. State разъехался. Это не гипотетическая ситуация — это то, с чего начинается половина IaC-аудитов. Только за прошлый квартал мы разобрали семь таких инцидентов, средний MTTR — 4 часа. Наши инженеры решают такие проблемы каждый месяц, ускоряя восстановление втрое по сравнению с ручным поиском.
Почему Terraform State — самое уязвимое место?
Terraform хранит карту реального мира в terraform.tfstate. Если state некорректен — Terraform либо пересоздаст ресурс, который уже есть, либо не увидит дрейф конфигурации. Оба варианта плохи: первый вызывает downtime, второй — незапланированные изменения. В среднем на проекте с 200 ресурсами дрейф обнаруживается раз в две недели, а его устранение занимает до 8 часов.
Remote state с locking — первое, что настраивается на любом проекте:
terraform { backend "s3" { bucket = "company-terraform-state" key = "production/eks/terraform.tfstate" region = "eu-west-1" encrypt = true dynamodb_table = "terraform-state-lock" } } DynamoDB-таблица с атрибутом LockID (тип String) обеспечивает locking: второй terraform apply получит ошибку Error acquiring the state lock и не запустится. На GCP то же самое через GCS backend с встроенным object locking. На Azure — azurerm backend с Storage Account.
Второй уровень проблем — terraform import устаревших ресурсов. Когда инфраструктура создавалась руками в консоли, а потом решили «перейти на IaC» — придётся импортировать каждый ресурс: terraform import aws_security_group.web sg-0abc123def. Это итеративный процесс на несколько дней для крупных окружений. Альтернатива — terraformer или former2 для генерации конфигурации из существующей инфраструктуры, но результат всегда требует ручной доводки. В одном из проектов импорт 150 ресурсов занял 3 дня, а доработка модулей — ещё неделю.
State drift — когда кто-то поменял ресурс вне Terraform (через консоль, CLI, другой инструмент). terraform plan покажет дрейф, но не всегда очевидно: восстанавливать state по конфигурации или обновить конфигурацию по state. Для production-инфраструктуры ставим lifecycle { prevent_destroy = true } на критические ресурсы — RDS, VPC, EKS кластер. Это предотвращает случайное удаление.
Архитектура Terraform-модулей
Плоский main.tf на 3000 строк — самая распространённая ошибка. Через полгода никто не понимает, что от чего зависит, и каждый plan занимает 10 минут. После разбивки на модули время плана сокращается в 3–5 раз.
Правильная структура — модульная:
infrastructure/ modules/ eks-cluster/ # переиспользуемый модуль main.tf variables.tf outputs.tf rds-postgres/ vpc/ environments/ production/ main.tf # вызывает модули с prod-параметрами backend.tf variables.tf staging/ main.tf # те же модули, другие размеры Модуль eks-cluster принимает через variables.tf параметры: версию K8s, типы нод, количество AZ. Производственное окружение вызывает его с instance_types = ["m5.xlarge"], staging — с ["t3.medium"]. Код один, параметры разные.
Версионирование модулей через Git tags — важно для воспроизводимости:
module "eks" { source = "git::https://github.com/company/tf-modules.git//eks-cluster?ref=v2.3.0" ... } Обновление модуля — осознанное действие с тегом, не случайный подхват изменений из main.
Terragrunt — надстройка над Terraform для DRY-конфигураций. Убирает дублирование backend-блоков и провайдеров между окружениями. terragrunt run-all plan — покажет план для всех модулей сразу. Оправдан при 5+ окружениях или регионах. Мы используем Terragrunt в проектах с мультирегиональной архитектурой, где количество окружений превышает 6.
Pulumi: IaC на реальном языке программирования
Terraform HCL — декларативный DSL с ограничениями: циклы через for_each и count, условия через тернарные выражения, отсутствие нормальных функций. Pulumi решает это радикально — пишешь на TypeScript, Python, Go или C#.
import * as aws from "@pulumi/aws"; import * as eks from "@pulumi/eks"; const cluster = new eks.Cluster("production", { instanceType: "m5.xlarge", desiredCapacity: 3, minSize: 2, maxSize: 10, deployDashboard: false, }); // Нормальный TypeScript: массивы, функции, условия const apps = ["api", "worker", "scheduler"]; apps.forEach(app => { new aws.ecr.Repository(app, { imageTagMutability: "IMMUTABLE", imageScanningConfiguration: { scanOnPush: true }, }); }); Pulumi хранит state в Pulumi Cloud (managed) или в S3/Azure Blob/GCS (self-hosted). Для команд без опыта TypeScript/Python — порог входа выше, чем у Terraform. Для команд с сильными разработчиками — Pulumi выигрывает на сложных сценариях. Сравнение: Pulumi с TypeScript позволяет сократить объём кода на 30% по сравнению с HCL при работе с цикличными ресурсами.
Ansible: конфигурация и не только
Ansible закрывает то, что Terraform не умеет: настройку внутри сервера. Terraform создал EC2-инстанс, Ansible настроил nginx, установил зависимости, задеплоил конфиги.
Идемпотентность — ключевое свойство. Плейбук можно запустить 10 раз, результат будет одинаковым. ansible-playbook -i inventory/production site.yml --diff покажет конкретные изменения в файлах конфигурации перед применением.
Организация ролей через Ansible Galaxy или внутренний репозиторий. Роль common — базовые настройки для всех серверов: пользователи, SSH, NTP, fail2ban. Роль kubernetes-node — настройки ядра для K8s-нод: vm.swappiness=0, net.bridge.bridge-nf-call-iptables=1, отключение swap.
Ansible Vault для секретов — зашифрованные переменные прямо в репозитории:
ansible-vault encrypt_string 'super_secret_password' --name 'db_password' Результат — зашифрованная строка в group_vars/production/vault.yml, расшифровывается при запуске через --vault-password-file.
Ansible vs Terraform: они не конкуренты, а complementary. Terraform — провизионирование инфраструктуры (VPC, инстансы, managed-сервисы). Ansible — конфигурация операционной системы и приложений. На Kubernetes Ansible используется реже — там Helm и Operators берут на себя управление конфигурацией.
CloudFormation: когда нужна нативная интеграция с AWS
CloudFormation — IaC-инструмент AWS. Преимущество одно, но существенное: нативность. Новый AWS-сервис появляется в CloudFormation в день релиза или на следующий день. В Terraform провайдер aws иногда отстаёт на недели.
AWS CDK (Cloud Development Kit) — синтаксический сахар над CloudFormation: пишешь на TypeScript/Python, генерирует CloudFormation шаблоны. Та же логика, что у Pulumi, но выходной формат — CloudFormation JSON/YAML.
Для чистых AWS-окружений без планов мультиклауда CDK — разумный выбор. Для гетерогенных окружений (AWS + частично GCP или Azure, или on-premise) — Terraform даёт единый инструментарий.
Как внедрить IaC с нуля: пошаговая инструкция
- Аудит текущей инфраструктуры — инвентаризация всех серверов, сервисов, сетей. Составляем карту зависимостей.
- Выбор инструмента и бекенда — для мультиклауда Terraform с remote state на S3+GCS, для AWS-only — CDK.
- Миграция state — перенос локальных tfstate в удалённое хранилище с locking (DynamoDB/GCS). На это уходит 1–2 дня.
- Импорт существующих ресурсов — используем terraformer, затем дорабатываем модули. Для 50–200 ресурсов — 1–2 недели.
-
Настройка CI/CD и тестирование — интеграция с GitLab CI/GitHub Actions:
terraform planна каждый PR,applyтолько после approval. Развёртывание staging окружения для тестов.
По данным HashiCorp, организации, внедрившие IaC, сокращают время развёртывания в 3–4 раза. (источник: Wikipedia: Infrastructure as Code)
Типичные ошибки при внедрении IaC
- Terraform без locking — первый же параллельный запуск сломает state.
- Один большой state —
terraform planдля 400 ресурсов занимает 15 минут,applyстрашно запускать. Разбиваем по слоям: networking, database, compute, application. - Секреты в
terraform.tfvarsв Git-репозитории. Используем Vault, AWS Secrets Manager или переменные окружения. -
terraform destroyдоступен всем — в production блокируем через IAM или CI/CD permissions. - Нет
terraform fmtиterraform validateв CI — несогласованный код и синтаксические ошибки попадают в main-ветку.
Как автоматизировать импорт существующей инфраструктуры?
Для быстрого импорта мы используем terraformer (от Google) или former2 — они генерируют Terraform-код по существующим ресурсам. Однако результат всегда требует ручной рефакторинг: группировка в модули, удаление лишних зависимостей, адаптация под корпоративные стандарты. На полное покрытие инфраструктуры из 50–200 ресурсов уходит 1–2 недели. После импорта мы автоматически запускаем terraform validate и tflint для проверки качества кода.
Сравнение инструментов IaC
| Инструмент | Язык | State | Locking | Когда выбирать |
|---|---|---|---|---|
| Terraform | HCL | Remote (S3, GCS, etc.) | DynamoDB/GCS locking | Мультиклауд, зрелость, сообщество |
| Pulumi | TS/Python/Go/С# | Pulumi Cloud / self-hosted | Встроенный | Команды разработчиков, сложная логика |
| CloudFormation | JSON/YAML | AWS native | Встроенный | Чистый AWS, нужна нативность |
| Ansible | YAML | Нет | Нет | Конфигурация ОС, ad-hoc задачи |
Ansible не конкурирует, а дополняет — для конфигурации после провизионирования.
Типичные сроки и стоимость
| Задача | Сроки |
|---|---|
| Terraform state migration (local → remote) | 1–2 дня |
| Покрытие существующей инфраструктуры Terraform (import) | 1–3 недели |
| Модульная структура с prod/staging окружениями | 1–2 недели |
| Ansible-автоматизация парка серверов (10–50 хостов) | 1–2 недели |
| Полное внедрение IaC с нуля | 4–8 недель |
Стоимость рассчитывается индивидуально после аудита текущего состояния инфраструктуры. Экономия времени инженеров — до 40% в месяц, а сокращение количества инцидентов, связанных с дрейфом конфигурации, — до 70%. Свяжитесь с нами — оценим проект и предложим оптимальное решение.
Пример успешного кейса: миграция state и оптимизация плана
Мы работали с клиентом, у которого был один state на 350 ресурсов и план выполнялся 12 минут. После разбивки на 4 слоя и подключения remote state с locking время плана уменьшилось до 2 минут, а apply стал безопасным — блокировка предотвращает параллельные запуски. Экономия времени дежурного инженера — 5 часов в неделю.Получите консультацию прямо сейчас: напишите нам в Telegram или оставьте заявку на сайте. Работаем под ключ — от аудита до полной автоматизации. Закажите аудит инфраструктуры уже сегодня, и мы покажем, сколько времени и денег вы сэкономите.







