Lester
Lester

Reputation: 1488

Ansible YAML append to list under a key (?)

I have the following role variable called groceries:

groceries:
  fruits:
    - name: 'Apples'
      cost: 100
    - name: 'Grapes'
      cost: 200
  vegetables:
    - name: 'Potatoes'
      cost: 120
  toiletries:
    - name: 'Toothpaste'
      cost: 20

These are used in a template.

Depending on the host and/or group, I want to append additional vegetables:

groceries_additional:
  vegetables:
    - brand: 'Aubergine'
      cost: 100

Or append fruits:

groceries_additional:
  fruits:
    - name: 'Blackberries'
      cost: 1000

I do not want to update the templates. Is there any way to append groceries_additional into groceries? This is my target result:

groceries:
  fruits:
    - name: 'Apples'
      cost: 100
    - name: 'Grapes'
      cost: 200
    - name: 'Blackberries'
      cost: 1000
  vegetables:
    - name: 'Potatoes'
      cost: 120
    - brand: 'Aubergine'
      cost: 100
  toiletries:
    - name: 'Toothpaste'
      cost: 20

I tried to "merge" into groceries with the following, but it did not work (groceries did not change at all).

- name: Merge
  set_fact:
    groceries: '{{ groceries_additional | combine(base_groceries, recursive=True) }}'
  vars:
    base_groceries: '{{ groceries | default({}) }}'
  when: groceries_additional is defined

Upvotes: 0

Views: 74

Answers (1)

Vladimir Botka
Vladimir Botka

Reputation: 68044

Use option list_merge, e.g.

    - set_fact:
        groceries: "{{ groceries|combine(groceries_additional,
                                         recursive=True,
                                         list_merge='append') }}"
      vars:
        groceries_additional:
          vegetables:
            - brand: 'Aubergine'
              cost: 100

gives

  groceries:
    fruits:
    - cost: 100
      name: Apples
    - cost: 200
      name: Grapes
    toiletries:
    - cost: 20
      name: Toothpaste
    vegetables:
    - cost: 120
      name: Potatoes
    - brand: Aubergine
      cost: 100

and consequent

    - set_fact:
        groceries: "{{ groceries|combine(groceries_additional,
                                         recursive=True,
                                         list_merge='append') }}"
      vars:
        groceries_additional:
          fruits:
            - name: 'Blackberries'
              cost: 1000

gives the expected result

  groceries:
    fruits:
    - cost: 100
      name: Apples
    - cost: 200
      name: Grapes
    - cost: 1000
      name: Blackberries
    toiletries:
    - cost: 20
      name: Toothpaste
    vegetables:
    - cost: 120
      name: Potatoes
    - brand: Aubergine
      cost: 100

Upvotes: 1

Related Questions