In theory Ansible should be declarative and have full control over the systems we touch with it.
In practice, this is unfortunately not always the case.
This combination of tasks loads a given yaml file from the remote host, combine
s a “overwrite dict” onto it, and writes the file back to disk.
- name: Load yaml file contents as fact
ansible.builtin.slurp:
src: /etc/some-file.yaml
register: yaml_file
- name: Parse yaml file contents
ansible.builtin.set_fact:
yaml_file_content: "{{ yaml_file.content | b64decode | from_yaml }}"
- name: Create the keys/values that should be overwritten
ansible.builtin.set_fact:
yaml_file_content_overwrite:
some:
key: "Overwrite value"
another: "Also overwritten"
- name: Write yaml file with changed values
ansible.builtin.copy:
content: "{{ yaml_file_content | combine(yaml_file_content_overwrite, recursive=true) | to_yaml }}"
dest: /etc/some-file.yaml
Info
I like keeping my learning public. The below is my very old and naive solution I did based on regex.
With this nifty task we can replace the value of a key (given as yaml_key
) to a new value (given as new_value
) while preserving it’s indentation.
- name: Replace values in YAML file while keeping their indentation
lineinfile:
backup: true
backrefs: true
state: present
path: foo.yaml
regexp: '^(\s*){{ yaml_key }}:.*'
line: '\1{{ yaml_key }}: {{ new_value }}'