ansible

Pass a variable as an import_playbook variable


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.


Solution

  • (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!
    

    Note: The error you see is the result of the syntax error (the unbalanced quotes)
      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