[DevOps] Рекомендации по Ansible (перевод)
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Переменные очень активно используются в 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] 7 советов DevOps-инженера, которые будут полезны любому программисту
- [Python, DevOps, Flask, Data Engineering] Развертывание нескольких моделей машинного обучения на одном сервере (перевод)
- [Настройка Linux, Сетевые технологии] Сетевая подсистема в ОС
- [Информационная безопасность, Сетевые технологии] Исследование сетевого трафика
- [Python, Программирование] Как строить красивые графики на Python с Seaborn (перевод)
- [Тестирование IT-систем, JavaScript] Не используйте фикстуры в Cypress и юнит-тесты — используйте фабричные функции (перевод)
- [MySQL, Администрирование баз данных] Развертывание кластера баз данных через Vagrant с помощью ClusterControl (перевод)
- [Системное администрирование, IT-инфраструктура, DevOps, Микросервисы] Пишем фильтры WASM для Envoy и деплоим их с Istio (перевод)
- [IT-инфраструктура, DevOps, Микросервисы, Kubernetes] Онлайн-интенсив «Service mesh» 19—21 марта
- [Системное администрирование, Серверное администрирование, DevOps, Kubernetes] Проблемные поды: эскалация привилегий подов в Kubernetes (перевод)
Теги для поиска: #_devops, #_devops, #_prometheus, #_ansible, #_blog_kompanii_otus (
Блог компании OTUS
), #_devops
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 19:15
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Переменные очень активно используются в Ansible. Но один из неприятных моментов заключается в том, что Ansible предлагает слишком много свободы. В этом есть как свои преимущества, так и недостатки. Недостаток состоит в сложности наряду с высокой ответственностью, а преимущество — в гибкости. Давайте вспомним и упорядочим то, что мы знаем о переменных Ansible.Переменные можно разделить на две категории:
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" } # 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" } - 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 }}" - block:
... rescue: ... - block:
- name: ..... - name: ..... - name: ..... always: file: path: /tmp/xxxx state: absent
---
- hosts: wordpress become: no ... role: - role: wordpress tasks/main.yml --- - name: Install mysql-server pkg apt: name: mysql-server state: present become: yes - name: Install apache httpd
apt: name: apache2 state: present - name: Install apache httpd
apt: pkg=apache2 state=pesent *.retry
*/__pycache__ *.pyc *.log ### IntelliJ IDEA ### .idea *.iws *.iml *.ipr ---
- src: git@gitlab.company.com:mygroup/ansible.git scm: git version: "0.1" ...
Перевод статьи подготовлен в преддверии старта курса «DevOps практики и инструменты».Приглашаем всех желающих записаться на бесплатный демо-урок курса по теме: «Prometheus: быстрый старт». На занятии участники вместе с экспертом рассмотрят архитектуру Prometheus и ее способ работы с метриками, а также разберут, как формировать алерты и события в системе.
=========== Источник: habr.com =========== =========== Автор оригинала: Sergii Bieliaievskyi ===========Похожие новости:
Блог компании OTUS ), #_devops |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 19:15
Часовой пояс: UTC + 5