doctore
doctore

Reputation: 334

Convert a list to dictionary - Ansible YAML

I have a playbook, where I get an error message

fatal: [localhost]: FAILED! => {"ansible_facts": {"tasks": {}}, "ansible_included_var_files": [], "changed": false, "message": "/home/user/invoke_api/automation/tmp/task.yml must be stored as a dictionary/hash"}

task.yml

The file task.yml is dynamically created, and filtered all the time from another source to give the output below.

-   key: gTest101
    value:
        Comments: FWP - Testing this
        IP: 10.1.2.3
        Name: gTest101
-   key: gTest102
    value:
        Comments: FWP - Applying this
        IP: 10.1.2.4
        Name: gTest102

Question: How do I convert the list in my task.yml to a dictionary? What's the code to convert from list to dictionary

playbook.yml

---
- name: Global Objects
  hosts: check_point
  connection: httpapi
  gather_facts: False
  vars_files:
    - 'credentials/my_var.yml'
    - 'credentials/login.yml'
  tasks:
  - name: read-new-tmp-file
    include_vars:
      file: tmp/task.yml
      name: tasks
    register: new_host

  - name: add-host-object-to-group
    check_point.mgmt.cp_mgmt_host:
      name: "{{ item.value.Name | quote }}"          
      ip_address: "{{ item.value.IP | quote }}"      
      comments: "{{ item.value.Comments }}"
      groups: gTest1A
      state: present
      auto_publish_session: yes
    loop: "{{ new_host.dict | dict2items }}"  
    delegate_to: Global
    ignore_errors: yes


Ansible core 2.9.13 python version = 2.7.17

Upvotes: 2

Views: 6250

Answers (2)

Vladimir Botka
Vladimir Botka

Reputation: 68024

Q: "How do I convert the list in my task.yml to a dictionary?"

A: Use items2dict. For example, read the file and create the list

    - set_fact:
        l1: "{{ lookup('file', 'task.yml')|from_yaml }}"

gives

    l1:
      - key: gTest101
        value:
          Comments: FWP - Testing this
          IP: 10.1.2.3
          Name: gTest101
      - key: gTest102
        value:
          Comments: FWP - Applying this
          IP: 10.1.2.4
          Name: gTest102

Then, the task below

    - set_fact:
        d1: "{{ l1|items2dict }}"

creates the dictionary

  d1:
    gTest101:
      Comments: FWP - Testing this
      IP: 10.1.2.3
      Name: gTest101
    gTest102:
      Comments: FWP - Applying this
      IP: 10.1.2.4
      Name: gTest102

Upvotes: 1

idriss Eliguene
idriss Eliguene

Reputation: 897

A vars file is a yaml dict file, so your list have to be a fields of a vars:

my_vars:
  - Comments: FWP - Testing this
    IP: 10.1.2.3
    Name: gTest101
  - Comments: FWP - Applying this
    IP: 10.1.2.4
    Name: gTest102

and you dont need to register the include_vars tasks. Just loop on the list var name (here my_vars).

---
- name: Global Objects
  hosts: check_point
  connection: httpapi
  gather_facts: False
  vars_files:
    - 'credentials/my_var.yml'
    - 'credentials/login.yml'
  tasks:
  - name: read-new-tmp-file
    include_vars:
      file: tmp/task.yml

  - name: add-host-object-to-group
    check_point.mgmt.cp_mgmt_host:
      name: "{{ item.Name }}"          
      ip_address: "{{ item.IP }}"      
      comments: "{{ item.Comments }}"
      groups: gTest1A
      state: present
      auto_publish_session: yes
    loop: "{{ my_vars }}"  
    delegate_to: Global
    ignore_errors: yes

Upvotes: 1

Related Questions