Автоматизация обновлений ИТ-систем: Ansible и Terraform для DevOps | AdminWiki

Автоматизация обновлений ИТ-систем: Ansible и Terraform для DevOps

09 августа 2026 12 мин. чтения
Содержание статьи

Введение: зачем автоматизировать обновления и как Ansible с Terraform решают эту задачу

Ручное обновление серверов и Kubernetes-кластеров отнимает часы, порождает ошибки и приводит к незапланированным простоям. Одна опечатка в команде, пропущенный хост или несовместимость версий пакетов могут обернуться аварией на продакшене. Автоматизация снимает эти риски: вы описываете желаемое состояние системы в коде, а инструменты гарантируют его достижение на всех целевых узлах.

Связка Ansible и Terraform закрывает полный цикл обновления. Terraform управляет инфраструктурой: разворачивает виртуальные машины, обновляет Kubernetes-ресурсы, переключает балансировщики. Ansible настраивает операционную систему и приложения: обновляет пакеты, правит конфигурационные файлы, перезапускает сервисы. Вместе они позволяют реализовать стратегии Canary и Blue-Green deployment, которые сводят к минимуму время недоступности сервиса и дают возможность быстрого отката.

В этом руководстве вы получите готовые плейбуки и конфигурации Terraform, которые можно адаптировать под свои задачи. Мы последовательно разберем настройку инструментов, автоматизацию обновления Linux-серверов, управление версиями контейнеров в Kubernetes и практическую реализацию Canary и Blue-Green. Все примеры проверены на Ubuntu 24.04 и Kubernetes 1.32, но логика переносится на любой современный дистрибутив и версию кластера.

Подготовка среды: настройка Ansible и Terraform для работы

Перед написанием автоматизации убедитесь, что инструменты установлены и имеют доступ к целевым системам. Минимальные требования: машина управления с Linux или macOS, Python 3.10+, доступ по SSH к серверам и настроенный kubeconfig для Kubernetes-кластера.

Установка и базовая конфигурация Ansible

Установите Ansible через пакетный менеджер системы. На Ubuntu 24.04 выполните:

sudo apt update && sudo apt install ansible -y

На CentOS Stream 10 или RHEL-подобных дистрибутивах:

sudo dnf install epel-release -y && sudo dnf install ansible -y

После установки создайте инвентарный файл hosts.ini. Он определяет, на каких серверах Ansible будет выполнять задачи. Для начала укажите тестовую группу серверов:

[web_servers]
web01 ansible_host=192.168.1.10 ansible_user=deploy
web02 ansible_host=192.168.1.11 ansible_user=deploy

[all:vars]
ansible_python_interpreter=/usr/bin/python3

Настройте ansible.cfg в рабочей директории. Для тестовой среды отключите проверку SSH-ключей, чтобы ускорить первое подключение:

[defaults]
inventory = ./hosts.ini
host_key_checking = False
retry_files_enabled = False

[ssh_connection]
pipelining = True

Проверьте соединение с серверами командой:

ansible all -m ping

Успешный вывод содержит "ping": "pong" для каждого хоста. Если соединение не устанавливается, проверьте SSH-ключи и доступность порта 22.

Установка и настройка Terraform с провайдером Kubernetes

Скачайте Terraform с официального сайта HashiCorp. На момент написания статьи актуальна версия 1.11. Распакуйте бинарник в директорию, доступную в PATH:

wget https://releases.hashicorp.com/terraform/1.11.0/terraform_1.11.0_linux_amd64.zip
unzip terraform_1.11.0_linux_amd64.zip
sudo mv terraform /usr/local/bin/

Создайте директорию для конфигураций Terraform и файл main.tf с настройкой провайдера Kubernetes:

terraform {
  required_providers {
    kubernetes = {
      source  = "hashicorp/kubernetes"
      version = "~> 2.35"
    }
  }
}

provider "kubernetes" {
  config_path = "~/.kube/config"
}

Выполните инициализацию и проверьте подключение к кластеру:

terraform init
terraform plan

