I have a values.yaml
file and I want to update the particular value of a dictionary based on its key.
For Example
input.yaml
env:
- name: "namespace1"
value: "abc"
- name: "namespace2"
value: "ijk"
Expected Result to be updated in the same input.yaml
env:
- name: "namespace1"
value: "xyz"
- name: "namespace2"
value: "ijk"
only if the key is namespace1
, its value should be as xyz
from abc
Updated input.yaml
operator:
operator:
replicaCount: 1
env:
- name: namespace1
value: abc
resources:
requests:
cpu: 200m
memory: 256Mi
ephemeral-storage: 500Mi
console:
replicaCount: 1
Here is a self explanatory playbook with intermediate step debugging
Example file structure:
$ tree
.
├── input.yml
└── test.yml
0 directories, 2 files
input.yaml
before running playbook
env:
- name: namespace1
value: abc
- name: namespace2
value: ijk
test.yml
playbook:
---
- name: Make sure var file contains what we expect
hosts: localhost
gather_facts: false
vars:
inputf: input.yml
env_as_dict: "{{ env | items2dict(key_name='name') }}"
env_as_dict_transformed: "{{ env_as_dict | combine({'namespace1': 'xyz'}) }}"
env_as_transformed_list: "{{ env_as_dict_transformed | dict2items(key_name='name') }}"
vars_files:
- "{{ inputf }}"
tasks:
- name: Convert original env var from a list of key/value pairs to a dict
ansible.builtin.debug:
var: env_as_dict
- name: Combine resulting dict with expected value
ansible.builtin.debug:
var: env_as_dict_transformed
- name: Convert the transformed dict back to a list
ansible.builtin.debug:
var: env_as_transformed_list
- name: Write the content back to original file
# Note: this works because we target localhost only
# `delegate_to: localhost` and `run_once: true`
# for a play targeting multiple non local hosts.
vars:
fcontent:
env: "{{ env_as_transformed_list }}"
ansible.builtin.copy:
dest: "{{ inputf }}"
content: "{{ fcontent | to_nice_yaml }}"
which gives as a result
$ ansible-playbook test.yml
PLAY [Make sure var file contains what we expect] ***********************************************************************************
TASK [Convert original env var from a list of key/value pairs to a dict] ************************************************************
ok: [localhost] => {
"env_as_dict": {
"namespace1": "abc",
"namespace2": "ijk"
}
}
TASK [Combine resulting dict with expected value] ***********************************************************************************
ok: [localhost] => {
"env_as_dict_transformed": {
"namespace1": "xyz",
"namespace2": "ijk"
}
}
TASK [Convert the transformed dict back to a list] **********************************************************************************
ok: [localhost] => {
"env_as_transformed_list": [
{
"name": "namespace1",
"value": "xyz"
},
{
"name": "namespace2",
"value": "ijk"
}
]
}
TASK [Write the content back to original file] **************************************************************************************
changed: [localhost]
PLAY RECAP **************************************************************************************************************************
localhost : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
And the content of input.yml
after running the playbook is
env:
- name: namespace1
value: xyz
- name: namespace2
value: ijk
Note that running the playbook again will report OK
on the last task as the content of the file will already be aligned with what is expected.