I'm attempting to prompt for a password in a parent playbook and then pass that variable to children playbooks imported with import_playbook. When I run it, I receive the following error. Is it possible to pass variables in this way? I was able to get around this by using extra_vars instead.
ERROR! failed at splitting arguments, either an unbalanced jinja2 block or quotes: child_playbook.yaml password="{{ parentVar }}""
Parent Playbook
- hosts: localhost
gather_facts: false
connection: local
vars_prompt:
- name: parentVar
prompt: "Enter parent var"
tasks:
- debug:
var: parentVar
- name: 'import child playbook'
import_playbook: child.yaml childVar="{{ parentVar }}""
Child Playbook
---
- hosts: localhost
connection: local
tasks:
- debug:
var: childVar
The reason for using import_playbook vs include_tasks is to be able to run the playbooks independently.
(updated with Ansible 2.14)
Q: "Is it possible to pass variables in this way?"
A: No. It's not possible. import_playbook including the vars in the scope of this import is evaluated before the playbook starts. The variable parentVar doesn't exist at this point. As a result, you should see
childVar: VARIABLE IS NOT DEFINED!
import_playbook: child.yaml childVar="{{ parentVar }}""
You can test it by setting the default value of the variable childVar. The plays
shell> cat child.yaml
- hosts: localhost
tasks:
- debug:
var: childVar
shell> cat pb.yml
- hosts: localhost
vars_prompt:
- name: parentVar
prompt: "Enter parent var"
tasks:
- debug:
var: parentVar
- name: Import child playbook
import_playbook: child.yaml
vars:
childVar: "{{ parentVar|d('default') }}"
always give
childVar: default
The extra variable works because it is available before the playbook starts
shell> ansible-playbook -e parentVar=ext_var pb.yml
PLAY [localhost] ******************************************************************************
TASK [debug] **********************************************************************************
ok: [localhost] =>
parentVar: ext_var
PLAY [localhost] ******************************************************************************
TASK [debug] **********************************************************************************
ok: [localhost] =>
childVar: ext_var
PLAY RECAP ************************************************************************************
localhost: ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Note: Prompts for individual vars_prompt variables will be skipped for any variable that is already defined through the command line --extra-vars option ...
The solution would be to 'instantiate' the variable childVar in the first play. This way the variable childVar would be available via hostvars in the scope of the whole playbook to all hosts from the first play
shell> cat pb.yml
- hosts: localhost
vars_prompt:
- name: parentVar
prompt: "Enter parent var"
tasks:
- debug:
var: parentVar
- set_fact:
childVar: "{{ parentVar }}"
- debug:
var: hostvars.localhost.childVar
- name: Import child playbook
import_playbook: child.yaml
vars:
childVar: "{{ parentVar|d('default') }}"
gives (provided the value prompt_var at the prompt Enter parent var:)
shell> ansible-playbook pb.yml
Enter parent var:
PLAY [localhost] ******************************************************************************
TASK [debug] **********************************************************************************
ok: [localhost] =>
parentVar: prompt_var
TASK [set_fact] *******************************************************************************
ok: [localhost]
TASK [debug] **********************************************************************************
ok: [localhost] =>
hostvars.localhost.childVar: prompt_var
PLAY [localhost] ******************************************************************************
TASK [debug] **********************************************************************************
ok: [localhost] =>
childVar: prompt_var
PLAY RECAP ************************************************************************************
localhost: ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0