3

I have a main_play.yml Ansible playbook in which I am importing a reusable playbook a.yml.

main_play.yml

- import_playbook: "reusable_playbooks/a.yml"

a.yml

---
- name: my_playbook
  hosts: "{{ HOSTS }}"
  force_handlers: true
  gather_facts: false

  environment:
    APP_DEFAULT_PORT: "{{ APP_DEFAULT_PORT }}"
 
  tasks:
    - name: Print Msg
      debug:
        msg: "hello"

My question is: how can I pass an additional environment variable from my main_playbook.yml playbook to my re-usable playbook a.yml (if needed) so that the environment variables become like

environment:
    APP_DEFAULT_PORT: "{{ APP_DEFAULT_PORT }}"
    SPRING_PROFILE: "{{ SPRING_PROFILE }}"
Zeitounator
  • 38,476
  • 7
  • 53
  • 66
Sanjesh M
  • 341
  • 2
  • 6
  • 22
  • yes technically will not print but you can see my key & value both has same name so it prints the value. example if say environment: APP_DEFAULT_PORT: "{{ APP_DEFAULT_PORT_VAL }}" & msg: "Port: {{ APP_DEFAULT_PORT_VAL }}" here it will fail. – Sanjesh M Sep 15 '21 at 05:09
  • anyway this is not the concern here, we can ignore the "Print msg" task – Sanjesh M Sep 15 '21 at 05:14
  • i edited the print msg as it is misleading the main ask – Sanjesh M Sep 15 '21 at 05:17

1 Answers1

0

import_playbook is not really a module but a core feature. It does not allow for any parameter to be passed to the imported playbook. You can see this keyword as a simple commodity to facilitate playing several playbooks in a row exactly as if they were defined in the same file.

So your problem comes down to:

How do I pass additional environment variables to a play?

Here is one solution with illustrations to use it with extra_vars or setting a fact from a previous play. This is far from being exhaustive but I hope it will guide you to your own best solution.

To ease readability:

  • I used the APP_ prefix for all environment variables in my below examples and filtered only on those for the results.
  • I truncated the playbook output to the only relevant debug task

We can define the following reusable.yml playbook containing a single play

 ---
 - hosts: localhost
   gather_facts: false
 
   vars:
     default_env:
       APP_DEFAULT_PORT: "{{ APP_DEFAULT_PORT | d(8080) }}"
 
   environment: "{{ default_env | combine(additionnal_env | d({})) }}"
 
   tasks:
     - name: get the output on env for APP_* vars
       shell: env | grep -i app_
       register: env_cmd
       changed_when: false
 
     - name: debug the output of env
       debug:
         var: env_cmd.stdout_lines

We can directly run this playbook as-is which will give

$ ansible-playbook reusable.yml
[... truncated ...]
TASK [debug the output of env] ************************************************************************************************************************************************************************************
ok: [localhost] => {
    "env_cmd.stdout_lines": [
        "APP_DEFAULT_PORT=8080"
    ]
}

We can override the default port with

$ ansible-playbook reusable.yml -e APP_DEFAULT_PORT=1234
[... truncated ...]
TASK [debug the output of env] ************************************************************************************************************************************************************************************
ok: [localhost] => {
    "env_cmd.stdout_lines": [
        "APP_DEFAULT_PORT=1234"
    ]
}

We can pass additional environment variables with:

$ ansible-playbook reusable.yml -e '{"additionnal_env":{"APP_SPRING_PROFILE": "/toto/pipo"}}'
[... truncated ...]
TASK [debug the output of env] ************************************************************************************************************************************************************************************
ok: [localhost] => {
    "env_cmd.stdout_lines": [
        "APP_SPRING_PROFILE=/toto/pipo",
        "APP_DEFAULT_PORT=8080"
    ]
}

Now if we want to do this from a parent playbook, we can set the needed variable for the given host in a previous play. We can define a parent.yml playbook:

 ---
 - hosts: localhost
   gather_facts: false
 
   tasks:
     - name: define additionnal env vars for this host to be used in next play(s)
       set_fact:
         additionnal_env:
           APP_WHATEVER: some_value
           APP_VERY_IMPORTANT: "ho yes!"
 
 - import_playbook: reusable.yml

which will give:

$ ansible-playbook parent.yml 
[... truncated ...]
TASK [define additionnal env vars for this host to be used in next play(s)] ************************************************************************************************************************
ok: [localhost]
[... truncated ...]
TASK [debug the output of env] ************************************************************************************************************************************************************************************
ok: [localhost] => {
    "env_cmd.stdout_lines": [
        "APP_WHATEVER=some_value",
        "APP_VERY_IMPORTANT=ho yes!",
        "APP_DEFAULT_PORT=8080"
    ]
}
Zeitounator
  • 38,476
  • 7
  • 53
  • 66