Spec-Zone.ru › Ansible 2.9

Рекомендованные подходы

Вот несколько советов для эффективного использования Ansible и Ansible playbooks.

Вы можете найти примеры playbooks, иллюстрирующие эти рекомендации, в нашем репозитории ansible-examples. (ПРИМЕЧАНИЕ: они могут не использовать все функции последней версии, но всё равно являются отличной справочной информацией!).

  • Организация контента
    • Структура каталогов
    • Альтернативная структура каталогов
    • Использование динамического инвентаря с облаками
    • Различия между этапами разработки (staging) и производства (production)
    • Переменные групп и узлов
    • Файлы playbooks верхнего уровня разделены по ролям
    • Организация задач и обработчиков для роли
    • Возможности этой организации (примеры)
    • Организация развертывания и конфигурации
  • Этап разработки (staging) против этапа производства (production)
  • Поэтапные обновления
  • Всегда указывайте состояние
  • Группировка по ролям
  • Различия в операционных системах и дистрибутивах
  • Использование модулей Ansible в playbooks
  • Отступы и комментарии
  • Всегда именовать задачи
  • Сохраняйте простоту
  • Система управления версиями
  • Переменные и хранилища

Организация контента

Следующий раздел демонстрирует один из возможных способов организации контента playbook.

Ваше использование Ansible должно соответствовать вашим потребностям, а не нашим, поэтому вы можете изменять этот подход и организовывать его по своему усмотрению.

Один из ключевых способов организации контента playbook — это функция организации Ansible «роли», которая документирована на странице основных playbooks. Вам следует потратить время на чтение и понимание документации по ролям, доступной здесь: Роли.

Структура каталогов

Верхний уровень каталога будет содержать файлы и каталоги следующим образом:

production                # inventory file for production servers
staging                   # inventory file for staging environment

group_vars/
   group1.yml             # here we assign variables to particular groups
   group2.yml
host_vars/
   hostname1.yml          # here we assign variables to particular systems
   hostname2.yml

library/                  # if any custom modules, put them here (optional)
module_utils/             # if any custom module_utils to support modules, put them here (optional)
filter_plugins/           # if any custom filter plugins, put them here (optional)

site.yml                  # master playbook
webservers.yml            # playbook for webserver tier
dbservers.yml             # playbook for dbserver tier

roles/
    common/               # this hierarchy represents a "role"
        tasks/            #
            main.yml      #  <-- tasks file can include smaller files if warranted
        handlers/         #
            main.yml      #  <-- handlers file
        templates/        #  <-- files for use with the template resource
            ntp.conf.j2   #  <------- templates end in .j2
        files/            #
            bar.txt       #  <-- files for use with the copy resource
            foo.sh        #  <-- script files for use with the script resource
        vars/             #
            main.yml      #  <-- variables associated with this role
        defaults/         #
            main.yml      #  <-- default lower priority variables for this role
        meta/             #
            main.yml      #  <-- role dependencies
        library/          # roles can also include custom modules
        module_utils/     # roles can also include custom module_utils
        lookup_plugins/   # or other types of plugins, like lookup in this case

    webtier/              # same kind of structure as "common" was above, done for the webtier role
    monitoring/           # ""
    fooapp/               # ""

Альтернативная структура каталогов

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

inventories/
   production/
      hosts               # inventory file for production servers
      group_vars/
         group1.yml       # here we assign variables to particular groups
         group2.yml
      host_vars/
         hostname1.yml    # here we assign variables to particular systems
         hostname2.yml

   staging/
      hosts               # inventory file for staging environment
      group_vars/
         group1.yml       # here we assign variables to particular groups
         group2.yml
      host_vars/
         stagehost1.yml   # here we assign variables to particular systems
         stagehost2.yml

library/
module_utils/
filter_plugins/

site.yml
webservers.yml
dbservers.yml

