ansible

how to create a list of dicts, based on a list of strings?


I am struggling with Ansible data transformation. Would need to create a list of dicts - for haproxy config - out of a list of hostnames. For example

backends:
  - web1
  - web2
  - web3

This is a plain simle list of hostnames. I would need to convert it into a list of dicts, like this:

backends_dict:
  - name: web1
    address: web1:80
  - name: web2
    address: web2:80
  - name: web3
    address: web3:80

I tried using map, dict, zip and combine filters in all combinations I could think of, also tried to get help from ChatGPT, but its all possible solution went into error. I think there must be a simple way to achieve this.


Solution

  • Create a list of addresses

      _port: 80
      address: "{{ backends | product([_port]) | map('join', ':') }}"
    

    gives

      address:
        - web1:80
        - web2:80
        - web3:80
    

    Create a dictionary

      backends_dict: "{{ dict(backends | zip(address)) }}"
    

    gives

      backends_dict:
        web1: web1:80
        web2: web2:80
        web3: web3:80
    

    You can convert it to a list

    backends_list: "{{ backends_dict | dict2items(key_name='name',
                                                  value_name='address') }}"
    

    gives what you want

      backends_list:
        - address: web1:80
          name: web1
        - address: web2:80
          name: web2
        - address: web3:80
          name: web3
    

    Example of a complete playbook for testing

    - hosts: localhost
    
      vars:
    
        backends: [web1, web2, web3]
        port: 80
        address: "{{ backends | product([port]) | map('join', ':') }}"
        backends_dict: "{{ dict(backends | zip(address)) }}"
        backends_list: "{{ backends_dict | dict2items(key_name='name',
                                                       value_name='address') }}"
    
      tasks:
    
        - debug:
            var: address
    
        - debug:
            var: backends_dict
    
        - debug:
            var: backends_list