在 ansible 模板化 yaml 中使用 jinja if 子句(通过模板查找)
Using jinja if clause in ansible templated yaml (through template lookup )
我使用带有动态定义的 ansible k8s 模块,我用
调用它
- name: install some tool
k8s:
state: present
definition: "{{ lookup('template', '{{item}}') }}"
context: "{{ cluster_name}}"
loop:
- "tool_template.yaml"
并且在模板中,我希望有一个条件块使用来自 ansible 角色的变量(is_major
在这种情况下)
metadata:
labels:
app: tool_name
{% if is_major | bool %}
annotations:
ad.datadoghq.com/container.check_names: '["openmetrics"]'
ad.datadoghq.com/container.init_configs: '[{}]'
ad.datadoghq.com/container.instances: |
[{
"prometheus_url": "http://pathto:port/,
"namespace": "myapp",
"metrics": ["somemetric*"]
}]
{% endif %}
不幸的是,这会引发一个可靠的异常,并且在文档中找不到关于如何做到这一点的线索(至少在最近的文档中)可能是我正在制作 yaml 模板的事实。所以搜索 solution/workaround
ansible 版本 2.9
编辑:完整错误(带有 vvv)
The full traceback is:
Traceback (most recent call last):
File "/home/username/.ansible/tmp/ansible-tmp-1588716858.967364-29993-207569799864998/AnsiballZ_k8s.py", line 102, in <module>
_ansiballz_main()
File "/home/username/.ansible/tmp/ansible-tmp-1588716858.967364-29993-207569799864998/AnsiballZ_k8s.py", line 94, in _ansiballz_main
invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
File "/home/username/.ansible/tmp/ansible-tmp-1588716858.967364-29993-207569799864998/AnsiballZ_k8s.py", line 40, in invoke_module
runpy.run_module(mod_name='ansible.modules.clustering.k8s.k8s', init_globals=None, run_name='__main__', alter_sys=True)
File "/home/username/.pyenv/versions/3.6.6/lib/python3.6/runpy.py", line 205, in run_module
return _run_module_code(code, init_globals, run_name, mod_spec)
File "/home/username/.pyenv/versions/3.6.6/lib/python3.6/runpy.py", line 96, in _run_module_code
mod_name, mod_spec, pkg_name, script_name)
File "/home/username/.pyenv/versions/3.6.6/lib/python3.6/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/tmp/ansible_k8s_payload_d7uua9ug/ansible_k8s_payload.zip/ansible/modules/clustering/k8s/k8s.py", line 279, in <module>
File "/tmp/ansible_k8s_payload_d7uua9ug/ansible_k8s_payload.zip/ansible/modules/clustering/k8s/k8s.py", line 275, in main
File "/tmp/ansible_k8s_payload_d7uua9ug/ansible_k8s_payload.zip/ansible/module_utils/k8s/raw.py", line 145, in __init__
File "/tmp/ansible_k8s_payload_d7uua9ug/ansible_k8s_payload.zip/ansible/module_utils/k8s/raw.py", line 145, in <listcomp>
File "/home/username/.local/lib/python3.6/site-packages/yaml/__init__.py", line 130, in load_all
yield loader.get_data()
File "/home/username/.local/lib/python3.6/site-packages/yaml/constructor.py", line 37, in get_data
return self.construct_document(self.get_node())
File "/home/username/.local/lib/python3.6/site-packages/yaml/composer.py", line 27, in get_node
return self.compose_document()
File "/home/username/.local/lib/python3.6/site-packages/yaml/composer.py", line 55, in compose_document
node = self.compose_node(None, None)
File "/home/username/.local/lib/python3.6/site-packages/yaml/composer.py", line 84, in compose_node
node = self.compose_mapping_node(anchor)
File "/home/username/.local/lib/python3.6/site-packages/yaml/composer.py", line 133, in compose_mapping_node
item_value = self.compose_node(node, item_key)
File "/home/username/.local/lib/python3.6/site-packages/yaml/composer.py", line 84, in compose_node
node = self.compose_mapping_node(anchor)
File "/home/username/.local/lib/python3.6/site-packages/yaml/composer.py", line 133, in compose_mapping_node
item_value = self.compose_node(node, item_key)
File "/home/username/.local/lib/python3.6/site-packages/yaml/composer.py", line 84, in compose_node
node = self.compose_mapping_node(anchor)
File "/home/username/.local/lib/python3.6/site-packages/yaml/composer.py", line 133, in compose_mapping_node
item_value = self.compose_node(node, item_key)
File "/home/username/.local/lib/python3.6/site-packages/yaml/composer.py", line 84, in compose_node
node = self.compose_mapping_node(anchor)
File "/home/username/.local/lib/python3.6/site-packages/yaml/composer.py", line 127, in compose_mapping_node
while not self.check_event(MappingEndEvent):
File "/home/username/.local/lib/python3.6/site-packages/yaml/parser.py", line 98, in check_event
self.current_event = self.state()
File "/home/username/.local/lib/python3.6/site-packages/yaml/parser.py", line 428, in parse_block_mapping_key
if self.check_token(KeyToken):
File "/home/username/.local/lib/python3.6/site-packages/yaml/scanner.py", line 116, in check_token
self.fetch_more_tokens()
File "/home/username/.local/lib/python3.6/site-packages/yaml/scanner.py", line 223, in fetch_more_tokens
return self.fetch_value()
File "/home/username/.local/lib/python3.6/site-packages/yaml/scanner.py", line 579, in fetch_value
self.get_mark())
yaml.scanner.ScannerError: mapping values are not allowed here
in "<unicode string>", line 18, column 24:
annotations:
^
failed: [localhost] (item=aks/monitor/datadog/datadog-agent-daemonset.yaml) => {
"ansible_loop_var": "item",
"changed": false,
"item": "aks/monitor/datadog/datadog-agent-daemonset.yaml",
"module_stderr": "Traceback (most recent call last):\n File \"/home/username/.ansible/tmp/ansible-tmp-1588716858.967364-29993-207569799864998/AnsiballZ_k8s.py\", line 102, in <module>\n _ansiballz_main()\n File \"/home/username/.ansible/tmp/ansible-tmp-1588716858.967364-29993-207569799864998/AnsiballZ_k8s.py\", line 94, in _ansiballz_main\n invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n File \"/home/username/.ansible/tmp/ansible-tmp-1588716858.967364-29993-207569799864998/AnsiballZ_k8s.py\", line 40, in invoke_module\n runpy.run_module(mod_name='ansible.modules.clustering.k8s.k8s', init_globals=None, run_name='__main__', alter_sys=True)\n File \"/home/username/.pyenv/versions/3.6.6/lib/python3.6/runpy.py\", line 205, in run_module\n return _run_module_code(code, init_globals, run_name, mod_spec)\n File \"/home/username/.pyenv/versions/3.6.6/lib/python3.6/runpy.py\", line 96, in _run_module_code\n mod_name, mod_spec, pkg_name, script_name)\n File \"/home/username/.pyenv/versions/3.6.6/lib/python3.6/runpy.py\", line 85, in _run_code\n exec(code, run_globals)\n File \"/tmp/ansible_k8s_payload_d7uua9ug/ansible_k8s_payload.zip/ansible/modules/clustering/k8s/k8s.py\", line 279, in <module>\n File \"/tmp/ansible_k8s_payload_d7uua9ug/ansible_k8s_payload.zip/ansible/modules/clustering/k8s/k8s.py\", line 275, in main\n File \"/tmp/ansible_k8s_payload_d7uua9ug/ansible_k8s_payload.zip/ansible/module_utils/k8s/raw.py\", line 145, in __init__\n File \"/tmp/ansible_k8s_payload_d7uua9ug/ansible_k8s_payload.zip/ansible/module_utils/k8s/raw.py\", line 145, in <listcomp>\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/__init__.py\", line 130, in load_all\n yield loader.get_data()\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/constructor.py\", line 37, in get_data\n return self.construct_document(self.get_node())\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/composer.py\", line 27, in get_node\n return self.compose_document()\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/composer.py\", line 55, in compose_document\n node = self.compose_node(None, None)\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/composer.py\", line 84, in compose_node\n node = self.compose_mapping_node(anchor)\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/composer.py\", line 133, in compose_mapping_node\n item_value = self.compose_node(node, item_key)\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/composer.py\", line 84, in compose_node\n node = self.compose_mapping_node(anchor)\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/composer.py\", line 133, in compose_mapping_node\n item_value = self.compose_node(node, item_key)\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/composer.py\", line 84, in compose_node\n node = self.compose_mapping_node(anchor)\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/composer.py\", line 133, in compose_mapping_node\n item_value = self.compose_node(node, item_key)\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/composer.py\", line 84, in compose_node\n node = self.compose_mapping_node(anchor)\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/composer.py\", line 127, in compose_mapping_node\n while not self.check_event(MappingEndEvent):\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/parser.py\", line 98, in check_event\n self.current_event = self.state()\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/parser.py\", line 428, in parse_block_mapping_key\n if self.check_token(KeyToken):\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/scanner.py\", line 116, in check_token\n self.fetch_more_tokens()\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/scanner.py\", line 223, in fetch_more_tokens\n return self.fetch_value()\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/scanner.py\", line 579, in fetch_value\n self.get_mark())\nyaml.scanner.ScannerError: mapping values are not allowed here\n in \"<unicode string>\", line 18, column 24:\n annotations:\n ^\n",
"module_stdout": "",
"msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
"rc": 1
}
您不能将 {{ }} 放在 {{ }} 中,因此请尝试删除多余的块:
- name: install some tool
k8s:
state: present
definition: "{{ lookup('template', item) }}"
context: "{{ cluster_name}}"
with_items:
- "tool_template.yaml"
你可能应该删除模板条件中的缩进,条件之前的空格被添加到下一行的空格中,因为条件标记后面的换行符被删除,这导致 anotations
映射为双缩进,这不是预期的。
您当前的模板结果是:
metadata:
labels:
app: tool_name
annotations:
ad.datadoghq.com/container.check_names: '["openmetrics"]'
ad.datadoghq.com/container.init_configs: '[{}]'
ad.datadoghq.com/container.instances: |
[{
"prometheus_url": "http://pathto:port/,
"namespace": "myapp",
"metrics": ["somemetric*"]
}]
模板应如下所示:
metadata:
labels:
app: tool_name
{% if is_major | bool %}
annotations:
ad.datadoghq.com/container.check_names: '["openmetrics"]'
ad.datadoghq.com/container.init_configs: '[{}]'
ad.datadoghq.com/container.instances: |
[{
"prometheus_url": "http://pathto:port/,
"namespace": "myapp",
"metrics": ["somemetric*"]
}]
{% endif %}
失败是件好事,因为如果之前的映射达到相同的缩进级别,它只会在部署中输入错误的值,或者在最好的情况下输入错误的值。
阅读更多关于 Jinja2 中空白的信息:https://jinja.palletsprojects.com/en/2.11.x/templates/#whitespace-control。
您还可以通过使用 trim_blocks
和 lstrip_blocks
标志来控制更多行为。
我使用带有动态定义的 ansible k8s 模块,我用
调用它- name: install some tool
k8s:
state: present
definition: "{{ lookup('template', '{{item}}') }}"
context: "{{ cluster_name}}"
loop:
- "tool_template.yaml"
并且在模板中,我希望有一个条件块使用来自 ansible 角色的变量(is_major
在这种情况下)
metadata:
labels:
app: tool_name
{% if is_major | bool %}
annotations:
ad.datadoghq.com/container.check_names: '["openmetrics"]'
ad.datadoghq.com/container.init_configs: '[{}]'
ad.datadoghq.com/container.instances: |
[{
"prometheus_url": "http://pathto:port/,
"namespace": "myapp",
"metrics": ["somemetric*"]
}]
{% endif %}
不幸的是,这会引发一个可靠的异常,并且在文档中找不到关于如何做到这一点的线索(至少在最近的文档中)可能是我正在制作 yaml 模板的事实。所以搜索 solution/workaround
ansible 版本 2.9
编辑:完整错误(带有 vvv)
The full traceback is:
Traceback (most recent call last):
File "/home/username/.ansible/tmp/ansible-tmp-1588716858.967364-29993-207569799864998/AnsiballZ_k8s.py", line 102, in <module>
_ansiballz_main()
File "/home/username/.ansible/tmp/ansible-tmp-1588716858.967364-29993-207569799864998/AnsiballZ_k8s.py", line 94, in _ansiballz_main
invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
File "/home/username/.ansible/tmp/ansible-tmp-1588716858.967364-29993-207569799864998/AnsiballZ_k8s.py", line 40, in invoke_module
runpy.run_module(mod_name='ansible.modules.clustering.k8s.k8s', init_globals=None, run_name='__main__', alter_sys=True)
File "/home/username/.pyenv/versions/3.6.6/lib/python3.6/runpy.py", line 205, in run_module
return _run_module_code(code, init_globals, run_name, mod_spec)
File "/home/username/.pyenv/versions/3.6.6/lib/python3.6/runpy.py", line 96, in _run_module_code
mod_name, mod_spec, pkg_name, script_name)
File "/home/username/.pyenv/versions/3.6.6/lib/python3.6/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/tmp/ansible_k8s_payload_d7uua9ug/ansible_k8s_payload.zip/ansible/modules/clustering/k8s/k8s.py", line 279, in <module>
File "/tmp/ansible_k8s_payload_d7uua9ug/ansible_k8s_payload.zip/ansible/modules/clustering/k8s/k8s.py", line 275, in main
File "/tmp/ansible_k8s_payload_d7uua9ug/ansible_k8s_payload.zip/ansible/module_utils/k8s/raw.py", line 145, in __init__
File "/tmp/ansible_k8s_payload_d7uua9ug/ansible_k8s_payload.zip/ansible/module_utils/k8s/raw.py", line 145, in <listcomp>
File "/home/username/.local/lib/python3.6/site-packages/yaml/__init__.py", line 130, in load_all
yield loader.get_data()
File "/home/username/.local/lib/python3.6/site-packages/yaml/constructor.py", line 37, in get_data
return self.construct_document(self.get_node())
File "/home/username/.local/lib/python3.6/site-packages/yaml/composer.py", line 27, in get_node
return self.compose_document()
File "/home/username/.local/lib/python3.6/site-packages/yaml/composer.py", line 55, in compose_document
node = self.compose_node(None, None)
File "/home/username/.local/lib/python3.6/site-packages/yaml/composer.py", line 84, in compose_node
node = self.compose_mapping_node(anchor)
File "/home/username/.local/lib/python3.6/site-packages/yaml/composer.py", line 133, in compose_mapping_node
item_value = self.compose_node(node, item_key)
File "/home/username/.local/lib/python3.6/site-packages/yaml/composer.py", line 84, in compose_node
node = self.compose_mapping_node(anchor)
File "/home/username/.local/lib/python3.6/site-packages/yaml/composer.py", line 133, in compose_mapping_node
item_value = self.compose_node(node, item_key)
File "/home/username/.local/lib/python3.6/site-packages/yaml/composer.py", line 84, in compose_node
node = self.compose_mapping_node(anchor)
File "/home/username/.local/lib/python3.6/site-packages/yaml/composer.py", line 133, in compose_mapping_node
item_value = self.compose_node(node, item_key)
File "/home/username/.local/lib/python3.6/site-packages/yaml/composer.py", line 84, in compose_node
node = self.compose_mapping_node(anchor)
File "/home/username/.local/lib/python3.6/site-packages/yaml/composer.py", line 127, in compose_mapping_node
while not self.check_event(MappingEndEvent):
File "/home/username/.local/lib/python3.6/site-packages/yaml/parser.py", line 98, in check_event
self.current_event = self.state()
File "/home/username/.local/lib/python3.6/site-packages/yaml/parser.py", line 428, in parse_block_mapping_key
if self.check_token(KeyToken):
File "/home/username/.local/lib/python3.6/site-packages/yaml/scanner.py", line 116, in check_token
self.fetch_more_tokens()
File "/home/username/.local/lib/python3.6/site-packages/yaml/scanner.py", line 223, in fetch_more_tokens
return self.fetch_value()
File "/home/username/.local/lib/python3.6/site-packages/yaml/scanner.py", line 579, in fetch_value
self.get_mark())
yaml.scanner.ScannerError: mapping values are not allowed here
in "<unicode string>", line 18, column 24:
annotations:
^
failed: [localhost] (item=aks/monitor/datadog/datadog-agent-daemonset.yaml) => {
"ansible_loop_var": "item",
"changed": false,
"item": "aks/monitor/datadog/datadog-agent-daemonset.yaml",
"module_stderr": "Traceback (most recent call last):\n File \"/home/username/.ansible/tmp/ansible-tmp-1588716858.967364-29993-207569799864998/AnsiballZ_k8s.py\", line 102, in <module>\n _ansiballz_main()\n File \"/home/username/.ansible/tmp/ansible-tmp-1588716858.967364-29993-207569799864998/AnsiballZ_k8s.py\", line 94, in _ansiballz_main\n invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n File \"/home/username/.ansible/tmp/ansible-tmp-1588716858.967364-29993-207569799864998/AnsiballZ_k8s.py\", line 40, in invoke_module\n runpy.run_module(mod_name='ansible.modules.clustering.k8s.k8s', init_globals=None, run_name='__main__', alter_sys=True)\n File \"/home/username/.pyenv/versions/3.6.6/lib/python3.6/runpy.py\", line 205, in run_module\n return _run_module_code(code, init_globals, run_name, mod_spec)\n File \"/home/username/.pyenv/versions/3.6.6/lib/python3.6/runpy.py\", line 96, in _run_module_code\n mod_name, mod_spec, pkg_name, script_name)\n File \"/home/username/.pyenv/versions/3.6.6/lib/python3.6/runpy.py\", line 85, in _run_code\n exec(code, run_globals)\n File \"/tmp/ansible_k8s_payload_d7uua9ug/ansible_k8s_payload.zip/ansible/modules/clustering/k8s/k8s.py\", line 279, in <module>\n File \"/tmp/ansible_k8s_payload_d7uua9ug/ansible_k8s_payload.zip/ansible/modules/clustering/k8s/k8s.py\", line 275, in main\n File \"/tmp/ansible_k8s_payload_d7uua9ug/ansible_k8s_payload.zip/ansible/module_utils/k8s/raw.py\", line 145, in __init__\n File \"/tmp/ansible_k8s_payload_d7uua9ug/ansible_k8s_payload.zip/ansible/module_utils/k8s/raw.py\", line 145, in <listcomp>\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/__init__.py\", line 130, in load_all\n yield loader.get_data()\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/constructor.py\", line 37, in get_data\n return self.construct_document(self.get_node())\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/composer.py\", line 27, in get_node\n return self.compose_document()\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/composer.py\", line 55, in compose_document\n node = self.compose_node(None, None)\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/composer.py\", line 84, in compose_node\n node = self.compose_mapping_node(anchor)\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/composer.py\", line 133, in compose_mapping_node\n item_value = self.compose_node(node, item_key)\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/composer.py\", line 84, in compose_node\n node = self.compose_mapping_node(anchor)\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/composer.py\", line 133, in compose_mapping_node\n item_value = self.compose_node(node, item_key)\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/composer.py\", line 84, in compose_node\n node = self.compose_mapping_node(anchor)\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/composer.py\", line 133, in compose_mapping_node\n item_value = self.compose_node(node, item_key)\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/composer.py\", line 84, in compose_node\n node = self.compose_mapping_node(anchor)\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/composer.py\", line 127, in compose_mapping_node\n while not self.check_event(MappingEndEvent):\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/parser.py\", line 98, in check_event\n self.current_event = self.state()\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/parser.py\", line 428, in parse_block_mapping_key\n if self.check_token(KeyToken):\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/scanner.py\", line 116, in check_token\n self.fetch_more_tokens()\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/scanner.py\", line 223, in fetch_more_tokens\n return self.fetch_value()\n File \"/home/username/.local/lib/python3.6/site-packages/yaml/scanner.py\", line 579, in fetch_value\n self.get_mark())\nyaml.scanner.ScannerError: mapping values are not allowed here\n in \"<unicode string>\", line 18, column 24:\n annotations:\n ^\n",
"module_stdout": "",
"msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
"rc": 1
}
您不能将 {{ }} 放在 {{ }} 中,因此请尝试删除多余的块:
- name: install some tool
k8s:
state: present
definition: "{{ lookup('template', item) }}"
context: "{{ cluster_name}}"
with_items:
- "tool_template.yaml"
你可能应该删除模板条件中的缩进,条件之前的空格被添加到下一行的空格中,因为条件标记后面的换行符被删除,这导致 anotations
映射为双缩进,这不是预期的。
您当前的模板结果是:
metadata:
labels:
app: tool_name
annotations:
ad.datadoghq.com/container.check_names: '["openmetrics"]'
ad.datadoghq.com/container.init_configs: '[{}]'
ad.datadoghq.com/container.instances: |
[{
"prometheus_url": "http://pathto:port/,
"namespace": "myapp",
"metrics": ["somemetric*"]
}]
模板应如下所示:
metadata:
labels:
app: tool_name
{% if is_major | bool %}
annotations:
ad.datadoghq.com/container.check_names: '["openmetrics"]'
ad.datadoghq.com/container.init_configs: '[{}]'
ad.datadoghq.com/container.instances: |
[{
"prometheus_url": "http://pathto:port/,
"namespace": "myapp",
"metrics": ["somemetric*"]
}]
{% endif %}
失败是件好事,因为如果之前的映射达到相同的缩进级别,它只会在部署中输入错误的值,或者在最好的情况下输入错误的值。
阅读更多关于 Jinja2 中空白的信息:https://jinja.palletsprojects.com/en/2.11.x/templates/#whitespace-control。
您还可以通过使用 trim_blocks
和 lstrip_blocks
标志来控制更多行为。