Photo by Etienne Girardet / Unsplash

Ansible - Prompts

Ansible Jul 20, 2022

Let's assume you have a playbook, but you want to use different values for your variables for each time you run it. For example, you want to create a new user on your machines or change the playbook behavior. This can be done, and it is very easy with Ansible Prompts.

Let's have a look how prompts work and how we can use them.

Ansible

Ansible is a very simple way to automate all kind of things. You can use it to configure your network, configurations, cloud providers or your workstation. It is also very simple to get started and learn about Ansible. You just need to write some easy to understand YAML files, and you are good to go.

Why Prompts?

So, why should you consider prompts for playbooks? In general, Ansible executes playbooks, based on an Inventory and other variables, that are defined in YAML or INI files. But, what if you want to change these variables between two runs?

Typical use cases are:

  • creating/changing/removing new users
  • creating/changing/deleting new containers
  • performing updates with different options
  • self-services for users that do not know Ansible

User Example

Let's stick with the User creation example. It is complex enough to showcase some nice features, but easy enough to be written in a very fast way.

The playbook

Let's start with a simple playbook, that manages a defined user with a password. We just need to create a single file for the same. Let's use an editor and create a file named "playbook.yml" with the below content.

---
- name: "Manage User Playbook"
  hosts: "all"
  
  vars:
    user_name: "Bob"
    user_pass: "SuperSecurePassword"
  
  tasks:
  
    - name: "Manage User"
      ansible.builtin.user:
      	name: "{{ user_name }}"
        password: "{{ user_pass | password_hash('sha512', 'SALT') }}"
        state: "present"
      become: true
...
playbook.yml

This playbook can now be used to create the user "Bob" on multiple machines. But, what if you want to remove Bob again, change his password or add another user?

One option is to edit the playbook accordingly and run it again. We only need to do this over and over again for each change. Ehm, nope. ;-)

Prompts for the rescue

To introduce prompts, we need to adjust the playbook, so it asks us some questions. So, let's do this. Grab your editor and adjust the playbook as shown below.

---
- name: "Manage User Playbook"
  hosts: "all"
  
  vars_prompt:

    - name: "user_name"
      prompt: "Username"
      private: false

    - name: "user_pass"        # The variable name
      prompt: "Password"       # What the user is asked
      private: true            # Don't display the variable on STDOUT
      confirm: true            # User must input twice
      unsafe: true             # Allow special chars like % and {
      encrypt: "sha512_crypt"  # Hash/Encrypt the value
      salt: "SALT"             # Use this salt for encryption

    - name: "user_state"
      prompt: "Userstate (present|absent)"
      default: "present"       # Define a default
      private: false

  tasks:
  
    - name: "Manage User"
      ansible.builtin.user:
        name: "{{ user_name }}"
        password: "{{ user_pass }}"
        state: "{{ user_state }}"
      become: true
...
playbook.yml

Our rework is also visible in the task section. Since Prompts allow us to encrypt values immediately, we do not need to this in the task itself. We can also ensure the user confirms his input.

Let's start with a simple example to create a local user.

$ ansible-playbook -i localhost, -c local -K playbook.yml 
BECOME password: 
Username: bob
Password: 
confirm Password: 
Userstate (present|absent) [present]: 

PLAY [Manage User Playbook] *************************************************************************

TASK [Gathering Facts] ******************************************************************************
ok: [localhost]

TASK [Manage User] **********************************************************************************
changed: [localhost]

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

Projects/temp/ansible-prompt took 12s 

With the above command, we will use "localhost" as our inventory with the option -i localhost,, connect locally (not via ssh) with the option -c local and will be asked for the sudo password with the option -K.

And we can re-use this playbook to create even more users.

$ ansible-playbook -i localhost, -c local -K playbook.yml 
BECOME password: 
Username: alice
Password: 
confirm Password: 
Userstate (present|absent) [present]: 

And if we want to remove a user again, this can be done, too.

$ ansible-playbook -i localhost, -c local -K playbook.yml 
BECOME password: 
Username: bob
Password: 
confirm Password: 
Userstate (present|absent) [present]: absent

$ ansible-playbook -i localhost, -c local -K playbook.yml 
BECOME password: 
Username: alice
Password: 
confirm Password: 
Userstate (present|absent) [present]: absent

Fine-Tuning

Extending this example is a good exercise to get in the mood with prompts. Below you can find some possibilities to play with prompts.

  • Make the password changeable
  • Allow an empty password if the state is absent
  • Allow to create system users
  • Let the password expire, so the user has to change it on first log in
  • Copy existing ssh keys
  • Provide some output

This functionality is not very well known and to be honest, not well documented. But the below links should give you a good idea how work from here.

ansible-examples/prompts.yml at master · ansible/ansible-examples
A few starter examples of ansible playbooks, to show features and how they work together. See http://galaxy.ansible.com for example roles from the Ansible community for deploying many popular appl...
Interactive input: prompts — Ansible Documentation
Ansible - Getting Started
Ansible is an OpenSource automation tool, that makes it very easy to automate workflows and has a strong focus on being simple and easy. This article describes how you can get started with Ansible and why you should.

Conclusion

For me, Prompts are a nice option to avoid rewriting playbooks for arbitrary tasks. I can choose between all updates or security updates only, or create users as explained in this article.

What do you think about prompts? Do you have some use cases, where it might be helpful? I would love to hear from you.

Tags

Daniel Schier

Just a guy doing stuff. Mostly #FLOSS like #Linux, #Ansible, #Podman, #k8s, #Python, #Nextcloud or whatever comes next.