Если terraform plan отрабатывает без ошибок аутентификации, провайдер настроен корректно. Для работы с облачными ресурсами добавьте соответствующий провайдер, например hashicorp/aws или yandex-cloud/yandex. Подробный разбор выбора инструментов IaC есть в сравнении Terraform, Ansible и Pulumi.

Автоматизация обновления серверов с помощью Ansible

Обновление пакетов на десятках серверов вручную - это гарантированные расхождения конфигураций и пропущенные хосты. Плейбук Ansible решает эту проблему: вы описываете процедуру один раз, а применяете её ко всем серверам группы параллельно или последовательно.

Пошаговый разбор плейбука обновления пакетов

Создайте файл update_servers.yml. Плейбук состоит из трех задач: обновление кэша пакетов, установка обновлений и условная перезагрузка. Модуль package абстрагирует различия между apt и dnf, поэтому плейбук работает на Debian- и Red Hat-семействах без изменений.

---
- name: Обновление пакетов на Linux-серверах
  hosts: web_servers
  become: yes
  serial: 1

  tasks:
    - name: Обновить кэш пакетов
      ansible.builtin.package:
        update_cache: yes
      register: cache_update

    - name: Установить все обновления пакетов
      ansible.builtin.package:
        name: "*"
        state: latest
      register: package_update

    - name: Проверить, требуется ли перезагрузка
      ansible.builtin.stat:
        path: /var/run/reboot-required
      register: reboot_required

    - name: Перезагрузить сервер, если необходимо
      ansible.builtin.reboot:
        msg: "Перезагрузка после обновления пакетов"
        reboot_timeout: 300
      when: reboot_required.stat.exists

    - name: Дождаться возврата сервера
      ansible.builtin.wait_for_connection:
        delay: 10
        timeout: 300

Параметр serial: 1 заставляет Ansible обрабатывать серверы по одному. Это критически важно для продакшен-среды: если обновление сломает сервис на первом хосте, вы остановите выполнение до того, как пострадают остальные. Директива become: yes повышает привилегии до root, что необходимо для установки пакетов и перезагрузки.

Задача проверки файла /var/run/reboot-required специфична для Debian/Ubuntu. На CentOS/RHEL можно заменить её на проверку вывода команды needs-restarting -r из пакета yum-utils. Модуль reboot корректно завершает сессию, ждет выключения и повторно подключается после загрузки системы.

Запуск плейбука и проверка результатов

Перед применением на продакшене выполните прогон в режиме проверки. Флаг --check показывает, какие изменения были бы внесены, не применяя их:

ansible-playbook update_servers.yml --check

Для обновления конкретной группы или одного сервера используйте флаг --limit:

ansible-playbook update_servers.yml --limit web01

После выполнения плейбука проверьте версии ключевых пакетов. Например, для ядра Linux:

ansible web_servers -m command -a "uname -r"

Вывод покажет одинаковую версию ядра на всех хостах, если перезагрузка прошла успешно. Для критически важных сервисов добавьте в плейбук задачу проверки их статуса после обновления - это закроет риск «сервер включился, но сервис не стартовал».

Если вы только начинаете внедрять автоматизацию, обратите внимание на практический гайд по автоматизации инфраструктуры, где разобраны сквозные сценарии от мониторинга до резервного копирования.

Управление инфраструктурой при обновлениях с Terraform

Terraform переводит управление инфраструктурой на декларативные рельсы. Вы описываете, как должны выглядеть ресурсы после обновления, а Terraform вычисляет разницу между текущим и желаемым состоянием и применяет только необходимые изменения. Этот подход исключает дрейф конфигураций и делает процесс повторяемым.

Пример: обновление образа контейнера в Kubernetes через Terraform

Предположим, у вас есть Deployment с веб-приложением, и нужно обновить образ контейнера с версии 1.2.0 на 1.3.0. Опишите ресурс в Terraform-конфигурации:

resource "kubernetes_deployment" "web_app" {
  metadata {
    name      = "web-app"
    namespace = "production"
    labels = {
      app = "web"
    }
  }

  spec {
    replicas = 3

    selector {
      match_labels = {
        app = "web"
      }
    }

    template {
      metadata {
        labels = {
          app = "web"
        }
      }

      spec {
        container {
          name  = "app"
          image = "registry.example.com/web-app:1.3.0"
          port {
            container_port = 8080
          }
        }
      }
    }
  }
}

