ansible script to set gradle home? - gradle

How to set gradle home using ansible script. I have a directory gradle_user_home in RHEL. I'm trying to set gradle home to this directory with ansible script. But ansible script says no such file or directory! Below is my script.
- name: Set gradle environment variable
command: export GRADLE_USER_HOME={{gradle_home}}
My vars file:
gradle_home: "/data1/deployment/gradle_user_home"

First of all, export is not a command (ie there is no /bin/export executable). It is a bash built-in. That's why you get a no such file or directory. You can use it in a shell task, not in a command task.
Secondly, this is not the proper way to set environment variables with Ansible.
You can set environment at the play level like this:
---
- hosts: all
environment:
GRADLE_USER_HOME: "{{gradle_home}}"
Or at the task level like this:
- name: Execute gradle build
shell: gradle build
environment:
GRADLE_USER_HOME: "{{gradle_home}}"

You can not export an environment variable in a single command task, because each command task is run in its own shell. After the command finishes the environment variable is lost.
You have to use the shell action to
set the environment variable and
run the command.
Example:
- name: Run the command
shell: >-
export GRADLE_USER_HOME={{gradle_home}}
my_command_which_requires_gradle_user_home

Related

How to export or convert Ansible playbook to a Bash script?

I need to export a rather long Ansible playbook to a Bash script.
The idea is to have a bash script that runs the same commands that Ansible would run from the playbook if the playbook was executed, with all Ansible variables properly resolved.
I need this because I want to run this playbook's commands sequence in an environment where Ansible does not exist or is not used.

Execute environment file in ansible

I am trying to setup a playbook which will execute the env file of a service before running the command to stop the service.
Note that stop or start service command will only work after execute that env file.
The command to execute the env file is . ./.env_file_name or ksh .env_file_name
I am not able to execute the file using the above command in command module and shell module.
How to execute the above env file in ansible ?
How to run the stop command after executing the env file ?
If env file contains some environment variables that you need to set before running stop, then you can read the file, store results in a variable, then use environment keyword to provide them to the task, that actually stops the service.
Alternatively, you can add multiple commands in shell module at once, like so:
- name: Example for a shell module
shell:
cmd: |
./.env_file_name
./stop.sh (insert command to stop the service here)

Accessing OS environment variables within a Jenkinsfile

Is this possible? I'm trying to access the linux env variable M2_REPO inside my Jenkinsfile using the Jenkins pipeline plugin, however it's constantly empty. I can run it on my bash shell just fine:
root#host-VirtualBox:~# echo $M2_REPO
/media/sf_apache-maven-repository
But running the command in a Jenkinsfile doesn't print anything:
sh 'echo $M2_REPO'
Does the Jenkinsfile have access to OS env variables?
When I set the variable using the Environment Inject plugin in jenkins it worked..

Loading global environment variables in an Ansible task

I have several global environment variables set in /etc/environment on my target machine that I need to present when running some Ansible tasks. E.g.
MY_VAR=Some global variable
The value of these global variables are not known to Ansible so I can't use the environment functionality.
Example task:
- shell: echo MY_VAR is $MY_VAR
register: my_var
- debug: msg={{ my_var.stdout }}
The output I get is MY_VAR is where I would like it to be MY_VAR is Some global variable. I understand that this is happening because non-interactive Bash shells (which Ansible uses) don't load the environment from /etc/environment, but is there a way to execute my command in the context of that environment?
Note: I don't actually want to retrieve the value of the environment variable (as shown above), I just want it to be present in the context that I execute the shell task in.
Remote environment variables are available via facts using the the ansible_env variable.
This prints out all variables of the user Ansible logs into a remote host with:
- debug: var=ansible_env
If global environment variables not available to the Ansible user, they can be sourced in a task before running your command:
- shell: . /etc/environment && commandhere

Ansible doesn't load ~/.profile

I'm asking myself why Ansible doesn't source ~/.profile file before execute template module on one host ?
Distant host ~/.profile:
export ENV_VAR=/usr/users/toto
A single Ansible task:
- template: src=file1.template dest={{ ansible_env.ENV_VAR }}/file1
Ansible fail with:
fatal: [distant-host] => One or more undefined variables: 'dict object' has no attribute 'ENV_VAR'
Ansible is not running remote tasks (command, shell, ...) in an interactive nor login shell. It's same like when you execute command remotely via 'ssh user#host "which python"'
To source ~/.bashrc won't work often because ansible shell is not interactive and ~/.bashrc implementation by default ignores non interactive shell (check its beginning).
The best solution for executing commands as user after its ssh interactive login I found is:
- hosts: all
tasks:
- name: source user profile file
#become: yes
#become_user: my_user # in case you want to become different user (make sure acl package is installed)
shell: bash -ilc 'which python' # example command which prints
register: which_python
- debug:
var: which_python
bash: '-i' means interactive shell, so .bashrc won't be ignored
'-l' means login shell which sources full user profile (/etc/profile and ~/.bash_profile, or ~/.profile - see bash manual page for more details)
Explanation of my example: my ~/.bashrc sets specific python from anaconda installed under that user.
Ansible is not running tasks in an interactive shell on the remote host. Michael DeHaan has answered this question on github some time ago:
The uber-basic description is ansible isn't really doing things through the shell, it's transferring modules and executing scripts that it transfers, not using a login shell.
i.e. Why does an SSH remote command get fewer environment variables then when run manually?
It's not a continous shell environment basically, nor is it logging in and typing commands and things.
You should see the same result (undefined variable) by running this:
ssh <host> echo $ENV_VAR
In a lot of places I've used below structure:
- name: Task Name
shell: ". /path/to/profile;command"
when ansible escalates the privilige to sudo it don't invoke the login shell of sudo user
we need to make changes in the way we call sudo like invoking it with -i and -H flags
"sudo_flags=-H" in your ansible.cfg file
If you can run as root, you can use runuser.
- shell: runuser -l '{{ install_user }}' -c "{{ cmd }}"
This effectively runs the command as install_user in a fresh login shell, as if you had used su - *install_user* (which loads the profile, though it might be .bash_profile and not .profile...) and then executed *cmd*.
I'd try not to run everything as root just so you can run it as someone else, though...
If you can modify the configuration of your target host and don't want to change your ansible yaml code. You can try this:
add the variable ENV_VAR=/usr/users/toto into /etc/environment file rather than ~/.profile.
shell: "bash -l scala -version"
by using bash -l will allow ansible to load corresponding bash_profile.
bash: '-i' (interactive shell) won't allow the ansible to run other task.
add the variable ENV_VAR=/usr/users/toto into /etc/environment file rather than ~/.profile.
You really can use /etc/environment, but only if a variable has a static value. If we use variable which gets the value of another variable it doesn't work. For example, if we put this line to /etc/environment
XDG_RUNTIME_DIR=/run/user/$(id -u)
Ansible can see exactly XDG_RUNTIME_DIR=/run/user/$(id -u), not XDG_RUNTIME_DIR=/run/user/1012.
And if we put this line to ~/.bash_profile or ~/.bashrc:
export XDG_RUNTIME_DIR=/run/user/$(id -u)
User can see XDG_RUNTIME_DIR=/run/user/1012 (if user's id is 1012) when he works manually, but Ansible doesn't get variable XDG_RUNTIME_DIR at all.

Resources