In Ansible, how to combine variables from separate files into one array?

后端 未结 7 641
执笔经年
执笔经年 2020-12-03 21:27

In Ansible, in a role, I have vars files like this:

vars/
    app1.yml
    app2.yml

Each file contains vars specific to an app/website like

相关标签:
7条回答
  • 2020-12-03 21:35

    Well, you cannot directly build an array, but you can achieve the same effort with a dict.

    Suppose you want to construct an array:

    [{
        name: 'bob',
        age: 30
    }, {
        name: 'alice',
        age: 35 
    }]
    

    You can put each element in a file like:

    bob.yml

    bob:
      name: bob
      age: 30
    

    alice.yml

    alice:
      name: alice
      age: 35
    

    Place these files in the same dir (e.g. user), then use include_vars to load the whole dir:

    - name: Include vars
      include_vars:
        name: users
        dir: user
    

    This will give you a dict users:

    users:
      alice:
        name: alice
        age: 35
      bob:
        name: bob
        age: 30
    

    User the dict2items filter in ansible, you get the array you want

    0 讨论(0)
  • 2020-12-03 21:40

    Wanted to post a possible alternate solution by getting a list of variables that match a pattern, then you can just process all those variables, sorta manual merge.

    The following code block gives an example of pulling all variables that match a specific pattern and looping. you could set a new fact with them merged, or simply process them all individually.

    - name: "debug2"   debug:
        msg: "value is: {{ lookup('vars', item) }} "   
      loop: "{{ hostvars[inventory_hostname] | select('match', '^linux_hosts_entries') |list  }}"
    

    see the following post for further details.

    0 讨论(0)
  • 2020-12-03 21:42

    Since Ansible 2.2, the include_vars (link) module has been expanded quite a bit.

    It's now possible to do something like:

    - include_vars:
        name: 'apps'
        dir: '../vars'
        extensions:
          - 'yaml'
          - 'yml'
    

    name is the key there. From the module page:

    The name of a variable into which assign the included vars. If omitted (null) they will be made top level vars.

    This allows you to convert:

    vars/
        app1.yml
        app2.yml
        ...
    

    app1.yml:

    name: app1
    git_repo: https://github.com/philgyford/app1.git
    # ...
    

    app2.yml:

    name: app2
    git_repo: https://github.com/philgyford/app2.git
    # ...
    

    Into...

    apps:
      - name: app1
        git_repo: https://github.com/philgyford/app1.git
        # ...
      - name: app2
        git_repo: https://github.com/philgyford/app2.git
        # ...
    
    0 讨论(0)
  • 2020-12-03 21:44

    Starting with Ansible v2.0 you can do it:

    - name: merging hash_a and hash_b into hash_c
      set_fact: hash_c="{{ hash_a|combine(hash_b) }}"
    

    Check more under Ansible filters - Combining hashes/dictionaries (coming from Jinja2)

    0 讨论(0)
  • 2020-12-03 21:44

    If you don't want to change default behavior of hash. I suggest you my solution. I define multiple variables (with same regex) when Ineed to merge them, I filter them from hostvars. Eg:

    - name: Combine variables with prefix enabled_services
      debug:
        msg: "{{ hostvars[inventory_hostname].keys() | map('regex_search', 'enabled_services.*') | select('string') | list }}"
    
    0 讨论(0)
  • 2020-12-03 21:53

    Use attribute name and put the included variables into the dictionaries. Fit the name of the dictionaries to your needs. For example

        - name: Load var files
          include_vars:
            file: "{{ item }}"
            name: "{{ 'incl_vars_' ~ item|basename|splitext|first }}"
          with_fileglob:
              - vars/*.yml
    

    Then, use the lookup plugin varnames (New in version 2.8.), find all dictionaries, and iterate the list. In the loop use the lookup plugin var (New in version 2.5.) and create the list. For example

        - set_fact:
            my_vars: "{{ my_vars|default([]) + [lookup('vars', item)] }}"
          loop: "{{ query('varnames', '^incl_vars_(.*)$') }}"
    
        - debug:
            var: my_vars
    

    give

      my_vars:
      - git_repo: https://github.com/philgyford/app2.git
        name: app2
      - git_repo: https://github.com/philgyford/app1.git
        name: app1
    
    0 讨论(0)
提交回复
热议问题