Hi All,
I am declaring an environment variables in a playbook as shown below:
Hi All,
I am declaring an environment variables in a playbook as shown below:
Hi All,
I am declaring an environment variables in a playbook as shown below:
- hosts: localhost
environment:
script_var1: hi
script_var2: there
tasks:- name: List
shell: bash test.sh
–I want to test the existence of the above environment variables in a separate task.yml file. How do I test their existence ? What is the syntax ?
Testing for existence means (in ansible terms) that you check if they’re defined.
If you just want to make sure they’re defined, you could use the assert module: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/assert_module.html
ansible.builtin.assert:
that:
etc
You say “separate task.yml file” - but what you have is not a task file but a playbook.
If you want to have the assert task in another file, then you should create that and then import that in your main playbook.
For example:
You can run a shell task, echo the variables, register the result, and examine that. Otherwise:
**[utoddl@tango ansible]$ cat ygkumar0.yml**
---
# Playbook ygkumar0.yml
- name: Test environment variables in included tasks file
hosts: localhost
gather_facts: false
environment:
script_var1: hi
script_var2: there
tasks:
- name: Run tasks file
ansible.builtin.include_tasks:
file: tasks/ygkumar0.yml
**[utoddl@tango ansible]$ cat tasks/ygkumar0.yml**
---
# tasks/ygkumar0.yml
- name: Test environment variables by shell script
ansible.builtin.shell: |
echo "We're here."
echo "script_var0: '${script_var0-missing}'"
echo "script_var1: '${script_var1-missing}'"
echo "script_var2: '${script_var2-missing}'"
echo "script_var3: '${script_var3-missing}'"
- name: Examine env vars directly
<i> # THIS WON'T WORK! ansible.builtin.env allows you to query
# the environment variables available on the controller when you invoked Ansible,
# not the environment that tasks on the remote nodes see.</i>
ansible.builtin.debug:
msg:
- "script_var0: {{ lookup('ansible.builtin.env', 'script_var0:') | default('missing') }}"
- "script_var1: {{ lookup('ansible.builtin.env', 'script_var1:') | default('missing') }}"
- "script_var2: {{ lookup('ansible.builtin.env', 'script_var2:') | default('missing') }}"
- "script_var3: {{ lookup('ansible.builtin.env', 'script_var3:') | default('missing') }}"
**[utoddl@tango ansible]$ ansible-playbook ygkumar0.yml -vv**
ansible-playbook [core 2.14.10]
config file = /etc/ansible/ansible.cfg
configured module search path = ['/home/utoddl/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3.11/site-packages/ansible
ansible collection location = /home/utoddl/.ansible/collections:/usr/share/ansible/collections
executable location = /usr/bin/ansible-playbook
python version = 3.11.5 (main, Aug 28 2023, 00:00:00) [GCC 13.2.1 20230728 (Red Hat 13.2.1-1)] (/usr/bin/python3)
jinja version = 3.0.3
libyaml = True
Using /etc/ansible/ansible.cfg as config file
redirecting (type: callback) ansible.builtin.yaml to community.general.yaml
redirecting (type: callback) ansible.builtin.yaml to community.general.yaml
Skipping callback 'default', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.
PLAYBOOK: ygkumar0.yml *****************************************************************************
1 plays in ygkumar0.yml
PLAY [Test environment variables in included tasks file] *******************************************
TASK [Run tasks file] ******************************************************************************
task path: /home/utoddl/ansible/ygkumar0.yml:10
included: /home/utoddl/ansible/tasks/ygkumar0.yml for localhost
TASK [Test environment variables by shell script] **************************************************
task path: /home/utoddl/ansible/tasks/ygkumar0.yml:3
changed: [localhost] => changed=true
cmd: |-
echo "We're here."
echo "script_var0: '${script_var0-missing}'"
echo "script_var1: '${script_var1-missing}'"
echo "script_var2: '${script_var2-missing}'"
echo "script_var3: '${script_var3-missing}'"
delta: '0:00:00.002717'
end: '2023-10-12 11:12:48.601248'
msg: ''
rc: 0
start: '2023-10-12 11:12:48.598531'
stderr: ''
stderr_lines: <omitted>
stdout: |-
We're here.
script_var0: 'missing'
script_var1: 'hi'
script_var2: 'there'
script_var3: 'missing'
stdout_lines: <omitted>
TASK [Examine env vars directly] *******************************************************************
task path: /home/utoddl/ansible/tasks/ygkumar0.yml:11
ok: [localhost] =>
msg:
- 'script_var0: '
- 'script_var1: '
- 'script_var2: '
- 'script_var3: '
PLAY RECAP *****************************************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Another thing you might consider is using a YAML reference to duplicate the environment in a regular playbook variable. Then you can use plain old variable references to see those values. See the example below:
**[utoddl@tango ansible]$ cat ygkumar1.yml**
---
# Playbook ygkumar1.yml
- name: Copy environment to testable variables using YAML reference
hosts: localhost
gather_facts: false
<b>environment: &environment
script_var1: hi
script_var2: there</b>
vars:
pb_dict:
not_env_var1: foo
not_env_var2: bar
<b>env_vars: *environment</b>
other_stuff: bas
tasks:
- name: Dump pb_dict to the job log
ansible.builtin.debug:
var: pb_dict
- name: Shell script to loop over pb_dict.env_vars
changed_when: false
ansible.builtin.shell: |
for vname in {{ pb_dict.env_vars.keys() | map('quote') | join(' ') }} ; do
printf -- "Environment variable %s: %s\n" "$vname" "$(eval echo \${$vname} )"
done
**[utoddl@tango ansible]$ ansible-playbook ygkumar1.yml -vv**
ansible-playbook [core 2.14.10]
config file = /etc/ansible/ansible.cfg
configured module search path = ['/home/utoddl/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3.11/site-packages/ansible
ansible collection location = /home/utoddl/.ansible/collections:/usr/share/ansible/collections
executable location = /usr/bin/ansible-playbook
python version = 3.11.5 (main, Aug 28 2023, 00:00:00) [GCC 13.2.1 20230728 (Red Hat 13.2.1-1)] (/usr/bin/python3)
jinja version = 3.0.3
libyaml = True
Using /etc/ansible/ansible.cfg as config file
redirecting (type: callback) ansible.builtin.yaml to community.general.yaml
redirecting (type: callback) ansible.builtin.yaml to community.general.yaml
Skipping callback 'default', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.
PLAYBOOK: ygkumar1.yml **********************************************************************
1 plays in ygkumar1.yml
PLAY [Copy environment to testable variables using YAML reference] **************************
TASK [Dump pb_dict to the job log] **********************************************************
task path: /home/utoddl/ansible/ygkumar1.yml:16
ok: [localhost] =>
pb_dict:
<b>env_vars:
script_var1: hi
script_var2: there</b>
not_env_var1: foo
not_env_var2: bar
other_stuff: bas
TASK [Shell script to loop over pb_dict.env_vars] *******************************************
task path: /home/utoddl/ansible/ygkumar1.yml:20
ok: [localhost] => changed=false
cmd: |-
for vname in script_var1 script_var2 ; do
printf -- "Environment variable %s: %s\n" "$vname" "$(eval echo \${$vname} )"
done
delta: '0:00:00.003708'
end: '2023-10-13 07:58:40.898459'
msg: ''
rc: 0
start: '2023-10-13 07:58:40.894751'
stderr: ''
stderr_lines: <omitted>
stdout: |-
Environment variable script_var1: hi
Environment variable script_var2: there
stdout_lines: <omitted>
PLAY RECAP **********************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Hi All,
Thanks for the responses. I am facing another issue with env variables.
I want to register a variable to capture the output of a shell command as shown below. So far its fine…
But I also want to save that command result in a remote environment variable and that is not working. My playbook is as follows:
This is because the expression in the environment parameter is evaluated before the task, and at that time it is not yet known.
In general, if you need the output of a command to actually run the command, that seems like a circular dependency to me.
Ansible will not help you fix that.
So, you mean to say that we can’t achieve this in ansible ?
It might help if you can describe what you’re trying to achieve more broadly.
Typically, if you’re trying to do something complicated, and propagate state from task to task with loads of ansible.builtin.shell, you are likely to be approaching the task from the wrong angle.
What Dick’s tried to explain is that the environment keyword used in the way you’ve used it in your example, sets the environment for the task at the level it’s running. Not for future tasks, which seems to be what you want/expect.
You presumably want to use disk_count.stdout in a subsequent task. So you would set disk_count.stdout in the environment clause for a subsequent task. (And you’d need to format it for use as an environment variable. Read the docs.)
Ultimately though, if you’re jumping through a bunch of hoops like this you probably want to step back from shell and environment variables and think about 1) what you’re trying to achieve end-to-end and 2) how you might do that using native modules rather than shell/command.?