Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why I cannot prompt for a variable that will be shared by multiple plays (ansible 1.6.5)

Tags:

I have distilled a playbook that has three plays. The goal is to collect the database password from a prompt in one play and then use the same password in the other two plays.

---

- name: database password
  hosts:
    - webservers
    - dbservers
  vars_prompt:
    - name: "db_password"
      prompt: "Enter Database Password for databse user root"
      default: "root"

- hosts: dbservers
  tasks:
    - command: echo {{db_password | mandatory }}


- hosts: webservers
  tasks:
    - command: echo {{db_password | mandatory }}

It fails as shown below.

Enter Database Password for databse user root [root]: 

PLAY [database password] ****************************************************** 

GATHERING FACTS *************************************************************** 
ok: [vc-dev-1]

PLAY [dbservers] ************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [vc-dev-1]

TASK: [command echo {{db_password | mandatory}}] *************************** 
fatal: [vc-dev-1] => One or more undefined variables: 'db_password' is undefined

FATAL: all hosts have already failed -- aborting

PLAY RECAP ******************************************************************** 
           to retry, use: --limit @.../playbook2.retry

vc-dev-1                   : ok=3    changed=0    unreachable=1    failed=0   
like image 444
gae123 Avatar asked Jun 27 '14 06:06

gae123


People also ask

How do you ask for variable prompt Ansible?

If you want your playbook to prompt the user for certain input, add a 'vars_prompt' section. Prompting the user for variables lets you avoid recording sensitive data like passwords.

Which argument will you use to specify a variable for your Ansible playbook?

Use the ansible-playbook -e var=value method when you want to use a playbook as you would a shell script that takes a command-line argument. The -e flag effectively allows you to pass variables as arguments. Example 4-12 shows a very simple playbook that outputs a message specified by a variable.


2 Answers

I have found the following workaround using set_fact to assign the variable entered by a user into a variable with playbook scope. It seems that var_prompt variables are not like facts and other variables, its scope is restricted in the play that prompts for them not the entire playbook. I am not sure if this is a feature or a bug.

---

- name: database password
  hosts:
    - webservers
    - dbservers
  vars_prompt:
    - name: "db_password"
      prompt: "Enter Database Password for databse user root"
      default: "root"
  tasks:
    - set_fact:
        db_root_password: "{{db_password}}"

- hosts: dbservers
  tasks:
    - command: echo {{db_root_password | mandatory }}


- hosts: webservers
  tasks:
    - command: echo {{db_root_password | mandatory }}
like image 58
gae123 Avatar answered Sep 22 '22 11:09

gae123


Improvising gae123's answer, in case if your hosts are added dynamically, it will not be possible to get and set the fact on the existing group of servers, in which case localhost can be used to set and get.

---
- name: database password
  hosts: localhost
  vars_prompt:
    - name: "db_password"
      prompt: "Enter Database Password for databse user root"
      default: "root"
  tasks:
    - set_fact:
        db_root_password: "{{db_password}}"

- hosts: dbservers
  vars:
    - db_root_password: "{{ hostvars['localhost']['db_root_password'] }}"
  tasks:
    - command: echo {{db_root_password | mandatory }}


- hosts: webservers
  vars:
    - db_root_password: "{{ hostvars['localhost']['db_root_password'] }}"
  tasks:
    - command: echo {{db_root_password | mandatory }}
like image 28
user3037143 Avatar answered Sep 23 '22 11:09

user3037143