Spec-Zone.ru › Ansible 2.10

Использование фильтров для управления данными

Фильтры позволяют преобразовывать данные JSON в YAML, разделять URL для извлечения имени хоста, получать SHA1-хеш строки, складывать или умножать целые числа и многое другое. Вы можете использовать специфичные для Ansible фильтры, документированные здесь, для управления данными или использовать стандартные фильтры, поставляемые с Jinja2 — см. список встроенных фильтров в официальной документации шаблонов Jinja2. Также вы можете использовать методы Python для преобразования данных. Вы также можете создавать собственные фильтры Ansible в качестве плагинов, хотя мы в целом приветствуем новые фильтры в репозиторий ansible-base, чтобы все могли ими пользоваться.

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

  • Обработка неопределенных переменных

    • Указание значений по умолчанию
    • Делаем переменные необязательными
    • Определение обязательных значений
  • Определение разных значений для true/false/null (тройное ветвление)
  • Управление типами данных

    • Определение типа данных
    • Преобразование словарей в списки
    • Преобразование списков в словари
    • Принудительное назначение типа данных
  • Форматирование данных: YAML и JSON

    • Фильтр to_json и поддержка Unicode
  • Объединение и выбор данных

    • Объединение элементов из нескольких списков: zip и zip_longest
    • Объединение объектов и подэлементов
    • Объединение хешей/словарей
    • Выбор значений из массивов или хеш-таблиц
    • Объединение списков

      • Перестановки
      • Комбинации
      • Декартово произведение
    • Выбор данных JSON: запросы JSON
  • Генерация случайных данных

    • Случайные MAC-адреса
    • Случайные элементы или числа
    • Перемешивание списка
  • Управление переменными-списками
  • Выбор из множеств или списков (теория множеств)
  • Вычисления с числами (математика)
  • Управление сетевыми взаимодействиями

    • Фильтры IP-адресов
    • Фильтры командной строки сети
    • Фильтры XML сети
    • Фильтры VLAN сети
  • Шифрование и вычисление контрольных сумм строк и паролей
  • Обработка текста

    • Добавление комментариев к файлам
    • Разделение URL
    • Поиск строк с использованием регулярных выражений
    • Управление именами файлов и путями
  • Обработка строк
  • Управление UUID
  • Обработка дат и времени
  • Получение имён ресурсов Kubernetes

Обработка неопределенных переменных

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

Указание значений по умолчанию

Вы можете задать значения по умолчанию для переменных непосредственно в шаблонах, используя фильтр Jinja2 ‘default’. Это часто лучший подход, чем игнорирование, если переменная не определена:

{{ some_variable | default(5) }}

В приведенном выше примере, если переменная ‘some_variable’ не определена, Ansible использует значение по умолчанию 5, а не генерирует ошибку «неопределенная переменная» и завершается с ошибкой. Если вы работаете внутри роли, вы также можете добавить defaults/main.yml для определения значений по умолчанию для переменных в вашей роли.

Начиная с версии 2.8, попытка получить доступ к атрибуту неопределённого значения в Jinja вернёт другое неопределённое значение, вместо немедленного вывода ошибки. Это означает, что вы теперь можете просто использовать значение по умолчанию со вложенной структурой данных (другими словами, {{ foo.bar.baz | default('DEFAULT') }}), когда вы не знаете, определены ли промежуточные значения.

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

{{ lookup('env', 'MY_USER') | default('admin', true) }}

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

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

- name: Touch files with an optional mode
  ansible.builtin.file:
    dest: "{{ item.path }}"
    state: touch
    mode: "{{ item.mode | default(omit) }}"
  loop:
    - path: /tmp/foo
    - path: /tmp/bar
    - path: /tmp/baz
      mode: "0444"

В этом примере, режим по умолчанию для файлов /tmp/foo и /tmp/bar определяется маской umask системы. Ansible не отправляет значение для mode. Только третий файл, /tmp/baz, получает опцию mode=0444.

Примечание

Если вы «цепляете» дополнительные фильтры после фильтра default(omit), вы должны вместо этого сделать следующее: "{{ foo | default(None) | some_filter or omit }}". В этом примере значение по умолчанию None (Python null) вызовет сбой последующих фильтров, что активирует часть логики or omit. Использование omit таким образом очень специфично для последующих фильтров, поэтому будьте готовы к некоторому пробою, если вы так делаете.

Определение обязательных значений

Если вы настроили Ansible на игнорирование неопределенных переменных, вам может потребоваться определить некоторые значения как обязательные. По умолчанию Ansible завершается неудачей, если переменная в вашем плейбуке или команде не определена. Вы можете настроить Ansible на разрешение неопределённых переменных, установив DEFAULT_UNDEFINED_VAR_BEHAVIOR на значение false. В этом случае вам может потребоваться потребовать определения некоторых переменных. Это можно сделать с помощью:

{{ variable | mandatory }}

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

Определение разных значений для true/false/null (тройное ветвление)

Вы можете создать проверку, а затем определить одно значение для использования, когда проверка возвращает true, и другое, когда она возвращает false (новая функция в версии 1.9):

{{ (status == 'needs_restart') | ternary('restart', 'continue') }}

Кроме того, вы можете определить одно значение для true, одно для false и третье для null (новая функция в версии 2.8):

{{ enabled | ternary('no shutdown', 'shutdown', omit) }}

Управление типами данных

Вам может потребоваться узнать, изменить или установить тип данных переменной. Например, зарегистрированная переменная может содержать словарь, когда следующая задача требует списка, или пользовательский запрос может вернуть строку, когда ваш плейбук нуждается в булевом значении. Используйте фильтры type_debug, dict2items и items2dict для управления типами данных. Вы также можете использовать сам тип данных для преобразования значения в конкретный тип данных.

Определение типа данных

Новое в версии 2.3.

Если вы не уверены в базовом типе Python переменной, вы можете использовать фильтр type_debug для его отображения. Это полезно при отладке, когда вам нужен определённый тип переменной:

{{ myvar | type_debug }}

Преобразование словарей в списки

Новое в версии 2.6.

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

{{ dict | dict2items }}

Данные словаря (до применения фильтра dict2items):

tags:
  Application: payment
  Environment: dev

Данные списка (после применения фильтра dict2items):

- key: Application
  value: payment
- key: Environment
  value: dev

Новое в версии 2.8.

Фильтр dict2items является обратным фильтру items2dict.

