0

We can query for a host in a play like

- name: Test1
  hosts: "{{ target1 }}"
  gather_facts: false
  vars_prompt:

    - name: target1
      prompt: "Specify deployment target1"
      private: false
      default: 'localhost'

  tasks:

    - name: Output 1
      ansible.builtin.debug:
        msg:
          - "{{ target1 }}"

The problem however is if I try to access target1 from another play, if we e.g. add

- name: Test2
  hosts: "{{ target1 }}"
  tasks:
    - name: Output 2
      ansible.builtin.debug:
        msg:
          - "{{ target1 }}"

It fails with an undefined variable error. In addition when I set target1 as a fact via

    - name: Store Variable for cross play visibility
      ansible.builtin.set_fact:
        target1: "{{ target1 }}"

in the play Test1, the play Test2 still fails with

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

once I remove the variable in hosts of play Test2 it works. So it seems that I need to add

I also tried to use add_host using something like

    - name: Define hosts dynamically
      ansible.builtin.add_host:
        hostname: "{{ target1 }}"
        groups: dynamically_created_hosts

but this also fails.

So how do I use the host variable defined via vars_prompt in one play in another one?

Stefan
  • 1,697
  • 15
  • 31
  • https://stackoverflow.com/questions/40992585/ansible-use-variable-for-defining-playbook-hosts explains that you can't use variables for 'hosts' in one variable that you were defined in other and suggests use of environment variable as well as refers to https://stackoverflow.com/questions/38630085/can-i-use-inventory-data-from-a-web-service-within-a-playbook/38631923#38631923 that provides information on using dynamic inventory. – Konstantin Volenbovskyi Mar 30 '23 at 07:59

1 Answers1

2

Solution 1: delegate facts to localhost

I found the solution here: https://jwkenney.github.io/creative-abuse-of-var-prompt/

Basically write the host / group to local host facts.

- name: Test1
  hosts: "{{ target1 }}"
  gather_facts: false
  vars_prompt:

    - name: target1
      prompt: "Specify deployment target1"
      private: false
      default: 'localhost'

  tasks:

    - name: Store Variable for cross play visibility
      ansible.builtin.set_fact:
        target: "{{ target1 }}"
      run_once: true
      delegate_facts: true
      delegate_to: localhost

    - name: Output 1
      ansible.builtin.debug:
        msg:
          - "{{ target1 }}"
          - "{{ hostvars['localhost']['target'] }}"

- name: Test2
  hosts: "{{ hostvars['localhost']['target'] }}"
  tasks:
    - name: Output 2
      ansible.builtin.debug:
        msg:
          - "{{ hostvars['localhost']['target'] }}"

Solution 2: create dynamic inventory

After looking at the links provided by @KonstantinVolenbovskyi I found my problem with dynamically_created_hosts. It is not a variable but of course an inventory group.

The playbook which works:

- name: Test1
  hosts: "{{ target1 }}"
  gather_facts: false
  vars_prompt:

    - name: target1
      prompt: "Specify deployment target1"
      private: false
      default: 'localhost'

  tasks:

    - name: Output 1
      ansible.builtin.debug:
        msg:
          - "{{ target1 }}"

    - name: Define hosts dynamically
      ansible.builtin.add_host:
        hostname: "{{ target1 }}"
        groups: dynamically_created_hosts

- name: Test2
  hosts: dynamically_created_hosts
  tasks:
    - name: Output 2
      ansible.builtin.debug:
        msg:
          - "{{ groups['dynamically_created_hosts'] }}"
Stefan
  • 1,697
  • 15
  • 31