Ansible export variable not working as expected - ansible

Inside my Ansible role i'd like to create an export variable which can be used by another script later in the task. But the export is not working for some reason, what am I missing?
- name: export php1_release
shell: export php1_release=8.0
- name: Echo my_env_var again
shell: echo $php1_release
register: php
- debug: var=php
I see the following output:
ok: [example.com] => {
"php": {
"changed": true,
"cmd": "echo $php1_release",
"delta": "0:00:00.003415",
"end": "2022-10-14 20:43:48.084293",
"failed": false,
"msg": "",
"rc": 0,
"start": "2022-10-14 20:43:48.080878",
"stderr": "",
"stderr_lines": [],
"stdout": "",
"stdout_lines": []
}
}

Setting an environment only affects the current process and any subprocesses that it spawns. Each shell task in your playbook starts a new, unrelated shell process, so environment variables set in one won't be visible in another (this isn't an Ansible issue; that's just how environment variables work).
You can set the variables with Ansible instead. Here, we set the variables at the play level so they will be visible in all tasks:
- hosts: somehost
environment:
php1_release: "8.0"
tasks:
- name: Echo my_env_var again
shell: echo $php1_release
register: php
- debug:
var: php.stdout
Which will output:
TASK [debug] ********************************************************************************************
ok: [localhost] => {
"php.stdout": "8.0"
}
You can also set environment variables per task:
- hosts: localhost
tasks:
- name: Echo my_env_var again
shell: echo $php1_release
register: php
environment:
php1_release: "8.0"
- debug:
var: php.stdout
This will produce the same output, but the environment variable is only visible in the Echo my_env_var again task.

Related

Ansible - environment variable playbook

I need to set the environment in the target machine. The environment variables are present in the file called .env. There are several variables inside that file like
export AB_HOME=/tl/dev/abinit/abinit-V3 #/gcc3p32 # for 32-bit
export PATH=${AB_HOME}/bin:${PATH}
I have tried the below playbook to set the environment and register the environment variables in order to use them in the environment keyword
- hosts: dev
gather_facts: false
tasks:
- name: set the environment
shell: 'su <user_id> & . ./.env'
args:
chdir: /path for the file
register: output1
- debug: var=output1
But I am not able to find the exported environment variables in the register variable.
"changed": true,
"cmd": ". ./.env",
"delta": "0:00:00.049610",
"end": "2020-02-18 09:22:16.912490",
"failed": false,
"rc": 0,
"start": "2020-02-18 09:22:16.862880",
"stderr": "",
"stderr_lines": [],
"stdout": "",
"stdout_lines": [],
I have tried cat the file and I am able to find the variables list but I don't know how to use that in playbook. The file also contains # at starting and also after some variables like below.
export AB_HOME=/tl/dev/abinit/abinit-V3 #/gcc3p32 # for 32-bit

Ansible single task variable on top of global variable

I have a playbook where I am configuring environment variables for multiple hosts.
these are the global vars set in defaults\main.yml:
environment:
http_proxy: blabla
https_proxy: blabla
Now I have a single task where I need to set another environment variable for the python library.
However, when I set the environment var for that single task it overwrites the global environment vars.
- name: some task
command: command
environment:
ENV_VAR: "blabla"
I want the ENV_VAR for the single task to be added on top of the global vars. But is that even possible?
https://docs.ansible.com/ansible/latest/user_guide/playbooks_environment.html
this page didn't give me anything conclusive.
Could I use the with_items option to achieve this possibly?
The following playbook demonstrates a possible implementation for your requirement using the combine filter associated with default. Run this with -v option to see output of shell commands:
---
- name: Parse several results as json strings
hosts: localhost
gather_facts: false
# This will automatically combine `default_env` (default to empty if it does not exists)
# with `more_env` if this latest var is defined somewhere
environment: "{{ default_env | default({}) | combine(more_env | default({})) }}"
vars:
# Define default environment variables
default_env:
http_proxy: blabla
https_proxy: blabla
tasks:
- name: Show some vars
vars:
# Inject more environment variables for this task
more_env:
toto: titi
shell: |-
echo $http_proxy
echo $https_proxy
echo $toto
- name: Same with default env
shell: |-
echo $http_proxy
echo $https_proxy
echo $toto
Which gives:
$ ansible-playbook test.yml -v
PLAY [Default env override] ****************************************************************************************************************************************************************************************************************************
TASK [Show some vars] ***************************************************************************************************************************************************************************************************************************************************
changed: [localhost] => {"changed": true, "cmd": "echo $http_proxy\necho $https_proxy\necho $toto", "delta": "0:00:00.002207", "end": "2020-01-07 09:57:30.178989", "rc": 0, "start": "2020-01-07 09:57:30.176782", "stderr": "", "stderr_lines": [], "stdout": "blabla\nblabla\ntiti", "stdout_lines": ["blabla", "blabla", "titi"]}
TASK [Same with default env] ********************************************************************************************************************************************************************************************************************************************
changed: [localhost] => {"changed": true, "cmd": "echo $http_proxy\necho $https_proxy\necho $toto", "delta": "0:00:00.001875", "end": "2020-01-07 09:57:30.626163", "rc": 0, "start": "2020-01-07 09:57:30.624288", "stderr": "", "stderr_lines": [], "stdout": "blabla\nblabla", "stdout_lines": ["blabla", "blabla"]}
PLAY RECAP **************************************************************************************************************************************************************************************************************************************************************
localhost : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

