К основному содержимому

Ansible или Terraform: что выбрать и когда объединять

Облако и DevOps · 29.09.2026

Вопрос "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 не перезапишет файл с тем же содержимым.

КритерийTerraformAnsible
Что описываетРесурсы облака: серверы, диски, сетиСостояние ОС и приложений на сервере
МодельДекларативная, с файлом состоянияПоследовательность задач по инвентарю
Хранение состояния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, а не запускать вручную
← Назад в базу знаний Задать вопрос поддержке