惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Heimdal Security Blog
C
Check Point Blog
Jina AI
Jina AI
T
Tailwind CSS Blog
IT之家
IT之家
Stack Overflow Blog
Stack Overflow Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
人人都是产品经理
人人都是产品经理
S
SegmentFault 最新的问题
U
Unit 42
Cyberwarzone
Cyberwarzone
T
The Blog of Author Tim Ferriss
I
Intezer
V
Visual Studio Blog
月光博客
月光博客
A
Arctic Wolf
L
LINUX DO - 热门话题
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
T
Threatpost
F
Fortinet All Blogs
Simon Willison's Weblog
Simon Willison's Weblog
酷 壳 – CoolShell
酷 壳 – CoolShell
K
Kaspersky official blog
L
Lohrmann on Cybersecurity
T
Tenable Blog
爱范儿
爱范儿
大猫的无限游戏
大猫的无限游戏
博客园_首页
Recent Announcements
Recent Announcements
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
C
Cybersecurity and Infrastructure Security Agency CISA
P
Privacy International News Feed
The Register - Security
The Register - Security
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
J
Java Code Geeks
I
InfoQ
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Webroot Blog
Webroot Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
The Last Watchdog
The Last Watchdog
AWS News Blog
AWS News Blog
Last Week in AI
Last Week in AI
Spread Privacy
Spread Privacy
云风的 BLOG
云风的 BLOG
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Apple Machine Learning Research
Apple Machine Learning Research
F
Full Disclosure
Vercel News
Vercel News
The Hacker News
The Hacker News

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Базированый Ansible
magnusroot · 2026-05-10 · via Все публикации подряд на Хабре

Уровень сложностиПростой

Время на прочтение15 мин

Охват и читатели2

Туториал

Введение

Настраивать оборудование можно разными способами. Можно ходить от одной железки к другой и делать всё руками, но это медленно и непродуктивно, сгодится максимум для дома. Можно использовать скрипты, но это может не всегда работать и вызывать проблемы. А можно использовать подход, который сейчас называют Infrastructure as Code, то есть описать в каком состоянии Вы хотите видеть свою инфраструктуру, а программа сделает всё сама. Вот про одну из таких программ, которая активно завоёвывает рынок, мы и поговорим, а именно об Ansible.

Часть 1. Что это такое

Ansible описывают как инструмент управления конфигурациями. В этом он практически идентичен таким утилитам как Puppet, Chef и Salt. Но чем выделяется Ansible на фоне конкурентов?

  1. Простота синтаксиса - всё в Ansible можно написать, используя YAML файлы;

  2. Простота аудита - вытекает из первого пункта;

  3. Отсутсвие демонов - на удалённых хостах нужны только SSH-доступ и Python версии 3.8+;

  4. Легко делиться - созданные роли, плагины и бибилотеки можно добавить в коллекцию и выложить в общий доступ;

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

  6. Принудительная настройка - после внесения изменений можно выполнить запуск сценария для немедленного применения, а не ждать пока агент с хоста придёт за новыми настройками;

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

  8. Многоуровневая оркестрация - управляемое оборудование можно делить по типам, применению и свойствам и к каждой группе применять свои настройки независимо от других;

  9. Самодокументирующийся код - правильно оформленные плейбуки и сценарии не нуждаются в дополнительной документации, а говорят сами за себя;

  10. Воспроизводимость - если настроить всю систему с помощью Ansible, то можно автоматически настроить любую аналогичную в любых количествах;

  11. Встроенное шифрование - с помощью ansible-vault можно шифровать секреты, хнарить их в Git и передавать напрямую на хосты;

  12. Идемподентность - сценарии можно применять сколько угодно раз без ущерба для целевого хоста.

Часть 2. Составные части

Сценарии

Основой Ansible являются сценарии. Сценарием или плейбуком называется файл, который описывает порядок управления конфигурациями. Рассмотрим пример сценария установки Angie (форк Nginx):

angie_install.yml 

- name: Different need soft install
  hosts: webservers
  become: true
  tasks:
    - name: Install Angie
      ansible.builtin.apt:
        name: angie
        state: present

    - name: Change angie.conf
      ansible.builtin.copy:
        src: files/angie.conf
        dest: /etc/angie/angie.conf
        mode: '0644'
        owner: root
        group: root

