Вопрос "Ansible или Terraform" возникает у каждого, кто впервые автоматизирует развёртывание серверов. Короткий ответ: это разные инструменты для разных задач, и в реальных проектах они почти всегда работают вместе. Terraform создаёт инфраструктуру — сервер, диск, сеть, а Ansible настраивает то, что уже создано. Разберём, где проходит граница и как собрать из двух инструментов один рабочий пайплайн.
Чем принципиально отличаются Ansible и Terraform
Terraform — инструмент для управления инфраструктурой как кодом. Он описывает конечное состояние: сколько нужно серверов, с какими дисками, в какой сети, и сам решает, что создать, изменить или удалить, чтобы прийти к этому состоянию. Ansible — инструмент конфигурационного управления. Он не создаёт серверы сам по себе, а выполняет на уже существующих машинах последовательность шагов: поставить пакет, положить файл, перезапустить службу.
Граница простая: Terraform отвечает на вопрос "сколько серверов и какие" — VDS, диски, приватная сеть, правила фаервола у провайдера. Ansible отвечает на вопрос "что внутри сервера" — какой веб-сервер, какая версия PHP, какие пользователи и cron-задачи.
Когда выбирать Terraform
Terraform нужен, если инфраструктура описывается через API облачного провайдера: заказ VDS, привязка плавающего IP, настройка приватной сети между серверами, создание балансировщика нагрузки. Если завтра нужно поднять второй такой же кластер серверов в другом регионе, Terraform сделает это за одну команду.
- Заказ и удаление серверов через API провайдера без ручных кликов в панели
- Версионирование инфраструктуры в git — изменения видны в diff перед применением
- Воспроизводимость: staging и production собираются из одного набора файлов
Когда выбирать Ansible
Ansible нужен там, где серверы уже существуют и их надо привести к одинаковому состоянию: установить nginx и PHP-FPM, развернуть SSH-ключи, настроить firewall на уровне ОС, применить обновления безопасности. Ему не важно, откуда взялся сервер — из Terraform, из ручного заказа в панели ZevsHost или из старого парка железа.
- Настройка ПО и служб на серверах, которые уже существуют
- Массовое применение изменений на десятках серверов одной командой
- Задачи, которые не описываются термином "инфраструктура": деплой кода, ротация логов, обновление сертификатов
Декларативный и процедурный подход: в чём разница на практике
Terraform декларативен: файл описывает желаемое состояние, а не список шагов. Запустили terraform apply дважды подряд без изменений в файлах — второй раз ничего не произойдёт. Ansible процедурен по структуре плейбука, но идемпотентен по каждому модулю: модуль apt не переустановит уже установленный пакет, а модуль copy не перезапишет файл с тем же содержимым.
| Критерий | Terraform | Ansible |
|---|---|---|
| Что описывает | Ресурсы облака: серверы, диски, сети | Состояние ОС и приложений на сервере |
| Модель | Декларативная, с файлом состояния | Последовательность задач по инвентарю |
| Хранение состояния | state-файл, обычно в S3 или Terraform Cloud | Состояние не хранится, проверяется при каждом запуске |
| Скорость правки одного параметра | Требует apply, может пересоздать ресурс | Точечный запуск playbook на нужный хост |
Как связать Terraform и Ansible в одном пайплайне
Стандартная схема: Terraform создаёт сервер и выводит его IP-адрес через output, Ansible берёт этот адрес как inventory и настраивает сервер. Провайдер VDS для примера — Hetzner Cloud, но схема работает с любым провайдером, у которого есть API.
resource "hcloud_server" "web" {
name = "web-01"
server_type = "cx22"
image = "ubuntu-24.04"
ssh_keys = [hcloud_ssh_key.main.id]
}
output "web_ip" {
value = hcloud_server.web.ipv4_address
}
Дальше динамический inventory для Ansible собирается из вывода Terraform одной командой, а сам плейбук ставит базовый набор пакетов:
- hosts: web
become: true
tasks:
- name: Установить nginx и PHP-FPM
apt:
name: ["nginx", "php-fpm"]
state: present
update_cache: true
- name: Запустить и включить nginx
service:
name: nginx
state: started
enabled: true
Полный процесс — от заказа сервера до готового к работе окружения — обычно оформляют отдельным этапом в пайплайне GitLab CI: сначала джоб с terraform apply, затем джоб с ansible-playbook, который получает адрес из артефактов первого шага. Подробнее про совместное описание инфраструктуры в коде смотрите в статье про Terraform для VPS.
Частые ошибки при совместном использовании
Первая ошибка — дублирование ответственности: часть настройки сервера прописывают через cloud-init внутри Terraform, а часть — через Ansible, и через полгода никто не помнит, где что менять. Вторая — хранение state-файла Terraform локально на ноутбуке разработчика без резервной копии: при потере файла Terraform перестаёт понимать, что уже создано, и норовит создать ресурсы заново.
- Смешивание задач настройки ОС между cloud-init и Ansible в одном проекте
- Локальный state-файл Terraform без удалённого бэкенда и блокировок
- Запуск Ansible без предварительной проверки playbook в режиме
--check
Итог: короткий чек-лист выбора
Если нужно управлять серверами, дисками и сетями у провайдера — берите Terraform. Если нужно настроить то, что уже работает, — берите Ansible. В большинстве проектов оба инструмента используются вместе, каждый в своей зоне ответственности.
- Инфраструктура облака и её версии в git — Terraform
- Пакеты, конфиги и службы внутри сервера — Ansible
- State Terraform хранить удалённо, с блокировкой
- Связывать оба шага одним пайплайном CI, а не запускать вручную