Search code examples
ansiblevmwareansible-inventory

Is it possible to wildcard a host_vars directory?


Long story short: I've established a home-lab where I use Ansible with VMware dynamic inventory plugin. To distinguish between the different VMs the plugin adds the uid to the hostname, example: unique-test-vm_2612e560x1284x8457e115. This makes it hard for me to create host_vars directories because I constantly have to run ansible-inventory -i ... and copy the inventory name.

Question
Is it possible to create "wildcarded" host_vars directories without including the uid in the directory name? Meaning the name of the directory would be unique-test-vm instead of unique-test-vm_2612e560x1284x8457e115.


Solution

  • It's not possible to create "wildcard" host_vars. But, this use-case can be solved either by include_vars or by group_vars. Mind the precedence of the variables. See Variable precedence: Where should I put a variable?.


    include_vars (single host)

    For example, let's have this inventory

    shell> cat hosts
    testX-vm_07
    

    Let's create host_vars

    shell> cat host_vars/testX-vm/main.yml 
    test_var: test var for hosts testX-vm_*
    

    Then the playbook below reads the variables from the directory host_vars/testX-vm. Fit the parsing of the inventory_hostname to your needs

    shell> cat pb.yml
    - hosts: testX-vm_07
      tasks:
        - include_vars:
            dir: "{{ 'host_vars/' ~ my_vars_dir }}"
          vars:
            my_vars_dir: "{{ inventory_hostname.split('_').0 }}"
        - debug:
            var: test_var
    

    gives

    
    shell> ansible-playbook -i hosts pb.yml
    
    PLAY [testX-vm_07] ****
    
    TASK [include_vars] ****
    ok: [testX-vm_07]
    
    TASK [debug] ****
    ok: [testX-vm_07] => 
      test_var: test var for hosts testX-vm_*
    

    group_vars (multiple hosts)

    For example, let's have this inventory

    shell> cat hosts
    testX-vm_01
    testX-vm_02
    testX-vm_03
    testY-vm_01
    testY-vm_02
    testY-vm_03
    

    Let's create group_vars that shall be shared by the hosts testX-vm_* and testY-vm_* respectively

    shell> cat group_vars/testX_vm/main.yml
    test_var: test var for testX_vm group
    
    shell> cat group_vars/testY_vm/main.yml
    test_var: test var for testY_vm group
    

    Then the playbook below creates groups testX_vm and testY_vm in the first play and uses the groups in the second and third play. For example,

    shell> cat pb.yml
    - hosts: all
      gather_facts: false
      tasks:
        - block:
            - add_host:
                name: "{{ item }}"
                groups: testX_vm
              loop: "{{ ansible_play_hosts_all|
                        select('match', '^testX-vm_(.*)$')|
                        list }}"
            - add_host:
                name: "{{ item }}"
                groups: testY_vm
              loop: "{{ ansible_play_hosts_all|
                        select('match', '^testY-vm_(.*)$')|
                        list }}"
          run_once: true
      
    - hosts: testX_vm
      tasks:
        - debug:
            var: test_var
    
    - hosts: testY_vm
      tasks:
        - debug:
            var: test_var
    

    gives

    shell> ansible-playbook -i hosts pb.yml 
    
    PLAY [all] ****
    TASK [add_host] ****
    changed: [testX-vm_01] => (item=testX-vm_01)
    changed: [testX-vm_01] => (item=testX-vm_02)
    changed: [testX-vm_01] => (item=testX-vm_03)
    
    TASK [add_host] ****
    changed: [testX-vm_01] => (item=testY-vm_01)
    changed: [testX-vm_01] => (item=testY-vm_02)
    changed: [testX-vm_01] => (item=testY-vm_03)
    
    PLAY [testX_vm] ****
    ok: [testX-vm_01] => 
      test_var: test var for testX_vm group
    ok: [testX-vm_02] => 
      test_var: test var for testX_vm group
    ok: [testX-vm_03] => 
      test_var: test var for testX_vm group
    
    PLAY [testY_vm] ****
    ok: [testY-vm_01] => 
      test_var: test var for testY_vm group
    ok: [testY-vm_02] => 
      test_var: test var for testY_vm group
    ok: [testY-vm_03] => 
      test_var: test var for testY_vm group