martin
martin

Reputation: 1787

Ansible - load multiplne local yml files and merge their content

my host_vars file has about 5k lines of yml code. So I would like to have separate yml files - one file per one service.

Simplified example:

user@test $ cat production/split_configs/a.example.net.yml 
my_array:
  - a.example.net
  
user@test $ cat production/split_configs/b.example.net.yml 
my_array:
  - b.example.net
  
user@test $ cat webhosts.yml 
- hosts: myservers

  pre_tasks:
    - name: merge ansible arrays
      tags: always
      delegate_to: localhost
      block:

        - name: find config files
          find:
            paths: production/configs/
            patterns: '*.yml'
          register: find_results

        - name: aaa
          debug:
            msg: "{{ find_results.files }}"

        - name: bbb
          debug:
            msg: "{{ item.path }}"
          with_items: "{{ find_results.files }}"

        - name: ccc
          debug:
            msg: "{{ lookup('file', 'production/configs/a.example.net.yml') }}"

        - name: ddd
          debug:
            msg: "{{ lookup('file', item.path) }}"
          loop: "{{ find_results.files }}"

  tasks:
    - name: eee
      debug:
        msg: "{{ my_array }}"

The goal is to merge content of both arrays an print the merged content in task eee:

my_array:
  - a.example.net
  - b.example.net

Task aaa print informations about files (path, mode, uid, ...) - it works.

Tasks bbb, and ddd print nothing. I do not understand why.

Task ccc print content of file. But the path is written in playbook :-(

After load files I need to merge them. My idea is to use something like set_fact: my_array="{{ my_array + my_array }}" in task with with_items: "{{ find_results.files }}". Is it good idea? Or how better I can do it?

Upvotes: 0

Views: 1152

Answers (2)

user20938820
user20938820

Reputation:

You can use the simple cat commnd to merge the files into the one file and later include var file for example -

    - raw: "cat production/split_configs/* >my_vars.yml"
    - include_vars: file=my_vars.yml name=my_vars

will give you the result -

  my_vars:
    my_array:
    - a.example.net
    - b.example.net

Upvotes: 0

Vladimir Botka
Vladimir Botka

Reputation: 67984

For example, the tasks below do the job

    - include_vars:
        file: "{{ item }}"
        name: "my_prefix_{{ item|regex_replace('\\W', '_') }}"
      with_fileglob: production/split_configs/*

    - set_fact:
        my_vars: "{{ my_vars|d({})|
                     combine(lookup('vars', item),
                             recursive=True,
                             list_merge='append') }}"
      loop: "{{ q('varnames', 'my_prefix_.*') }}"

give

  my_vars:
    my_array:
    - a.example.net
    - b.example.net

Upvotes: 1

Related Questions