Послуги Infrastructure as Code: автоматизація, модулі, Terraform
terraform apply зависає на aws_db_instance.main: Still modifying... — і ніхто не знає, чи безпечно його перервати. State зберігається локально в terraform.tfstate, останні три інженери працювали з ним по черзі, зараз двоє запустили apply одночасно. State роз’їхався. Це не гіпотетична ситуація — з неї починається половина наших IaC-аудитів. За минулий квартал ми розібрали сім таких інцидентів, середній MTTR — 4 години. Наші інженери (5+ років досвіду в IaC, сертифіковані HashiCorp та AWS) вирішують такі проблеми щомісяця, прискорюючи відновлення втричі порівняно з ручним пошуком.
Чому 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 — покаже план для всіх модулів одразу. Ми використовуємо Terragrunt у проектах з мультирегіональною архітектурою, де кількість оточень перевищує 6.
Pulumi vs CloudFormation: коли що вибрати?
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 при роботі з циклічними ресурсами.
CloudFormation — IaC-інструмент AWS. Перевага одна, але суттєва: нативність. Новий AWS-сервіс з'являється в CloudFormation майже одночасно з релізом. AWS CDK (Cloud Development Kit) — синтаксичний цукор над CloudFormation: пишеш на TypeScript/Python, генерує CloudFormation шаблони. Для чистих AWS-оточень без планів мультиклауду CDK — розумний вибір. Для гетерогенних оточень (AWS + частково GCP або Azure, або on-premise) — Terraform дає єдиний інструментарій.
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 беруть на себе управління конфігурацією.
Процес впровадження IaC та що входить у роботу
Кожен проект починається з аудиту поточної інфраструктури — інвентаризації всіх серверів, сервісів, мереж, складання карти залежностей. Далі вибираємо інструмент та бекенд (для мультиклауду — Terraform з remote state на S3+GCS, для AWS-only — CDK). Міграція state з локального сховища у віддалене з locking займає 1–2 дні. Імпорт існуючих ресурсів (50–200 шт.) — 1–2 тижні, після чого доопрацьовуємо модулі та перевіряємо terraform validate + tflint у CI.
У результаті ви отримуєте:
- Документовану модульну структуру з версіонуванням (Git tags)
- Налаштований CI/CD пайплайн (plan на кожен PR, apply тільки після approval)
- Remote state з locking (S3 + DynamoDB або еквівалент)
- Розбивку state на шари (networking, database, compute, application)
- Ansible-ролі для парку серверів (10–50 хостів — 1–2 тижні)
- Інструкції для команди та навчання (2 години демо)
- Гарантію на стабільність state та відтворюваність деплоїв
Повне впровадження IaC з нуля займає від 4 до 8 тижнів залежно від складності. Вартість розраховується індивідуально після аудиту. Економія часу інженерів — до 40% на місяць, а скорочення кількості інцидентів, пов’язаних із дрейфом конфігурації, — до 70%.
| Задача | Терміни |
|---|---|
| Terraform state migration (local → remote) | 1–2 дні |
| Покриття існуючої інфраструктури Terraform (import) | 1–3 тижні |
| Модульна структура з prod/staging оточеннями | 1–2 тижні |
| Ansible-автоматизація парку серверів (10–50 хостів) | 1–2 тижні |
| Повне впровадження IaC з нуля | 4–8 тижнів |
Типові помилки та як їх уникнути
Найпоширеніші помилки — відсутність locking, монолітний state, секрети в коді, доступний всім terraform destroy. Щоб уникнути їх, налаштовуйте remote state з locking одразу, розбивайте state на шари (мережа, бази даних, обчислення, додатки), використовуйте Vault або менеджер секретів для чутливих даних, обмежуйте права на destroy через IAM політики, і додайте terraform fmt та validate у ваш CI/CD пайплайн.
Порівняння інструментів — для швидкого вибору:
| Інструмент | Мова | 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 завдання |
Наш досвід та гарантії
Ми впровадили IaC на понад 120 проектах — від стартапів до enterprise з 400+ ресурсами. Середній MTTR критичних інцидентів після автоматизації — менше 30 хвилин. Усі інженери мають сертифікації Terraform, AWS, Kubernetes. Гарантуємо відтворюваність деплоїв та підтримку протягом 2 тижнів після здачі. Замовте консультацію — ми оцінимо ваш проект і запропонуємо оптимальне рішення. Зв’яжіться з нами у зручний спосіб: форма на сайті, Telegram або email.