roles/
    common/
    webtier/
    monitoring/
    fooapp/

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

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

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

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

Различия между этапами разработки (staging) и производства (production)

Если вы управляете статическим инвентарём, часто возникает вопрос о том, как отличить разные типы сред. Следующий пример показывает хороший способ сделать это. Аналогичные методы группировки могут быть адаптированы к динамическому инвентарю (например, рассмотрите применение тега AWS «environment:production», и вы получите автоматически обнаруженную группу систем с именем «ec2_tag_environment_production»).

Давайте покажем пример статического инвентаря. Ниже, файл production содержит инвентаризацию всех ваших хостов производства.

Рекомендуется определять группы на основе назначения хоста (роли) и также географического местоположения или местоположения дата-центра (если применимо):

# file: production

[atlanta_webservers]
www-atl-1.example.com
www-atl-2.example.com

[boston_webservers]
www-bos-1.example.com
www-bos-2.example.com

[atlanta_dbservers]
db-atl-1.example.com
db-atl-2.example.com

[boston_dbservers]
db-bos-1.example.com

# webservers in all geos
[webservers:children]
atlanta_webservers
boston_webservers

# dbservers in all geos
[dbservers:children]
atlanta_dbservers
boston_dbservers

# everything in the atlanta geo
[atlanta:children]
atlanta_webservers
atlanta_dbservers

# everything in the boston geo
[boston:children]
boston_webservers
boston_dbservers

Переменные групп и узлов

Этот раздел расширяет предыдущий пример.

Группы хороши для организации, но это не всё, на что они способны. Вы также можете назначить им переменные! Например, у Атланты есть свои NTP-серверы, поэтому при настройке ntp.conf мы должны использовать их. Давайте настроим их сейчас:

---
# file: group_vars/atlanta
ntp: ntp-atlanta.example.com
backup: backup-atlanta.example.com

Переменные не только для географической информации! Возможно, у веб-серверов есть некоторые настройки, которые не имеют смысла для серверов базы данных:

---
# file: group_vars/webservers
apacheMaxRequestsPerChild: 3000
apacheMaxClients: 900

Если у нас есть какие-либо значения по умолчанию или значения, которые являются общеприменимыми, мы поместим их в файл group_vars/all:

---
# file: group_vars/all
ntp: ntp-boston.example.com
backup: backup-boston.example.com

Мы можем определить специфические различия в оборудовании систем в файле host_vars, но избегайте этого, если это не необходимо:

---
# file: host_vars/db-bos-1.example.com
foo_agent_port: 86
bar_agent_port: 99

Опять же, если мы используем динамические источники инвентаризации, многие динамические группы создаются автоматически. Таким образом, тег «class:webserver» автоматически загрузит переменные из файла «group_vars/ec2_tag_class_webserver».

Файлы playbooks верхнего уровня разделены по ролям

В файле site.yml мы импортируем playbook, который определяет всю нашу инфраструктуру. Это очень короткий пример, потому что он просто импортирует некоторые другие playbooks:

---
# file: site.yml
- import_playbook: webservers.yml
- import_playbook: dbservers.yml

В файле webservers.yml (также на верхнем уровне) мы сопоставляем конфигурацию группы webservers с ролями, выполняемыми группой webservers:

---
# file: webservers.yml
- hosts: webservers
  roles:
    - common
    - webtier

Идея в том, что мы можем настроить всю нашу инфраструктуру, «запустив» site.yml, или мы можем настроить только подмножество, запустив webservers.yml. Это аналогично параметру «–limit» в ansible, но немного более явно:

ansible-playbook site.yml --limit webservers
ansible-playbook webservers.yml

Организация задач и обработчиков для роли

Ниже приведён пример файла задач, который объясняет, как работает роль. Здесь наша общая роль просто настраивает NTP, но она могла бы делать больше, если бы мы этого захотели:

---
# file: roles/common/tasks/main.yml

