如何使用 jinja2 输出作为 ansible 指令而不是字符链?
How to use the jinja2 output as an ansible directive instead of a chain of characters?
我目前正在显示一些带有 'extract' 的变量:
- name: Display hostvars over conditionnal
hosts: all
tasks:
- debug:
msg: "{{
ansible_play_hosts
| map('extract', hostvars, inventory_hostname)
|selectattr('ansible_distribution', 'regex', 'Rocky|CentOS' )
|selectattr('ansible_distribution_major_version', '==', '8' )
|flatten
}}"
结果是符合这些条件的名称列表:
TASK [debug]
ok: [ancolie-lba] => {
"msg": [
"vm703-dev"
]
}
现在我想用 jinja2 ansible_facts.j2
模板化这个显示
{{'{{'}}
ansible_play_hosts
|map('extract', hostvars)
{% for condition in conditions %}
|selectattr('{{condition.attribute}}', '{{condition.verb}}', '{{condition.text}}' )
{% endfor %}
|flatten
{{'}}'}}
以便像下面这样使用 jinja2 输出文件:
- block:
- name: generate a conf
template:
src: ansible_facts.j2
dest: /tmp/ansible_facts
- debug:
msg: "{{lookup('file', '/tmp/ansible_facts')}}"
tags: template
delegate_to: localhost
vars:
conditions:
- attribute: 'ansible_distribution'
verb: 'regex'
text: 'Rocky|CentOS'
- attribute: 'ansible_distribution_major_version'
verb: '=='
text: '8'
但 ansible 似乎将查找输出解释为链字符,而不是像最初那样执行过滤器:
返回的内容:
"msg": "{{ansible_play_hosts|map('extract', hostvars, os)|selectattr('ansible_distribution', 'regex', 'Rocky|CentOS' )|selectattr('ansible_distribution_major_version', '==', '8' )|flatten}}"
预期结果:
TASK [debug] *********************************************************************************************************************************************************************************
ok: [ancolie-lba] => {
"msg": [
"vm703-dev"
]
}
如何使用 jinja2 输出作为 ansible 指令而不是字符链?
您似乎在尝试生成 Jinja 模板作为模板的结果,然后以某种方式诱导 Ansible re-do 它认为已经完成的模板。这在技术上可能可以实现,但正在与 Ansible 的 Jinja 集成作斗争而不是与之合作。
只要您至少有 Jinja 2.10(为了 namespace()
支持),您就可以以相当直接的方式完成此操作,而无需 double-templating。它也可能在旧版本上可行,但会更痛苦。
test.j2
:
{% set ns = namespace(result=(ansible_play_hosts | map('extract', hostvars))) %}
{% for condition in conditions %}
{% set ns.result = ns.result | selectattr(condition.attribute, condition.verb, condition.text) %}
{% endfor %}
{{ ns.result | map(attribute='inventory_hostname') | to_nice_yaml }}
test.yml
:
- hosts: all
tasks:
- debug:
msg: "{{ lookup('template', 'test.j2') | from_yaml }}"
run_once: true
vars:
conditions:
- attribute: ansible_facts.hostname
verb: match
text: pe
输出:
PLAY [all] ************************************************************************
TASK [Gathering Facts] ************************************************************ok: [rotten-rusalka.authz-relay.x.mail.umich.edu]
ok: [persistent-servitor.relay-egress.x.mail.umich.edu]
ok: [bounteous-abumiguchi.mx.x.mail.umich.edu]
ok: [worthy-yithian.vdc-relay.x.mail.umich.edu]
ok: [commutual-chthonian.syslog.x.mail.umich.edu]
ok: [yern-elderthing.authz-static.x.mail.umich.edu]
ok: [diligent-griffin.authn-relay.x.mail.umich.edu]
ok: [dauntless-ratthing.dnsbl.x.mail.umich.edu]
ok: [powerful-yithian.covid-relay.x.mail.umich.edu]
ok: [legible-sansei.egress.x.mail.umich.edu]
ok: [dominant-shantak.dnsbl.x.mail.umich.edu]
ok: [trustworthy-dhole.jail.x.mail.umich.edu]
ok: [rose-dobyoshi.mx.x.mail.umich.edu]
ok: [pear-kaichigo.mx.x.mail.umich.edu]
ok: [pandora.x.mail.umich.edu]
ok: [queenly-kuzunoha.egress.x.mail.umich.edu]
TASK [debug] *********************************************************************$
ok: [worthy-yithian.vdc-relay.x.mail.umich.edu] => {
"msg": [
"persistent-servitor.relay-egress.x.mail.umich.edu",
"pear-kaichigo.mx.x.mail.umich.edu"
]
}
我目前正在显示一些带有 'extract' 的变量:
- name: Display hostvars over conditionnal
hosts: all
tasks:
- debug:
msg: "{{
ansible_play_hosts
| map('extract', hostvars, inventory_hostname)
|selectattr('ansible_distribution', 'regex', 'Rocky|CentOS' )
|selectattr('ansible_distribution_major_version', '==', '8' )
|flatten
}}"
结果是符合这些条件的名称列表:
TASK [debug]
ok: [ancolie-lba] => {
"msg": [
"vm703-dev"
]
}
现在我想用 jinja2 ansible_facts.j2
模板化这个显示{{'{{'}}
ansible_play_hosts
|map('extract', hostvars)
{% for condition in conditions %}
|selectattr('{{condition.attribute}}', '{{condition.verb}}', '{{condition.text}}' )
{% endfor %}
|flatten
{{'}}'}}
以便像下面这样使用 jinja2 输出文件:
- block:
- name: generate a conf
template:
src: ansible_facts.j2
dest: /tmp/ansible_facts
- debug:
msg: "{{lookup('file', '/tmp/ansible_facts')}}"
tags: template
delegate_to: localhost
vars:
conditions:
- attribute: 'ansible_distribution'
verb: 'regex'
text: 'Rocky|CentOS'
- attribute: 'ansible_distribution_major_version'
verb: '=='
text: '8'
但 ansible 似乎将查找输出解释为链字符,而不是像最初那样执行过滤器:
返回的内容:
"msg": "{{ansible_play_hosts|map('extract', hostvars, os)|selectattr('ansible_distribution', 'regex', 'Rocky|CentOS' )|selectattr('ansible_distribution_major_version', '==', '8' )|flatten}}"
预期结果:
TASK [debug] *********************************************************************************************************************************************************************************
ok: [ancolie-lba] => {
"msg": [
"vm703-dev"
]
}
如何使用 jinja2 输出作为 ansible 指令而不是字符链?
您似乎在尝试生成 Jinja 模板作为模板的结果,然后以某种方式诱导 Ansible re-do 它认为已经完成的模板。这在技术上可能可以实现,但正在与 Ansible 的 Jinja 集成作斗争而不是与之合作。
只要您至少有 Jinja 2.10(为了 namespace()
支持),您就可以以相当直接的方式完成此操作,而无需 double-templating。它也可能在旧版本上可行,但会更痛苦。
test.j2
:
{% set ns = namespace(result=(ansible_play_hosts | map('extract', hostvars))) %}
{% for condition in conditions %}
{% set ns.result = ns.result | selectattr(condition.attribute, condition.verb, condition.text) %}
{% endfor %}
{{ ns.result | map(attribute='inventory_hostname') | to_nice_yaml }}
test.yml
:
- hosts: all
tasks:
- debug:
msg: "{{ lookup('template', 'test.j2') | from_yaml }}"
run_once: true
vars:
conditions:
- attribute: ansible_facts.hostname
verb: match
text: pe
输出:
PLAY [all] ************************************************************************
TASK [Gathering Facts] ************************************************************ok: [rotten-rusalka.authz-relay.x.mail.umich.edu]
ok: [persistent-servitor.relay-egress.x.mail.umich.edu]
ok: [bounteous-abumiguchi.mx.x.mail.umich.edu]
ok: [worthy-yithian.vdc-relay.x.mail.umich.edu]
ok: [commutual-chthonian.syslog.x.mail.umich.edu]
ok: [yern-elderthing.authz-static.x.mail.umich.edu]
ok: [diligent-griffin.authn-relay.x.mail.umich.edu]
ok: [dauntless-ratthing.dnsbl.x.mail.umich.edu]
ok: [powerful-yithian.covid-relay.x.mail.umich.edu]
ok: [legible-sansei.egress.x.mail.umich.edu]
ok: [dominant-shantak.dnsbl.x.mail.umich.edu]
ok: [trustworthy-dhole.jail.x.mail.umich.edu]
ok: [rose-dobyoshi.mx.x.mail.umich.edu]
ok: [pear-kaichigo.mx.x.mail.umich.edu]
ok: [pandora.x.mail.umich.edu]
ok: [queenly-kuzunoha.egress.x.mail.umich.edu]
TASK [debug] *********************************************************************$
ok: [worthy-yithian.vdc-relay.x.mail.umich.edu] => {
"msg": [
"persistent-servitor.relay-egress.x.mail.umich.edu",
"pear-kaichigo.mx.x.mail.umich.edu"
]
}