Search code examples
ansibleansible-2.xansible-inventoryansible-facts

Making prompted vars usable across the playbook


I have one playbook with multiple tasks that have to run on different hosts. In the beginning of the play I want to prompt the operator for their credentials which are the same for every host in the play. I want to have those credentials "stored" somewhere so they can be used across the tasks to log in on the provided host(s).

Playbook looks as followed,

---
- name: Ask for credentials
  vars_prompt:
    - name: username
      prompt: "Username?"
    - name: password
      prompt: "Password?"
  tasks:
    - set_fact:
        username: "{{username}}"
    - set_fact:
        password: "{{password}}"

- hosts: Host1
  vars:
    ansible_user: "{{ username }}"
    ansible_password: "{{ password }}"
  tasks:
    - name: Do stuff  

- hosts: Host2
  vars:
    ansible_user: "{{username}}"
    ansible_password: "{{password}}"
  tasks:
    - name: Do stuff
...

From the moment the play hits the first task it will fail with the flowing error,

msg: 'The field ''remote_user'' has an invalid value, which includes an undefined variable. The error was: ''username'' is undefined'

Anyone that has experience in making prompted vars usable across the whole play and all tasks?


Solution

  • Q: "Make prompted vars usable across the whole play and all tasks>"

    A: Run the first play with the group of all hosts that should be connected later. Run once the set_fact task. This will create the variables username and password for all hosts in the group.

    For example if the group test_jails comprises hosts test_01, test_02, test_03 the play

    - hosts: test_jails
      vars_prompt:
        - name: "username"
          prompt: "Username?"
        - name: "password"
          prompt: "Password?"
      tasks:
        - set_fact:
            username: "{{ username }}"
            password: "{{ password }}"
          run_once: true
    
    - hosts: test_01
      vars:
        ansible_user: "{{ username }}"
        ansible_password: "{{ password }}"
      tasks:
        - debug:
            msg: "{{ ansible_user }} {{ ansible_password }}"
    

    gives

    ok: [test_01] => {
        "msg": "admin 1234"
    }