Здесь мы можем увидеть сразу несколько важных моментов, а именно:

  • name - названия тасков (Рекоммендуется писать с заглавной буквы);

  • hosts - к каким узлам применять данные таски

  • become - нужно ли повышение привилегий (пользователь указывается в конфигурационном файле в параметре bacome_user);

  • ansible.builtin.apt и ansible.builtin.copy - названия модулей;

  • name, state, src, dest, mode, owner, group - параметры модулей. Первый модуль принимает имя нужного пакета и его состояние. Если Angie не установлен, то установит его, а если он уже есть на хосте, то просто пропустит данный таск, написав OK в лог.

Второй модуль скопирует конфигурационный файл с хоста, откуда запущен и поместит его по пути указанному в dest с указанными правами.

Запускается сценарий так:

ansible-playbook ansible_install.yml

YAML

Ещё раз напомню, что всё в Ansible пишется в YAML. Конечно, можно писать и в JSON, так как YAML интерпиритруется в него, но это сложно и для написания, и для дальнейшего прочтения.

Есть несколько правил, которые рекомендуется применять при оформлении YAML:

  • В начале файла указываются ---;

  • В конце файл указываются ... и пусатя строка;

  • Комментарии начинаются с #

  • Отсутпы состоят из двух пробелов;

  • Строки не заключаются в кавычки в YAML, но Ansible требует это делать. В двойные кавычки принято заключать имена переменных в выражениях интерполяции, а в одинарные литеральные значения, где подстановка переменных не требуется. Логические значения никогда не заключаются в кавычки;

  • Булевы выражения можно писать как true, True, TRUE, yes, Yes, YES, on, On, ON, false, False, FALSE, no, No, NO, off, Off, OFF. Но так как YAML интерпритируется в JSON, а в нём есть только false и true, то удобнее использовать только их. Плюс это позволит избежать предупреждений при проверке кода через yamllint;

  • Списки (или последовательности) оформляются с помощью отступов и дефиса:

need_support_soft:
  - xrdp
  - tree
  - mc
  - wget
  - gpg
  - python3
  - ansible
  - git
  - apt-transport-https
  - ca-certificates
  - curl
  - apt-utils
  - gnupg2
  • Словари (или отображения) выглядят так:

address:
  street: Lenina
  city: Moscow

(также есть поддержка строенных словарей address: { street: Lenina, city: Moscow});

  • Многострочные значения поддерживаются через распознавание оператторных скобок (| и >), символы начала многострочного текста (+ и -) и отступы (от 1 до 9)

---
visiting_address: |+
  Department of Computer Science
  
  A.V. Williams Building
  University of Maryland

Форматирование сохраняется.

Задачи

Как видно из примера сценария, он состоит из более мелких частей, а именно задач. В нашем случае это, например:

- name: Install Angie
  ansible.builtin.apt:
    name: angie
    state: present

Задача делает ровно одно действие - вызывает модуль apt и передаёт ему параметры angie и present.

Модули

Модуль - это сценарий, который поставляется вместе с Angie. Модули могут быть как встроенные, так и подключаемые дополнительно. Документацию по модулям можно посмотреть с помощью утилиты ansible-doc. Например, документацию по модулю apt можно посмотреть с помощью ansible-doc apt или ansible-doc -l | grep apt.

Переменные

Могут задаваться прямо в сценарии с помощью vars, например:

vars:
  key_file: nginx.key
  conf_file: /etc/nginx/sites-available/default

Далее значение из vars можно подставить в задачу:

- name: Nginx config install
    ansible.builtin.copy:
      src: files/nxinx.conf
      dest: "{{ conf_file }}"

Но удобнее определять их в отдельных файлах. Для этого все переменные выносятся в отдельный файл, а в сценарии просто укахывается его имя:

vars_files:
  nginx.yml

Но можно сделать ещё проще и разместить все переменные относящиеся к роли в файле defaults/main.yml.

Если при отладке роли нужно посмотреть какая переменная используется по факту, то можно использовать модуль debug:

- debug: var=varname

Также значения переменнных можно объединять в двойных фигурных скобках с помощью ~:

debug:
  msg: "The URL is {{ server_name ~'.'~ domain.name }}"

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

- name: Whoami found
  command: whoami
  register: login
  
- debug: var=login
- debug: msg="You are {{ login.stdout }}"

