You are currently viewing Ansible – Getting User Input Using vars_prompt & Pause Module With Examples

Ansible – Getting User Input Using vars_prompt & Pause Module With Examples

Introduction

There are some use cases where the playbook execution depends on the input passed by the user. Users may be prompted to enter the input as the first step or anywhere in the middle of the playbook execution. In this article, we will see two different ways to get inputs from the user when running the ansible playbook.

Users can pass input in a couple of ways.

  1. Predefine a variable with a value.
  2. Pass the variable as an argument when triggering the playbook with the -e flag.
  3. vars_prompt directive – Prompt the user to provide input as the first step in the playbook.
  4. pause module – Prompt the user to provide input at any stage in the playbook.

Here we will be focusing mainly on the vars_prompt directive and pause module.

Getting Input Using vars_prompt directive

The vars_prompt will run as the first step when you run the playbook. Below is the syntax for vars_prompt.

vars:
  release: ["1.0", "2.0", "3.0"]

vars_prompt:
  - name: release
    prompt: Choose version {{ release }}
    private: False                
    default: 3.0
    confirm: True

1. name – This is the variable where the input given by the user is stored. Here the variable name is set as “user_input”.
2. prompt – Prompt message to stdout(Terminal)
3. private – When set to true, user input will not be displayed in the terminal as they type.
4. default – Set the default value if the user is not providing any input the default value will be used.
5. confirm – This will prompt the user for double confirmation.

---
- name: Getting user input when running the playbook
  hosts: localhost
  connection: local
  gather_facts: False

  vars:
    release: ["1.0", "2.0", "3.0"]

  vars_prompt:
    - name: user_input
      prompt: Choose version {{ release }}
      private: False               
      default: 3.0
      confirm: True

  tasks:
    - name: task1
      ansible.builtin.debug:
        var: user_input

You can copy and paste the above code into your playbook and run it using the following command.

# Syntax check
$ ansible-playbook --syntax-check playbook_name.yml

# Run the playbook
$ ansible-playbook playbook_name.yml
Choose version ['1.0', '2.0', '3.0'] [3.0]: 1.0
confirm Choose version ['1.0', '2.0', '3.0'] [3.0]: 1.0

PLAY [Getting user input when running the playbook] ***************************************************************************************************

TASK [task1] ******************************************************************************************************************************************
ok: [localhost] => {
    "user_input": "1.0"
}

PLAY RECAP ********************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Getting Input Using Pause Module

The pause module comes as part of your ansible installation. The pause module is used to hold the task execution either for a given time period or on user input.

The following playbook contains three tasks.

  1. In the first task, the playbook will be paused for three seconds. You can also use “minutes” instead of seconds.
  2. The second task will prompt for the user’s response. Setting “echo: True|False” will show the user input in the terminal as the input is typed. To store the user input “register” directive should be used.
  3. Print the user input using the debug module. The user input will be stored in the key “user_input”, so you should use “variable.user_input” to access the user input value.
---
- name: PAUSE MODULE - Getting user input when running the playbook 
  hosts: localhost
  connection: local
  gather_facts: False

  tasks:
    
    - name: Pause for 3 seconds
      ansible.builtin.pause:
        seconds: 3
    
    - name: Using pause module to get user input
      ansible.builtin.pause:
        prompt: "Choose the release version :: "
        echo: True
      register: response

    - name: Print the user response
      ansible.builtin.debug:
        var: response.user_input

Difference Between Vars_prompt Directive And Pause Module

Now that you know how syntactically both vars_prompt and pause module works, you should also understand the difference between vars_prompt and pause so you can use the right one for your use case.

Control Where to Prompt For User Response

The vars_prompt directive always executes before any roles or tasks. Even if you have pre_tasks in the playbook, vars_prompt will execute first then pre_tasks will be executed. So if your use case requires getting user input as the first step then vars_prompt will be a good choice.

The pause module will be executed as a separate task and you can use it to get user input anywhere in the playbook. You can also create a pre_task using the pause module and execute it as the first task in the playbook.

pre_tasks:

  - name: Using pause module to get user input
    ansible.builtin.pause:
      prompt: "Choose the release version :: "
      echo: True
    register: response

