Infrastructure as Code: Terraform, Ansible
Infrastructure as Code: Terraform, Ansible
1) Почему IaC и чем отличаются инструменты
Terraform — декларативное orchestrator-IaC: создает/изменяет облачную инфраструктуру (VPC, K8s, LB, БД, IAM) через провайдеры. Управляет жизненным циклом ресурсов и хранит состояние.
Ansible — процедурный config-IaC и конфигурационный менеджмент: настраивает хосты/ПО (пакеты, файлы, сервисы), умеет провижнинг приложений, темплейтинг, оркестрацию шагов. Без агента (SSH/WinRM), с идемпотентностью задач.
Комбинация: Terraform — “из чего сделана платформа”, Ansible — “как она настроена и запускается”.
2) Структура репозиториев и слоев
Рекомендуем 3 слоя:1. Foundation (Landing Zone): сети, IAM, KMS, базовые журналы/мониторинг.
2. Platform: кластеры Kubernetes, базы, очереди, observability-стек.
3. Workloads: пространства/неймспейсы, сервисные аккаунты, политики, конфиги.
Репо:- `iac/terraform/` — модули и окружения (`modules/`, `envs/`).
- `iac/ansible/` — роли (`roles/`), плейбуки (`playbooks/`), инвентари (`inventories/`).
- `policies/` — OPA/Conftest правила.
- `pipelines/` — CI/CD скрипты (lint/plan/apply/test).
3) Terraform: модули, стейт, окружения
3.1 Модули
Малые, переиспользуемые: `vpc`, `eks`, `rds`, `redis`, `alb`, `iam-role`.
Входы → `variables.tf`, выходы → `outputs.tf`, версии — через реестр модулей/git-теги.
hcl module "vpc" {
source = "git::ssh://git@repo/iac. git//modules/vpc? ref=v1. 6. 0"
name = "prod-core"
cidr = "10. 0. 0. 0/16"
azs = ["eu-central-1a","eu-central-1b"]
}
3.2 Состояние (state)
Удаленный backend (S3/GCS + DynamoDB/LockTable) + блокировки.
Разделение по окружениям: `prod.tfstate`, `staging.tfstate`.
State-drift: `terraform plan` в CI по расписанию; алерт при дрейфе.
hcl terraform {
backend "s3" {
bucket = "iac-state"
key = "prod/network/terraform. tfstate"
region = "eu-central-1"
dynamodb_table = "iac-locks"
encrypt = true
}
}
3.3 Workspaces / Envs
Варианты:- Отдельные каталоги `envs/prod`, `envs/stage` (наглядно).
- Workspaces для легких вариаций, но избегайте смешивания секретов.
- Параметры через `tfvars`: `prod.tfvars`, `stage.tfvars`.
4) Ansible: роли, инвентари, идемпотентность
4.1 Роли и плейбуки
Стандарт Galaxy:
roles/
nginx/
tasks/main. yml templates/.j2 handlers/main. yml defaults/main. yml playbooks/
site. yml
Пример плейбука:
yaml
- hosts: web become: true roles:
- role: nginx vars:
nginx_listen_port: 8080
4.2 Инвентари и динамика
`inventories/prod/hosts.yml` + переменные `group_vars/host_vars`.
Динамический инвентарь: `aws_ec2`, `gcp_compute`, `kubernetes.core`.
4.3 Идемпотентность
Используйте модули (не `shell`) там, где возможно.
`changed_when`/`check_mode` для сухих прогонов.
Handlers рефлексируют только при изменениях.
5) Секреты и конфиги
Terraform: секреция значений через `sensitive = true`; сами секреты — не в state (храните в AWS Secrets Manager/HashiCorp Vault/KMS и ссылайтесь data-источником).
Ansible: Vault для шифрования переменных (`ansible-vault encrypt`), интеграция с HashiCorp Vault/KMS.
GitOps: секреты в отдельном репо/хранилище, доступ по least-privilege.
6) Политики и соответствие (Policy as Code)
OPA/Conftest для Terraform планов: запрет публичных S3, открытых SG, непомеченных ресурсов (tags).
Terraform Cloud/Enterprise — Sentinel как альтернатива.
Ansible Lint: стиль и безопасность (без `sudo: yes` где не нужно, без raw-shell).
rego package terraform. security
deny[msg] {
input. resource_type == "aws_security_group_rule"
input. values. cidr_blocks[_] == "0. 0. 0. 0/0"
input. values. from_port == 22 msg:= "SSH from 0. 0. 0. 0/0 is forbidden"
}
7) Тестирование IaC
Terraform: `tflint`, `tfsec`/`checkov`, Terratest (Go) для интеграционных проверок.
Ansible: `ansible-lint`, Molecule (+Docker/Podman/EC2) для проверки ролей.
Смоук-тесты после apply: HTTP probes, порт/процессы, права.
8) CI/CD и GitOps
Пайплайн (на Pull/Merge Request):1. Lint/Sec: tflint, tfsec/checkov, ansible-lint.
2. Plan: `terraform plan` с публикацией артефакта (комментарий в MR).
3. Policy Gate: Conftest/Sentinel.
4. Apply (manual/approved): только на main с подписью артефактов.
5. Ansible deploy: `--check` на stage, затем `--diff` в prod.
6. Post-checks: синтетика/Probe, дашборд аннотации релиза.
GitOps:- Храните манифесты как источник правды; Argo CD/Flux для Kubernetes, но базовые кластеры/примитивы — через Terraform.
9) Паттерны для Kubernetes, сетей, БД
9.1 Kubernetes
Terraform: EKS/GKE/AKS кластеры, узлы, IAM, StorageClass, LB.
Ansible: подготовка AMI/бастионов, сборка образов/репозитории, post-install (логгеры/агенты/OTel).
9.2 Сети и периметр
Terraform: VPC/подсети/NAT/Transit-Gateway/WAF, маршруты.
Ansible: конфиг NGINX/Envoy/HAProxy, TLS, конфиги WAF правил.
9.3 Базы/кэши/очереди
Terraform: RDS/CloudSQL параметр-группы, Redis/ElastiCache, Kafka/MSK.
Ansible: прогрев кэша, задания миграций, настройка бэкапов/агентов.
10) Примеры конфигов
10.1 Terraform — RDS PostgreSQL + SG
hcl module "db" {
source = "terraform-aws-modules/rds/aws"
engine = "postgres"
engine_version = "15. 4"
instance_class = "db. m6g. large"
allocated_storage = 100 name = "core"
username = var. db_user password = var. db_password # см. secret data source vpc_security_group_ids = [module. db_sg. security_group_id]
multi_az = true backup_retention = 7
}
module "db_sg" {
source = "terraform-aws-modules/security-group/aws"
name = "db-core"
vpc_id = module. vpc. vpc_id ingress_cidr_blocks = ["10. 0. 0. 0/8"]
ingress_rules = ["postgresql-tcp"]
}
10.2 Terraform — data-источник секрета
hcl data "aws_secretsmanager_secret_version" "db" {
secret_id = "prod/db/core"
}
variable "db_password" {
type = string sensitive = true default = jsondecode(data. aws_secretsmanager_secret_version. db. secret_string). password
}
10.3 Ansible — роль postgresql-client (фрагмент)
yaml
- name: Install packages apt:
name: [ "postgresql-client-15" ]
state: present update_cache: yes
- name: Create. pgpass copy:
dest: /home/deploy/.pgpass mode: '0600'
content: "{{ db_host }}:5432:core:{{ db_user }}:{{ db_password }}"
no_log: true
- name: Smoke query shell: psql -h {{ db_host }} -U {{ db_user }} -d core -c "select 1"
register: psql_out changed_when: false
10.4 Ansible — NGINX с темплейтом
yaml
- name: Deploy nginx. conf template:
src: templates/nginx. conf. j2 dest: /etc/nginx/nginx. conf notify: Restart nginx
- name: Ensure nginx running service:
name: nginx state: started enabled: true
handlers:
- name: Restart nginx service: { name: nginx, state: restarted }
11) Управление дрейфом и соответствием
Периодический `terraform plan` в read-only ключом; создает тикет при расхождении.
Ansible --check по расписанию для критичных ролей (audit-режим).
Отчеты: невыполненные политики OPA/Conftest, ресурсы без тегов/backup/мониторинга.
12) Наблюдаемость и аудит
Логи `terraform apply` и артефакты планов — сохраняйте в объектное хранилище.
Ansible: `callback_plugins` (json) → центральный лог/ELK; включайте job ID, commit SHA, trace_id.
Метрики: время выполнения планов/плейбуков, частота изменений, покрытие тестами.
13) Безопасность
Подпись модулей/ролей или фиксированные теги/хэши.
Минимальные IAM-права (`plan` ≠ `apply`), разделяйте роли CI и человека-аппрувера.
Шифрование состояния/логов, приватные реестры модулей/ролей.
Политика «no plaintext secrets in VCS», секрет-сканеры (gitleaks/trufflehog).
14) Анти-паттерны
Один монстр-модуль Terraform «на все»; отсутствие версий модулей.
Локальный `terraform.tfstate` и отсутствие блокировок.
Ручные правки в облаке поверх IaC → вечный дрейф.
Ansible `shell`/`command` вместо модулей (ломает идемпотентность).
Инвентарь «в одном файле» без групп/переменных, смешивание prod/stage.
Секреты в vars/репозитории, отсутствие Vault/KMS.
Apply без Plan и без Peer Review.
15) Чек-лист внедрения (0–45 дней)
0–10 дней
Настроить удаленный backend/lock, разложить модули Terraform.
Включить tflint/tfsec/checkov, ansible-lint; договориться о тегах/лейблах ресурсов.
Завести Ansible роли для NGINX/агентов/логеров; организовать инвентари.
11–25 дней
Добавить Conftest/OPA, Terratest и Molecule для критичных модулей/ролей.
CI: `plan` на MR, артефакт плана, manual-apply с аппрувом; Ansible `--check` на stage.
Интегрировать секрет-хранилище (Vault/KMS/Secrets Manager).
26–45 дней
Авто-план по расписанию для drift-детекта, отчеты по политикам.
Каталог модулей/ролей с версионированием; документация `README.md` в каждом.
GitOps: аннотации релизов, связка с мониторингом и алерт-гейтами.
16) Метрики зрелости
% окружений с удаленным state и локами = 100%.
Доля модулей/ролей с тестами (Terratest/Molecule) ≥ 70%.
Среднее время от MR до apply (prod) — часы, не дни.
Нулевой «ручной дрейф» (все изменения идут через MR).
100% критичных ресурсов покрыты Policy as Code (теги, шифрование, backup).
17) Заключение
Terraform задает предсказуемую, повторяемую базу инфраструктуры; Ansible доводит хосты и сервисы до требуемого состояния. Добавьте Policy as Code, удаленный state с локацией, тесты, секрет-менеджмент и CI/CD с plan→review→apply — и ваш контур IaC станет управляемым, безопасным и быстрым, а релизы — атомарными и обратимыми.