Read the file into a dictionary
- ansible.builtin.include_vars:
file: dir.yml
name: arch
gives
arch:
aarch64:
alpine:
update: null
version: 3.14.0
x86_64:
alpine:
update: null
version: 3.14.0
Update the dictionary
- ansible.builtin.set_fact:
arch: "{{ arch|combine({'x86_64': _x86_64}) }}"
vars:
_update: "{{ arch.x86_64.alpine.version is version(new_version, '<') }}"
_x86_64_alpine: "{{ arch.x86_64.alpine|combine({'update': _update}) }}"
_x86_64: "{{ arch.x86_64|combine({'alpine': _x86_64_alpine}) }}"
gives
arch:
aarch64:
alpine:
update: null
version: 3.14.0
x86_64:
alpine:
update: true
version: 3.14.0
and rewrite the file
- ansible.builtin.copy:
dest: dir.yml
content: |-
{% for k,v in arch.items() %}
{{ k }}:
{{ v|to_nice_yaml }}
{% endfor %}
gives
shell> cat dir.yml
x86_64:
alpine:
update: true
version: 3.14.0
aarch64:
alpine:
update: null
version: 3.14.0
Notes
The empty values of attribute update will be replaced by 'null'. This shouldn't be a problem because 'null' translates to boolean 'false' in YAML.
The values of updated attributes update will be replaced either by 'true' or 'false'.
The tasks are idempotent as a result of the previous two notes.
You might want to update more items. For example, given the variable
new_version:
x86_64: 3.15.0
aarch64: 3.14.0
The task below updates the dictionary
- ansible.builtin.set_fact:
arch: "{{ arch|combine({item: _arch}) }}"
loop: "{{ new_version.keys()|list }}"
vars:
_update: "{{ arch[item].alpine.version is version(new_version[item], '<') }}"
_arch_alpine: "{{ arch[item].alpine|combine({'update': _update}) }}"
_arch: "{{ arch[item]|combine({'alpine': _arch_alpine}) }}"
gives
arch:
aarch64:
alpine:
update: false
version: 3.14.0
x86_64:
alpine:
update: true
version: 3.14.0
I have also added a new field to the directory called "version_new" to update the field with new available version
. Open a new question and make it mre.