Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Фильтры Основы автоматизации в Ansible

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

Фильтры применяются к переменным или значениям внутри двойных фигурных скобок {{ }} с использованием символа вертикальной черты |. Например, {{ some_variable | filter_name }}. Ниже, несколько примеров:

- hosts: all
  gather_facts: no
  vars:
    numbers: [3, 2, 1, 3, 2]
  tasks:
    - name: get min number
      ansible.builtin.debug: msg={{ numbers | min }}
    - name: get max number
      ansible.builtin.debug: msg={{ numbers | max }}
    - name: get unique values
      ansible.builtin.debug: var={{ item }}
      loop: "{{ numbers | unique }}"
    - name: get random value
      ansible.builtin.debug: msg={{ ['a', 'b', 'c'] | random }}

Здесь применяются различные фильтры к списку чисел (переменная numbers). Синтаксически это выглядит как имя функции фильтрации, указанное после вертикальной черты. Вот что делают эти фильтры:

  • min находит минимальное значение
  • max находит максимальное значение
  • unique находит уникальные значения (результатом является список, поэтому для вывода на печать используем цикл)
  • random позволяет выбрать случайное значение из списка

При выполнении этого плейбука мы получим вот такой результат:

ansible-playbook playbook.yml -i inventory.ini
TASK [get min number] *************************
ok: [localhost] => {
    "msg": "1"
}

TASK [get max number] *************************
ok: [localhost] => {
    "msg": "3"
}

TASK [get unique values] **********************
ok: [localhost] => (item=numbers | unique) => {
    "ansible_loop_var": "item",
    "item": "numbers | unique",
    "numbers | unique": [
        3,
        2,
        1
    ]
}

TASK [get random value] ***********************
ok: [localhost] => {
    "msg": "a"
}

Какие реальные задачи можно решать с помощью этих фильтров? Предположим, что мы хотим выбрать сервер из списка по определенным параметрам. Как мы можем применить фильтры:

  • Найти сервер с самым большим количеством CPU.
  • Найти сервер с наименьшим количеством оперативной памяти.

Ниже еще несколько примеров фильтров, которые встречаются достаточно часто в реальной жизни:

- hosts: all
  gather_facts: no
  vars:
    path: /var/log/upstart/nginx.log
  tasks:
    - ansible.builtin.debug: msg={{ '192.0.2.1/24' | ipaddr('address') }}
    - ansible.builtin.debug: msg={{ 'test1' | hash('sha1') }}
    - ansible.builtin.debug: msg={{ path | basename }}
    - ansible.builtin.debug: msg={{ path | dirname }}
    - ansible.builtin.debug: msg={{ "~/Movies" | expanduser }}

Рассмотрим фильтры, которые мы использовали, более подробно:

  • Фильтр ipaddr позволяет извлекать из ip-адреса различные его части. В примере выше извлекается адрес.
  • Фильтр hash создает хэш, который затем может быть использован, например, в файлах конфигурации.
  • Фильтры basename и dirname работают с путями. С помощью них можно выделить имя файла и путь к директории
  • expanduser раскрывает путь. ~/Movies, для пользователя hexlet превратится в /home/hexlet/Movies.

Другие популярные фильтры:

  • default: Устанавливает значение по умолчанию для переменной, если она не определена.
  • map: Преобразует каждый элемент в списке.
  • json_query: Позволяет запросить структуры JSON с помощью специального запроса.
  • regex_replace: Заменяет текст, используя регулярные выражения.

Ansible позволяет разработчикам создавать собственные фильтры на Python, что расширяет возможности кастомизации и адаптации инструмента под конкретные задачи.


Самостоятельная работа

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

    1. Создайте новую переменную, которая содержит строку This is server web1!, где web1 это динамическое имя сервиса (взятое из фактов)
    2. В шаблоне HTML файла templates/index.html.j2 Выведите сообщение в верхнем регистре с помощью фильтра upper.
  2. Также выведем текущую дату. Используйте факты, и выведите текущую дату в любом формате.

  3. Залейте изменения на Github

В результате получится следующее:

<html lang="en"><head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Hello World!</title>
</head>
<body>
  <h1>Hello World!</h1>
  <h2>THIS IS SERVER WEB1!</h2> <!-- Эта строка была приведена в верхний регистр с помощью фильтра -->
  <small>Deployed at: Вт 21 дек 2021 20:18:03</small> <!-- Локализованная дата -->
</body>
</html>

Дополнительные материалы

  1. Использование фильтров для манипулирования данными / Документация Ansible

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Об обучении на Хекслете

Для полного доступа к курсу нужен базовый план

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

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»