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#]
Так что это решило мою проблему.