Videos
Not a direct answer to your question about the error with modify_json but a working solution.
I would go with jq for that. jq is a lightweight and flexible command-line JSON processor and available for nearly every Linux distribution. When not, use the prebuilt binaries that come without dependencies.
As the website states:
jq is like sed for JSON data - you can use it to slice and filter and map and transform structured data with the same ease that sed, awk, grep and friends let you play with text.
I shrinked your play to a minimal working solution with the same result. The jq executable must be in the PATH of the system it is running on. Feel free to customize it to your needs.
---
- name: Sync Power Schedules From Database to Survey Spec
hosts: localhost
gather_facts: no
vars:
choices_key: ".spec[6].choices"
choices_value: "23:00-02:00\n02:00-04:00\n04:00-06:00\n00:00-04:00"
json_file: "{{playbook_dir}}/s.json"
tasks:
- name: "modify json"
command: >
jq "{{choices_key}}=\"{{choices_value}}\"" "{{json_file}}"
register: json
- debug:
var: json.stdout
I think this is more elegant as the solution with the extra json_modify.py module. For more information on jq please see the manual page.
There's just a couple of minor issues in your playbook
You are loading the json data from the file as a string, rather than json/dict. Instead of your command/cat task, use this to load the data in:
- set_fact: surveySpec: "{{ lookup('file', sharedDataPathFile) | from_json }}"The other problem you would have hit is you are attempting to update just the
choicesvalue (i.e. a string), rather than thechoicesdict item. Just a small change required in yourjson_modifypointer:- json_modify: data: "{{ surveySpec }}" pointer: "/spec/5" action: update update: "{{ new_choices }}" register: result
One other thing .. the array index is 5, not 6
There is no ansible json module for doing this. But you can use third-party modules like ansible-jsonpatch for this.
That is a simple case and you can use what @JGK has replied with, or you could just define a list and add those json elements to it. Without any modules!
i.e.:
- vars:
elem:
- {"firstname": "John", "lastname": "Smith", "user": "john"}
- {"firstname": "John", "lastname": "Smith", "user": "john"}
- {"firstname": "John", "lastname": "Smith", "user": "john"}
- set_fact:
my_list: []
- name: add to list
set_fact:
my_list: "{{ my_list + [item] }}"
loop: "{{ elem }}"
- debug:
msg: "{{ my_list }}"
- copy:
content: "{{ my_list }}"
dest: ./x.json
delegate_to: localhost
and here's the result validated with json python module or jq:
$ jq . x.json
[
{
"lastname": "Smith",
"user": "john",
"firstname": "John"
},
{
"lastname": "Smith",
"user": "john",
"firstname": "John"
},
{
"lastname": "Smith",
"user": "john",
"firstname": "John"
}
]
Python:
$ python -m json.tool x.json
[
{
"firstname": "John",
"lastname": "Smith",
"user": "john"
},
{
"firstname": "John",
"lastname": "Smith",
"user": "john"
},
{
"firstname": "John",
"lastname": "Smith",
"user": "john"
}
]