Search code examples
ansiblejinja2

Problem with map when the key does not exist


I have a var_file with this format:

bds_info:

  - id:   BD1
    db_name: BD1
    db_port: XXXX
    server: server1
    repo_url: repo1

  - id:   BD2
    db_name: BD2
    db_port: XXXX
    server: server2
    repo_url: repo2
    scan_name: scan2

What I'm trying to do is to select the scan_name from the var_file into a variable like this:

var_scan_name_to_use:       "{{ (bds_info   | selectattr('id', 'equalto', (db_name|upper) ) | map(attribute='scan_name') | join) }}"

it works correctly if the id selected has the key but if it hasn't then I get the following error:

{
    "msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'scan_name
}

Is it possible to return undefined instead of a lookup error?


Solution

  • You can specify a default value to use if an object in the list does not have the given attribute.

    {{ users|map(attribute="username", default="Anonymous")|join(", ") }}
    

    Source: https://jinja.palletsprojects.com/en/2.11.x/templates/#map


    So, given the task:

    - debug:
        msg: >-
          {{
            bds_info
              | selectattr('id', 'equalto', db_name | upper)
              | map(attribute='scan_name', default='undefined')
              | join
          }}
      vars:
        db_name: BD1
        bds_info:
          - id: BD1
            db_name: BD1
            db_port: XXXX
            server: server1
            repo_url: repo1
          - id: BD2
            db_name: BD2
            db_port: XXXX
            server: server2
            repo_url: repo2
            scan_name: scan2
    
    

    This yields:

    ok: [localhost] => 
      msg: undefined