Если вы хотите настроить имена ключей, фильтр dict2items принимает 2 именованных аргумента. Передайте аргументы key_name и value_name, чтобы настроить имена ключей в выходном списке:

{{ files | dict2items(key_name='file', value_name='path') }}

Данные словаря (до применения фильтра dict2items):

files:
  users: /etc/passwd
  groups: /etc/group

Данные списка (после применения фильтра dict2items):

- file: users
  path: /etc/passwd
- file: groups
  path: /etc/group

Преобразование списков в словари

Новое в версии 2.7.

Используйте фильтр items2dict, чтобы преобразовать список в словарь, сопоставив содержимое в key: value пары:

{{ tags | items2dict }}

Данные списка (до применения фильтра items2dict):

tags:
  - key: Application
    value: payment
  - key: Environment
    value: dev

Данные словаря (после применения фильтра items2dict):

Application: payment
Environment: dev

Фильтр items2dict является обратным фильтру dict2items.

Не все списки используют key для обозначения ключей и value для обозначения значений. Например:

fruits:
  - fruit: apple
    color: red
  - fruit: pear
    color: yellow
  - fruit: grapefruit
    color: yellow

В этом примере вы должны передать аргументы key_name и value_name для настройки преобразования. Например:

{{ tags | items2dict(key_name='fruit', value_name='color') }}

Если вы не передадите эти аргументы или не передадите правильные значения для вашего списка, вы увидите KeyError: key или KeyError: my_typo.

Принудительное задание типа данных

Вы можете приводить значения к определённым типам. Например, если вы ожидаете входное значение «True» из vars_prompt и хотите, чтобы Ansible распознавал его как булевое значение, а не строку:

- debug:
  msg: test
  when: some_string_value | bool

Если вы хотите выполнить математическое сравнение с фактом и хотите, чтобы Ansible распознавал его как целое число, а не строку:

- shell: echo "only on Red Hat 6, derivatives, and later"
  when: ansible_facts['os_family'] == "RedHat" and ansible_facts['lsb']['major_release'] | int >= 6

Новое в версии 1.6.

Форматирование данных: YAML и JSON

Вы можете переключить структуру данных в шаблоне на формат JSON или YAML с параметрами форматирования, отступов и загрузки данных. Базовые фильтры иногда полезны для отладки:

{{ some_variable | to_json }}
{{ some_variable | to_yaml }}

Для удобочитаемого вывода вы можете использовать:

{{ some_variable | to_nice_json }}
{{ some_variable | to_nice_yaml }}

Вы можете изменить отступы для обоих форматов:

{{ some_variable | to_nice_json(indent=2) }}
{{ some_variable | to_nice_yaml(indent=8) }}

Фильтры to_yaml и to_nice_yaml используют библиотеку PyYAML, которая имеет предельную длину строки в 80 символов по умолчанию. Это вызывает неожиданный перенос строки после 80-го символа (если после 80-го символа есть пробел). Чтобы избежать такого поведения и генерировать длинные строки, используйте параметр width. Вы должны использовать жёстко заданное число для определения ширины, вместо конструкции, подобной float("inf"), потому что фильтр не поддерживает проксирование функций Python. Например:

{{ some_variable | to_yaml(indent=8, width=1337) }}
{{ some_variable | to_nice_yaml(indent=8, width=1337) }}

Фильтр поддерживает передачу других параметров YAML. Полный список см. в документации PyYAML.

Если вы читаете уже отформатированные данные:

{{ some_variable | from_json }}
{{ some_variable | from_yaml }}

например:

tasks:
  - name: Register JSON output as a variable
    ansible.builtin.shell: cat /some/path/to/file.json
    register: result

  - name: Set a variable
    ansible.builtin.set_fact:
      myvar: "{{ result.stdout | from_json }}"

Фильтр to_json и поддержка Unicode

По умолчанию to_json и to_nice_json преобразуют полученные данные в ASCII, поэтому:

{{ 'München'| to_json }}

вернёт:

'M\u00fcnchen'

Чтобы сохранить символы Unicode, передайте параметр ensure_ascii=False в фильтр:

{{ 'München'| to_json(ensure_ascii=False) }}

'München'

Новое в версии 2.7.

Для разбора многодокументных строк YAML предоставляется фильтр from_yaml_all. Фильтр from_yaml_all вернёт генератор распарсенных документов YAML.

например:

tasks:
  - name: Register a file content as a variable
    ansible.builtin.shell: cat /some/path/to/multidoc-file.yaml
    register: result

  - name: Print the transformed variable
    ansible.builtin.debug:
      msg: '{{ item }}'
    loop: '{{ result.stdout | from_yaml_all | list }}'

Комбинирование и выбор данных

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

Комбинирование элементов из нескольких списков: zip и zip_longest

Новое в версии 2.3.

Чтобы получить список, объединяющий элементы других списков, используйте zip:

- name: Give me list combo of two lists
  ansible.builtin.debug:
   msg: "{{ [1,2,3,4,5] | zip(['a','b','c','d','e','f']) | list }}"

- name: Give me shortest combo of two lists
  ansible.builtin.debug:
    msg: "{{ [1,2,3] | zip(['a','b','c','d','e','f']) | list }}"

Чтобы всегда исчерпать все списки, используйте zip_longest:

- name: Give me longest combo of three lists , fill with X
  ansible.builtin.debug:
    msg: "{{ [1,2,3] | zip_longest(['a','b','c','d','e','f'], [21, 22, 23], fillvalue='X') | list }}"

Аналогично выводу фильтра items2dict, упомянутого выше, эти фильтры могут использоваться для построения dict:

{{ dict(keys_list | zip(values_list)) }}

Данные списка (до применения фильтра zip):

keys_list:
  - one
  - two
values_list:
  - apple
  - orange

Данные словаря (после применения фильтра zip):

one: apple
two: orange

Комбинирование объектов и подэлементов

Новое в версии 2.7.

Фильтр subelements производит произведение объекта и значений подэлементов этого объекта, подобно lookup subelements. Это позволяет указать отдельные подэлементы для использования в шаблоне. Например, это выражение:

{{ users | subelements('groups', skip_missing=True) }}

Данные до применения фильтра subelements:

users:
- name: alice
  authorized:
  - /tmp/alice/onekey.pub
  - /tmp/alice/twokey.pub
  groups:
  - wheel
  - docker
