简体   繁体   English

Ansible 从文件中获取类似字典的值到剧本或循环

[英]Ansible to get the dict like values from a file to the playbook or loop

I am looking for a way to get the value from a text, yaml or json file while going through loop.我正在寻找一种在循环时从文本 yaml 或 json 文件中获取值的方法。

My code is working as i'm Iterating over a list of hashes with loop but the problem is when i'll have multiple entries to be Iterate over that's why i want to place all these values into a file and then call them in the task/playbook rather than writing bunch of line into the play.我的代码正在工作,因为我正在使用loop迭代哈希列表,但问题是当我将有多个条目进行迭代时,这就是为什么我想将所有这些值放入一个文件中,然后在任务中调用它们/playbook 而不是在剧本中写一堆线。

Please suggest or help to get it through..请建议或帮助通过..

Below is the working code:下面是工作代码:

---
- 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 }}"

...

What is intended:目的是什么:

$ cat bayfile.yml
---

-  'Bay: "ENT0005, bay 11", Profilename: "test_profile01"'
-  'Bay: "ENT0005, bay 12", Profilename: "test_profile02"'

...

What i tried:我尝试了什么:

loop: "{{ lookup('file', '{{ bayfile.yml }}') }}"

But above not working.但以上不起作用。

You're headed in the right direction, but there are a couple of issues:您正朝着正确的方向前进,但有几个问题:

Bad YAML syntax in your datafile.数据文件中的 YAML 语法错误。

In your example, you show:在您的示例中,您显示:

-  'Bay: "ENT0005, bay 11", Profilename: "test_profile01"'
-  'Bay: "ENT0005, bay 12", Profilename: "test_profile02"'

That's a list of strings (because you have each list item enclosed in single quotes).这是一个字符串列表(因为每个列表项都用单引号括起来)。 If you want to reproduce the data you've shown in your playbook, you want a list of dictionaries.如果您想重现您在剧本中显示的数据,您需要一个字典列表。 You probably want this instead:你可能想要这个:

- Bay: "ENT0005, bay 11"
  Profilename: "test_profile01"

- Bay: "ENT0005, bay 12"
  Profilename: "test_profile02"

The following is identical, just using a slightly different syntax:以下是相同的,只是使用了稍微不同的语法:

- {Bay: "ENT0005, bay 11", Profilename: "test_profile01"}
- {Bay: "ENT0005, bay 12", Profilename: "test_profile02"}

Nested jinja2 template markers嵌套 jinja2 模板标记

You never nest {{...}} markers;你永远不会嵌套{{...}}标记; you only need the outermost set...everything inside is already in a Jinja template context.你只需要最外面的集合......里面的一切都已经在 Jinja 模板上下文中了。 Rather than:而不是:

loop: "{{ lookup('file', '{{ bayfile.yml }}') }}"

You would write:你会写:

loop: "{{ lookup('file', 'bayfile.yml') }}"

Convert data to YAML将数据转换为 YAML

Lastly, when you use a file lookup like that, the result is simply a string (the contents of the file).最后,当您使用这样的file查找时,结果只是一个字符串(文件的内容)。 You want to de-serialize that into Ansible data structures, so you'll need the from_yaml filter:您想将其反序列化为 Ansible 数据结构,因此您需要from_yaml过滤器:

loop: "{{ lookup('file', 'bayfile.yml')  | from_yaml }}"

Putting that all together, we get something like this:把所有这些放在一起,我们得到这样的东西:

- hosts: localhost
  gather_facts: false

  tasks:
    - name: Create server profile
      debug:
        msg:
          - "{{ item.Bay }}"
          - "{{ item.Profilename }}"
      loop: "{{ lookup('file', 'bayfile.yml') | from_yaml }}"

Using include_vars使用 include_vars

Note that instead of using the file lookup and the from_yaml filter, you could use an include_vars task in your playbook.请注意,您可以在 playbook 中使用include_vars任务,而不是使用file查找和from_yaml过滤器。 You would first need to reformat your datafile so that it's a dictionary instead of a list, like this:您首先需要重新格式化您的数据文件,使其成为字典而不是列表,如下所示:

oneview_servers:
  - Bay: "ENT0005, bay 11"
    Profilename: "test_profile01"

  - Bay: "ENT0005, bay 12"
    Profilename: "test_profile02"

And then you could write your playbook like this:然后你可以这样写你的剧本:

- 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 }}"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM