Ansible: Часть 3. Сценарии (плейбуки) — Playbooks.

На чем было опробовано:

  1. Ansible 2.9.18
  2. Hyper-V на Windows 10 Pro.
  3. Сервер Ansible: CentOS Linux release 7.9.2009 (Core).
  4. Node 1: CentOS Linux release 7.9.2009 (Core).
  5. Node 2: CentOS Linux release 7.9.2009 (Core).
  6. Node 3: CentOS Linux release 7.9.2009 (Core).

1. Введение.

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

Ссылка: docs.ansible.com.
Раздел: «ansible-playbook».

Как установить и первоначально настроить Ansible описано здесь:

Ссылка: «Ansible: Часть 1. Описание, установка и первоначальная настройка.»

Так как простые задачи для Ansible реально простые, в буквальном смысле слова, то я принял решение вынести их в отдельную инструкцию:

Ссылка: «Ansible: Часть 2. Примеры простых задач.»

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

Ссылка: «Ansible: Часть 4. Практические примеры плейбуков.»

Как настраивать защищенные плейбуки описано в этом разделе.

Ссылка: «Ansible: Часть 5. Настройка защищенных плейбуков.»

2. Сценарии — playbooks.

Ansible позволяет не только выполнять единичные задачи, но и писать сценарии, которые необходимо выполнить на управляемых узлах.

Рассмотрим структуру и правила написания таких сценариев более подробно.

Все сценарии в Ansible пишутся на YAML — это удобный для человека формат данных, гораздо более простой, чем XML или JSON.

Чтобы выполнить сценарий используется команда ansible-playbook со следующим синтаксисом:

# ansible-playbook <имя_файла_сценария.yml> ... [другие параметры]

Для Ansible практически каждый YAML файл начинается со списка. Каждый элемент списка — список пар «ключ-значение», часто называемая словарем.

В начале сценария обязательно должна присутствовать последовательность символов ‘---‘ (так в YAML обозначается начало документа).

Перед каждым новым разделом списка ставится дефис ( - ):

---
- name: Операции с SELinux
  hosts: webservers
  become_method: sudo
  become_user: root

  tasks:
  - name: Отключаем SELinux
    selinux:
      state: disabled

Основными параметрами/группами простого сценария являются:

  • hosts — в нем указываются управляемые узлы или группы узлов, к которым нужно применить изменения;
  • tasks — здесь описывается состояние, в которое необходимо привести управляемый узел, альтернативой этому могут служить роли;

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

  • gather_facts — собирать или нет информацию об узлах перед выполнением задач, по умолчанию — да;
  • vars — в нем указываются различные переменные, которые будут использованы при выполнении сценария;
  • connection — можно указать метод соединения с узлами: pure sshparamikofireballchrootjaillocalaccelerate (применимо также для выполнения отдельного модуля);
  • sudo — после установления соединения выполнять задачу с привилегиями другого пользователя, по умолчанию другой пользователь — root;
  • sudo_user — в сочетании с предыдущим параметром можно указать с привилегиями какого именно пользователя будет выполнена задача;
  • vars_prompt — перед выполнением плейбука Ansible в интерактивном режиме может уточнить указанные в этом разделе параметры;
  • remote_user (в предыдущих версиях — просто user) — имя пользователя для авторизации на удалённом узле.

Рассмотрим все эти разделы более подробно.

В разделе hosts указывается группа управляемых узлов, к которой будут применены описываемые в сценарии изменения.

Так, строка формата:

hosts: webservers

Это означает, что изменения будут применены к узлам из группы webservers.

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

В следующем примере авторизация на узле будет произведена с именем yourname, но задачи будут выполняться от имени пользователя root (если, конечно, этому пользователю это разрешено):

---
- name: Операции с SELinux
  hosts: webservers
  become_method: sudo
  become_user: yourname

Если добавить параметр ‘user: postgres‘, то все действия будут выполняться с привилегиями пользователя postgres.

В разделе vars указываются переменные, которые будут использованы в сценарии, и их значения:

- hosts: webservers
  vars:
     http_port: 80
     max_clients: 200

Список изменений, которые необходимо произвести на управляемом узле, приводится в разделе tasks. Каждой задаче (task) присваивается имя (name).

Далее указываются модули Ansible, которые будут задействованы при ее выполнении:

---
- hosts: webservers
  user: yourname
  tasks:
  - service:
      name: nginx
      state: started

Для каждой задачи можно указывать пользователя, от имени которого она будет выполнена:

---
- hosts: webservers
  user: yourname
  tasks:
  - service:
      name: nginx
      state: started
    sudo: yes

Еще некоторые примеры.

Все члены списка должны находится с одинаковым отступом от начала строки, и должны начинаться с пробела или «-». Комментарии начинаются с «#».

Например:

---
# Message
- Hosting
  Cloud

Словарь представлен в виде «ключ:» (двоеточие и пробел) «значение»:

---
# Message
site: habr
blog: infobox

При необходимости словари могут быть представлены в сокращенной форме:

