ansible 剧本中的 jinja2 '{% set ... %}' 处理
jinja2 '{% set ... %}' processing in ansible playbook
我不明白如何在 ansible 剧本中使用 jinja2 模板命令。
我的理解是剧本应该在执行前作为 jinja2 模板处理,但显然不是在文件被解析为 yaml 之前,因为在文件顶部使用 jinja2 命令会产生语法错误,例如:
{% set test_var = "test_value" %}
- hosts: all
remote_user: "my_user"
tasks:
- debug: var=test_var
{% set another_var = "another_value" %}
- debug: var=another_var
$ ansible-playbook -vv -K ansible/playbooks/test.yml
ERROR! Syntax Error while loading YAML.
found character '%' that cannot start any token
...
如果我注释 jinja2 命令以避免此解析错误,顶部的第一个命令会被处理,但剧本中间的其他命令不会被处理:
# {% set test_var = "test_value" %}
- hosts: all
remote_user: "my_user"
tasks:
- debug: var=test_var # this works
# {% set another_var = "another_value" %}
- debug: var=another_var
# ok: [localhost] => {
# "another_var": "VARIABLE IS NOT DEFINED!: 'another_var' is undefined"
# }
我不明白 ansible 是如何处理 playbook 模板的。难道不应该有一个只处理 jinja2 语法的第一遍,然后输出删除了 jinja2 语法的 yaml 吗?
$ ansible-playbook --version
ansible-playbook 2.9.1
config file = /etc/ansible/ansible.cfg
configured module search path = ['/home/me/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /home/me/.local/lib/python3.7/site-packages/ansible
executable location = /home/me/.local/bin/ansible-playbook
python version = 3.7.3 (default, Apr 3 2019, 19:16:38) [GCC 8.0.1 20180414 (experimental) [trunk revision 259383]]
谢谢!
jinja2在ansible运行时处理的是yaml vars的内容,而不是yaml文件本身。这是分几步完成的,如果您想准确了解幕后内容,请深入了解 ansible 代码。
只是为了让您走上正轨,这是您在问题中尝试过的可靠方法。
- hosts: all
remote_user: "my_user"
# These are playbook vars set at playbook level
# Vars can also be in inventories, roles....
# see https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html
vars:
test_var: test_value
tasks:
- name: debug my test_var
debug:
var: test_var
- name: if you need to set var at run time you can use set_fact
set_fact:
# Jinja2 templating will be honored here
another_var: "another_{{ test_var }}"
- name: debug var we just valued
debug:
var: another_var
我不明白如何在 ansible 剧本中使用 jinja2 模板命令。
我的理解是剧本应该在执行前作为 jinja2 模板处理,但显然不是在文件被解析为 yaml 之前,因为在文件顶部使用 jinja2 命令会产生语法错误,例如:
{% set test_var = "test_value" %}
- hosts: all
remote_user: "my_user"
tasks:
- debug: var=test_var
{% set another_var = "another_value" %}
- debug: var=another_var
$ ansible-playbook -vv -K ansible/playbooks/test.yml
ERROR! Syntax Error while loading YAML.
found character '%' that cannot start any token
...
如果我注释 jinja2 命令以避免此解析错误,顶部的第一个命令会被处理,但剧本中间的其他命令不会被处理:
# {% set test_var = "test_value" %}
- hosts: all
remote_user: "my_user"
tasks:
- debug: var=test_var # this works
# {% set another_var = "another_value" %}
- debug: var=another_var
# ok: [localhost] => {
# "another_var": "VARIABLE IS NOT DEFINED!: 'another_var' is undefined"
# }
我不明白 ansible 是如何处理 playbook 模板的。难道不应该有一个只处理 jinja2 语法的第一遍,然后输出删除了 jinja2 语法的 yaml 吗?
$ ansible-playbook --version
ansible-playbook 2.9.1
config file = /etc/ansible/ansible.cfg
configured module search path = ['/home/me/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /home/me/.local/lib/python3.7/site-packages/ansible
executable location = /home/me/.local/bin/ansible-playbook
python version = 3.7.3 (default, Apr 3 2019, 19:16:38) [GCC 8.0.1 20180414 (experimental) [trunk revision 259383]]
谢谢!
jinja2在ansible运行时处理的是yaml vars的内容,而不是yaml文件本身。这是分几步完成的,如果您想准确了解幕后内容,请深入了解 ansible 代码。
只是为了让您走上正轨,这是您在问题中尝试过的可靠方法。
- hosts: all
remote_user: "my_user"
# These are playbook vars set at playbook level
# Vars can also be in inventories, roles....
# see https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html
vars:
test_var: test_value
tasks:
- name: debug my test_var
debug:
var: test_var
- name: if you need to set var at run time you can use set_fact
set_fact:
# Jinja2 templating will be honored here
another_var: "another_{{ test_var }}"
- name: debug var we just valued
debug:
var: another_var