Выполните terraform plan. Terraform покажет, что изменится тег образа в определении пода, и ничего больше. Вывод будет содержать строку вроде:

~ image = "registry.example.com/web-app:1.2.0" -> "registry.example.com/web-app:1.3.0"

Примените изменения:

terraform apply

Terraform отправит новый манифест в Kubernetes API, и контроллер Deployment выполнит rolling update согласно стратегии, заданной в самом Deployment. Важно: Terraform не ждет завершения rolling update по умолчанию. Для гарантии, что все поды перешли на новую версию, добавьте в конфигурацию ресурс time_sleep или используйте внешний скрипт проверки, который запускается через local-exec.

Совместное использование Ansible и Terraform в пайплайне

Инструменты не конкурируют, а дополняют друг друга. Terraform создает виртуальные машины, сети и Kubernetes-ресурсы. Ansible настраивает операционную систему и приложения на уже существующих серверах. Типичный сценарий выглядит так:

  1. Terraform разворачивает три новые виртуальные машины в облаке и добавляет их IP-адреса в выходные переменные.
  2. Ansible динамически формирует инвентарь из этих IP-адресов и запускает плейбук установки зависимостей, обновления пакетов и развертывания кода приложения.
  3. Terraform обновляет конфигурацию балансировщика, включая новые серверы в пул.

Связать инструменты можно через local-exec в Terraform. Пример вызова Ansible после создания серверов:

resource "aws_instance" "web" {
  count         = 3
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.medium"

  provisioner "local-exec" {
    command = "ansible-playbook -i '${self.public_ip},' update_servers.yml"
  }
}

Этот подход удобен для небольших проектов. В крупных CI/CD-пайплайнах лучше разделить шаги: Terraform выполняется на стадии provision, Ansible - на стадии configure, а оркестрацию берет на себя Jenkins, GitLab CI или GitHub Actions. Готовый IaC-стек для отказоустойчивого веб-приложения с такой интеграцией описан в руководстве по развертыванию с Terraform и Ansible.

Стратегии развертывания: Canary и Blue-Green для минимизации рисков

Обновление «в лоб», когда новая версия раскатывается на все серверы одновременно, опасно для критичных сервисов. Ошибка в коде, несовместимость с базой данных или утечка памяти проявятся сразу у всех пользователей. Стратегии Canary и Blue-Green решают эту проблему, ограничивая радиус поражения и давая время на обнаружение дефектов до полного перехода.

Реализация Canary deployment в Kubernetes с Terraform

Canary-развертывание направляет небольшой процент трафика на новую версию, оставляя основную нагрузку на стабильной. Если метрики канареечной версии в порядке, долю трафика постепенно увеличивают до 100%. В Kubernetes это реализуется через два Deployment и один Service с селектором, который не различает версии, плюс Ingress или Service Mesh для управления весами.

Создайте стабильный и канареечный Deployment. Различие только в имени и версии образа:

resource "kubernetes_deployment" "app_stable" {
  metadata {
    name      = "app-stable"
    namespace = "production"
  }
  spec {
    replicas = 9
    selector {
      match_labels = {
        app     = "web"
        version = "stable"
      }
    }
    template {
      metadata {
        labels = {
          app     = "web"
          version = "stable"
        }
      }
      spec {
        container {
          name  = "app"
          image = "registry.example.com/web-app:1.2.0"
        }
      }
    }
  }
}

resource "kubernetes_deployment" "app_canary" {
  metadata {
    name      = "app-canary"
    namespace = "production"
  }
  spec {
    replicas = 1
    selector {
      match_labels = {
        app     = "web"
        version = "canary"
      }
    }
    template {
      metadata {
        labels = {
          app     = "web"
          version = "canary"
        }
      }
      spec {
        container {
          name  = "app"
          image = "registry.example.com/web-app:1.3.0"
        }
      }
    }
  }
}

