Search code examples
ansibleansible-inventory

Ansible - Is it possible to override an inventory file to run for specific tasks within a playbook?


I am trying to re-design a playbook, where I am using idiomatic Ansible in order to create new configuration objects. I am basically sending the following command, in order to start the playbook:

ansible-playbook test-playbook.yaml -v -i roles/test-role/vars/inventory

The playbook calls various roles, which in turn use delegations and override the inventory_hostname variable in order to use the correct target hostname. For example, in this playbook snippet:

- name: "Upload certificate"
  import_role:
    name: certificate_manager
    tasks_from: certificate_upload
  delegate_to: localhost
  vars:
    inventory_hostname: "{{ target_hostname }}"

This of course uses the files contained within the roles/test-role/vars/inventory folder as an inventory file; this contains the configuration.yml file which specifies the details of the configuration object which will be created.

If useful, the configuration.yml file is formatted like so:

virtual_servers:
  hosts:
   test-1.test.local
     name: test-1.test.local
     type: 'standard'
     description: 'Test'
... 

This, however, closes the possibility to use the actual inventory, which also contains other useful variables - also considering that within the playbook I am using tasks from other roles.

Since the approach to use the actual inventory (without the -i override) I think is better, especially considering that it is going to be centrally updated if the need arises, is there a better (and maybe simpler) way to run the configuration file with the hosts definition, without impacting the actual inventory?

Thanks in advance for any inputs you might have.


Solution

  • Q: "Override the inventory_hostname variable in order to use the correct target hostname."

    A: The variable inventory_hostname is a special variable provided for your convenience. It does not make sense to override it because this variable doesn't control any connection plugin. Test it. For example,

    - hosts: test_11:test_12:test_13
      tasks:
        - command: hostname
          register: hostname
          vars:
            inventory_hostname: foo.bar.baz
        - debug:
            var: hostname.stdout
    

    gives

    PLAY [test_11:test_12:test_13] ***************************************************************
    
    TASK [command] *******************************************************************************
    changed: [test_11]
    changed: [test_12]
    changed: [test_13]
    
    TASK [debug] *********************************************************************************
    ok: [test_11] => 
      hostname.stdout: test_11
    ok: [test_12] => 
      hostname.stdout: test_12
    ok: [test_13] => 
      hostname.stdout: test_13
    
    PLAY RECAP ***********************************************************************************
    test_11: ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    test_12: ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    test_13: ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    

    You can see that overridden inventory_hostname didn't influence which remote host was connected.