[Ansible] How to json_query a key that contains a dot

Today I found myself needing to extract the value of a json key that contained a dot (‘.’). As usual, json_query to the rescue, except that it didn’t work, returning an empty value. With a little bit of digging and trial and error testing, the solution presented itself. The key is to enclose the json key in quotes and then escape them.

 

Here is an example json file:

{
	"menu": {
		"id": "file",
		"value": "File",
		"popup": {
			"dot.key": [{
					"value": "New",
					"onclick": "CreateNewDoc()"
				},
				{
					"value": "Open",
					"onclick": "OpenDoc()"
				},
				{
					"value": "Close",
					"onclick": "CloseDoc()"
				}
			]
		}
	}
}

 

And an example ansible playbook:

- name: json manipulation 
  gather_facts: no
  hosts: localhost
  vars:
    json_var: "{{ lookup('file', 'file.json') | from_json }}"
  tasks:
  - name: get "menu.item" from json
    set_fact:
      json_out: "{{ json_var | json_query('menu.popup.\"dot.key\"[].value') }}"

 

We can clearly see the result:

PLAY [json manipulation] ******************************************************************************************************************************************************************************************
META: ran handlers

TASK [get "menu.item" from json] **********************************************************************************************************************************************************************************
task path: /tmp/1/1.yaml:7
ok: [localhost] => {
    "ansible_facts": {
        "json_out": [
            "New", 
            "Open", 
            "Close"
        ]
    }, 
    "changed": false
}
META: ran handlers
META: ran handlers

PLAY RECAP ********************************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0   

 

PS: In this case we have 3x keys under “dot.key”. We obtain all of them in our result because we are selecting the whole dictionary ( ‘\”dot.key\”[]’ ) — notice the square brackets. We insert a number here and select the position of the key we want to get the value for. If for instance we would only need the 2nd key, we would use ‘\”dot.key\”[1]’ — “0” being the first value