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

时光总嘲笑我的痴心妄想 提交于 2021-02-05 18:51:42

问题


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   

回答1:


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



回答2:


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



回答3:


I ended up taking user3037143 answer for my localhost sudo password problem:

---
- hosts: localhost
  tags:
    - always
  vars_prompt:
    - name: sudo_password
      prompt: "Sudo password for localhost ONLY"
  tasks:
    - set_fact: ansible_become_password={{ sudo_password }}
      no_log: true

Now it's shared between every include playbooks I have.

I'm on ansible > 2.



来源:https://stackoverflow.com/questions/24444964/why-i-cannot-prompt-for-a-variable-that-will-be-shared-by-multiple-plays-ansibl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!