Search code examples
dictionaryansible

Ansible. getting empty list as trying to access a value stored in a ansible dictionary


I have the following main playbook

- hosts: localhost

  vars_files:
    - ../vars/environment-mapping.yml

  tasks:

    - name: echo and register controller's ip
      ansible.builtin.shell:
        cmd: |
          echo "$(hostname -I)" | sed 's/\s*$//'

      register: bash_echoed__controller_ip


    - name: set controller_ip_stringified
      set_fact:
        controller_ip: "{{ bash_echoed__controller_ip.stdout }}"


    - name: set environment
      set_fact:
        environment: "{{ controller_ip_environment_map[controller_ip] | default('unknown') }}"


    - name: show debug
      debug:
        msg:
          - "controller_ip_environment_map: {{ controller_ip_environment_map }}"
          - "controller_ip: {{ controller_ip }}"
          - "environment: {{ environment }}"

and the vars_file ../vars/environment-mapping.yml

---

controller_ip_environment_map: {
  "XX.XXX.X.Y": "DEV",
  "XX.XXX.X.W": "TEST",
  "XX.XXX.X.Z": "PROD",
}

when I run the playbook, I get

- localhost on hosts: localhost -
Gathering Facts...
  localhost ok
echo and register controller's ip...
  localhost done | stdout: XX.XXX.X.Y
set controller_ip_stringified...
  localhost ok
set environment...
  localhost ok
show debug...
  localhost ok: {
    "changed": false,
    "msg": [
        "controller_ip: XX.XXX.X.Y",
        "controller_ip_environment_map: {'XX.XXX.X.Y': 'DEV', 'XX.XXX.X.W': 'TEST', 'XX.XXX.X.Z': 'PROD'}",
        "environment: []",

    ]
}

But since XX.XXX.X.Y is a key of controller_ip_environment_map, I expected environment to get the value DEV, while it gets the walue of empty list.

Why does it happen?


Solution

  • Renaming the variable environment (e.g. to machines_envronment) fixed the issue.

    As indicated by @U880D, environment is a playbook keyword (See Creating valid variable names: "Not valid: playbook keywords such as environment")

    From ansible documentation about playbook keywords:

    This (i.e. environment) can ONLY be used with modules. This is not supported for any other type of plugins nor Ansible itself nor its configuration, it just sets the variables for the code responsible for executing the task

    details

    - hosts: localhost
    
      vars_files:
        - ../vars/environment-mapping.yml
    
      tasks:
    
        - name: echo and register controller's ip
          ansible.builtin.shell:
            cmd: |
              echo "$(hostname -I)" | sed 's/\s*$//'
    
          register: bash_echoed__controller_ip
    
    
        - name: set controller_ip_stringified
          set_fact:
            controller_ip: "{{ bash_echoed__controller_ip.stdout }}"
    
    
        - name: set machines_environment
          set_fact:
            machines_environment: "{{ controller_ip_environment_map[controller_ip] | default('unknown') }}"
    
    
        - name: show debug
          debug:
            msg:
              - "controller_ip_environment_map: {{ controller_ip_environment_map }}"
              - "controller_ip: {{ controller_ip }}"
              - "machines_environment: {{ machines_environment }}"
    

    - localhost on hosts: localhost -
    Gathering Facts...
      localhost ok
    echo and register controller's ip...
      localhost done | stdout: XX.XXX.X.Y
    set controller_ip_stringified...
      localhost ok
    set environment...
      localhost ok
    show debug...
      localhost ok: {
        "changed": false,
        "msg": [
            "controller_ip: XX.XXX.X.Y",
            "controller_ip_environment_map: {'XX.XXX.X.Y': 'DEV', 'XX.XXX.X.W': 'TEST', 'XX.XXX.X.Z': 'PROD'}",
            "environment: DEV",
    
        ]
    }