4

I'm trying to get the value of an attribute in a json array with Ansible. Example data:

"domains.json.data": [
        {
            "axfr_ips": [],
            "description": "",
            "domain": "mydomain.net",
            "expire_sec": 0,
            "group": "",
            "id": 687088,
        },
        {
            "axfr_ips": [],
            "description": "",
            "domain": "myotherdomain.net",
            "expire_sec": 0,
            "group": "",
            "id": 687089,
        }
    ]
}

So I tried with json query:

"{{ domains.json.data | json_query(\"data[?domain=='{{ server_domain }}'].id\") }}"

or with:

- set_fact:
    domain_id: "{{ domains | json_query(query) | first }}"
  vars:
    query: "domains.json[?name=='{{ server_domain }}'].id"

Also tried with selectattrib:

"{{ linode_domains.json.data | selectattr(\"domain\", \"{{ server_domain }}\") | list }}"

So what I need is to get the id of the domain I got in {{ server_domain }}.

1
  • What's the data you'd want from this example? ["mydomain.net", "myotherdomain.net"]? Commented Oct 3, 2019 at 1:55

2 Answers 2

4

The query can't work because there is no attribute name in the dictionary

        query: "domains.json[?name=='{{ server_domain }}'].id"

Use the attribute domain. For example the task below

    - debug:
        msg: "{{ domains.json.data|json_query(query) }}"
      vars:
        server_domain: 'mydomain.net'
        query: "[?domain=='{{ server_domain }}'].id"

gives

    "msg": [
        687088
    ]

Notes

  • json_query returns a list.
  • use filter first to get the first element of a list
        msg: "{{ domains.json.data|json_query(query)|first }}"
Sign up to request clarification or add additional context in comments.

1 Comment

Added '| first' so I don't get an array with 1 element (id is unique), tx!
3

You can use selectattr to filter and use map to get the id value. Below is the sample you can try.

- name: Retrieve value from JSON array
  debug:
    msg: "{{ test.domains | selectattr('domain', 'equalto', server_domain) | map(attribute='id') | join(',') }}"

As map returns list, I have used join to convert to string.

I have set server_domain value to myotherdomain.net for testing.

Below is the output of the command

TASK [Retrieve value from JSON array] **************************
ok: [localhost] => {
    "msg": "687089"
}

EDIT: equalto was introduced in v2.8 of jinja2. If you get TemplateRuntimeError: no test named 'equalto', update the jinja2.

To check version use pip list | grep Jinja2. To update use following command pip install --upgrade Jinja2.

2 Comments

This still throws me 'TemplateRuntimeError: no test named 'equalto'' ... 'Unexpected failure during module execution.'
@willemdh equalto was introduced in v2.8 of jinja2. So you need to update jinja2. To check version use "pip list | grep Jinja2". Try the following command to update "pip install --upgrade Jinja2". I have updated the answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.