Service выбирает поды по общему лейблу app: web, поэтому трафик распределяется между обоими Deployment пропорционально количеству подов. При 9 репликах стабильной версии и 1 канареечной на новую версию попадает 10% запросов. Для более точного управления весами используйте Ingress-контроллер с поддержкой canary (например, NGINX Ingress с аннотациями) или Service Mesh вроде Istio.

Изменение доли канареечного трафика в Terraform сводится к изменению переменной replicas для app_canary и повторному terraform apply. Это безопасно: Terraform обновит только количество реплик, не трогая остальные ресурсы.

Реализация Blue-Green deployment с Ansible и Terraform

Blue-Green держит две идентичные среды: «синюю» с текущей версией и «зеленую» с новой. Переключение происходит мгновенно - изменением конфигурации балансировщика. Откат так же быстр: возвращаем трафик на старую среду.

Terraform создает два набора инфраструктуры. Для упрощения используйте модули или параметризованные конфигурации с переменной environment:

module "blue" {
  source      = "./modules/web_cluster"
  environment = "blue"
  image_tag   = "1.2.0"
}

module "green" {
  source      = "./modules/web_cluster"
  environment = "green"
  image_tag   = "1.3.0"
}

После развертывания обеих сред Ansible переключает трафик. Если балансировщик - это Nginx на выделенном сервере, плейбук обновляет его конфигурацию и перезагружает сервис:

- name: Переключить трафик на зеленую среду
  hosts: load_balancer
  become: yes
  vars:
    upstream_hosts:
      - 10.0.2.10
      - 10.0.2.11
  tasks:
    - name: Обновить конфигурацию upstream
      ansible.builtin.template:
        src: nginx_upstream.conf.j2
        dest: /etc/nginx/conf.d/upstream.conf
      notify: reload nginx

  handlers:
    - name: reload nginx
      ansible.builtin.service:
        name: nginx
        state: reloaded

Шаблон nginx_upstream.conf.j2 принимает список IP-адресов зеленой среды и формирует блок upstream. После переключения старая синяя среда остается работать еще некоторое время - это страховка на случай, если в новой версии обнаружится дефект, пропущенный на тестировании. Когда новая версия подтверждена, Terraform уничтожает синюю среду командой terraform destroy -target=module.blue.

Сравнение Canary и Blue-Green: когда что выбрать

КритерийCanaryBlue-Green
Скорость полного переходаМинуты или часы, зависит от числа шаговСекунды
Стоимость инфраструктурыНебольшое увеличение (канареечные реплики)Удвоение на время переключения
Сложность реализацииСредняя, нужен контроль весов трафикаНизкая, два независимых стека
Обнаружение проблемПостепенное, на реальных пользователяхДо переключения, на синтетических тестах
ОткатУменьшение веса до нуляМгновенное переключение обратно
Подходит дляЧастые релизы, проверка гипотезКрупные обновления, миграции схем БД

Canary выбирайте, когда релизы частые и нужно проверять изменения на небольшой доле реального трафика. Blue-Green оправдана для инфраструктурных обновлений, смены версии базы данных или когда простой даже в секунду недопустим. В Kubernetes-окружении Canary реализуется проще благодаря встроенным механизмам Service и Ingress, тогда как Blue-Green требует дублирования ресурсов на уровне инфраструктуры.

Если вы стоите перед выбором между Ansible и Terraform для конкретной задачи, обратитесь к сравнению инструментов для управления инфраструктурой, где разобраны сильные стороны каждого.

Лучшие практики и типичные ошибки при автоматизации обновлений

Автоматизация не отменяет инженерной дисциплины. Плейбук, примененный без проверки на staging-окружении, способен нанести ущерб не меньше ручной ошибки. Следующие практики снижают вероятность инцидентов до минимума.

Всегда тестируйте на staging. Среда должна быть максимально приближена к продакшену по версиям ОС, пакетов и конфигурации. Разница в минорной версии ядра или системной библиотеки может привести к тому, что плейбук отработает на staging без ошибок, а на продакшене вызовет падение сервиса.

