42

I would like to be able to prompt for my super secure password variable if it is not already in the environment variables. (I'm thinking that I might not want to put the definition into .bash_profile or one of the other spots.)

This is not working. It always prompts me.

vars:
  THISUSER: "{{ lookup('env','LOGNAME') }}"
  SSHPWD:   "{{ lookup('env','MY_PWD') }}"

vars_prompt:
  - name: "release_version"
    prompt: "Product release version"
    default: "1.0"
    when: SSHPWD == null

NOTE: I'm on a Mac, but I'd like for any solutions to be platform-independent.

1
  • @AnnTheAgile When you hardcode the above variable (SSHPWD) to some dummy / actual value, did the above piece of code work for you, i.e. for NOT prompting you at all? My understanding is, it'll alway prompt you no matter whether SSHPWD was set to null or was set to a valid value (if hardcoded to some value instead of using/depending upon an ENV variable).
    – AKS
    Commented Jan 2, 2017 at 13:43

8 Answers 8

51

According to the replies from the devs and a quick test I've done with the latest version, the vars_prompt is run before "GATHERING FACTS". This means that the env var SSHPWD is always null at the time of your check with when.

Unfortunately it seems there is no way of allowing the vars_prompt statement at task level.

Michael DeHaan's reasoning for this is that allowing prompts at the task-level would open up the doors to roles asking a lot of questions. This would make using Ansible Galaxy roles which do this difficult:

There's been a decided emphasis in automation in Ansible and asking questions at task level is not something we really want to do.

However, you can still ask vars_prompt questions at play level and use those variables throughout tasks. You just can't ask questions in roles.

And really, that's what I would like to enforce -- if a lot of Galaxy roles start asking questions, I can see that being annoying :)

1
  • 4
    good explanation for the ordering of GATHERING FACTS vs vars_prompt part.
    – AKS
    Commented Jan 2, 2017 at 11:45
36

I might be late to the party but a quick way to avoid vars_prompt is to disable the interactive mode by doing that simple trick:

echo -n | ansible-playbook -e MyVar=blih site.yaml

This add no control over which vars_prompt to avoid but coupled with default: "my_default" it can be used in a script.

Full example here:

---
- hosts: localhost
  vars_prompt:
    - prompt: Enter blah value
    - default: "{{ my_blah }}"
    - name: blah

echo -n | ansible-playbook -e my_blah=blih site.yaml

EDIT:

I've found that using the pause module and the prompt argument was doing what I wanted:

---
- pause:
      prompt: "Sudo password for localhost "
  when: ( env == 'local' ) and
      ( inventory_hostname == "localhost" ) and
      ( hostvars["localhost"]["ansible_become_password"] is not defined )
  register: sudo_password
  no_log: true
  tags:
       - always
0
10

Based on tehmoon's answer with some modifications I did it that way:

- hosts:
    - hostA
  become: yes
  pre_tasks:
    - pause:
        prompt: "Give your username"
      register: prompt
      no_log: yes
      run_once: yes
    - set_fact:
        username: "{{prompt.user_input}}"
      no_log: yes
      run_once: yes
    - pause:
        prompt: "Give your password"
        echo: no
      register: prompt
      no_log: yes
      run_once: yes
    - set_fact:
        password: "{{prompt.user_input}}"
      no_log: yes
      run_once: yes
  tags: [my_role_using_user_pass]
  roles:
    - role: my_role_using_user_pass
1
  • 1
    Thanks! I use tag and this works for me without 2 last lines (roles: and - role:)
    – Rapekas
    Commented May 6, 2022 at 15:11
4

This is indeed not possible by default in Ansible. I understand the reasoning behind not allowing it, yet I think it can be appropriate in some contexts. I've been writing an AWS EC2 deploy script, using the blue/green deploy system, and at some point in the role I need to ask the user if a rollback needs to be done if something has gone awry. As said, there is no way to do this (conditionally and/or non-fugly).

So I wrote a very simple Ansible (2.x) action plugin, based on the pause action from the standard library. It a bit spartan in that it only accepts a single key press, but it might be of use. You can find it in a Github gist here. You need to copy the whole Gist file to the action_plugins directory of your playbook directory. See the documentation in the file.

2
  • Pleae include the relevant part of your link in your answer. GitHub depositories may change at any time. Thanks.
    – zx485
    Commented Mar 21, 2016 at 16:36
  • The whole file is the relevant part. It's a module than needs to be included wholly to add extra functionality to Ansible. I added a bit more documentation to the anwer. If you mean 'relevant git commit': if I find a bug tomorrow I want future visitors to see the newer version.
    – Confiks
    Commented Mar 21, 2016 at 17:46
3

As can be seen in the source code, the when keyword isn't implemented for vars_prompt (and in fact never was). The same was mentioned in this Github comment.

The only way in which vars_prompt is currently conditional is that it only prompts when the variable (defined in name) is already defined (using the command-line extra_vars argument).

2

This works for me (2.3) .. do two bits in the one file. This allows me to consruct a tmp vars file when running the playbook via jenkins.. but also allow prompting on the command line

And you get to do it with only the one var used

---
- name: first bit                                    
  hosts:                            all
  connection:                       local            
  tasks: 
  - set_fact:                                  
      favColour:                   "{{ favColour }}" 
    when: favColour is defined

- name: second bit                                    
  hosts:                            all
  connection:                       local            
  vars_prompt:
    favColour: 
      prompt:                       "Whats ya favorite colour: "
    when: favColour is not defined

  tasks:
    - debug:                        msg="{{favColour}}"
0

Based on @tehmoon's answer, this is what worked for me with ansible-core 2.14:

  tasks:
    - name: Prompt SSH password if necessary
      when: ansible_password is undefined
      block:
        - name: Conditionally prompt for ssh/sudo password
          ansible.builtin.pause:
            prompt: "Password for {{ ansible_user_id }}@{{ ansible_host }}"
            echo: false
          register: password_prompt
          no_log: true

        - name: Set ansible_password
          ansible.builtin.set_fact:
            ansible_password: "{{ password_prompt.user_input }}"
          no_log: true

    - name: Set ansible_become_password
      ansible.builtin.set_fact:
        ansible_become_password: "{{ ansible_password }}"
      no_log: true
      when: ansible_become_password is undefined

0

You can conditionally skip execution of the vars_prompt: prompt by defining the variable on the command line.

Let's say you have:

  vars_prompt:
    - name: server
      prompt: New Server Name? (skip with -e "server=foo")
      private: false

If you run this playbook with `ansible-playbook your_playbook.yml -e "server=foo", then the prompt will be skipped. And if you run the playbook without the extra_vars definition, you'll be prompted for the undefined variable.

The actual ansible code in question is here. extra_vars is the long form of -e.

if vname not in self._variable_manager.extra_vars

If your goal is more of a programmatic usage of extra_vars with an actual when: clause, this is not possible. Instead the official recommendation from the Ansible team is to use the pause module:

when is not a supported keyword on vars (even in vars_prompt), if you want to use conditional input look at the pause module

https://docs.ansible.com/ansible/latest/collections/ansible/builtin/pause_module.html

2
  • Isn't that the same thing as already discussed in stackoverflow.com/a/38905217/161972 ?
    – huyz
    Commented Jun 12 at 8:09
  • A little similar... No idea why a variable blih would be used or why an extra echo -n needs to be prefixed or why it needs to begin with unrelated prose.
    – erwin
    Commented Jun 12 at 16:01

Not the answer you're looking for? Browse other questions tagged or ask your own question.