Home > Enterprise >  Dictionary value access using ansible
Dictionary value access using ansible

Time:09-24

I have a situation where we have 2 dictionary defined in ansible role default and the selection of dictionary is based of an input variable. I want to set the fact with one of the dict's specific key value.

Below is the example code:

test.yml paybook content:

- hosts: localhost
  gather_facts: true
  roles:
    - role1
  tags: ['role1']

roles/role1/tasks/main.yml content:

- name: set fact
  set_fact:
    node_vip: "{% if node_vip_run == 'no' %}node_vip_no{% elif node_vip_run == 'yes' %}node_vip_yes{% endif %}"

- debug:
    var: node_vip
    verbosity: 1

- debug:
    var: "{{ node_vip }}.ece_endpoint"
    verbosity: 1

- name: set fact
  set_fact:
    ece_endpoint_fact: "{{ node_vip[ece_endpoint] }}"

- debug:
    var: ece_endpoint
    verbosity: 1

roles/role1/defaults/main.yml content:

node_vip_yes:
  ece_endpoint: "https://1.1.1.1:8080"
  cac_endpoint: "https:2.2.2.2:8080"
node_vip_no:
  ece_endpoint: "http://3.3.3.3:8080"
  cac_endpoint: "http:4.4.4.4:8080"

Run playbook:

ansible-playbook test.yaml --extra-vars 'node_vip_run=no' -v

The set fact of variable "ece_endpoint_fact" should have value "https://1.1.1.1:8080 OR http://3.3.3.3:8080" depending on the parameter input in ansible command. But I keep on getting below error:

TASK [role1 : set fact] *******************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'unicode object' has no attribute u'http://3.3.3.3:8080'\n\nThe error appears to be in '/root/roles/role1/tasks/main.yml': line 46, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: set fact\n  ^ here\n"}

Please suggest what needs to be done to resolve this.

Thanks

CodePudding user response:

Right now, you set node_vip to either the literal string "node_vip_no" or "node_vip_yes". But if you change it to do {{ node_vip_no }} / {{ node_vip_yes }}, then node_vip will have the value of the variable node_vip_no / node_vip_yes instead of being a literal string.

- name: set fact
  set_fact:
    node_vip: "{% if node_vip_run == 'no' %}{{ node_vip_no }}{% elif node_vip_run == 'yes' %}{{ node_vip_yes }}{% endif %}"

This will have node_vip's value be something like:

TASK [debug] ***************************************************************
ok: [localhost] => {
    "node_vip": {
        "cac_endpoint": "https:2.2.2.2:8080",
        "ece_endpoint": "https://1.1.1.1:8080"
    }
}

Then in your other set_fact, it should work if you put quotes around the property name:

- name: set fact
  set_fact:
    ece_endpoint_fact: "{{ node_vip['ece_endpoint'] }}"
#                     Added quotes  ^            ^
  • Related