--
# Comment
{site: habr, blog: infobox}

Можно указать логические значение (истина/ложь) так:

---
need_access: no
use_service: yes
file_conf: TRUE
read_value: True
kill_process: false

Целиком наш пример YAML–файла будет выглядеть так:

---
# About blog
site: hamstersen.ru
blog: infobox
must_read: true
themes:
- hosting
- cloud
- it
- geeks
  brands:
  - infobox
  - infoboxcloud

Для переменных Ansible использует «{{ var }}». Если значение после двоеточия начинается с «{», то YAML будет думать, что это словарь.

Для использования переменных нужно заключить скобки в кавычки:

word: "{{ variable }}"

Этого достаточно для начала написания playbooks.

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

Ссылка: «Ansible: Часть 4. Практические примеры плейбуков.»

3. Обработчики событий — handlers.

Ansible не просто выполняет задачи в указанном порядке, но и проверяет их состояние на наличие изменений. Если при выполнении сценария требовалось, например, добавить строку в конфигурационный файл, и в результате выполнения он изменился (необходимой строки действительно не было), то Ansible может выполнить специальную задачу, описанную как обработчик события (handler). Если при выполнении строка уже была в конфигурационном файле, то обработчик выполнен не будет. Обработчики событий описываются в конце сценария. В описании задачи они указываются через параметр notify.

Приведём пример:

---
- hosts: webservers
  vars:
    max_clients: 200

  tasks:
  # генерируем файл конфигурации на основе шаблона
  # и укажем, что требуется выполнить задачу “restart apache”
  # если файл изменился
  - name: write the apache config file
    template:
      src: /srv/httpd.j2
      dest: /etc/httpd.conf
    notify:
    - restart apache
  - name: ensure apache is running
    service: 
      name: httpd
      state: started
# раздел описания обработчиков
  handlers:
    - name: restart apache
    # используем модуль service для перезапуска веб-сервера
      service:
        name: httpd
        state: restarted

4. Контроль выполнения.

Допустим, что при выполнении сценария нам нужно проверять определённые переменные или состояния и, в зависимости от них, выполнять или не выполнять какие-либо задачи.

Для этого можно использовать оператор «when»:

tasks:
    # сохраняем файл шаблона и сохраняем результат задачи
    # в переменную last_result
    - template:
        src: /templates/foo.j2
        dest: /etc/foo.conf
      register: last_result
    # проверяем переменную last_result.changed и если она имеет
    # значение true - задача будет выполнена, иначе - будет пропущена
    - command:
        echo 'the file has changed'
        when: last_result.changed

5. Шаблонизация.

В Ansible используется шаблонизатор Jinja2.

Приведём пример шаблона (часть конфигурации powerdns):

# пароль для подключения к базе данных
gpgsql-password={{ lookup('password', 'credentials/' + inventory_hostname + '/postgresql/powerdns', length=15) }}

# IPv4-адрес, который будет “слушать” powerdns
local-address={{ ansible_default_ipv4.address }}

# IPv6-адрес, который будет “слушать” powerdns
local-ipv6={{ ansible_default_ipv6.address }}

# nsid dns-сервера (EDNS option 3, rfc5001)
server-id={{ ansible_hostname }}

В приведённом примере мы подставляем в шаблон следующие значения:

  • из заранее собранных фактов об узле:
    • ansible_default_ipv4.address — основной IPv4-адрес узла;
    • ansible_default_ipv6.address — основной IPv6-адрес узла;
    • ansible_hostname — имя узла (результат выполнения команды hostname).
  • inventory_hostname — имя узла в инвентарном файле;
  • пароль пользователя powerdns из внешнего источника данных (в данном случае файл) для подключения к базе Postgresql , полученный с помощью lookup-плагина password из стандартной поставке. Особенность некоторых lookup-плагинов — если данных нет, то они могут их генерировать и сохранить для последующего использования.

Обработку шаблонов и, в данном случае, генерацию конфигурационного файла выполняет модуль template; он же может задать необходимые права доступа и изменить владельца/группу:

- name: generate powerdns config
template: src=pdns.conf.j2 dest=/etc/powerdns/pdns.conf owner=powerdns group=powerdns mode=600

Внимание! Файл шаблона и файл с паролем пользователя базы данных находятся на машине управления, а результатом будет файл на удалённом узле.

6. Делегирование задачи другому узлу.

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

Например, во время обновления узла может возникнуть необходимость отключить для него мониторинг, находящийся на отдельном сервере. Для этого используется управляющая директива delegate_to.

Приведём пример:

- name: disable nagios alerts for this host webserver service
  nagios:
    action: disable_alerts
    host: {{inventory_hostname}}
    services: dnsserver
  delegate_to: mon_host.example.com

Результатом выполнения этой задачи будет отключение сообщений для сервиса dnsserver в Nagios.

7. Роли.

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

В сценариях роли назначаются следующим образом:

---
- name: check and apply basic configuration to all hosts
   hosts: all
   roles:
     - common

- name: check and apply configuration to group1
   hosts: group1
   roles:
     - pgsql

- name: check and apply configuration to group2
   hosts: group2
   roles:
     - fooapp

8. Структура проекта.

9. Пишем первые playbook’и.

Playbook может состоять из списка обслуживаемых серверов, переменных пользователя, задач, обработчиков (хендлеров) и так далее. Большинство настроек конфигурации можно переопределить в playbook. Каждый playbook состоит из одного или более действия (игры) в списке.

Цель игры — связать группу хостов с предопределенными ролями, представленными как вызов задач Ansible.

В качестве другого примера давайте рассмотрим процесс установки nginx.

Создадим директорию, где будут хранится playbooks:

# mkdir ~/ansible/playbooks

Создадим файл setup_nginx.yml в директории playbooks со следующим содержанием:

---
- hosts: experiments
  tasks:
  - name: Install nginx package
    apt: 
      name: nginx
      update_cache: yes
    sudo: yes
  - name Starting nginx service
    service:
      name: nginx
      state: started
    sudo: yes

Давайте рассмотрим содержимое:

  • hosts: Список узлов или группа, на которой вы запускаете задачу.

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

Узнать, на каких узлах будет происходить работа, можно командой:

# ansible-playbook --list-host

где – путь к вашему playbook (playbooks/setup_nginx.yml).

  • tasks: Задачи. Все playbooks содержат задачи.

Задача — это список действий, которые вы хотите выполнить. Поле задачи содержит имя задачи (справочная информация о задаче для пользователя playbook), модуль, который должен быть выполнен и аргументы, требуемые для модуля. Параметр «name» может добавляться опционально, но, в целом,  рекомендуемый.

10. Пример сценария.

В этом примере первое воспроизведение предназначено для web-серверов, а второе — для серверов баз данных:

Пример сценария:

---
- name: update web servers
  hosts: webservers
  remote_user: root

  tasks:
  - name: ensure apache is at the latest version
    yum:
      name: httpd
      state: latest
  - name: write the apache config file
    template:
      src: /srv/httpd.j2
      dest: /etc/httpd.conf

- name: update db servers
  hosts: databases
  remote_user: root

  tasks:
  - name: ensure postgresql is at the latest version
    yum:
      name: postgresql
      state: latest
  - name: ensure that postgresql is started
    service:
      name: postgresql
      state: started

11. Практические примеры плейбуков.

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

Ссылка: «Ansible: Часть 4. Практические примеры плейбуков.»

12. Запуск плейбуков.

Чтобы запустить плейбук и выполнить все определенные в нем задачи, используйте команду ansible-playbook:

# ansible-playbook myplaybook.yml

Чтобы перезаписать в плейбуке опцию hosts по умолчанию и ограничить выполнение определенной группой или узлом, включите в команду опцию -l:

# ansible-playbook -l server1 myplaybook.yml

13. Запрос информации о play.

Опция --list-tasks используется для перечисления всех задач, которые будут выполнены в play, при этом не внося никаких изменений на удаленные серверы:

# ansible-playbook myplaybook.yml --list-tasks

Точно так же можно запросить все узлы, которые будут затронуты выполнением play, без запуска каких-либо задач на удаленных серверах:

# ansible-playbook myplaybook.yml --list-hosts

Вы можете использовать теги, чтобы ограничить выполнение play.

Чтобы вывести список всех тегов, доступных в play, используйте параметр --list-tags:

# ansible-playbook myplaybook.yml --list-tags

14. Управление выполнением плейбука.

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

Эта опция в качестве аргумента требует правильное имя задачи:

# ansible-playbook myplaybook.yml --start-at-task="Set Up Nginx"

Чтобы выполнять только задачи, связанные с конкретными тегами, вы можете использовать опцию --tags.

Например, если вы хотите выполнить только задачи, помеченные как nginx или mysql, вы можете использовать:

# ansible-playbook myplaybook.yml --tags=mysql,nginx

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

Следующая команда будет выполнять myplaybook.yml, пропуская все задачи, помеченные как mysql:

# ansible-playbook myplaybook.yml --skip-tags=mysql

15. Настройка защищенных плейбуков.

Если ваши плейбуки Ansible содержат конфиденциальные данные, такие как пароли, ключи API и учетные данные, важно обеспечить их безопасность с помощью шифрования. Ansible предоставляет ansible-vault для шифрования файлов и переменных.

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

Ссылка: «Ansible: Часть 5. Настройка защищенных плейбуков.»

16. Оригиналы источников информации.

  1. selectel.ru «Система управления конфигурацией Ansible».
  2. dmosk.ru «Инструкция по установке и запуску Ansible на CentOS».
  3. dmosk.ru «Что такое ansible».
  4. 8host.com «Как работать с Ansible: простая удобная шпаргалка».
  5. habr.com «Автоматизируем и ускоряем процесс настройки облачных серверов с Ansible. Часть 1: Введение».
  6. kamaok.org.ua «Установка и использование Ansible на Centos7».
  7. Источник: https://hamsterden.ru/ansible-playbooks/

Was this helpful?

2 / 0