ansibleansible-inventory

Set become password for all hosts in an inventory without using the all group


TL;DR Is there an easy way to set the become password for all hosts in a particular inventory file without using the all group?

I'm an Ansible noob so maybe there's a better way to construct my inventory files, but here is my problem: I have groups of hosts in multiple inventory files. Each inventory file is structured with the same group names, but with different hosts. Currently I'm using the all group to set the become password per inventory file. If I run a playbook against one inventory then all is well.

The problem comes in when I try run a playbook on multiple inventory files. From what I can tell, the become password in the last inventory file that gets parsed is used for all hosts in all group. I realize that I can create other groups in each inventory to get around this, but it makes each inventory overly complicated IMO.

I was expecting the scope of all to be limited to that particular inventory, but it does make sense to have the ability to set variables for all hosts across all inventories. However I'm a bit surprised there isn't an easier way to set a variable for all hosts in an inventory and limit the scope to only that inventory.


Solution

  • Q: " ... the scope of all to be limited to that particular inventory ... easier way to set a variable for all hosts in an inventory and limit the scope to only that inventory."

    A: The special variable inventory_file keeps

    The file name of the inventory source in which the inventory_hostname was first defined.

    For example, given the inventory

    shell> tree inventory/
    inventory/
    ├── 01_hosts
    ├── 02_hosts
    └── 03_hosts
    
    shell> cat inventory/01_hosts 
    [g1]
    test_11
    test_12
    
    shell> cat inventory/02_hosts 
    [g2]
    test_21
    test_22
    
    shell> cat inventory/03_hosts 
    [g3]
    test_31
    test_32
    

    The play

    - hosts: all
    
      tasks:
    
        - debug:
            var: inventory_file | basename
    

    gives

    ok: [test_11] => 
        inventory_file | basename: 01_hosts
    ok: [test_12] => 
        inventory_file | basename: 01_hosts
    ok: [test_21] => 
        inventory_file | basename: 02_hosts
    ok: [test_31] => 
        inventory_file | basename: 03_hosts
    ok: [test_22] => 
        inventory_file | basename: 02_hosts
    ok: [test_32] => 
        inventory_file | basename: 03_hosts
    

    Create a dictionary with the passwords and declare ansible_become_password

    shell> cat inventory/group_vars/all/become_password_dict.yml 
    become_password_dict:
      01_hosts: become password 01
      02_hosts: become password 02
      03_hosts: become password 03
    ansible_become_password: "{{ become_password_dict[inventory_file | basename] }}"
    

    Note: Encrypting files comprising passwords is recommended.


    Then the play does what you want set a variable for all hosts in an inventory and limit the scope to only that inventory

    shell> cat pb.yml
    - hosts: all
    
      tasks:
    
        - debug:
            var: ansible_become_password
    

    gives (abridged)

    k: [test_12] => 
        ansible_become_password: become password 01
    ok: [test_21] => 
        ansible_become_password: become password 02
    ok: [test_11] => 
        ansible_become_password: become password 01
    ok: [test_31] => 
        ansible_become_password: become password 03
    ok: [test_22] => 
        ansible_become_password: become password 02
    ok: [test_32] => 
        ansible_become_password: become password 03
    

    You can limit the groups. For example,

    shell> ansible-playbook -i inventory pb.yml -l g1,g3
      ...
    ok: [test_11] => 
        ansible_become_password: become password 01
    ok: [test_31] => 
        ansible_become_password: become password 03
    ok: [test_12] => 
        ansible_become_password: become password 01
    ok: [test_32] => 
        ansible_become_password: become password 03
    

    To run a playbook on multiple inventory files use the option -i multiple times. For example,

    shell> ansible-playbook pb.yml -i inventory/01_hosts -i inventory/03_hosts
      ...