Setting and using environment variable in Ansible

I want to set one value as an environment variable in Ansible and then use it another playbook.
Below is my playbook:
get_cmd.yaml
[root#a6296ab33a34 test_code]# vi get-cwd.yaml
- hosts: localhost
connection: local
gather_facts: False
tasks:
#- name: Get directory
# shell: export ACWD="{{ playbook_dir }}"
# when: platform == 'jenkins'
- name: Get CWD
shell: "export ACWD=/test_code_demo"
when: platform != 'jenkins'
- name: DEMO
shell: echo $ACWD
Output
[root#a6296ab33a34 test_code]# vi get-cwd.yaml
[root#a6296ab33a34 test_code]# ansible-playbook get-cwd.yaml --extra-vars="#deploy-vars.yaml" -vv
[WARNING] Ansible is being run in a world writable directory (/test_code), ignoring it as an ansible.cfg source. For more information see https://docs.ansible.com/ansible/devel/reference_appendices/config.html#cfg-in-world-writable-dir
ansible-playbook 2.8.4
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible-playbook
python version = 2.7.5 (default, Jun 20 2019, 20:27:34) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]
Using /etc/ansible/ansible.cfg as config file
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
PLAYBOOK: get-cwd.yaml *********************************************************************************************************************************************************************************************************************
1 plays in get-cwd.yaml
PLAY [localhost] ***************************************************************************************************************************************************************************************************************************
META: ran handlers
TASK [Get CWD] *****************************************************************************************************************************************************************************************************************************
task path: /test_code/get-cwd.yaml:11
changed: [localhost] => {"changed": true, "cmd": "export ACWD=/test_code_demo", "delta": "0:00:00.713703", "end": "2019-12-13 14:43:37.054390", "rc": 0, "start": "2019-12-13 14:43:36.340687", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
TASK [DEMO] ********************************************************************************************************************************************************************************************************************************
task path: /test_code/get-cwd.yaml:15
changed: [localhost] => {"changed": true, "cmd": "echo $ACWD", "delta": "0:00:00.705605", "end": "2019-12-13 14:43:37.919962", "rc": 0, "start": "2019-12-13 14:43:37.214357", "stderr": "", "stderr_lines": [], "stdout": "/test_code_dinesh", "stdout_lines": ["/test_code_dinesh"]}
META: ran handlers
META: ran handlers
PLAY RECAP *********************************************************************************************************************************************************************************************************************************
localhost : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root#a6296ab33a34 test_code]#
You can see, though I have tried to set the value to test_code_demo, still old value test_code_dinesh is reflecting.
Please let me know way to resolve the above issue.
Remember that when you set an environment variable (anywhere, not just in Ansible), it only effects the current process and its children.
When you run something like this:
- name: Get CWD
shell: "export ACWD=/test_code_demo"
when: platform != 'jenkins'
You are:
Spawning a shell
Setting the environment variable ACWD in that shell
Exiting the shell
At this point, the environment is destroyed. There's no way to set an environment variable in one task and have it effect another task. You can set per-task environment variables using the environment key on your task, like this:
- name: DEMO
shell: echo $ACWD
environment:
ACWD: '/test_code_demo'
If you need to apply the environment setting to multiple tasks, you can set it on a play instead:
- hosts: localhost
environment:
ACWD: '/test_code_demo'
tasks:
- command: 'echo $ACWD'
register: output1
- command: 'echo $ACWD'
register: output2
- debug:
msg:
- "{{ output1.stdout }}"
- "{{ output2.stdout }}"

How to set shell in module user via registered variable?

To disable logins for root I would like to set its shell to the path of nologin, which is determined by a command.
The command module registers the variable properly:
- name: Get nologin path
command: which nologin
register: nologin
- debug:
var: nologin
Debug info:
ok: [192.168.178.25] => {
"nologin": {
"changed": true,
"cmd": [
"which",
"nologin"
],
"delta": "0:00:00.001612",
"end": "2019-08-26 11:23:41.764847",
"failed": false,
"rc": 0,
"start": "2019-08-26 11:23:41.763235",
"stderr": "",
"stderr_lines": [],
"stdout": "/usr/sbin/nologin",
"stdout_lines": [
"/usr/sbin/nologin"
]
}
}
But when I use the user module it takes the registered variable as a string:
- name: Disable root
user:
name: root
shell: nologin.stdout
state: present
Result in /etc/passwd:
$ cat /etc/passwd
root:x:0:0:root:/root:nologin.stdout
Thanks for any help!
It's a variable, to use it you need to put in jinja2 template {{ }} and inside " " as it is required by YAML:
shell: "{{ nologin.stdout }}"
Ref:
https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#using-variables-with-jinja2
https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#hey-wait-a-yaml-gotcha

Register Ansible variable property

Using Ansible I'm having a problem registering a variable the way I want. Using the implementation below I will always have to call .stdout on the variable - is there a way I can do better?
My playbook:
Note the unwanted use of .stdout - I just want to be able to use the variable directly without calling a propery...?
---
- name: prepare for new deployment
hosts: all
user: ser85
tasks:
- name: init deploy dir
shell: echo ansible-deploy-$(date +%Y%m%d-%H%M%S-%N)
# http://docs.ansible.com/ansible/playbooks_variables.html
register: deploy_dir
- debug: var=deploy_dir
- debug: var=deploy_dir.stdout
- name: init scripts dir
shell: echo {{ deploy_dir.stdout }}/scripts
register: scripts_dir
- debug: var=scripts_dir.stdout
The output when I execute the playbook:
TASK [init deploy dir] *********************************************************
changed: [123.123.123.123]
TASK [debug] *******************************************************************
ok: [123.123.123.123] => {
"deploy_dir": {
"changed": true,
"cmd": "echo ansible-deploy-$(date +%Y%m%d-%H%M%S-%N)",
"delta": "0:00:00.002898",
"end": "2016-05-27 10:53:38.122217",
"rc": 0,
"start": "2016-05-27 10:53:38.119319",
"stderr": "",
"stdout": "ansible-deploy-20160527-105338-121888719",
"stdout_lines": [
"ansible-deploy-20160527-105338-121888719"
],
"warnings": []
}
}
TASK [debug] *******************************************************************
ok: [123.123.123.123] => {
"deploy_dir.stdout": "ansible-deploy-20160527-105338-121888719"
}
TASK [init scripts dir] ********************************************************
changed: [123.123.123.123]
TASK [debug] *******************************************************************
ok: [123.123.123.123] => {
"scripts_dir.stdout": "ansible-deploy-20160527-105338-121888719/scripts"
}
Any help or insights appreciated - thank you :)
If I understood it right you want to assign deploy_dir.stdout to a variable that you can use without stdout key. It can be done with set_fact module:
tasks:
- name: init deploy dir
shell: echo ansible-deploy-$(date +%Y%m%d-%H%M%S-%N)
# http://docs.ansible.com/ansible/playbooks_variables.html
register: deploy_dir
- set_fact: my_deploy_dir="{{ deploy_dir.stdout }}"
- debug: var=my_deploy_dir

Resources