Search code examples
ansiblejinja2

Ansible change all dict key values only by filters


I have an ansible dict like

ports:
  webui: 7200
  webadmin: 7209
  core_api: 7201
  stock_api: 7204
  import_export: 7207

And i want to transform all keys in it, like

ports:
  staging-webui: 7200
  staging-webadmin: 7209
  staging-core_api: 7201
  staging-stock_api: 7204
  staging-import_export: 7207

I do that in 'vars' section, so i can't use 'set_fact' with 'with_items' to iterate over dict. Is it possible to it only by filters?

I found working answer,

env: staging # comes from outside

regex_env: "\"key\": \"{{ env }}-\\1\""
app_upstreams: "{{ ports | dict2items | map('to_json') | map('regex_replace', '\"key\":\\s\"(.*)\"', lookup('vars', 'regex_env')) | map('from_json') }}"

but it looks really ugly, is there more good-looking solution?


Solution

  • For example, the playbook below

    - hosts: localhost
      vars:
        env: staging_
        ports:
          webui: 7200
          webadmin: 7209
          core_api: 7201
          stock_api: 7204
          import_export: 7207
        env_ports_keys: "{{ [env]|product(ports.keys()|list)|map('join') }}"
        env_ports_vals: "{{ ports.values()|list }}"
        env_ports: "{{ dict(env_ports_keys|zip(env_ports_vals)) }}"
      tasks:
        - debug:
            var: env_ports
    

    gives (abridged)

      env_ports:
        staging_core_api: 7201
        staging_import_export: 7207
        staging_stock_api: 7204
        staging_webadmin: 7209
        staging_webui: 7200
    

    To simplify the code, you can create a custom filter

    shell> cat filter_plugins/dict_utils.py
    def prefix_key(d, prefix='prefix'):
        temp = {}
        for key in d.keys():
            temp[prefix + key] = d[key]
        return temp
    
    
    class FilterModule(object):
        ''' utility filters for operating on dictionary '''
        def filters(self):
            return {
                'prefix_key': prefix_key,
            }
    

    The playbook below gives the same result

    - hosts: localhost
      vars:
        env: staging_
        ports:
          webui: 7200
          webadmin: 7209
          core_api: 7201
          stock_api: 7204
          import_export: 7207
        env_ports: "{{ ports|prefix_key(prefix=env) }}"
      tasks:
        - debug:
            var: env_ports