Search code examples
jsonansiblejson-query

Ansible : How to split json data with some seperator in json_query


Im making some ansible playbook to output json data.

I got json data through uri module. I saved the data as a variable and even managed to extract the desired array with json_query.

---
- name: get lti id
  hosts: web
  become: yes

  tasks:
  - name : "get lti"
    
    ...

  - name : "print returned json"
    debug:
            var: data.json

  - name : "write var to file"
    copy:
            content: " {{ data.json | json_query('[*].{id:id, url:url}') | to_nice_json }}"
            dest: "/data/test.json"

and my result json file is below one.


 [
    {
        "id": 7,
        "url": "https://template.com/test/lti/admin/policy/red"
    },
    {
        "id": 8,
        "url": "https://template.com/test/lti/admin/blue"
    },
    {
        "id": 10,
        "url": "https://template.com/test/lti/yellow"
    }
]


But I'd like to additionally extract only the last part of the url here. ex) red, blue

so I tried to change my playbook like this

---
- name: get lti id
  hosts: web
  become: yes

  tasks:

    ...

  - name : "print returned json"
    debug:
            var: data.json

  - name : "write var to file"
    copy:
            content: " {{ data.json | json_query('[*].{id:id, url:url}')| url.split('/')[-1] | to_nice_json }}"
            dest: "/data/test.json"

but this makes fatal error

TASK [write var to file] ******************************************************************************************************** fatal: [lms-web-template]: FAILED! => {"msg": "template error while templating string: expected token 'end of print statement', got '['. String: {{ data.json | json_query('[*].{id:id, url:url}') | url.split('/')[-1] | to_nice_json }}"}

I want to get the result like below.


 [
    {
        "id": 7,
        "url": "red"
    },
    {
        "id": 8,
        "url": "blue"
    },
    {
        "id": 10,
        "url": "yellow"
    }
]

I need your help... Thank you :)


Solution

  • Modify the list in a standalone task. For example

        - set_fact:
            content2: "{{ content2|default([]) + [item|combine({'url':url})] }}" 
          loop: "{{ content }}"
          vars:
            url: "{{ item.url.split('/')|last }}"
        - copy:
            content: "{{ content2|to_nice_json }}"
            dest: data.json
    

    gives

    shell> cat data.json 
    [
        {
            "id": "7,",
            "url": "red"
        },
        {
            "id": "8,",
            "url": "blue"
        },
        {
            "id": "10,",
            "url": "yellow"
        }
    ]
    

    The next option is the modification of the data in Jinja. For example

        - copy:
            content: |
              {% for item in content %}
              - id: {{ item.id }}
                url: {{ item.url.split('/')|last }}
              {% endfor %}
            dest: data.yml
        - debug:
            msg: "{{ lookup('file', 'data.yml')|from_yaml|to_nice_json }}"
    

    gives

        [
            {
                "id": "7,",
                "url": "red"
            },
            {
                "id": "8,",
                "url": "blue"
            },
            {
                "id": "10,",
                "url": "yellow"
            }
        ]