-2

I have a YAML values file and I want to update the particular value of a dictionary based on its key via Ansible playbooks.

input.yaml

operator:
  operator:
    replicaCount: 1
    env:
      - name: namespace1
        value: abc
      - name: namespace2
        value: xyz
    resources:
      requests:
        cpu: 200m
        memory: 256Mi
        ephemeral-storage: 500Mi
  console:
    replicaCount: 1

I want update the value of namespace1 as test under env array in the input.yaml.

Expected Result in input.yaml

operator:
  operator:
    replicaCount: 1
    env:
      - name: namespace1
        value: test
      - name: namespace2
        value: xyz
    resources:
      requests:
        cpu: 200m
        memory: 256Mi
        ephemeral-storage: 500Mi
  console:
    replicaCount: 1
Zeitounator
  • 38,476
  • 7
  • 53
  • 66
  • Does [How to replace a value of dictionary based on a key condition in values.yaml via Ansible playbook?](https://stackoverflow.com/a/76724470/6771046) answer your question? – U880D Jul 20 '23 at 15:31
  • Hi @U880D, Thanks for your comment. But the solution for the above link doesn't fulfill completely. Actually, I posted both the questions. :) From that solution, am not able to replace the updated dictionary in input.yaml – Sharanya M Jul 20 '23 at 15:35
  • Since it answer the question for me, what doesn't fulfill it for you? Are there any question regarding the solution? "_not able to replace the updated dictionary in `input.yaml`_", does this mean you want to edit or update a text file? – U880D Jul 20 '23 at 15:40
  • Yes, I want to update a particular namespace value in env array in the **input.yaml** file. I want the updated file completely. – Sharanya M Jul 20 '23 at 15:50

1 Answers1

3

According your description I wonder if you could use the update_fact module – Update currently set facts? It is intended for updating variables and one of the documented Examples seems to be similar to yours.

Based on the former (or already) given answer and Ansible: How to update or change a value in a nested dictionary?, a minimal example playbook

---
- hosts: localhost
  become: false
  gather_facts: false

  tasks:

  - include_vars:
      file: input.yaml
      name: input

  - ansible.utils.update_fact:
      updates:
        - path: input.operator.operator.env[0]
          value: { name: namespace1, value: test}
    register: updated

  - debug:
      var: updated

  - copy:
      dest: output.yaml
      content: "{{ updated.input | to_nice_yaml(indent=2) }}"

will result into the requested output.yaml file

operator:
  console:
    replicaCount: 1
  operator:
    env:
    - name: namespace1
      value: test
    - name: namespace2
      value: xyz
    replicaCount: 1
    resources:
      requests:
        cpu: 200m
        ephemeral-storage: 500Mi
        memory: 256Mi

Please take note that even if using update_fact module – Update currently set facts

Variables are not modified in place, instead they are returned by the module.

and that is the expected behavior.

Further Q&A

U880D
  • 8,601
  • 6
  • 24
  • 40
  • One doubt - Instead of hard coding the 0th index (- path: input.operator.operator.env[0]), can we loop the env array in update_fact utils – Sharanya M Jul 20 '23 at 17:29
  • "_can we loop the `env` array in `update_fact` utils_", on such I haven't worked yet, therefore, I don't know at the moment. – U880D Jul 20 '23 at 17:31
  • okay, I just tried with env (-path: valuesFile.operator.operator.env), it is replacing the entire env array. It means it removes all other values. Do you know any way to append as new entry in existing env array – Sharanya M Jul 20 '23 at 17:42
  • Are you like to append an additional new key:value and not updating an existing one? But then you have two keys with the same name and different values. – U880D Jul 20 '23 at 18:44
  • Yes, tried and not possible. And looping with items won't support for update_fact... We can't give item from a loop to "path" attribute – Sharanya M Jul 20 '23 at 19:04