- name: bob
  authorized:
  - /tmp/bob/id_rsa.pub
  groups:
  - docker

Данные после применения фильтра subelements:

-
  - name: alice
    groups:
    - wheel
    - docker
    authorized:
    - /tmp/alice/onekey.pub
    - /tmp/alice/twokey.pub
  - wheel
-
  - name: alice
    groups:
    - wheel
    - docker
    authorized:
    - /tmp/alice/onekey.pub
    - /tmp/alice/twokey.pub
  - docker
-
  - name: bob
    authorized:
    - /tmp/bob/id_rsa.pub
    groups:
    - docker
  - docker

Вы можете использовать преобразованные данные с loop для итерации по одному и тому же подэлементу для нескольких объектов:

- name: Set authorized ssh key, extracting just that data from 'users'
  ansible.posix.authorized_key:
    user: "{{ item.0.name }}"
    key: "{{ lookup('file', item.1) }}"
  loop: "{{ users | subelements('authorized') }}"

Комбинирование словарей/хешей

Новое в версии 2.0.

Фильтр combine позволяет объединять словари. Например, следующее перезаписывает ключи в одном словаре:

{{ {'a':1, 'b':2} | combine({'b':3}) }}

Результат словаря будет:

{'a':1, 'b':3}

Фильтр также может принимать несколько аргументов для объединения:

{{ a | combine(b, c, d) }}
{{ [a, b, c, d] | combine }}

В этом случае ключи в d перезапишут ключи в c, которые перезапишут ключи в b, и так далее.

Фильтр также принимает два необязательных параметра: recursive и list_merge.

recursive

Булево значение, по умолчанию False. Нужно ли рекурсивно объединять вложенные словари. Примечание: это не зависит от значения hash_behaviour в ansible.cfg.

list_merge

Строка, возможные значения: replace (по умолчанию), keep, append, prepend, append_rp или prepend_rp. Это изменяет поведение combine, когда объединяемые словари содержат массивы/списки.

default:
  a:
    x: default
    y: default
  b: default
  c: default
patch:
  a:
    y: patch
    z: patch
  b: patch

Если recursive=False (по умолчанию), вложенные словари не объединяются:

{{ default | combine(patch) }}

Это приведет к:

a:
  y: patch
  z: patch
b: patch
c: default

Если recursive=True, рекурсивно войдите в вложенный словарь и объедините их ключи:

{{ default | combine(patch, recursive=True) }}

Это приведет к:

a:
  x: default
  y: patch
  z: patch
b: patch
c: default

Если list_merge='replace' (по умолчанию), массивы из правого словаря «заменят» массивы в левом словаре:

default:
  a:
    - default
patch:
  a:
    - patch
{{ default | combine(patch) }}

Это приведет к:

a:
  - patch

Если list_merge='keep', массивы из левого словаря сохранятся:

{{ default | combine(patch, list_merge='keep') }}

Это приведет к:

a:
  - default

Если list_merge='append', массивы из правого словаря будут добавлены к массивам в левом словаре:

{{ default | combine(patch, list_merge='append') }}

Это приведет к:

a:
  - default
  - patch

Если list_merge='prepend', массивы из правого словаря будут добавлены в начало массивов в левом словаре:

{{ default | combine(patch, list_merge='prepend') }}

Это приведет к:

a:
  - patch
  - default

Если list_merge='append_rp', поведение аналогично поведению для append_rp, но элементы массивов из правого словаря будут добавлены в начало:

default:
  a:
    - 1
    - 1
    - 2
    - 3
patch:
  a:
    - 3
    - 4
    - 5
    - 5
{{ default | combine(patch, list_merge='append_rp') }}

Это приведет к:

a:
  - 1
  - 1
  - 2
  - 3
  - 4
  - 5
  - 5

Если list_merge='prepend_rp', поведение аналогично поведению для append_rp, но элементы массивов из правого словаря будут добавлены в начало:

{{ default | combine(patch, list_merge='prepend_rp') }}

Это приведет к:

a:
  - 3
  - 4
  - 5
  - 5
  - 1
  - 1
  - 2

recursive и list_merge могут использоваться вместе:

default:
  a:
    a':
      x: default_value
      y: default_value
      list:
        - default_value
  b:
    - 1
    - 1
    - 2
    - 3
patch:
  a:
    a':
      y: patch_value
      z: patch_value
      list:
        - patch_value
  b:
    - 3
    - 4
    - 4
    - key: value
{{ default | combine(patch, recursive=True, list_merge='append_rp') }}

Это приведет к:

a:
  a':
    x: default_value
    y: patch_value
    z: patch_value
    list:
      - default_value
      - patch_value
b:
  - 1
  - 1
  - 2
  - 3
  - 4
  - 4
  - key: value

Выбор значений из массивов или словарей

Новое в версии 2.1.

Фильтр extract используется для сопоставления списка индексов со списком значений из контейнера (словаря или массива):

{{ [0,2] | map('extract', ['x','y','z']) | list }}
{{ ['x','y'] | map('extract', {'x': 42, 'y': 31}) | list }}

Результаты вышеуказанных выражений будут:

['x', 'z']
[42, 31]

Фильтр может принимать другой аргумент:

{{ groups['x'] | map('extract', hostvars, 'ec2_ip_address') | list }}

Это берёт список хостов в группе «x», ищет их в hostvars, а затем ищет ec2_ip_address результата. Конечный результат — список IP-адресов для хостов в группе «x».

Третий аргумент фильтра также может быть списком для рекурсивного поиска внутри контейнера:

{{ ['a'] | map('extract', b, ['x','y']) | list }}

Это вернёт список, содержащий значение b[‘a’][‘x’][‘y’].

Комбинирование списков

Этот набор фильтров возвращает список объединённых списков.

перестановки

Чтобы получить перестановки списка:

- name: Give me largest permutations (order matters)
  ansible.builtin.debug:
    msg: "{{ [1,2,3,4,5] | permutations | list }}"

- name: Give me permutations of sets of three
  ansible.builtin.debug:
    msg: "{{ [1,2,3,4,5] | permutations(3) | list }}"

сочетания

Комбинации всегда требуют размера набора:

- name: Give me combinations for sets of two
  ansible.builtin.debug:
    msg: "{{ [1,2,3,4,5] | combinations(2) | list }}"

См. также Объединение элементов из нескольких списков: zip и zip_longest

продукты

Фильтр products возвращает декартово произведение входных итерируемых объектов. Это примерно эквивалентно вложенным циклам for в выражении генератора.

