Ansible: переменная интерполяция в имени задачи

Я не могу получить этот, казалось бы, простой пример для работы в Ansible 1.8.3. Интерполяция переменных не вызывает имени задачи. Все примеры Я видел, похоже, что это должно сработать. Учитывая, что переменная определена в разделе vars, я ожидал, что имя задачи напечатает значение переменной. Почему это не работает?

Даже пример из документации Ansible похоже, не печатает значение переменной.

---
- hosts: 127.0.0.1
  gather_facts: no
  vars:
    vhost: "foo"
  tasks:
    - name: create a virtual host file for {{ vhost }}
      debug: msg="{{ vhost }}"

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

PLAY [127.0.0.1]     
************************************************************** 

TASK: [create a virtual host file for {{ vhost }}] 
**************************** 
ok: [127.0.0.1] => {
   "msg": "foo"
}

PLAY RECAP 
******************************************************************** 
127.0.0.1                  : ok=1    changed=0    unreachable=0    failed=0   

Обновление Это работает с 1.7.2, но не работает с 1.8.3. Поэтому либо это ошибка, либо функция.

Ответ 1

Переменные не разрешаются внутри name. Только внутри реальных задач/условий и т.д. Заполнители будут решены. Думаю, это по дизайну. Представьте, что у вас есть цикл with_items и используйте {{ item }} в name. Задачи name будут печататься только один раз, но {{ item }} будет изменяться на каждой итерации.

Я вижу примеры, даже те, в которых вы связаны, используют переменные в name. Но это не значит, что результат будет таким, каким вы его ожидали. Документы управляются сообществом. Возможно, кто-то просто поставил эту строку там без тестирования - или, возможно, он работал так, как в предыдущей версии Ansible, и документы не были обновлены. (Я использую Ansible только около года). Но даже если это не работает, как мы этого хотим, я все еще использую переменные в name, чтобы указать, что задача основана на динамических параметрах. Возможно, примеры были написаны с тем же намерением.

Интересное наблюдение, которое я недавно сделал (Ansible 1.9.4), значения по умолчанию выписаны в имени задачи.

- name: create a virtual host file for {{ vhost | default("foo") }}

При выполнении Ansible отобразит название задачи как:

TASK: [создать файл виртуального хоста для foo]

Таким образом, вы можете избежать уродливых имен задач на выходе.

Ответ 2

Вы должны окружить строку кавычками.

tasks:
    - name: "create a virtual host file for {{ vhost }}"
      debug: msg="{{ vhost }}"

Из доступная документация:

Синтаксис YAML требует, чтобы при запуске значения с {{foo}} вы указывали всю строку, так как она хочет убедиться, что вы пытаетесь запустить словарь YAML. Это описано на странице YAML Syntax.

Ответ 3

объяснение

Будет ли переменная интерполирована, зависит от того, где она была объявлена.

Представьте, что у вас есть два хозяина: A и B

  • Если переменная foo имеет только значения для каждого хоста, когда Ansible запускает воспроизведение, она не может решить, какое значение использовать.
  • С другой стороны, если оно имеет глобальное значение (глобальное в смысле инвариантности хоста), нет никакой путаницы, какое значение использовать.

Источник: https://github.com/ansible/ansible/issues/3103#issuecomment-18835432

Руки на playbook

  • ansible_user - переменная инвентаря
  • greeting является инвариантной переменной
- name: Test variable substitution in names
  hosts: localhost
  connection: local
  vars:
    greeting: Hello
  tasks:
    - name: Sorry {{ ansible_user }}
      debug:
        msg: this won't work
    - name: You say '{{ greeting }}'
      debug:
        var: ansible_user

Ответ 4

Я столкнулся с той же проблемой сегодня в одной из моих ролей Ansible, и я заметил кое-что интересное.
Когда я использую модуль set_fact перед тем, как использовать переменные в имени задачи, они фактически переводятся в правильные значения.

В этом примере я хотел установить пароль для удаленного пользователя:
Обратите внимание, что я использую vars test_user и user_password которые я установил в качестве фактов ранее.

- name: Prepare to set user password
  set_fact:
    user_password: "{{ linux_pass }}"
    user_salt: "s0m3s4lt"
    test_user: "{{ ansible_user }}"

- name: "Changing password for user {{ test_user }} to {{ user_password }}"
  user:
   name: "{{ ansible_user }}"
   password: "{{ user_password | password_hash('sha512', user_salt) }}"
   state: present
   shell: /bin/bash
   update_password: always

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

TASK [install : Changing password for user linux to LiNuXuSeRPaSs#]

Так что это решило мою проблему.