Ansible to Conditionally Prompt for a Variable?

2019-02-02 21:14发布

问题:

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:

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 :)



回答2:

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


回答3:

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.



回答4:

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}}"


回答5:

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).



回答6:

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