Tag-Based Execution

You cannot apply tags to the vars_prompt directive. If you try to add a tag you will get the following error.

ERROR! Invalid vars_prompt data structure, found unsupported key 'tags'

Since the pause module is executed as a task you can create tags. In the following snippet, you can see that I have added tags to the tasks and now have control over what to execute based on the tags. This way I can group multiple tasks that require user responses and create them with tags.

pre_tasks:

  - name: Using pause module to get user input
    ansible.builtin.pause:
      prompt: "Choose the release version :: "
      echo: True
    register: response
    tags: version-control

  - name: Pause for 3 seconds
    ansible.builtin.pause:
      seconds: 3
    tags: general

Conditional-Based User Input

If you wish to set any condition-based execution to the vars_prompt it will throw the following error.

ERROR! Invalid vars_prompt data structure, found unsupported key 'when'

The conditional-based execution is possible with the pause module. Here I am checking if the variable build_type is set to “full_build”.

vars:
  build_type: "inc_build"

pre_tasks:

  - name: Using pause module to get user input
    ansible.builtin.pause:
      prompt: "Choose the release version :: "
      echo: True
    register: response
    when: build_type == "full_build"
If the condition is matched the task will be executed else the task will be skipped.
TASK [Using pause module to get user input] ***********************************************************************************************************
skipping: [localhost]

Multiple Inputs In A Single Task Using Loops

Using loops in the vars_prompt directive is not possible but you can use it with the pause module to ask for multiple user inputs with a single task. In the following playbook, the first task is set to ask multiple user responses using the loop and will be stored as a list of dictionary values. The second task is printing the inputs.

pre_tasks:

  - name: Using pause module to get user input
    ansible.builtin.pause:
      prompt: "{{ item }}"
      echo: True
    register: response
    loop:
      - "Choose the release version :: "
      - "Press [Yy] for incremental build:: "

  - name: Print the user response
    ansible.builtin.debug:
      var: response.results[{{ item }}].user_input
    loop: [0,1]

Output

PLAY [PAUSE MODULE - Getting user input when running the playbook] ************************************************************************************

TASK [Using pause module to get user input] ***********************************************************************************************************
[Using pause module to get user input]
Choose the release version :: :
1.15^Mok: [localhost] => (item=Choose the release version :: )
[Using pause module to get user input]
Press [Yy] for incremental build:: :
y^Mok: [localhost] => (item=Press [Yy] for incremental build:: )

TASK [Print the user response] ************************************************************************************************************************
ok: [localhost] => (item=0) => {
    "ansible_loop_var": "item",
    "item": 0,
    "response.results[0].user_input": "1.15"
}
ok: [localhost] => (item=1) => {
    "ansible_loop_var": "item",
    "item": 1,
    "response.results[1].user_input": "y"

NOTE: This example is just to show the feasibility of using loops to get user inputs. But in real cases creating separate tasks for each user input is a recommended practice.

Passing User Input Using -e Flag

Alternate to the vars_prompt and pause module you can also create empty variables and pass the values using the -e flag when running the playbook. In the below playbook, I created two variables. The first variable is empty and the second variable value is set to “n” which will act as the default value when the user is not passing any inputs.

vars:
  release_version: ""
  incremental_build: "n"

pre_tasks:

  - name: Validating user input
    ansible.builtin.debug:
      msg: "Building with {{ release_version }} and incremental_build is set to {{ incremental_build }}"

You have to pass the values using the -e flag which takes higher precedence.

$ ansible-playbook -i ../../config/hosts from_command_line.yml -e "release_version=1.15" -e"incremental_build=y"

PLAY [Getting user input when running the playbook] ***************************************************************************************************

TASK [Validating user input] **************************************************************************************************************************
ok: [localhost] => {
    "msg": "Building with 1.15 and incremental_build is set to y"
}

PLAY RECAP ********************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Wrap Up

Now you should be having a good understanding on how to get user response using the vars_prompt directive, pause module and with -e flag. Ansible has multiple ways to accomplish a task so it is important that you understand which method suits your use case.

Leave a Reply

five × four =