В данном случае - debug: var=login понадобился, чтобы понять в каком именно ключе хранятся нужные нам данные.

И ещё один момент. Если по какой либо причине Ansible не сможет выполнить задачу, то он свалится в ошибку и прервёт дальнейшее выполнение сценария. Чтобы этого избежать на рисковых задачах безопаснее будет указать на пропуск ошибок:

- name: Whoami found
  command: whoami
  register: login
  ignore_errors: true
  # или если нужно только в режиме проверки
  ignore_errors: {{ ansible_check_mode }}
  # ansible_check_mode вернёт true, если включен режим проверки через опцию --check

Переменные могут переопределяться. Вот как выглядит приоритет в порядке возрастания:

  1. В роли(в defaults/main.yml);

  2. В реестре или сценарии для группы хостов;

  3. Секция group_vars/all в реестре;

  4. Секция group_vars/all в сценарии;

  5. Секция group_vars/* в реестре;

  6. Секция group_vars/* в сценарии;

  7. В реестре или сценарии для хоста;

  8. Секция host_vars/* в реестре;

  9. Секция host_vars/* в сценарии;

  10. Кэшированные факты из `set_facts;

  11. Переменные операции;

  12. Секция vars_prompt в операции;

  13. Секция vars_files в операции;

  14. Переменные роли(в `vars/main.yml);

  15. Переменные блока задач;

  16. Переменные задач;

  17. Секция include_vars;

  18. Факты возвращаемые из set_facts;

  19. Параметры ролей;

  20. Подключаемые параметры;

  21. Переданные из командной строки. То есть переменная объявленная для конкретного хоста всегда будет иметь приоритет над переменной для группы, а переменная из include_vars перекроет переменную для хоста. Наивысший уровень работает лишь тогда, когда Вы запускаете Ansible из командной строки с параметрами -e var=value. Также можно передать целый файл с переменными -e @filename.yml.

Встроенные переменные

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

  • hostvars - словарь, где ключи - имена хостов Ansible, а значения словари, содержащие данные об этих хостах;

  • inventory_hostname - имя текущего хоста, как оно задано в Ansible;

  • inventory_hostname_short - имя текущего хоста, без имени домена;

  • group_name - список групп куда входит хост;

  • groups - словарь, где ключи - имена групп в Ansible, а значения - список имён хостов, входящих в группы;

  • ansible_check_mjde - логическая переменная, принимающая true, при включении режима проверки;

  • ansible_play_batch - логическая переменная, принимающая true, при выполнении сценария в тестовом режиме;

  • ansible_olay_hosts - список хостов из реестра, участвующих в текущей операции;

  • ansible_version - словарь с информацией об Ansible.

Факты

При выполнении сценария, до начала запуска первой задачи Ansible подключается к хосту и запрашивает всю информацию: аппаратную архитектуру, название ОС, IP-адреса, объём памяти и прочее. Доступ ко всем этим данным можно получить через переменную ansible_facts и обращаться к ним можно, используя префикс ansible_. Также можно устанавливать факты во рвемя выполнения задача, по сути, создавать новые переменные:

- name: Set nginx state
  when: ansible_facts.service.nginx.state is defined
  set_fact:
    nginx_state: "{{ ansible_facts.service.nginx.state }}"

Шаблоны

Шаблон - это простой текстовый файл, где использованием специального синтаксиса определяются переменные, которые должны заменяться файктическим значением. В случае Ansible эти шаблоны пишутся с использованием механизма jinja2. Эти файлы обычно аналогичны тем, что должны получиться на целевой машине, хранятся в формате .j2 и на месте значений имеют указатели на подстановку переменных в формате {{ }}. Пример строки с использованием шаблона:

deb https://download.angie.software/angie/ubuntu/{{ ubuntu_version }} {{ ubuntu_codename }} main

Циклы

Если необходимо запустить задачу для каждого элемента из списка, то можно использовать цикл loop. Задача будет выполнена несколько раз, заменяя элемент item значениями из списка.

- name: Copy TLS
  ansible.builtin.copy:
    src: "{{ item }}"
    dest: "{{ tls_dir }}"
  loop:
    - "{{ key_file }}"
    - "{{ cert_file }}"
  notify: Restart nginx

Обработчики

В прошлом примере присутствует строка notify: Restart nginx, это вызов обработчика. Они конфигурируются в блоке handlers

handlers:
  - name: Restart nginx
    service:
      name: nginx
      state: restarted

Обработчики - это одна из форм условного выполнения. Обработчик похож на задачу, но выполняется только после получения уведомления (notify). Обработчики выполняются после завершения всех задач и только один раз, даже если получено несколько уведомлений. Чтобы была возможность запустить обработчик раньше, нужно заменить notify на meta. Если сценарий содержит несколько обработчиков, то они выполняются в порядке следования в разделе handlers, а не в порядке вызова.

Реестр

Реестр в простейшем виде - это список имён хостов, перечисленных через запятую. Это может быть тесктовый файл, причём в разных форматах, каталог или выполняемый файл. В данном реестре (или inventory) хранится список хостов, которыми нужно управдять. Я предпочитаю держать данный файл в виде YAML-файла:

inventory/hosts.yml

all:
  children:  
    prod:
      children:
        webservers:
          hosts:
            test01:
              ansible_host: 10.10.10.4
            test02:
              ansible_host: 10.10.10.5

Здесь видно, что присутствуют группы all, prod и webservers. При этом prod и webservers являются дочерними от all, а webservers является дочерней от prod. То есть если указать для сценария вышестоящий уровень, то он будет применён и к нижестоящим, но не наоборот. Помимо ansible_host можно указать следующее:

  • ansible_port - SSH порт. По умолчанию 22;

  • ansible_user - SSH пользователь. По умолчанию $USER;

  • ansible_password - пароль пользователя. По умолчанию его нет;

  • ansible_connection - как будет происходить подключение. По умолчанию smart. Этот механизм проверяет поддержку локальным SSH-клиентом функции ControlPersist и если её нет, то использует библиотеку Paramiko;

  • ansible_ssh_private_key_file - закрытый ключ. По умолчанию нет;

  • ansible_shell_type - командная оболочка для выполнения команд. По умолчанию sh. Для Linux можно указать любую, которая есть на хосте. Для Windows - powershell;

  • ansible_python_interpreter - путь к интерпретатору Python на хосте. По умолчанию /usr/bin/python; Чтобы не прописывать переопределённое значение для каждого хоста, можно изменить их глобально через ansible.cfg. В этом файле аналогии следующие:

ansible_port = remote_portansible_host: 10.10.10.5
ansible_user = remote_user
ansible_ssh_private_key_file = ssh_private_key_file
ansible_shell_type = executable (но здесь необходимо указать полный путь /usr/local/bin/fish)

Также совсем необязательно указывать ansible_host: 10.10.10.5, если настроено разрешение имён. Ansible может резолвить имена из реестра, конфигурационного файла SSH, файла /etc/hosts и DNS. Запись имён тоже можно сильно упростить. Если имеется 50 серверов с именами webserver01, webserver02 и так, далее, то можно записать это просто webserver[01:50]. Перебор букв также поддерживается - webserver-[a-z].

Часть 3. Собираем всё вместе

Роли

Роли - это основной механизм деления сценария на отдельные файлы.

Роль помогает собрать в одном месте несколько задач или других ролей для выполнения определённого действия без привязки к определённому хосту и без сохранения каких-либо данных. Базовая структрура роли может содержать в себе:

defaults/main.yml - переменные по умолчанию
files/main.yml - файлы для загрузки на хосты
handlers/main.yml - обработчики
meta/main.yml - информация о роли
tasks/main.yml - точка входа
templates/angie.conf.j2 - шаблоны для загрузки на хосты
vars/main.yml - переменные, которые переопределять нежелательно

Но при это ни один из этих файлов, кроме tasks/main.yml, не является обязательным и может отсутствовать. Ansible ищет роли в подкаталоге roles, но системные роли можно разместить по пути /etc/ansible/roles. Переопределить данный путь можно с помощью ansible.cfg

[defaults]
roles_path = /usr/bin/roles

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

pre_tasks:
  - name: Update apt cache
    apt:
      update_cache: true
      
roles:
  - role...
    
post_tasks:
  - name: Notify to Telegram
    ...

Каталог для роли можно сгенерировать автоматически. Для этого можно использовать немного не по назначению ansible-galaxy.

ansible-galaxy init --init-path playbooks/roles ansible_install

Ansible Galaxy

Galaxy - это хранилище ролей с открытым исходным кодом, пополняемое членами сообщества. Роли хранятся на GitHub, устанавливаются через ansible-galaxy, а подробнее почитать об этом можно на сайте. Но если кратко, то роль можно установить или удалить вот так:

ansible-galaxy install ...
ansible-galaxy revove ...

Список установленных ролей можно посмотреть с помощью list.

Роли сохраняются в директорию, которая указана первой в roles_path в galaxy_roles/. Путь можно изменить при установке с помощью ключа -p.

Если ваша роль требует какой-либо зависимости, то будет правильно указать её в файле roles/requirements.yml и требуемая роль будет автоматически подключена или, при необходимости, скачана из Galaxy.

Часть 4. Что может пригодиться в реальной эксплуатации

Фильтры

Фильтры пришли в Ansible из Jinja2, чтобы упростить подстановку нужных значений, а также избежать некоторых ошибок

default

Если в задаче нам нужно указать хост, отличный от стандартного, то можно использовать фильтр default:

host: "{{ database_host | default('localhost') }}"

В этом случае, если переменная database_host не определена, то будет подставлен localhost.

Фильтры зарегистрированных переменных

Если нам нужно запустить задачу и вывести её результат, если она выполнилась с определённым результатом и завершить сценарий:

- name: Test task
  command: /opt/muscript
  register: result
  ignore_errors: true
  
- debug: var=result
  
- debug:
    msg: "Stop tasks"
    failed_when: result|failed

Фильтры для статусов могут быть следующие:

failed - задача завершилась неудачей
changed - задача внесла изменения
success - задача завершилась успешно
skipped - задача пропущена

Фильтры для путей к файлам

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

vars:
  homepage: /usr/share/angie/html/index.html

а потом использовать фильтр basename, который позволяет получить index.html

- name: Copy home page
  copy:
    src: "files/{{ homepage | basename }}"
    dest: "{{ homepage }}"

Подключение задач и ролей

Бывает так, что одинаковые задачи могут использоваться в разных местах. Поэтому чтобы не плодить одинаковый код можно описать такие задачи в одной и потом их использовать через подключение. Например установку и включение nginx можно добавить в файл nginx_install.yml

- name: Nginx install
  package:
    name: nginx
    
- name: Nginx start
  service:
    name: nginx
    state: started
    enabled: true

и при необходимости добавить его

- include_tasks: nginx_install.yml

Также есть возможность использовать динамическое подключение. Например, использовать задачу в зависимости от типа ОС:

- name: Platform specific actions
  include_tasks: "{{ ansible_os_family }}.yml"

Подключение ролей работает по такому же принципу:

- name: Install php
  include_role
    name: php

Но также есть и возможность указать с какого таска начинать выполнение:

- name: Install php
  include_role
    name: php
    tasks_from: install

Блоки

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

- block:
  - name: Nginx install
    ...
    
  - name: Nginx start
    ...
when: ansible_os_family == 'RedHat'

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

- block:
    ...
    - debug: msg="You never see this message"
  rescue:
    - debug: msg="You see this message in case of failure in the block"
  always:
    - debug: msg="This will be always executed"

Тут логика работы такая, в rescue будут задачи, которые необходимо выполнить, если на каком-то из хостов произойдёт ошибка, а в блоке always будут задачи, которые выполняются всегда.

Шифрование секретов

Очень часто возникает необходимость хранить чувствительную информацию прямо в Ansible, например пароли, ключи или сертификаты в переменных. Ansible даёт такую возможность, шифруя всё, что ему скажут встроенным механизмом через ansible_vault. Чтобы зашифровать целый файл, нужно ввести

ansible-vault encrypt srt.key

и после этого дважды указать пароль для шифрования. Этот пароль нужно сохранить и использовать при запуске Ansible

ansible-playbook --ask-vault-pass cert_update.yml

Также можно шифровать отдельные переменные:

ansible-vault encrypt_string 'oun394ossa' --name="telegram_cannel_id" 

и полученный результат занести в файл.

Использование разных паролей

Начиная с версии 2.4, Ansible позволяет использование разных паролей с помощью идентификатора шифрования. Для этого в файле ansible.cfg, в разделе [defaults], создаются ссылки на идентификаторы паролей и соответствующие им файлы:

[defaults]
vault_identity_list = dev@~/.vault_dev, prod@~/.vault_prod

Файлы же при этом шифруются так

ansible-vault encrypt --encrypt-vault-id=prod group_vars/prod/vault

Выбор хостов для применения

На какие группы хостов применять сценарий можно выбрать в самом сценарии. Выше был показан пример - hosts: all. Но есть способы выбрать несколько групп, для этого применяются шаблоны:

all или * - все хосты
dev:stage - объединение групп
dev:&stage - выбор только общих хостов для двух групп
dev:!stage - только уникальные хосты из первой группы
*.test.com - шаблон
test[1:5].com - шаблон с диапазоном
~web\d\/test\.(com|ru) - регулярное выражение

Также выбор хостов для запуска можно определить и через ansible-playbook с использованием ключа -l или --limit.

Выполнение задач на машине отличной от целевой

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

- name: Download test binary
  delegate_to: localhost
  connection: local
  become: false
  get_url:
    url: "https://test.com"
    dest: "~/Downloads/test"
    mode: '0755'
  ignore_errors: true

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

Управление количеством одновременного запуска

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

- name: Upgrade package
  hosts: web
  serial: 1

В этом случае будет обрабатываться один хост за раз.

Также может пригодиться выражение max_fail_percentage. В нём будет учитываться количество неудачных выполнений задачи и в связке с serial можно остановить выпонение при заданном пороге ошибок.

Если мы точно не знаем сколько у нас хостов, то можно сделать пакетную обработку, указав serial: 50%. Значения можно комбинировать и сначала выполнить установку на одном хосте, потом на половине, а потом и на всех:

serial:
  - 1
  - 50%
  - 100%

Если задачу нужно выполнить разово, то поможет выражение run_once: true.

Флаг --step при запуске ansible-playbook заставляет Ansible запрашивать подверждение на запуск каждой задачи.

Теги

Каждую задачу можно пометить тегом

- name: Download test binary
  get_url:
    url: "https://test.com"
    dest: "~/Downloads/test"
    mode: '0755'
  tags:
    - first

После этого действия появляется возможность либо запускать только таски с нужным тегом --tags first или пропускать их --skip-tags.

Стратегии выполнения

По умолчанию Ansible использует стратегию линейного выполнения (linear), это значит, что задача запускается на всех хостах сразу, ждёт результата и двигается дальше. Но данное поведение можно изменить. Если указать стратегию free, то Ansible не будет ждать окончания опреаций на других хостах.

- name: Strategies
  hosts: web
  strategy: free

Плагины обратного вызова

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

  • плагины стандартного вывода;

  • плагины уведомлений;

  • плагины агрегирования.

Плагины стандартного вывода

Единовременно может быть активен один плагин стандартного вывода. Назначается он установкой параметра stdout_callback в секции defaults файла ansible.cfg. Например, можно сделать вывод Ansible в более читаемом формате:

[defaults]
stdout_callback = yaml

Список доступных плагинов можно посмотреть командой ansible-doc -t callback -l.

Плагины уведомлений и агрегирования

Данные плагины позволяют выполнять разнообразные действия, от записи времени выполнения, до отправки уведомлений в Jabber. Подобных плагинов может быть активировано несколько одновременно. Активируются они также через ansible.cfg

[defaults]
callback_whitelist = mail, slack
# или callback_enabled = mail, slack

Многие из этих плагинов имеют дополнительные параметры, посмотреть которые можно через ansible-doc -t callback plugin_name

Режим проверки

Ну и одна из самых важных возможностей - пробный прогон. Когда написана новая роль или изменён какой-либо таск, то можно выполнить сценарий в безопасном режиме, добавив к ansible-playbook ключ --check или -c. В этом режиме Ansible не производит на хосте никаких изменений, а просто показывает что будет сделано и успешно ли. Но есть пара но. Во-первых, модуль должен поддерживать режим проверки. А во-вторых, если задача требует чего-то, что должно быть добавлено на хост одной из прошлых задач, например должен быть скачан файл или установлен пакет, но так как в режиме проверки изменения не вносятся, то следующая задача, где будет использование файла или пакета упадёт с ошибкой. Чтобы этого не произошло, нужно в уязвимых для этого тасках указывать ignore_errors: {{ ansible_check_mode }}.

Вместо заключения

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