问题描述
我正在寻找一种在遍历循环时从文本、yaml 或 json 文件中获取值的方法。
我的代码正在运行,因为我正在使用 loop
迭代哈希列表,但问题是当我有多个条目要迭代时,这就是我想将所有这些值放入一个文件的原因然后在任务/剧本中调用它们,而不是在剧本中写一堆行。
请提出建议或帮助通过它..
以下是工作代码:
---
- hosts: localhost
gather_facts: no
vars:
config: "{{ playbook_dir }}/{{ config_file }}"
contents: "{{lookup('file',config)}}"
server_profile_template: 'Test_apc_SY 480 Gen10 2 NVMe Application Template 20190601 V1.0'
server_hardware: "SY 480 Gen9 1"
template_name: []
server_list: []
tasks:
- name: Create server profile
oneview_server_profile:
config: "{{ config }}"
data:
serverProfileTemplateName: "{{ server_profile_template }}"
serverHardwareName: "{{ item.Bay }}"
name: "{{ item.Profilename }}"
params:
force: True
loop:
- { Bay: "ENT0005,bay 11",Profilename: "test_profile01" }
- { Bay: "ENT0005,bay 12",Profilename: "test_profile02" }
delegate_to: localhost
register: result
- debug: msg= "{{ result }}"
- debug: msg= "{{ result.msg }}"
...
目的:
$ cat bayfile.yml
---
- 'Bay: "ENT0005,Profilename: "test_profile01"'
- 'Bay: "ENT0005,Profilename: "test_profile02"'
...
我尝试了什么:
loop: "{{ lookup('file','{{ bayfile.yml }}') }}"
但上面不起作用。
解决方法
您的方向是正确的,但有几个问题:
数据文件中有错误的 YAML 语法。
在您的示例中,您显示:
- 'Bay: "ENT0005,bay 11",Profilename: "test_profile01"'
- 'Bay: "ENT0005,bay 12",Profilename: "test_profile02"'
这是一个字符串列表(因为每个列表项都用单引号括起来)。如果您想重现您在剧本中显示的数据,您需要一个字典列表。你可能想要这个:
- Bay: "ENT0005,bay 11"
Profilename: "test_profile01"
- Bay: "ENT0005,bay 12"
Profilename: "test_profile02"
以下是相同的,只是使用了稍微不同的语法:
- {Bay: "ENT0005,Profilename: "test_profile01"}
- {Bay: "ENT0005,Profilename: "test_profile02"}
嵌套的 jinja2 模板标记
您从不嵌套 {{...}}
标记;你只需要最外层的集合……里面的所有东西都已经在 Jinja 模板上下文中了。而不是:
loop: "{{ lookup('file','{{ bayfile.yml }}') }}"
你会写:
loop: "{{ lookup('file','bayfile.yml') }}"
将数据转换为 YAML
最后,当您像这样使用 file
查找时,结果只是一个字符串(文件的内容)。您想将其反序列化为 Ansible 数据结构,因此您需要 from_yaml
过滤器:
loop: "{{ lookup('file','bayfile.yml') | from_yaml }}"
综合起来,我们得到了这样的结果:
- hosts: localhost
gather_facts: false
tasks:
- name: Create server profile
debug:
msg:
- "{{ item.Bay }}"
- "{{ item.Profilename }}"
loop: "{{ lookup('file','bayfile.yml') | from_yaml }}"
使用 include_vars
请注意,您可以在剧本中使用 file
任务,而不是使用 from_yaml
查找和 include_vars
过滤器。您首先需要重新格式化您的数据文件,使其成为字典而不是列表,如下所示:
oneview_servers:
- Bay: "ENT0005,bay 11"
Profilename: "test_profile01"
- Bay: "ENT0005,bay 12"
Profilename: "test_profile02"
然后你可以像这样写你的剧本:
- hosts: localhost
gather_facts: false
tasks:
- name: Read data
include_vars:
file: bayfile.yml
name: data
- name: Create server profile
debug:
msg:
- "{{ item.Bay }}"
- "{{ item.Profilename }}"
loop: "{{ data.oneview_servers }}"