Например:

- name: Generate multiple hostnames
  ansible.builtin.debug:
    msg: "{{ ['foo', 'bar'] | product(['com']) | map('join', '.') | join(',') }}"

Это приведет к:

{ "msg": "foo.com,bar.com" }

Выбор данных JSON: запросы JSON

Чтобы выбрать один элемент или подмножество данных из сложной структуры данных в формате JSON (например, факты Ansible), используйте фильтр json_query. Фильтр json_query позволяет вам запросить сложную структуру JSON и итерироваться по ней с помощью цикла.

Примечание

Этот фильтр переместился в коллекцию community.general. Следуйте инструкциям по установке для установки этой коллекции.

Примечание

Этот фильтр основан на jmespath, и вы можете использовать тот же синтаксис. Примеры см. на странице примеров jmespath.

Рассмотрим эту структуру данных:

{
    "domain_definition": {
        "domain": {
            "cluster": [
                {
                    "name": "cluster1"
                },
                {
                    "name": "cluster2"
                }
            ],
            "server": [
                {
                    "name": "server11",
                    "cluster": "cluster1",
                    "port": "8080"
                },
                {
                    "name": "server12",
                    "cluster": "cluster1",
                    "port": "8090"
                },
                {
                    "name": "server21",
                    "cluster": "cluster2",
                    "port": "9080"
                },
                {
                    "name": "server22",
                    "cluster": "cluster2",
                    "port": "9090"
                }
            ],
            "library": [
                {
                    "name": "lib1",
                    "target": "cluster1"
                },
                {
                    "name": "lib2",
                    "target": "cluster2"
                }
            ]
        }
    }
}

Чтобы извлечь все кластеры из этой структуры, вы можете использовать следующий запрос:

- name: Display all cluster names
  ansible.builtin.debug:
    var: item
  loop: "{{ domain_definition | community.general.json_query('domain.cluster[*].name') }}"

Чтобы извлечь все имена серверов:

- name: Display all server names
  ansible.builtin.debug:
    var: item
  loop: "{{ domain_definition | community.general.json_query('domain.server[*].name') }}"

Чтобы извлечь порты из cluster1:

- ansible.builtin.name: Display all ports from cluster1
  debug:
    var: item
  loop: "{{ domain_definition | community.general.json_query(server_name_cluster1_query) }}"
  vars:
    server_name_cluster1_query: "domain.server[?cluster=='cluster1'].port"

Примечание

Вы можете использовать переменную, чтобы сделать запрос более удобочитаемым.

Чтобы вывести порты из cluster1 в строке, разделенной запятыми:

- name: Display all ports from cluster1 as a string
  ansible.builtin.debug:
    msg: "{{ domain_definition | community.general.json_query('domain.server[?cluster==`cluster1`].port') | join(', ') }}"

Примечание

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

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

- name: Display all ports from cluster1
  ansible.builtin.debug:
    var: item
  loop: "{{ domain_definition | community.general.json_query('domain.server[?cluster==''cluster1''].port') }}"

Примечание

Экранирование одинарных кавычек внутри одинарных кавычек в YAML выполняется путем удвоения одинарной кавычки.

Чтобы получить хеш-таблицу со всеми портами и именами кластера:

- name: Display all server ports and names from cluster1
  ansible.builtin.debug:
    var: item
  loop: "{{ domain_definition | community.general.json_query(server_name_cluster1_query) }}"
  vars:
    server_name_cluster1_query: "domain.server[?cluster=='cluster2'].{name: name, port: port}"

Генерация случайных данных

При необходимости случайного значения используйте один из этих фильтров.

Случайные MAC-адреса

Новая функция в версии 2.6.

Этот фильтр может использоваться для генерации случайного MAC-адреса из префикса строки.

Примечание

Этот фильтр переместился в коллекцию community.general. Следуйте инструкциям по установке для установки этой коллекции.

Чтобы получить случайный MAC-адрес из префикса строки, начинающегося с ‘52:54:00’:

"{{ '52:54:00' | community.general.random_mac }}"
# => '52:54:00:ef:1c:03'

Обратите внимание, что при ошибке в строке префикса фильтр выдаст ошибку.

Новая функция в версии 2.9.

Начиная с версии Ansible 2.9, вы также можете инициализировать генератор случайных чисел из значения семян, чтобы создать случайные, но идентичные MAC-адреса:

"{{ '52:54:00' | community.general.random_mac(seed=inventory_hostname) }}"

Случайные элементы или числа

Фильтр random в Ansible — это расширение стандартного фильтра Jinja2 random, который может использоваться для возвращения случайного элемента из последовательности элементов или генерации случайного числа на основе диапазона.

Чтобы получить случайный элемент из списка:

"{{ ['a','b','c'] | random }}"
# => 'c'

Чтобы получить случайное число от 0 до указанного числа:

"{{ 60 | random }} * * * * root /script/from/cron"
# => '21 * * * * root /script/from/cron'

Чтобы получить случайное число от 0 до 100 с шагом 10:

{{ 101 | random(step=10) }}
# => 70

Чтобы получить случайное число от 1 до 100 с шагом 10:

{{ 101 | random(1, 10) }}
# => 31
{{ 101 | random(start=1, step=10) }}
# => 51

Вы можете инициализировать генератор случайных чисел из значения семян, чтобы создать случайные, но идентичные числа:

"{{ 60 | random(seed=inventory_hostname) }} * * * * root /script/from/cron"

Перемешивание списка

Фильтр shuffle случайным образом меняет порядок элементов в существующем списке, давая каждый раз другой порядок.

Чтобы получить случайный список из существующего списка:

{{ ['a','b','c'] | shuffle }}
# => ['c','a','b']
{{ ['a','b','c'] | shuffle }}
# => ['b','c','a']

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

{{ ['a','b','c'] | shuffle(seed=inventory_hostname) }}
# => ['b','a','c']

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

Управление переменными списка

Вы можете искать минимальное или максимальное значение в списке или расплощать многоуровневый список.

Чтобы получить минимальное значение из списка чисел:

{{ list1 | min }}

Чтобы получить максимальное значение из списка чисел:

{{ [3, 4, 2] | max }}

Новая функция в версии 2.5.

Расплющить список (то же самое, что делает lookup flatten):

{{ [3, [4, 2] ] | flatten }}

Расплющить только первый уровень списка (аналогично lookup items):

