在 ansible 中构建 group_vars 时循环遍历列表
Looping through a list when building group_vars in ansible
我是 ansible 的新手,我想部署 prometheus-grok-exporter(通过 ansible-grok-exporter 角色),并为我的 运行 cacti 应用程序的所有节点配置特定配置。
我的库存是这样的:
cacti_first ansible_host=192.168.50.50
cacti_second ansible_host=192.168.50.51
[group__cacti]
cacti_first
cacti_second
里面 group_vars/group__cacti
我想添加这样的东西:
---
prometheus_grok_services_template:
- name: cacti_metrics
config_version: 3
input:
type: file
paths:
{% for cacti_dir in cacti_path %}
- "{{cacti_dir}}/log/cacti.log"
{% endfor %}
readall: false
extaConfigContinuesFromHere: true
我有这样的主机配置:
host_vars/cacti_first
:
---
cacti_path:
- /usr/share/cacti
prometheus_grok_services:
- prometheus_grok_services_template
host_vars/cacti_second
:
---
cacti_path:
- /usr/share/cacti
- /usr/share/cacti2
prometheus_grok_services:
- prometheus_grok_services_template
在剧本中,我为 prometheus_grok_services
循环并使用 yaml 数据来提供服务。
现在 - 只要我不尝试在 group_vars/group__cacti
中使用循环,它就可以工作。 ansible-inventory 报告说:
$ ansible-inventory -i hosts --list cacti_second
ERROR! Syntax Error while loading YAML.
found character that cannot start any token
The error appears to be in '/home/bastion/ansible-playbooks/group_vars/group__cacti': line 8, column 10, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
paths:
{% for cacti_dir in cacti_path %}
^ here
所以,我想问一下 - 是否允许使用 jinja 循环来为组变量构建 yaml?这是我的语法错误吗?我应该如何模板化它?
我想避免将块移动到主机变量(我知道这是可行的),主要是因为它是一大段代码(大约 2KB 的 yaml 配置)并且它不像使用组变量那样优雅。
谢谢!
您不能在变量文件或剧本中使用这种 for 循环 - 它只适用于模板文件。要实现您的目标,您可以使用产品过滤器,如 https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#products
所述
在您的示例中,您将拥有:
---
prometheus_grok_services_template:
- name: cacti_metrics
config_version: 3
input:
type: file
paths: "{{ cacti_path | product(['/log/cacti.log']) | map('join') | list }}"
readall: false
extaConfigContinuesFromHere: true
修复 group_vars。例如
shell> cat group_vars/group__cacti
---
prometheus_grok_services_template:
- name: cacti_metrics
config_version: 3
input:
type: file
paths: "{{ paths_str|from_yaml }}"
readall: false
extaConfigContinuesFromHere: true
paths_str: |
{% for cacti_dir in cacti_path %}
- {{ cacti_dir }}/log/cacti.log
{% endfor %}
然后,剧本
- hosts: group__cacti
gather_facts: false
tasks:
- debug:
msg: "{{ lookup('vars', item) }}"
loop: "{{ prometheus_grok_services }}"
给予
ok: [cacti_first] => (item=prometheus_grok_services_template) =>
msg:
- config_version: 3
input:
extaConfigContinuesFromHere: true
paths:
- /usr/share/cacti/log/cacti.log
readall: false
type: file
name: cacti_metrics
ok: [cacti_second] => (item=prometheus_grok_services_template) =>
msg:
- config_version: 3
input:
extaConfigContinuesFromHere: true
paths:
- /usr/share/cacti/log/cacti.log
- /usr/share/cacti2/log/cacti.log
readall: false
type: file
name: cacti_metrics
我是 ansible 的新手,我想部署 prometheus-grok-exporter(通过 ansible-grok-exporter 角色),并为我的 运行 cacti 应用程序的所有节点配置特定配置。
我的库存是这样的:
cacti_first ansible_host=192.168.50.50
cacti_second ansible_host=192.168.50.51
[group__cacti]
cacti_first
cacti_second
里面 group_vars/group__cacti
我想添加这样的东西:
---
prometheus_grok_services_template:
- name: cacti_metrics
config_version: 3
input:
type: file
paths:
{% for cacti_dir in cacti_path %}
- "{{cacti_dir}}/log/cacti.log"
{% endfor %}
readall: false
extaConfigContinuesFromHere: true
我有这样的主机配置:
host_vars/cacti_first
:
---
cacti_path:
- /usr/share/cacti
prometheus_grok_services:
- prometheus_grok_services_template
host_vars/cacti_second
:
---
cacti_path:
- /usr/share/cacti
- /usr/share/cacti2
prometheus_grok_services:
- prometheus_grok_services_template
在剧本中,我为 prometheus_grok_services
循环并使用 yaml 数据来提供服务。
现在 - 只要我不尝试在 group_vars/group__cacti
中使用循环,它就可以工作。 ansible-inventory 报告说:
$ ansible-inventory -i hosts --list cacti_second
ERROR! Syntax Error while loading YAML.
found character that cannot start any token
The error appears to be in '/home/bastion/ansible-playbooks/group_vars/group__cacti': line 8, column 10, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
paths:
{% for cacti_dir in cacti_path %}
^ here
所以,我想问一下 - 是否允许使用 jinja 循环来为组变量构建 yaml?这是我的语法错误吗?我应该如何模板化它?
我想避免将块移动到主机变量(我知道这是可行的),主要是因为它是一大段代码(大约 2KB 的 yaml 配置)并且它不像使用组变量那样优雅。
谢谢!
您不能在变量文件或剧本中使用这种 for 循环 - 它只适用于模板文件。要实现您的目标,您可以使用产品过滤器,如 https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#products
所述在您的示例中,您将拥有:
---
prometheus_grok_services_template:
- name: cacti_metrics
config_version: 3
input:
type: file
paths: "{{ cacti_path | product(['/log/cacti.log']) | map('join') | list }}"
readall: false
extaConfigContinuesFromHere: true
修复 group_vars。例如
shell> cat group_vars/group__cacti
---
prometheus_grok_services_template:
- name: cacti_metrics
config_version: 3
input:
type: file
paths: "{{ paths_str|from_yaml }}"
readall: false
extaConfigContinuesFromHere: true
paths_str: |
{% for cacti_dir in cacti_path %}
- {{ cacti_dir }}/log/cacti.log
{% endfor %}
然后,剧本
- hosts: group__cacti
gather_facts: false
tasks:
- debug:
msg: "{{ lookup('vars', item) }}"
loop: "{{ prometheus_grok_services }}"
给予
ok: [cacti_first] => (item=prometheus_grok_services_template) =>
msg:
- config_version: 3
input:
extaConfigContinuesFromHere: true
paths:
- /usr/share/cacti/log/cacti.log
readall: false
type: file
name: cacti_metrics
ok: [cacti_second] => (item=prometheus_grok_services_template) =>
msg:
- config_version: 3
input:
extaConfigContinuesFromHere: true
paths:
- /usr/share/cacti/log/cacti.log
- /usr/share/cacti2/log/cacti.log
readall: false
type: file
name: cacti_metrics