Travis
Travis

Reputation: 444

Ansible - json parsing - "variable is not defined"

Environment:

Given an API response, I'm trying to grab the address, but getting "variable is not defined". Here's a playbook that has the API response as a var:

---

- name: test
  gather_facts: no
  hosts: localhost
  vars:
    pool_details: {
        "allow": "",
        "cache_control": "no-store, no-cache, must-revalidate",
        "changed": false,
        "connection": "close",
        "content_length": "668",
        "content_security_policy": "default-src 'self'  'unsafe-inline' 'unsafe-eval' data: blob:; img-src 'self' data:  http://127.4.1.1 http://127.4.2.1",
        "content_type": "application/json; charset=UTF-8",
        "cookies": {},
        "cookies_string": "",
        "date": "Tue, 24 Aug 2021 16:34:47 GMT",
        "elapsed": 0,
        "expires": "-1",
        "failed": false,
        "json": {
            "items": [
                {
                    "address": "10.200.136.22",
                    "connectionLimit": 0,
                    "dynamicRatio": 1,
                    "ephemeral": "false",
                    "fqdn": {
                        "autopopulate": "disabled"
                    },
                    "fullPath": "/Common/sensor01:443",
                    "generation": 103,
                    "inheritProfile": "enabled",
                    "kind": "tm:ltm:pool:members:membersstate",
                    "logging": "disabled",
                    "monitor": "default",
                    "name": "sensor01:443",
                    "partition": "Common",
                    "priorityGroup": 0,
                    "rateLimit": "disabled",
                    "ratio": 1,
                    "selfLink": "https://localhost/mgmt/tm/ltm/pool/~Common~sensor01/members/~Common~sensor01:443?ver=16.1.0",
                    "session": "monitor-enabled",
                    "state": "up"
                }
            ],
            "kind": "tm:ltm:pool:members:memberscollectionstate",
            "selfLink": "https://localhost/mgmt/tm/ltm/pool/~Common~sensor01/members?ver=16.1.0"
        },
        "msg": "OK (668 bytes)",
        "pragma": "no-cache",
        "redirected": false,
        "server": "Jetty(9.2.22.v20170606)",
        "status": 200,
        "strict_transport_security": "max-age=16070400; includeSubDomains",
        "x_content_type_options": "nosniff",
        "x_frame_options": "SAMEORIGIN",
        "x_xss_protection": "1; mode=block"
    }
  tasks:
    - debug:
        var: pool_details

    - debug:
        var: pool_details.json.items[0].address

The full error, with verbosity enabled is:

pool_details.json.items[0].address: 'VARIABLE IS NOT DEFINED!: builtin_function_or_method object has no element 0'

My second debug to grab the address isn't working ("not defined"), & I can't figure out why. If I take the same json, & pipe it to jq, it works just fine:

pbpaste | jq '.json.items[0].address'
"10.200.136.22"

Upvotes: 1

Views: 1189

Answers (2)

Vladimir Botka
Vladimir Botka

Reputation: 68189

If there are more items in the list you might want to use json_query, e.g.

    - set_fact:
        list_address: "{{ pool_details.json['items']|
                          json_query('[].address') }}"

gives

  list_address:
  - 10.200.136.22

If you don't want to, or can't, install JmesPath, the next option would be map attribute, e.g. the code below gives the same result

    - set_fact:
        list_address: "{{ pool_details.json['items']|
                          map(attribute='address')|
                          list }}"

Upvotes: 1

sborsky
sborsky

Reputation: 561

items is a Python dictionary method.

To return the value to the key "items":

- debug:
    var: pool_details.json['items'][0].address

Upvotes: 1

Related Questions