{{ [3, [4, [2]] ] | flatten(levels=1) }}

Выбор из множеств или списков (теория множеств)

Вы можете выбирать или объединять элементы из множеств или списков.

Новая функция в версии 1.4.

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

# list1: [1, 2, 5, 1, 3, 4, 10]
{{ list1 | unique }}
# => [1, 2, 5, 3, 4, 10]

Чтобы получить объединение двух списков:

# list1: [1, 2, 5, 1, 3, 4, 10]
# list2: [1, 2, 3, 4, 5, 11, 99]
{{ list1 | union(list2) }}
# => [1, 2, 5, 1, 3, 4, 10, 11, 99]

Чтобы получить пересечение 2 списков (уникальный список всех элементов в обоих):

# list1: [1, 2, 5, 3, 4, 10]
# list2: [1, 2, 3, 4, 5, 11, 99]
{{ list1 | intersect(list2) }}
# => [1, 2, 5, 3, 4]

Чтобы получить разность 2 списков (элементы в 1, которых нет во 2):

# list1: [1, 2, 5, 1, 3, 4, 10]
# list2: [1, 2, 3, 4, 5, 11, 99]
{{ list1 | difference(list2) }}
# => [10]

Чтобы получить симметрическую разность 2 списков (элементы, уникальные для каждого списка):

# list1: [1, 2, 5, 1, 3, 4, 10]
# list2: [1, 2, 3, 4, 5, 11, 99]
{{ list1 | symmetric_difference(list2) }}
# => [10, 11, 99]

Вычисления с числами (математика)

Новая функция в версии 1.9.

Вы можете вычислять логарифмы, степени и корни чисел с помощью фильтров Ansible. Jinja2 предоставляет другие математические функции, такие как abs() и round().

Получить логарифм (по умолчанию по основанию e):

{{ myvar | log }}

Получить логарифм по основанию 10:

{{ myvar | log(10) }}

Получить степень 2 (или 5):

{{ myvar | pow(2) }}
{{ myvar | pow(5) }}

Квадратный корень или 5-й корень:

{{ myvar | root }}
{{ myvar | root(5) }}

Управление сетевыми взаимодействиями

Эти фильтры помогают в выполнении общих сетевых задач.

Примечание

Эти фильтры переместились в коллекцию ansible.netcommon. Следуйте инструкциям по установке для установки этой коллекции.

Фильтры IP-адресов

Новая функция в версии 1.9.

Проверить, является ли строка допустимым IP-адресом:

{{ myvar | ansible.netcommon.ipaddr }}

Вы также можете потребовать определенную версию IP-протокола:

{{ myvar | ansible.netcommon.ipv4 }}
{{ myvar | ansible.netcommon.ipv6 }}

Фильтр IP-адресов также может использоваться для извлечения определенной информации из IP-адреса. Например, чтобы получить сам IP-адрес из CIDR, можно использовать:

{{ '192.0.2.1/24' | ansible.netcommon.ipaddr('address') }}

Дополнительную информацию о фильтре ipaddr и полное руководство по использованию можно найти в фильтре ipaddr.

Фильтры сетевой командной строки

Новая функция в версии 2.4.

Для преобразования вывода команды сетевого устройства командной строки в структурированный JSON-вывод используйте фильтр parse_cli:

{{ output | ansible.netcommon.parse_cli('path/to/spec') }}

Фильтр parse_cli загрузит файл спецификаций и передаст вывод команды через него, вернув JSON-вывод. Файл спецификации YAML определяет способ парсинга вывода командной строки.

Файл спецификации должен быть валидным файлом YAML. Он определяет способ парсинга вывода командной строки и возвращения данных JSON. Ниже приведен пример валидного файла спецификации, который будет парсить вывод команды show vlan.

---
vars:
  vlan:
    vlan_id: "{{ item.vlan_id }}"
    name: "{{ item.name }}"
    enabled: "{{ item.state != 'act/lshut' }}"
    state: "{{ item.state }}"

keys:
  vlans:
    value: "{{ vlan }}"
    items: "^(?P<vlan_id>\\d+)\\s+(?P<name>\\w+)\\s+(?P<state>active|act/lshut|suspended)"
  state_static:
    value: present

Файл спецификации выше вернет JSON-структуру данных, которая представляет собой список хешей с проанализированной информацией о VLAN.

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

---
vars:
  vlan:
    key: "{{ item.vlan_id }}"
    values:
      vlan_id: "{{ item.vlan_id }}"
      name: "{{ item.name }}"
      enabled: "{{ item.state != 'act/lshut' }}"
      state: "{{ item.state }}"

keys:
  vlans:
    value: "{{ vlan }}"
    items: "^(?P<vlan_id>\\d+)\\s+(?P<name>\\w+)\\s+(?P<state>active|act/lshut|suspended)"
  state_static:
    value: present

Другой распространенный случай использования для парсинга команд командной строки заключается в разбиении большой команды на блоки, которые могут быть обработаны. Это можно сделать, используя директивы start_block и end_block для разделения команды на блоки, которые можно обработать.

---
vars:
  interface:
    name: "{{ item[0].match[0] }}"
    state: "{{ item[1].state }}"
    mode: "{{ item[2].match[0] }}"

keys:
  interfaces:
    value: "{{ interface }}"
    start_block: "^Ethernet.*$"
    end_block: "^$"
    items:
      - "^(?P<name>Ethernet\\d\\/\\d*)"
      - "admin state is (?P<state>.+),"
      - "Port mode is (.+)"

Приведенный выше пример проанализирует вывод show interface в список хешей.

Сетевые фильтры также поддерживают парсинг вывода команды командной строки с использованием библиотеки TextFSM. Для парсинга вывода командной строки с TextFSM используйте следующий фильтр:

{{ output.stdout[0] | ansible.netcommon.parse_cli_textfsm('path/to/fsm') }}

Использование фильтра TextFSM требует установки библиотеки TextFSM.

Фильтры сетевого XML

Новая функция в версии 2.5.

Для преобразования XML-вывода команды сетевого устройства в структурированный JSON-вывод используйте фильтр parse_xml:

{{ output | ansible.netcommon.parse_xml('path/to/spec') }}

Фильтр parse_xml загрузит файл спецификаций и передаст вывод команды в формате JSON.

Файл спецификаций должен быть валидным файлом YAML. Он определяет способ парсинга XML-вывода и возвращения данных JSON.