Храните плейбуки и конфигурации Terraform в системе контроля версий. Git дает историю изменений, возможность code review и быстрый откат к последней рабочей версии. Привязывайте теги репозитория к релизам приложения - так вы всегда знаете, какая версия инфраструктурного кода соответствует конкретной версии сервиса.

Планируйте откат до начала обновления. Для Ansible это может быть снапшот виртуальной машины или резервная копия конфигурационных файлов, снятая модулем fetch. Для Terraform - сохраненный state-файл и уверенность, что terraform destroy на целевые ресурсы не заденет соседние.

Мониторьте процесс обновления. Добавьте в плейбук задачи, которые отправляют метрики в систему мониторинга до и после обновления. Резкий скачок ошибок 5xx после переключения трафика - сигнал к немедленному откату.

Типичные ошибки, которых следует избегать:

  • Обновление без проверки зависимостей. Пакетный менеджер может предложить удалить пакет, от которого зависит ваше приложение. Всегда анализируйте вывод terraform plan и ansible-playbook --check.
  • Игнорирование блокировок пакетов. Если вы зафиксировали версию PostgreSQL через apt-mark hold, а плейбук пытается обновить все пакеты, возникнет конфликт. Явно описывайте исключения в плейбуке.
  • Параллельное обновление всех серверов. Параметр serial: 1 в Ansible или for_each с паузами в Terraform спасает от полной деградации сервиса.
  • Хранение секретов в открытом виде. Пароли, токены и ключи API не должны лежать в репозитории. Используйте Ansible Vault для шифрования переменных и Terraform sensitive variables или интеграцию с HashiCorp Vault.

Обеспечение безопасности: управление секретами и доступом

Ansible Vault шифрует файлы с переменными. Создайте зашифрованный файл:

ansible-vault create secrets.yml

Внесите в него пароли и токены. При запуске плейбука передайте пароль через флаг --ask-vault-pass или файл с паролем. В CI/CD-пайплайнах пароль Vault передается через защищенную переменную окружения.

State-файлы Terraform содержат всю конфигурацию ресурсов в открытом виде, включая сгенерированные пароли. Храните state в защищенном удаленном бэкенде: S3 с включенным шифрованием, Terraform Cloud или Yandex Object Storage с политикой доступа. Никогда не коммитьте terraform.tfstate в Git-репозиторий.

Ограничивайте права сервисных учетных записей, от имени которых работают Ansible и Terraform. У пользователя, запускающего плейбук обновления, должен быть доступ только к тем серверам и командам, которые действительно нужны. Принцип наименьших привилегий снижает ущерб от компрометации учетной записи.

Если вы планируете масштабную миграцию или переход на новые версии инструментов, изучите руководство по безопасной миграции Ansible и Terraform. Там разобраны алгоритмы переноса state-файлов и синхронизации конфигураций между средами.

Заключение: ваш путь к надежным автоматическим обновлениям

Вы прошли путь от настройки инструментов до реализации Canary и Blue-Green деплоя. У вас есть плейбук Ansible, который обновляет пакеты и перезагружает серверы с контролем очередности. Есть конфигурации Terraform для управления версиями контейнеров в Kubernetes и переключения трафика между средами. Эти артефакты - не просто примеры, а фундамент, который масштабируется на десятки и сотни серверов.

Начните с малого: автоматизируйте обновление тестового кластера. Убедитесь, что плейбук отрабатывает идемпотентно - повторный запуск не вносит изменений. Добавьте мониторинг и алертинг на время обновления. Когда процесс станет рутинным и предсказуемым, перенесите его на продакшен.

Автоматизация обновлений - это непрерывный процесс. Меняются версии пакетов, появляются новые уязвимости, эволюционируют инструменты. Регулярно пересматривайте плейбуки и конфигурации Terraform, адаптируйте их под изменения в инфраструктуре. Инвестиции в качественную автоматизацию окупаются отсутствием ночных инцидентов и уверенностью, что обновление безопасности, выпущенное вчера, уже установлено на всех серверах.

Поделиться:
Сохранить гайд? В закладки браузера