Spec-Zone.ru › Ansible 2.5

Рекомендованные Практики

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

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

  • Организация Содержимого
    • Структура Директорий
    • Альтернативная Структура Директорий
    • Использование Динамической Инвентаризации с Облаками
    • Разделение Этапов Staging и Production
    • Переменные Групп и Хостов
    • Файлы Playbook Верхнего Уровня Разделены по Ролям
    • Организация Задач и Обработчиков для Роли
    • Возможности Такой Организации (Примеры)
    • Организация Развертывания и Конфигурации
  • Staging vs Production
  • Постепенные Обновления
  • Всегда Указывайте Состояние
  • Группировка по Ролям
  • Различия в Операционных Системах и Дистрибутивах
  • Объединение Модулей Ansible с Playbooks
  • Отступы и Комментарии
  • Всегда Называйте Задачи
  • Держите Просто
  • Система Управления Версиями
  • Переменные и Хранилища

Организация Содержимого

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

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

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

Структура Директорий

На верхнем уровне каталога будут файлы и каталоги, например:

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

group_vars/
   group1                 # here we assign variables to particular groups
   group2                 # ""
host_vars/
   hostname1              # if systems need specific variables, put them here
   hostname2              # ""

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           # here we assign variables to particular groups
         group2           # ""
      host_vars/
         hostname1        # if systems need specific variables, put them here
         hostname2        # ""

   staging/
      hosts               # inventory file for staging environment
      group_vars/
         group1           # here we assign variables to particular groups
         group2           # ""
      host_vars/
         stagehost1       # if systems need specific variables, put them here
         stagehost2       # ""

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 содержит инвентаризацию всех ваших хостов 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».

Файлы Playbook Верхнего Уровня Разделены по Ролям

В файле 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: installed
  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 vs Production

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

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

Постепенные Обновления

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

См. Делегирование, Постепенные Обновления и Местные Действия.

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

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

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

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

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

См. Роли.

Различия в Операционных Системах и Дистрибутивах

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

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

---

 # talk to all hosts just so we can learn about them
 - hosts: all
   tasks:
     - group_by:
         key: os_{{ ansible_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:
    - include_vars: "os_{{ ansible_distribution }}.yml"
    - debug:
        var: asdf

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

Связывание модулей Ansible с плейбуками

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

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

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

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

Можно опустить поле ‘name’ для конкретной задачи, хотя рекомендуется указать описание того, почему что-то делается. Это имя отображается при выполнении плейбука.

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

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

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

Система контроля версий

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

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

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

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

Эта лучшая практика не ограничивает количество файлов переменных и хранилищ или их имена.

См. также

Синтаксис YAML
Узнайте о синтаксисе YAML
Работа с плейбуками
Изучите основные возможности плейбуков
Все модули
Узнайте о доступных модулях
Разработка модулей
Узнайте, как расширить Ansible, написав свои собственные модули
Работа с шаблонами
Узнайте о том, как выбирать хосты
Директория примеров GitHub
Полные файлы плейбуков из исходного кода проекта 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.5/user_guide/playbooks_best_practices.html

Spec-Zone.ru

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