[DevOps] Рекомендации по Ansible (перевод)

Автор Сообщение
news_bot ®

Стаж: 6 лет 9 месяцев
Сообщений: 27286

Создавать темы news_bot ® написал(а)
03-Фев-2021 18:32


Переменные очень активно используются в Ansible. Но один из неприятных моментов заключается в том, что Ansible предлагает слишком много свободы. В этом есть как свои преимущества, так и недостатки. Недостаток состоит в сложности наряду с высокой ответственностью, а преимущество — в гибкости. Давайте вспомним и упорядочим то, что мы знаем о переменных Ansible.Переменные можно разделить на две категории:
  • Переменные в отдельных файлах (в таблице ниже "Filesystem").
  • Переменные в коде (в таблице ниже "Code").
Теперь, если вы посмотрите на их приоритет, то все встает на свои места.
Filesystem-переменные имеют более низкий приоритет по сравнению с Code-переменными. Обратили ли вы внимание на упомянутую выше гибкость и чрезмерную свободу? Давайте продолжим далее с учетом этих знаний.1. Объявляйте переменные в отдельных файлахПеременные лучше располагать в отдельных файлах (Inventory, group_vars, host_vars, role/defaults/main.yml и role/vars/main.yml). Все "постоянные" переменные должны быть явно определены. Постоянные переменные — это переменные, влияющие на роль или поведение плейбука. В отличие от "временных" переменных, используемых в качестве буфера для временного хранения значений, часто с ограниченной областью видимости. Например, переменные, объявленные в vars, существуют только внутри block. Например:
- name: Variables scope
  hosts: localhost
  connection: local
  vars:
    MY_VAR: "I am global var"
  tasks:
    - block:
      - name: Print variable inside the block.
        debug:
          var: MY_VAR
        vars:
          MY_VAR: "I am local var"
- name: Print variable outside the block.
  debug:
    var: MY_VAR
PLAY [Variables scope]
TASK [Gathering Facts]
ok: [localhost]
TASK [Print variable inside the block.]
ok: [localhost] => {
"MY_VAR": "I am local var"
}
TASK [Print variable outside the block.]
ok: [localhost] => {
"MY_VAR": "I am global var"
}
Таким образом, мы должны определять переменные в файлах. И все переменные должны быть определены явно. Для роли есть файл defaults/main.yml. Значения в этом файле имеют самый низкий приоритет, поэтому здесь можно размещать в том числе пустые переменные. Это облегчит жизнь контрибьюторам, особенно тем, кто видит код впервые.2. Используйте READMEЕсли роль использует много различных переменных, возможно, все они даже нужные и полезные, то описывайте их в файле README. Команда ansible-galaxy init поможет вам в этом, сгенерировав шаблон README. Вероятно, вам самому, в незнакомом репозитории будет приятно увидеть README с информацией о том, что роль ожидает увидеть на входе и что будет на выходе. Плохим примером будет разделение кода и описания. Например, код в git, а описание на wiki-странице. Нет никакой гарантии, что контрибьюторы обновят и код, и wiki-страницу. Обычно после пул реквеста работа заканчивается.3. Используйте префиксыУ всех "постоянных" переменных (упомянутых в первом совете) должны быть префиксы. В качестве префикса лучше всего использовать имя роли. Это очень полезно, когда переменные для разных ролей нужно разместить в одном месте. Например, что произойдет в плейбуке с несколькими ролями, если все роли используют переменную port? Добавляя префикс, мы гарантируем, что одни переменные не будут перезаписаны другими. Пример: роль — consul. переменная — url, имя переменной — consul_url.4. Называйте задачи осмысленными именамиУ задач в Ansible есть имена. Используйте для них осмысленные названия, так как они отображаются в выводе. Помните: это ваш лог, по которому в случае ошибок вы можете понять что пошло не так.Например:
# No name/description
- copy: dest=/tmp/text.txt, content="bla-bla"
- name: Print variable global var.
debug:
   var: MY_VAR
TASK [copy]
changed: [localhost]
TASK [Print variable global var.] *
ok: [localhost] => {
"MY_VAR": "I am global var"
}
5. DRY (Don't Repeat Yourself)Ansible похож на обычный язык программирования. И как и в обычном языке, в Ansible есть различные механизмы, которые помогают следовать принципу DRY (Don't Repeat Yourself). Но это требует предварительного планирования организации вашего кода. При написании кода думайте, чтобы его можно было переиспользовать.Крупные блоки:NAMEURLimport_playbookhttps://docs.ansible.com/ansible/latest/modules/importplaybookmodule.html#import-playbook-moduleimport_rolehttps://docs.ansible.com/ansible/latest/modules/importrolemodule.html#import-role-moduleinclude_rolehttps://docs.ansible.com/ansible/latest/modules/includerolemodule.html#include-role-moduleimport_taskshttps://docs.ansible.com/ansible/latest/modules/importtasksmodule.html#import-tasks-moduleinclude_taskshttps://docs.ansible.com/ansible/latest/modules/includetasks_module.html#include-tasks-moduleБлоки внутри роли: (include/import)tasks, (include/import)role. Как это может использоваться? Например, вы используете модуль uri для отправки API-запросов. Допустим, это POST-запросы. Вместо того чтобы повторять 10 раз uri со всеми настройками, можно создать что-то вроде метода и использовать его где угодно. Аналогично методам в обычных языках программирования наш метод тоже принимает входные параметры.Например: send_post.yml
- name: .::::::::::::. [ Sent POST request ] .::::::::::::.
uri:
   url: "{{ URL }}"
   method: POST
   status_code: 200
   body: "{{ BODY_VAR | to_nice_json }}"
   body_format: json
   validate_certs: yes
   client_cert: tls.crt
   client_key: tls.key
   register: return_values