- name: be sure ntp is installed
  yum:
    name: ntp
    state: present
  tags: ntp

- name: be sure ntp is configured
  template:
    src: ntp.conf.j2
    dest: /etc/ntp.conf
  notify:
    - restart ntpd
  tags: ntp

- name: be sure ntpd is running and enabled
  service:
    name: ntpd
    state: started
    enabled: yes
  tags: ntp

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

---
# file: roles/common/handlers/main.yml
- name: restart ntpd
  service:
    name: ntpd
    state: restarted

См. Роли для получения дополнительной информации.

Возможности этой организации (примеры)

Выше мы поделились нашей базовой структурой организации.

Какие сценарии использования это позволяет? Много! Если я хочу перенастроить всю свою инфраструктуру, это просто:

ansible-playbook -i production site.yml

Для перенастройки NTP для всех:

ansible-playbook -i production site.yml --tags ntp

Для перенастройки только моих веб-серверов:

ansible-playbook -i production webservers.yml

Только для моих веб-серверов в Бостоне:

ansible-playbook -i production webservers.yml --limit boston

Только для первых 10 и затем следующих 10:

ansible-playbook -i production webservers.yml --limit boston[0:9]
ansible-playbook -i production webservers.yml --limit boston[10:19]

И, конечно же, возможны и простые ad-hoc задачи:

ansible boston -i production -m ping
ansible boston -i production -m command -a '/sbin/reboot'

И есть несколько полезных команд, которые нужно знать:

# confirm what task names would be run if I ran this command and said "just ntp tasks"
ansible-playbook -i production webservers.yml --tags ntp --list-tasks

# confirm what hostnames might be communicated with if I said "limit to boston"
ansible-playbook -i production webservers.yml --limit boston --list-hosts

Организация развертывания и конфигурации

Вышеприведённая настройка моделирует типичную топологию конфигурации. При выполнении многоуровневых развертываний появятся дополнительные playbooks, которые переходят между уровнями, чтобы развернуть приложение. В этом случае, ‘site.yml’ может быть дополнен playbooks, такими как ‘deploy_exampledotcom.yml’, но общие концепции по-прежнему могут применяться.

Рассматривайте «playbooks» как метафору в спорте — вам не нужно использовать только один набор тактик против вашей инфраструктуры всё время — вы можете иметь ситуационные тактики, которые вы используете в разное время и для разных целей.

Ansible позволяет развертывать и настраивать с помощью одного инструмента, поэтому вы, скорее всего, будете повторно использовать группы и просто сохраните конфигурацию ОС в отдельных playbooks от развертывания приложения.

Этап разработки (staging) против этапа производства (production)

Как уже упоминалось выше, хороший способ отделить среды разработки (staging) и производства (production) — использование отдельного файла инвентаризации для каждой среды. Таким образом, вы выбираете целевую среду с помощью параметра -i. Сохранение всего в одном файле может привести к неожиданным результатам!

Тестирование чего-либо в среде разработки (staging) перед использованием в среде производства — всегда хорошая идея. Ваши среды могут иметь разный размер, и вы можете использовать групповые переменные для управления различиями между этими средами.

Поэтапные обновления

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

См. Делегирование, поэтапные обновления и локальные действия.

Всегда указывайте состояние

Параметр ‘state’ является необязательным для многих модулей. Независимо от того, ‘state=present’ или ‘state=absent’, лучше всего оставлять этот параметр в своих playbooks, чтобы было ясно, особенно так как некоторые модули поддерживают дополнительные состояния.

Группировка по ролям

Мы несколько повторяемся с этим советом, но стоит повторить. Одна система может входить в несколько групп. См. Как создать инвентаризацию и Шаблоны: таргетинг хостов и групп. Наличие групп, названных, например, webservers и dbservers, повторяется в примерах, потому что это очень мощная концепция.

Это позволяет playbooks таргетить машины на основе роли, а также назначать переменные, специфичные для роли, используя систему групповых переменных.

