Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a one-time user prompt input in ansible?

I have a the following oversimplified ansible playbook:


- name: Prepare worker nodes
  hosts: "{{ hosts }}"
  serial:
    - 1
    - 3
  remote_user: root
  any_errors_fatal: true
  vars:
    hosts: nodes
    reboot: false
  tasks:

    - pause:
        prompt: "Reboot server(s) to make sure things are working during setup? (Y/n)"
        echo: true
      register: confirm_reboot
      tags: [ untagged, hostname, netplan, firewalld ]

    - set_fact:
        reboot: "{{ (confirm_reboot.user_input == '' or confirm_reboot.user_input == 'Y' or confirm_reboot.user_input == 'y' ) | ternary('True', 'False') }}"
      tags: [ untagged, hostname, netplan, firewalld, firewalld-install, firewalld-config ]

    - debug:
        msg: "{{ reboot }}"

It asks for the user's input so it can decide on some reboot policies. This works just fine when you have just one node, but when you have multiple nodes it will prompt for each one. Suppose you have 42 nodes -- it will ask you 42 times.

I'm trying to figure out if there is an easy way to make the prompt appear just once and share the result among the nodes. Maybe I have missed something in the docs?

like image 743
tftd Avatar asked Dec 04 '25 14:12

tftd


1 Answers

Given the inventory

shell> cat hosts
[test]
host1
host2
host3
host4
host5

the playbook

shell> cat playbook.yml
---
- hosts: test
  serial:
    - 1
    - 3
  gather_facts: false
  tasks:
    - pause:
        prompt: "Reboot? (Y/n)"
        echo: true
      register: confirm_reboot
      run_once: true
    - debug:
        msg: "Reboot {{ inventory_hostname }}"
      when: confirm_reboot.user_input|lower == 'y'

works as expected

shell> ansible-playbook -i hosts playbook.yml

PLAY [test] *********************************

TASK [pause] ********************************
[pause]
Reboot? (Y/n):
ok: [host1]

TASK [debug] ********************************
ok: [host1] => 
  msg: Reboot host1

PLAY [test] *********************************

TASK [pause] ********************************
[pause]
Reboot? (Y/n):
ok: [host2]

TASK [debug] ********************************
ok: [host2] => 
  msg: Reboot host2
ok: [host3] => 
  msg: Reboot host3
ok: [host4] => 
  msg: Reboot host4

PLAY [test] *********************************

TASK [pause] ********************************
[pause]
Reboot? (Y/n):
ok: [host5]

TASK [debug] ********************************
ok: [host5] => 
  msg: Reboot host5

Q: "Require the input just once for the entire playbook and be propagated to all hosts."

A: Split the playbook, e.g.

shell> cat playbook.yml
---
- hosts: test
  gather_facts: false
  tasks:
    - pause:
        prompt: "Reboot? (Y/n)"
        echo: true
      register: confirm_reboot
      run_once: true

- hosts: test
  serial:
    - 1
    - 3
  gather_facts: false
  tasks:
    - debug:
        msg: "Reboot {{ inventory_hostname }}"
      when: confirm_reboot.user_input|lower == 'y'

the variable from the first play will be shared among all hosts in the second play

shell> ansible-playbook -i hosts playbook.yml

PLAY [test] *********************************

TASK [pause] ********************************
[pause]
Reboot? (Y/n):
ok: [host1]

PLAY [test] *********************************

TASK [debug] ********************************
ok: [host1] =>
  msg: Reboot host1

PLAY [test] *********************************

TASK [debug] ********************************
ok: [host3] =>
  msg: Reboot host3
ok: [host2] =>
  msg: Reboot host2
ok: [host4] =>
  msg: Reboot host4

PLAY [test] *********************************

TASK [debug] ********************************
ok: [host5] =>
  msg: Reboot host5
like image 141
Vladimir Botka Avatar answered Dec 07 '25 17:12

Vladimir Botka



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!