Какие основные элементы включает в себя Ansible playbook?

«Какие основные элементы включает в себя Ansible playbook?» — вопрос из категории Ansible, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Ansible playbook — это YAML-файл, который описывает желаемое состояние инфраструктуры или последовательность операций. В своей работе я структурирую playbook, используя следующие ключевые элементы:

1. hosts (или - hosts): Определяет целевую группу хостов из инвентарного файла, на которых будет выполняться playbook. Это может быть группа (webservers), несколько групп (webservers:&production) или все хосты (all).

2. vars (Переменные): Позволяет задавать переменные для всего playbook, делая его гибким и переиспользуемым. Я определяю здесь параметры, специфичные для окружения (например, версии пакетов, порты).

3. tasks (Задачи): Сердце playbook. Это упорядоченный список действий, которые Ansible выполнит на целевых хостах. Каждая задача использует модуль (например, apt, copy, template, service).

  • Важно: Задачи идут последовательно. Я добавляю become: yes для задач, требующих прав суперпользователя.

4. handlers (Обработчики): Специальные задачи, которые запускаются только один раз в конце playbook, если были уведомлены (notify) другими задачами, которые внесли изменения. Классический пример — перезапуск сервиса после изменения его конфигурационного файла.

5. templates (Использование шаблонов Jinja2): Хотя шаблоны сами по себе не являются отдельным элементом в структуре playbook, задача template — это мощный способ генерировать конфигурационные файлы динамически, подставляя переменные (из vars, фактов или инвентаря) в файлы-шаблоны с расширением .j2.

6. roles (Роли): Для сложной инфраструктуры я выношу логически связанные части в роли. Роль — это автономная структура каталогов, содержащая свои tasks, handlers, templates, vars и files. Playbook затем становится лаконичным списком применяемых ролей.

Пример практического playbook для развертывания Nginx:

---
- name: Deploy and configure Nginx web server
  hosts: web_servers  # Группа из инвентаря
  become: yes  # Выполнять задачи с правами sudo
  vars:
    http_port: 8080
    server_name: "myapp.example.com"

  tasks:
    - name: Ensure Nginx is installed (latest version)
      apt:
        name: nginx
        state: latest
        update_cache: yes  # Эквивалент apt update

    - name: Deploy custom Nginx configuration from template
      template:
        src: nginx-site.conf.j2  # Шаблон Jinja2
        dest: /etc/nginx/sites-available/myapp
      notify:  # Уведомляем handler, если задача изменила файл
        - Reload Nginx
        - Check Nginx config

    - name: Enable the site configuration
      file:
        src: /etc/nginx/sites-available/myapp
        dest: /etc/nginx/sites-enabled/myapp
        state: link
      notify:
        - Reload Nginx

  handlers:
    - name: Check Nginx config
      command: nginx -t
      listen: "Reload Nginx"  # Более современный стиль (Ansible 2.2+)

    - name: Reload Nginx
      service:
        name: nginx
        state: reloaded
      listen: "Reload Nginx"

Структура роли (например, roles/nginx/):

roles/nginx/
├── tasks/
│   └── main.yml          # Основные задачи роли
├── handlers/
│   └── main.yml          # Обработчики роли
├── templates/
│   └── nginx-site.conf.j2 # Шаблоны
└── defaults/
    └── main.yml          # Значения переменных по умолчанию

Использование ролей делает код модульным, тестируемым и пригодным для повторного использования в разных проектах.