См. Роли.

Изменение параметров в зависимости от операционной системы

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

Это создаёт динамическую группу хостов, соответствующих определённым критериям, даже если эта группа не определена в файле инвентаризации:

---

 - name: talk to all hosts just so we can learn about them
   hosts: all
   tasks:
     - name: Classify hosts depending on their OS distribution
       group_by:
         key: os_{{ ansible_facts['distribution'] }}

 # now just on the CentOS hosts...

 - hosts: os_CentOS
   gather_facts: False
   tasks:
     - # tasks that only happen on CentOS go here

Это поместит все системы в динамическую группу на основе имени операционной системы.

Если нужны настройки, специфичные для группы, это также можно сделать. Например:

---
# file: group_vars/all
asdf: 10

---
# file: group_vars/os_CentOS
asdf: 42

В приведённом примере машины CentOS получают значение «42» для asdf, но другие машины получают «10». Это можно использовать не только для установки переменных, но и для применения определённых ролей только к определённым системам.

В качестве альтернативы, если нужны только переменные:

- hosts: all
  tasks:
    - name: Set OS distribution dependent variables
      include_vars: "os_{{ ansible_facts['distribution'] }}.yml"
    - debug:
        var: asdf

Это позволит загрузить переменные на основе имени ОС.

Упаковывание модулей Ansible с playbook

Если playbook имеет директорию ./library относительно файла YAML, эта директория может использоваться для добавления модулей ansible, которые автоматически будут присутствовать в пути модулей ansible. Это отличный способ хранить модули, которые используются с playbook, вместе. Это показано в примере структуры каталогов в начале этого раздела.

Пробелы и комментарии

Рекомендуется использовать достаточное количество пробелов для разделения элементов и комментарии (начинающиеся с символа «#»).

Всегда называйте задачи

Возможна опускание поля «name» для задачи, хотя рекомендуется предоставлять описание того, почему что-то делается. Это имя отображается при выполнении playbook.

Держите это просто

Когда вы можете сделать что-то просто, делайте это просто. Не пытайтесь использовать все возможности Ansible сразу. Используйте то, что работает для вас. Например, вам, вероятно, не понадобятся vars, vars_files, vars_prompt и --extra-vars одновременно, при использовании внешнего файла инвентаризации.

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

Система управления версиями

Используйте систему управления версиями. Храните ваши playbook и файл инвентаризации в git (или другой системе управления версиями) и делайте коммиты при внесении изменений в них. Таким образом, у вас есть история изменений, описывающая, когда и почему вы изменили правила, которые автоматизируют вашу инфраструктуру.

Переменные и хранилища

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

Рекомендованный подход для этого заключается в создании подкаталога group_vars/ с именем группы. Внутри этого подкаталога создайте два файла с именами vars и vault. В файле vars определите все необходимые переменные, включая любые конфиденциальные. Затем скопируйте все конфиденциальные переменные в файл vault и добавьте к этим переменным префикс vault_. Вы должны настроить переменные в файле vars для указания на соответствующие переменные vault_ с использованием синтаксиса jinja2 и убедиться, что файл vault зашифрован vault.

Данный подход не ограничен количеством файлов переменных и хранилищ или их именами.

См. также

Синтаксис YAML
Узнайте о синтаксисе YAML
Работа с playbook
Просмотрите основные возможности playbook
Все модули
Узнайте о доступных модулях
Разработка модуля?
Узнайте, как расширить Ansible, написав собственные модули
Шаблоны: нацеливание на хосты и группы
Узнайте о выборе хостов
Директория примеров GitHub
Полные файлы playbook из исходного кода проекта github
Список рассылки
Вопросы? Помощь? Идеи? Обратитесь к списку на Google Groups

© 2012–2018 Michael DeHaan
© 2018–2019 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/ansible/2.9/user_guide/playbooks_best_practices.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API