when: BODY_VAR is defined
Этот код можно использовать повторно.
- name: Bla-bla
   include_tasks: send_post.yml
   vars:
       URL: "{{ main_url }}/{{ item }}"
       BODY_VAR: "{{ item }}"
URL и BODY_VAR — это параметры метода.6. Используйте блоки (block)Используйте block.   Описывайте параметры задач только один раз, группируя их. Также block может использоваться аналогично блоку try / catch в традиционных языках программирования.
- block:
   ...
  rescue:
   ...
block/rescue — отличная альтернатива ignore_errors. По сути, расширенная обработка ошибок. Это может быть полезным, например, когда вам нужно выполнить какой-то код в плейбуке, даже в случае сбоя. Например, удалить некоторые файлы.
- block:
   - name: .....
   - name: .....
   - name: .....
   always:
     file:
       path: /tmp/xxxx
       state: absent
7. Не используйте модули command и shellСтарайтесь не использовать модули command и shell, потому что они не идемпотентные. Хотя есть ряд приемов, которые помогают смягчить эту проблему. Используйте:
  • when
  • creates (если файл существует, то этот шаг не выполняется).
  • removes (если файл существует, то этот шаг выполняется).
  • changedwhen.
Тем не менее если это возможно, держитесь подальше от command и shell.8. Не используйте тегиНе используйте теги. Теги могут стать ночным кошмаром для людей, которые видят ваш код впервые. Комбинации тегов увеличивает количество возможных вариантов выполнения плейбука. Но если у вас нет выбора, то подробно описывайте теги и их комбинации в README. Однако не все теги плохи. Есть исключения. Например, always, never —  читать подробнее. skip_ansible_lint — пропустить ansible-lint для задачи.9. Принцип минимальных привилегийИспользуйте принцип минимальных привилегий. Параметр become должен быть no, пока вам это действительно не будет необходимо. Всегда используйте become явно. Например:
---
- hosts: wordpress
    become: no
     ...
    role:
      - role: wordpress
tasks/main.yml
---
- name: Install mysql-server pkg
  apt:
    name: mysql-server
    state: present
  become: yes
10. Используйте YAML-синтаксис для параметровИспользуйте YAML вместо встраиваемого синтаксиса. Сравните эти два варианта:YAML
- name: Install apache httpd
  apt:
    name: apache2
    state: present
Встраиваемый
- name: Install apache httpd
  apt: pkg=apache2 state=pesent
11. Используйте gitignoreДобавьте .gitignore к своим ролям, если вы храните код в git-репозитории. Простой .gitignore может выглядеть следующим образом:
*.retry
*/__pycache__
*.pyc
*.log
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
12. Используйте советы из документации AnsibleИспользуйте рекомендации по организации контента с официальной страницы ansible  13. Используйте отдельный каталог для ролей сообществаИспользуйте отдельный каталог для ролей сообщества, наряду с рекомендациями из предыдущего совета.14. Тестируйте Ansible-кодИспользуйте фреймворки для тестирования кода Ansible. Например, molecule. Этот фреймворк позволяет тестировать ваш код с разных сторон. Помимо традиционного тестирования, он также может запускать все виды линтеров и проверять код на идемпотентность.15. Версионирование ролейЧто такое версионирование в мире Ansible? Это подход, используемый git и позволяющий запускать различные версии ролей, просто указав версию. Версией может быть тег, ветка или конкретный коммит. Подробнее об этом можно почитать здесь. Ваша задача — настроить процедуру в соответствии с вашими требованиями к управлению версиями ролей.requirements.yaml:
---
- src: git@gitlab.company.com:mygroup/ansible.git
scm: git
version: "0.1"
...
Допустимые атрибуты:
  • src
  • scm
  • version
  • name
Перевод статьи подготовлен в преддверии старта курса «DevOps практики и инструменты».Приглашаем всех желающих записаться на бесплатный демо-урок курса по теме: «Prometheus: быстрый старт». На занятии участники вместе с экспертом рассмотрят архитектуру Prometheus и ее способ работы с метриками, а также разберут, как формировать алерты и события в системе.

===========
Источник:
habr.com
===========

===========
Автор оригинала: Sergii Bieliaievskyi
===========
Похожие новости: Теги для поиска: #_devops, #_devops, #_prometheus, #_ansible, #_blog_kompanii_otus (
Блог компании OTUS
)
, #_devops
Профиль  ЛС 
Показать сообщения:     

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

Текущее время: 22-Ноя 19:15
Часовой пояс: UTC + 5