Ниже приведен пример валидного файла спецификаций, который будет парсить вывод команды show vlan | display xml.

---
vars:
  vlan:
    vlan_id: "{{ item.vlan_id }}"
    name: "{{ item.name }}"
    desc: "{{ item.desc }}"
    enabled: "{{ item.state.get('inactive') != 'inactive' }}"
    state: "{% if item.state.get('inactive') == 'inactive'%} inactive {% else %} active {% endif %}"

keys:
  vlans:
    value: "{{ vlan }}"
    top: configuration/vlans/vlan
    items:
      vlan_id: vlan-id
      name: name
      desc: description
      state: ".[@inactive='inactive']"

Файл спецификаций выше вернет JSON-структуру данных, которая представляет собой список хешей с проанализированной информацией о VLAN.

Ту же команду можно разобрать в хеш-значение, используя директивы ключа и значения. Вот пример того, как разобрать вывод в хеш-значение, используя ту же команду show vlan | display xml.

---
vars:
  vlan:
    key: "{{ item.vlan_id }}"
    values:
        vlan_id: "{{ item.vlan_id }}"
        name: "{{ item.name }}"
        desc: "{{ item.desc }}"
        enabled: "{{ item.state.get('inactive') != 'inactive' }}"
        state: "{% if item.state.get('inactive') == 'inactive'%} inactive {% else %} active {% endif %}"

keys:
  vlans:
    value: "{{ vlan }}"
    top: configuration/vlans/vlan
    items:
      vlan_id: vlan-id
      name: name
      desc: description
      state: ".[@inactive='inactive']"

Значение top — это XPath, относительный к корневому узлу XML. В приведенном ниже примере XML-вывода значение top равно configuration/vlans/vlan, что является выражением XPath относительно корневого узла (<rpc-reply>). configuration в значении top — это внешний контейнерный узел, а vlan — внутренний контейнерный узел.

items — это словарь пар ключ-значение, которые сопоставляют пользовательские имена с выражениями XPath, выбирающими элементы. Выражение XPath является относительным к значению XPath, содержащемуся в top. Например, vlan_id в файле спецификаций — это пользовательское имя, а его значение vlan-id — это значение, относительное к XPath в top

END_OF_DOCUMENT_MARKER

Атрибуты тегов XML можно извлечь с помощью выражений XPath. Значение state в спецификации — это выражение XPath, используемое для получения атрибутов тега vlan в выходном XML.:

<rpc-reply>
  <configuration>
    <vlans>
      <vlan inactive="inactive">
       <name>vlan-1</name>
       <vlan-id>200</vlan-id>
       <description>This is vlan-1</description>
      </vlan>
    </vlans>
  </configuration>
</rpc-reply>

Примечание

Дополнительную информацию о поддерживаемых выражениях XPath см. в поддержке XPath.

Фильтры VLAN сети

Новое в версии 2.8.

Используйте фильтр vlan_parser для преобразования неупорядоченного списка целых чисел VLAN в отсортированный строковый список целых чисел в соответствии с правилами списков VLAN в стиле IOS. Этот список обладает следующими свойствами:

  • VLANы перечислены в порядке возрастания.
  • Три или более последовательных VLAN перечисляются через дефис.
  • Первая строка списка может иметь длину first_line_len символов.
  • Последующие строки списка могут иметь длину other_line_len символов.

Для сортировки списка VLAN:

{{ [3003, 3004, 3005, 100, 1688, 3002, 3999] | ansible.netcommon.vlan_parser }}

Этот пример отображает следующий отсортированный список:

['100,1688,3002-3005,3999']

Другой пример шаблона Jinja:

{% set parsed_vlans = vlans | ansible.netcommon.vlan_parser %}
switchport trunk allowed vlan {{ parsed_vlans[0] }}
{% for i in range (1, parsed_vlans | count) %}
switchport trunk allowed vlan add {{ parsed_vlans[i] }}

Это позволяет динамически генерировать списки VLAN на интерфейсе Cisco IOS с тегами. Вы можете хранить исчерпывающий исходный список точных VLAN, необходимых для интерфейса, а затем сравнить его с результатом парсинга вывода IOS, который фактически будет сгенерирован для конфигурации.

Шифрование и вычисление контрольных сумм строк и паролей

Новое в версии 1.9.

Для получения хэша sha1 строки:

{{ 'test1' | hash('sha1') }}

Для получения хэша md5 строки:

{{ 'test1' | hash('md5') }}

Получение контрольной суммы строки:

{{ 'test2' | checksum }}

Другие хэши (зависит от платформы):

{{ 'test2' | hash('blowfish') }}

Для получения хэша пароля sha512 (случайная соль):

{{ 'passwordsaresecret' | password_hash('sha512') }}

Для получения хэша пароля sha256 с определённой солью:

{{ 'secretpassword' | password_hash('sha256', 'mysecretsalt') }}

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

{{ 'secretpassword' | password_hash('sha512', 65534 | random(seed=inventory_hostname) | string) }}

