Упаковка многократно используемой автоматизации в роль

AnsibleBeginner
Практиковаться сейчас

Введение

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

Создайте и вызовите роль со значениями по умолчанию

На этом шаге вы перенесёте автоматизацию сайта в роль и вызовете её через короткий плейбук с многократно используемыми входными значениями по умолчанию.

Роль группирует связанные задачи, переменные по умолчанию, шаблоны и обработчики в стандартном каталоге. Её tasks/main.yml — точка входа задач; defaults/main.yml предоставляет значения с низким приоритетом, которые потребители могут переопределять. Источники шаблонов находятся в templates, а handlers/main.yml позже будет содержать действия службы, вызываемые изменениями.

Подготовленный инвентарь уже размещает web1 в canary, а web2 в stable внутри родительской группы sites. Nginx установлен как предварительное условие. Изучите группы:

cd /home/labex/project
ansible-inventory --graph

Создайте каталоги роли через mkdir -p. Несколько аргументов путей создают каждый указанный каталог:

mkdir -p roles/managed_site/tasks roles/managed_site/defaults roles/managed_site/templates roles/managed_site/handlers

Добавляйте к открытым переменным роли префикс site_, чтобы обозначить их назначение. Начните с общих значений по умолчанию, доступных любому потребителю:

cat > roles/managed_site/defaults/main.yml <<'YAML'
site_environment: training
site_port: 8080
site_maintenance: false
YAML

Шаблон страницы использует входное значение роли вместе с именем каждого целевого узла и собранным дистрибутивом:

cat > roles/managed_site/templates/page.txt.j2 <<'JINJA'
host={{ inventory_hostname }}
environment={{ site_environment }}
distribution={{ ansible_facts.distribution }}
JINJA

Создайте точку входа задач роли. Внутри роли src: page.txt.j2 разрешается в каталоге templates этой роли; назначение остаётся абсолютным управляемым путём:

cat > roles/managed_site/tasks/main.yml <<'YAML'
- name: Prepare the role-managed website directory
  ansible.builtin.file:
    path: /var/www/role-site
    state: directory
    owner: root
    group: root
    mode: "0755"

- name: Render the role-managed page
  ansible.builtin.template:
    src: page.txt.j2
    dest: /var/www/role-site/index.html
    owner: root
    group: root
    mode: "0644"
YAML

Вызовите роль ключевым словом roles. Окружающий play выбирает целевые узлы, собирает факты и запрашивает become; роль предоставляет многократно используемые задачи:

cat > site.yml <<'YAML'
- name: Apply the managed site role with defaults
  hosts: sites
  gather_facts: true
  become: true
  roles:
    - managed_site
YAML

Проверьте и запустите роль через плейбук-потребитель:

ansible-playbook site.yml --syntax-check
ansible-playbook site.yml

Изучите фактические страницы, созданные ролью:

ansible sites -m ansible.builtin.command -a 'cat /var/www/role-site/index.html'

Обе должны показывать environment=training из значения по умолчанию со своими именами хостов и distribution=Ubuntu. Простое создание каталогов роли не выполняло бы роль и не создавало эти управляемые файлы.

Сохраняйте шаблоны и обработчики внутри многократно используемой роли

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

Поместите полный шаблон nginx рядом с источником страницы. Он использует входные данные site_ роли, ранее отработанный фильтр upper и логическую ветвь:

cat > roles/managed_site/templates/nginx.conf.j2 <<'JINJA'
events {}
http {
    server_tokens off;
    server {
        listen {{ site_port }};
        root /var/www/role-site;
        index index.html;
        add_header X-Environment "{{ site_environment | upper }}" always;
{% if site_maintenance %}
        add_header X-Maintenance "enabled" always;
{% else %}
        add_header X-Maintenance "disabled" always;
{% endif %}
    }
}
JINJA

Добавьте задачи роли, проверяющие сформированную конфигурацию перед заменой и явно сохраняющие nginx запущенным. Изменённая конфигурация уведомляет именованный обработчик роли:

cat >> roles/managed_site/tasks/main.yml <<'YAML'

- name: Render and validate the role-managed nginx configuration
  ansible.builtin.template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
    owner: root
    group: root
    mode: "0644"
    validate: /usr/sbin/nginx -t -c %s
  notify: Reload managed site

- name: Keep the role-managed service running
  ansible.builtin.service:
    name: nginx
    state: started
YAML

Запишите обработчик в точке входа обработчиков роли вместо его дублирования в каждом плейбуке-потребителе:

cat > roles/managed_site/handlers/main.yml <<'YAML'
- name: Reload managed site
  ansible.builtin.service:
    name: nginx
    state: reloaded
YAML

Запустите неизменный плейбук-потребитель. Теперь роль предоставляет полное поведение развёртывания:

ansible-playbook site.yml

Оба хоста должны запустить собственный сайт на порту по умолчанию 8080. Изучите каждый целевой узел через собственную петлевую конечную точку:

ansible sites -m ansible.builtin.command -a 'curl --fail --silent --show-error -i http://127.0.0.1:8080/'

Каждое тело должно обозначать свой хост и environment=training. Заголовки должны включать X-Environment: TRAINING и X-Maintenance: disabled. Вывод поступает от работающих служб, настроенных ролью, а не от демонстрации только на управляющем узле.

Повторно используйте одну роль с переопределениями переменных групп

На этом шаге вы примените одну роль к двум контекстам групп без редактирования её многократно используемых значений по умолчанию и файлов задач.

Значения роли по умолчанию намеренно имеют низкий приоритет. Переменные групп инвентаря могут переопределять эти открытые входные данные при сохранении одной реализации. Оставьте defaults/main.yml неизменным и создайте данные потребителя каждой группы:

cat > group_vars/canary.yml <<'YAML'
site_environment: development
site_port: 8081
site_maintenance: true
YAML
cat > group_vars/stable.yml <<'YAML'
site_environment: production
site_port: 8082
site_maintenance: false
YAML

Замените плейбук-потребитель двумя plays, вызывающими одну и ту же роль managed_site. Каждая группа получает собственные разрешённые входные данные. Не дублируйте каталог роли для каждого окружения:

cat > site.yml <<'YAML'
- name: Apply the shared role to canary
  hosts: canary
  gather_facts: true
  become: true
  roles:
    - managed_site

- name: Apply the shared role to stable
  hosts: stable
  gather_facts: true
  become: true
  roles:
    - managed_site
YAML

Проверьте и примените оба контекста:

ansible-playbook site.yml --syntax-check
ansible-playbook site.yml

Оба окружения должны загрузить изменённую конфигурацию через обработчик внутри роли. Изучите фактические конечные точки на новых настроенных портах:

ansible canary -m ansible.builtin.command -a 'curl --fail --silent --show-error -i http://127.0.0.1:8081/'
ansible stable -m ansible.builtin.command -a 'curl --fail --silent --show-error -i http://127.0.0.1:8082/'

Canary должен обозначать web1 и development с заголовками DEVELOPMENT/enabled. Stable должен обозначать web2 и production с заголовками PRODUCTION/disabled. Эти различия происходят из входных данных групп, а одна общая роль по-прежнему содержит значения по умолчанию, задачи, шаблоны и обработчики.

Повторите тот же плейбук-потребитель:

ansible-playbook site.yml

Обе строки итога должны сообщать changed=0, unreachable=0 и failed=0 без запланированного обработчика. Многократно используемую роль нужно вызвать, и она должна создать правильное достигнутое управляемое состояние; один каркас каталогов не является развёртыванием.

Резюме

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