Search code examples
if-statementansibleruntime-errordynamic-programmingansible-inventory

Is it possible to conditionally set ansible host from within the play?


If the user passes perform_action parameter as any of these telnetcurlnslookuptracerouteget_ip_address then i want the play to run on localhost else it should run on remotehosts

ansible-playbook test.yml -e perform_action='nslookup'

- name: "Play 1"
  hosts: localhost
  tasks:
    - set_fact:
        final_delegate: "{{ 'localhost' if perform_action in 'telnetcurlnslookuptracerouteget_ip_address' else 'remotehosts' }}    "

    - debug:
        msg: "Play needs to run on {{ final_delegate }}"

- name: "Play 2"
  hosts: "{{ final_delegate }}"
  tasks:
    - debug:
        msg: "Im running on {{ inventory_hostname }}"

Output:

The Play needs to run on localhost

However, Play 2 fails with the below error:

ERROR! The field 'hosts' has an invalid value, which includes an undefined variable. The error was: 'final_delegate' is undefined

Can this condition be set with the play as i m doing or is it possible only by putting a condition on -e parameter?


Solution

  • Your problem is that at the moment of evaluating which hosts to run play 2 on, you are polling a variable which is only defined for localhost. It's the chicken or the egg thing. It's technically not running on localhost, so it doesn't know which host to check the variable on, to find that it should run on localhost.

    I would try...

    hosts: "{{ hostvars['localhost']['final_delegate'] }}"
    

    That might work for you. The templating for host patterns can be a little picky about things.