Доступные типы хэшей зависят от системного Ansible, ‘hash’ зависит от hashlib, password_hash зависит от passlib (https://passlib.readthedocs.io/en/stable/lib/passlib.hash.html).

Новое в версии 2.7.

Некоторые типы хэшей позволяют задавать параметр rounds:

{{ 'secretpassword' | password_hash('sha256', 'mysecretsalt', rounds=10000) }}

Обработка текста

Несколько фильтров работают с текстом, включая URL, имена файлов и пути.

Добавление комментариев к файлам

Фильтр comment позволяет создавать комментарии в файле из текста в шаблоне с различными стилями комментариев. По умолчанию Ansible использует # для начала строки комментария и добавляет пустую строку комментария выше и ниже вашего текста комментария. Например, следующее:

{{ "Plain style (default)" | comment }}

производит такой вывод:

#
# Plain style (default)
#

Ansible предлагает стили комментариев для C (//...), блоков C (/*...*/), Erlang (%...) и XML (<!--...-->):

{{ "C style" | comment('c') }}
{{ "C block style" | comment('cblock') }}
{{ "Erlang style" | comment('erlang') }}
{{ "XML style" | comment('xml') }}

Можно определить собственный символ комментария. Этот фильтр:

{{ "My Special Case" | comment(decoration="! ") }}

производит:

!
! My Special Case
!

Можно полностью настроить стиль комментария:

{{ "Custom style" | comment('plain', prefix='#######\n#', postfix='#\n#######\n   ###\n    #') }}

Это создаёт следующий вывод:

#######
#
# Custom style
#
#######
   ###
    #

Фильтр также может быть применён к любой переменной Ansible. Например, чтобы сделать вывод переменной ansible_managed более читаемым, можно изменить определение в файле ansible.cfg на это:

[defaults]

ansible_managed = This file is managed by Ansible.%n
  template: {file}
  date: %Y-%m-%d %H:%M:%S
  user: {uid}
  host: {host}

и затем использовать переменную с фильтром comment:

{{ ansible_managed | comment }}

что даёт такой вывод:

#
# This file is managed by Ansible.
#
# template: /home/ansible/env/dev/ansible_managed/roles/role1/templates/test.j2
# date: 2015-09-10 11:02:58
# user: ansible
# host: myhost
#

Разделение URL

Новое в версии 2.4.

Фильтр urlsplit извлекает фрагмент, имя хоста, netloc, пароль, путь, порт, запрос, схему и имя пользователя из URL. Без аргументов возвращает словарь всех полей:

{{ "http://user:password@www.acme.com:9000/dir/index.html?query=term#fragment" | urlsplit('hostname') }}
# => 'www.acme.com'

{{ "http://user:password@www.acme.com:9000/dir/index.html?query=term#fragment" | urlsplit('netloc') }}
# => 'user:password@www.acme.com:9000'

{{ "http://user:password@www.acme.com:9000/dir/index.html?query=term#fragment" | urlsplit('username') }}
# => 'user'

{{ "http://user:password@www.acme.com:9000/dir/index.html?query=term#fragment" | urlsplit('password') }}
# => 'password'

{{ "http://user:password@www.acme.com:9000/dir/index.html?query=term#fragment" | urlsplit('path') }}
# => '/dir/index.html'

{{ "http://user:password@www.acme.com:9000/dir/index.html?query=term#fragment" | urlsplit('port') }}
# => '9000'

{{ "http://user:password@www.acme.com:9000/dir/index.html?query=term#fragment" | urlsplit('scheme') }}
# => 'http'

{{ "http://user:password@www.acme.com:9000/dir/index.html?query=term#fragment" | urlsplit('query') }}
# => 'query=term'

{{ "http://user:password@www.acme.com:9000/dir/index.html?query=term#fragment" | urlsplit('fragment') }}
# => 'fragment'

{{ "http://user:password@www.acme.com:9000/dir/index.html?query=term#fragment" | urlsplit }}
# =>
#   {
#       "fragment": "fragment",
#       "hostname": "www.acme.com",
#       "netloc": "user:password@www.acme.com:9000",
#       "password": "password",
#       "path": "/dir/index.html",
#       "port": 9000,
#       "query": "query=term",
#       "scheme": "http",
#       "username": "user"
#   }

Поиск строк с помощью регулярных выражений

Для поиска строки с помощью регулярного выражения используйте фильтр «regex_search»:

# search for "foo" in "foobar"
{{ 'foobar' | regex_search('(foo)') }}

# will return empty if it cannot find a match
{{ 'ansible' | regex_search('(foobar)') }}

# case insensitive search in multiline mode
{{ 'foo\nBAR' | regex_search("^bar", multiline=True, ignorecase=True) }}

Для поиска всех вхождений совпадений с регулярным выражением используйте фильтр «regex_findall»:

# Return a list of all IPv4 addresses in the string
{{ 'Some DNS servers are 8.8.8.8 and 8.8.4.4' | regex_findall('\\b(?:[0-9]{1,3}\\.){3}[0-9]{1,3}\\b') }}

Для замены текста в строке с помощью регулярного выражения используйте фильтр «regex_replace»:

# convert "ansible" to "able"
{{ 'ansible' | regex_replace('^a.*i(.*)$', 'a\\1') }}

# convert "foobar" to "bar"
{{ 'foobar' | regex_replace('^f.*o(.*)$', '\\1') }}

# convert "localhost:80" to "localhost, 80" using named groups
{{ 'localhost:80' | regex_replace('^(?P<host>.+):(?P<port>\\d+)$', '\\g<host>, \\g<port>') }}

# convert "localhost:80" to "localhost"
{{ 'localhost:80' | regex_replace(':80') }}

# change a multiline string
{{ var | regex_replace('^', '#CommentThis#', multiline=True) }}

Примечание

Если требуется соответствие всей строке и используется *, убедитесь, что ваше регулярное выражение всегда окружено якорями начала/конца. Например, ^(.*)$ всегда будет соответствовать только одному результату, в то время как (.*) на некоторых версиях Python будет соответствовать всей строке и пустой строке в конце, что означает, что это произведёт две замены:

# add "https://" prefix to each item in a list
GOOD:
{{ hosts | map('regex_replace', '^(.*)$', 'https://\\1') | list }}
{{ hosts | map('regex_replace', '(.+)', 'https://\\1') | list }}
{{ hosts | map('regex_replace', '^', 'https://') | list }}

BAD:
{{ hosts | map('regex_replace', '(.*)', 'https://\\1') | list }}

# append ':80' to each item in a list
GOOD:
{{ hosts | map('regex_replace', '^(.*)$', '\\1:80') | list }}
{{ hosts | map('regex_replace', '(.+)', '\\1:80') | list }}
{{ hosts | map('regex_replace', '$', ':80') | list }}

BAD:
{{ hosts | map('regex_replace', '(.*)', '\\1:80') | list }}

Примечание

До версии Ansible 2.0, если фильтр «regex_replace» использовался с переменными внутри YAML-аргументов (по сравнению с более простыми аргументами типа ‘ключ=значение’), необходимо было экранировать обратные ссылки (например, \\1) четырьмя обратными слешами (\\\\), а не двумя (\\).

Новое в версии 2.0.

Для экранирования специальных символов в стандартном регулярном выражении Python используйте фильтр «regex_escape» (используя опцию re_type=’python’ по умолчанию):

# convert '^f.*o(.*)$' to '\^f\.\*o\(\.\*\)\$'
{{ '^f.*o(.*)$' | regex_escape() }}

Новое в версии 2.8.

Для экранирования специальных символов в базовом регулярном выражении POSIX используйте фильтр «regex_escape» с опцией re_type=’posix_basic’:

# convert '^f.*o(.*)$' to '\^f\.\*o(\.\*)\$'
{{ '^f.*o(.*)$' | regex_escape('posix_basic') }}

Управление именами файлов и путями

Для получения последнего имени файла, такого как ‘foo.txt’ из ‘/etc/asdf/foo.txt’:

{{ path | basename }}

Для получения последнего имени файла в стиле Windows (новое в версии 2.0):

{{ path | win_basename }}

Для разделения буквы диска Windows от остальной части пути файла (новое в версии 2.0):

{{ path | win_splitdrive }}

Для получения только буквы диска Windows:

{{ path | win_splitdrive | first }}

Для получения остальной части пути без буквы диска:

{{ path | win_splitdrive | last }}

Для получения каталога из пути:

{{ path | dirname }}

Для получения каталога из пути в стиле Windows (новая версия 2.0):

{{ path | win_dirname }}

Для расширения пути, содержащего символ тильды (~) (новое в версии 1.5):

{{ path | expanduser }}

Для расширения пути, содержащего переменные окружения:

{{ path | expandvars }}

Примечание

expandvars расширяет локальные переменные; использование его для удалённых путей может привести к ошибкам.

Новое в версии 2.6.

Для получения реального пути ссылки (новое в версии 1.8):

{{ path | realpath }}

Для получения относительного пути ссылки от начальной точки (новое в версии 1.7):

{{ path | relpath('/etc') }}

Для получения корня и расширения пути или имени файла (новое в версии 2.0):

# with path == 'nginx.conf' the return would be ('nginx', '.conf')
{{ path | splitext }}

Фильтр splitext возвращает строку. К отдельным компонентам можно обратиться, используя фильтры first и last:

# with path == 'nginx.conf' the return would be 'nginx'
{{ path | splitext | first }}

# with path == 'nginx.conf' the return would be 'conf'
{{ path | splitext | last }}

Для объединения одного или нескольких компонентов пути:

{{ ('/etc', path, 'subdir', file) | path_join }}

Новое в версии 2.10.

Обработка строк

Для добавления кавычек для использования в оболочке:

- name: Run a shell command
  ansible.builtin.shell: echo {{ string_value | quote }}

Для конкатенации списка в строку:

{{ list | join(" ") }}

Для работы с Base64 закодированными строками:

{{ encoded | b64decode }}
{{ decoded | string | b64encode }}

Начиная с версии 2.6, можно определить тип кодирования, по умолчанию используется utf-8:

{{ encoded | b64decode(encoding='utf-16-le') }}
{{ decoded | string | b64encode(encoding='utf-16-le') }}

Примечание

Фильтр string необходим только для Python 2 и гарантирует, что текст для кодирования является строкой Unicode. Без этого фильтра перед b64encode будет закодировано неправильное значение.

Новое в версии 2.6.

Управление UUID

Для создания пространственно-именованного UUIDv5:

{{ string | to_uuid(namespace='11111111-2222-3333-4444-555555555555') }}

Новое в версии 2.10.

Для создания пространственно-именованного UUIDv5, используя пространство имён Ansible по умолчанию «361E6D51-FAEC-444A-9079-341386DA8E2E»:

{{ string | to_uuid }}

Новое в версии 1.9.

Для использования одного атрибута из каждого элемента в списке сложных переменных, используйте Jinja2 map filter:

# get a comma-separated list of the mount points (for example, "/,/mnt/stuff") on a host
{{ ansible_mounts | map(attribute='mount') | join(',') }}

Обработка дат и времени

Для получения объекта даты из строки используйте фильтр to_datetime:

# Get total amount of seconds between two dates. Default date format is %Y-%m-%d %H:%M:%S but you can pass your own format
{{ (("2016-08-14 20:00:12" | to_datetime) - ("2015-12-25" | to_datetime('%Y-%m-%d'))).total_seconds()  }}

# Get remaining seconds after delta has been calculated. NOTE: This does NOT convert years, days, hours, and so on to seconds. For that, use total_seconds()
{{ (("2016-08-14 20:00:12" | to_datetime) - ("2016-08-14 18:00:00" | to_datetime)).seconds  }}
# This expression evaluates to "12" and not "132". Delta is 2 hours, 12 seconds

# get amount of days between two dates. This returns only number of days and discards remaining hours, minutes, and seconds
{{ (("2016-08-14 20:00:12" | to_datetime) - ("2015-12-25" | to_datetime('%Y-%m-%d'))).days  }}

Новое в версии 2.4.

Для форматирования даты с использованием строки (как с командой shell date), используйте фильтр «strftime»:

# Display year-month-day
{{ '%Y-%m-%d' | strftime }}

# Display hour:min:sec
{{ '%H:%M:%S' | strftime }}

# Use ansible_date_time.epoch fact
{{ '%Y-%m-%d %H:%M:%S' | strftime(ansible_date_time.epoch) }}

# Use arbitrary epoch value
{{ '%Y-%m-%d' | strftime(0) }}          # => 1970-01-01
{{ '%Y-%m-%d' | strftime(1441357287) }} # => 2015-09-04

Примечание

Чтобы получить все возможные строки, проверьте https://docs.python.org/3/library/time.html#time.strftime

Получение имён ресурсов Kubernetes

Примечание

Эти фильтры переехали в коллекцию community.kubernetes. Следуйте инструкциям по установке, чтобы установить эту коллекцию.

Используйте фильтр «k8s_config_resource_name», чтобы получить имя Kubernetes ConfigMap или Secret, включая его хэш:

{{ configmap_resource_definition | community.kubernetes.k8s_config_resource_name }}

Это можно использовать для ссылки на хэши в спецификациях Pod:

my_secret:
  kind: Secret
  name: my_secret_name

deployment_resource:
  kind: Deployment
  spec:
    template:
      spec:
        containers:
        - envFrom:
            - secretRef:
                name: {{ my_secret | community.kubernetes.k8s_config_resource_name }}

Новое в версии 2.8.

См. также

Вступление в плейбуки

Введение в плейбуки

Условные операторы

Условные операторы в плейбуках

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

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

Циклы

Использование циклов в плейбуках

Роли

Организация плейбуков по ролям

Советы и рекомендации

Советы и рекомендации по работе с плейбуками

Список рассылки пользователей

Есть вопрос? Заходите на форум!

irc.freenode.net

Канал IRC #ansible

© 2012–2018 Michael DeHaan
© 2018–2019 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/ansible/2.10/user_guide/playbooks_filters.html

Spec-Zone.ru

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