Определение

Зачем нужен ansible_managed в Ansible?

ansible_managed это специальная переменная, созданная исключительно для модулей ansible.builtin.template и ansible.windows.win_template, которая позволяет оставлять специальную опознавательную метку в генерируемых шаблонах

Согласно best-practice в каждом Jinja2 шаблоне нужно оставлять такую метку в начале шаблона для того, чтобы можно было легко определять какие файлы были созданы или изменены при помощи Ansible

Для ansible_managed существуют дополнительные подпеременные:

  • {file} — полный путь к шаблону (на хосте-контроллере)
  • {host} — hostname контроллера
  • {uid} — имя пользователя на хосте-контроллере
  • strftime timestamp — %Y-%m-%d %H:%M:%S (man strftime 3)

Учтите, что использование любой из вышеперечисленных переменных (особенно timestamp) может нарушить идемпотентность!

Желательно использовать вариант {{ ansible_managed | comment }} вместо # {{ ansible_managed }}, поскольку фильтр comment может автоматически подобрать комменатрий под тип файла и количество знаков комментария при мультистрочной обработке, например, при следующей конфигурации:

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

Практика

Вариант # {{ ansible_managed }} добавит (значение взяты для примера):

# This file is managed by Ansible.

template: tmpl.j2
date: 2024-01-01 01:01:01
user: admin
host: localhost

В то же время вариант {{ ansible_managed | comment }} добавит:

#
# This file is managed by Ansible.
#
# template: tmpl.j2
# date: 2024-01-01 01:01:01
# user: admin
# host: localhost
#

Ansible Managed

Ну а поскольку Ansible позволяет расширять свой функционал при помощи плагинов, мы можем определить любой lookup плагин и подставить его значение в ansible_managed. Вот так, например, можно добавить последний коммит проекта в шаблон (пример взят отсюда https://jpmens.net/2020/09/29/using-ansible-managed/):

[defaults]
ansible_managed = "$Ansible {{{{ template_path|basename + lookup('pipe', 'git log --format=",%%h %%ad %%ae" -1 --date=format:"%%Y/%%m/%%d %%H:%%M" ' + template_fullpath|quote)|default(",UNCOMMITED", True) }}}}$"