ansiblezabbixzabbix-api

How to convert a list into a dictionary?


I can't reuse the content of a variable for two different parameters. (host_groups and tags). (Documentation here)

I have a variable in this form :

probe:
  - name: prob1
    groups:
      - group1
      - group2
  - name: prob2
    groups:
      - group1
      - group3

Then, I have a task that loops for each probes that works well.

- name: Probe
  community.zabbix.zabbix_host:
    host_name: "{{ item.name }}"
    host_groups: "{{ item.groups }}"
  loop: "{{ zabbix_sensor }}"

But I would like to add the values I have in the groups variable in the tags parameter of my task.

- name: Probe
  community.zabbix.zabbix_host:
    host_name: "{{ item.name }}"
    host_groups: "{{ item.groups }}"
    tags: "{{ item.groups }}"
  loop: "{{ zabbix_sensor }}"

This doesn't work because it expects the key in the following format - tag: {{value}}. I don't want to create another tag variable containing the same values as groups because the values will be identical.

The result for this to work would be something like :

- name: Probe
  community.zabbix.zabbix_host:
    host_name: probe1
    host_groups: ['group1','group2']
    tags:
      - tag: group1
      - tag: group2

Any idea how to get there?

I've tried a lot of things, but I can't get my result


Solution

  • Use the filter community.general.dict_kv to create the dictionary. For example, given the list

      l: 
        - group1
        - group2
    

    declare the dictionary

      d: "{{ l|map('community.general.dict_kv', 'tag') }}"
    

    gives

      d:
        - tag: group1
        - tag: group2
    

    Example of a complete playbook for testing

    - hosts: localhost
    
      vars:
    
        zabbix_sensor:
          - name: prob1
            groups:
              - group1
              - group2
          - name: prob2
            groups:
              - group1
              - group3
    
      tasks:
    
        - debug:
            msg: |
              host_name: {{ item.name }}
              host_groups: {{ item.groups }}
              tags: {{ item.groups|map('community.general.dict_kv', 'tag') }}
          loop: "{{ zabbix_sensor }}"
    

    gives (abridged)

    TASK [debug] *********************************************************************************
    ok: [localhost] => (item={'name': 'prob1', 'groups': ['group1', 'group2']}) => 
      msg: |-
        host_name: prob1
        host_groups: ['group1', 'group2']
        tags: [{'tag': 'group1'}, {'tag': 'group2'}]
    ok: [localhost] => (item={'name': 'prob2', 'groups': ['group1', 'group3']}) => 
      msg: |-
        host_name: prob2
        host_groups: ['group1', 'group3']
        tags: [{'tag': 'group1'}, {'tag': 'group3'}]
    

    Q: "Have a tag with name and value."

    A: Concatenate the lists

        - debug:
            msg: |
              host_name: {{ item.name }}
              host_groups: {{ item.groups }}
              tags: |
                {{ _tags|to_nice_yaml(indent=2)|indent(2) }}
          loop: "{{ zabbix_sensor }}"
          vars:
            _tags: "{{ item.groups|map('community.general.dict_kv', 'tag') +
                       [{'tag': 'name', 'value': item.name}] }}"
    

    gives

    TASK [debug] *********************************************************************************
    ok: [localhost] => (item={'name': 'prob1', 'groups': ['group1', 'group2']}) => 
      msg: |-
        host_name: prob1
        host_groups: ['group1', 'group2']
        tags: |
          - tag: group1
          - tag: group2
          - tag: name
            value: prob1
    ok: [localhost] => (item={'name': 'prob2', 'groups': ['group1', 'group3']}) => 
      msg: |-
        host_name: prob2
        host_groups: ['group1', 'group3']
        tags: |
          - tag: group1
          - tag: group3
          - tag: name
            value: prob2
    

    Q: "For groups, I don't need a value, but in some cases I do."

    A: In the example below, any list will be converted to tags only and any other type, expecting a hash, will be converted to the tag and value

    - hosts: localhost
    
      vars:
    
        zabbix_sensor:
          - name: prob1
            attr1: A
            attr2: B
            groups:
              - group1
              - group2
            regions:
              - r1
              - r2
          - name: prob2
            attr1: C
            attr2: D
            groups:
              - group1
              - group3
            regions:
              - r3
              - r4
    
      tasks:
    
        - debug:
            msg: |
              host_name: {{ item.name }}
              host_groups: {{ item.groups }}
              tags: |
                {{ _tags|to_nice_yaml(indent=2)|indent(2) }}
          loop: "{{ zabbix_sensor }}"
          vars:
            _tags_str: |-
              {% for k,v in item.items() %}
              {% if v|type_debug == 'list' %}
              {% for i in v %}
              - tag: {{ i }}
              {% endfor %}
              {% else %}
              - tag: {{ k }}
                value: {{ v }}
              {% endif %}
              {% endfor %}
            _tags: "{{ _tags_str|from_yaml }}"
    

    gives (abridged)

    TASK [debug] *********************************************************************************
    ok: [localhost] => (item={'name': 'prob1', 'attr1': 'A', 'attr2': 'B', 'groups': ['group1', 'group2'], 'regions': ['r1', 'r2']}) => 
      msg: |-
        host_name: prob1
        host_groups: ['group1', 'group2']
        tags: |
          - tag: name
            value: prob1
          - tag: attr1
            value: A
          - tag: attr2
            value: B
          - tag: group1
          - tag: group2
          - tag: r1
          - tag: r2
    ok: [localhost] => (item={'name': 'prob2', 'attr1': 'C', 'attr2': 'D', 'groups': ['group1', 'group3'], 'regions': ['r3', 'r4']}) => 
      msg: |-
        host_name: prob2
        host_groups: ['group1', 'group3']
        tags: |
          - tag: name
            value: prob2
          - tag: attr1
            value: C
          - tag: attr2
            value: D
          - tag: group1
          - tag: group3
          - tag: r3
          - tag: r4