How to execute shell commands in ansible containing special characters - ansible

How to execute shell commands in ansible along with special characters?
---
- name: Displaying the ORACLE_HOME
hosts: "{{ hostname }}"
tasks:
- name:
shell: echo $ORACLE_HOME
I want the output of echo $ORACLE_HOME

You need to write something like this :
---
- name: Displaying the ORACLE_HOME
hosts: "{{ hostname }}"
tasks:
- name:
shell: echo $ORACLE_HOME
register: var
- debug: msg="{{ var }}"
or
you can use the registered variable as var.stdout in your code.
As per your comment, use below command to use the shell variable in your playbook :
shell: source <Absolute-Path>/.bash_profile && echo $ORACLE_HOME

Related

How to Use command in Envoirment Variable Ansible Playbook

I am trying to use hostname -f command in variable with ansible-playbook. After I set the variable, I will use it in sed command. When manually execute the commands it works but with Ansible, variable does not work.
When I echo $hostn output is empty.
---
- hosts: test
become: true
become_user: root
tasks:
- name: test
shell: "{{ item }}"
with_items:
- hostn=`hostname -f` <<<<<< not working
- echo $hostn <<<<<< not working
- sed -i "s/test/$hostn/g" /file <<<< manually works
Can you help me?
My advise would be that you should not try to fit all your commands in Ansible shell this way, but rather translate them into the corresponding Ansible modules.
What you are looking to achieve can be done with the replace module — in place of sed — and the Ansible fact ansible_hostname — in place of hostname -f.
This would be the equivalent playbook:
- hosts: test
become: true
become_user: root
tasks:
- replace:
path: /file
regexp: test
replace: "{{ ansible_hostname }}"

How to set shell output to a variable in ansible

I need to get a shell output to a variable in set_fact in ansible. And this variable is referred in the somewhere in the same playbook but targeting a different set of hosts
But I am not sure how to do that.
This is my playbook:
---
- hosts: kube-master
tasks:
- name: Print the value
become: true
shell: |
echo "hi"
set_fact:
banuka: <value-taken-from-above-shell-command>
- hosts: kube-minions
tasks:
- name: Print the variable
become: true
shell: |
echo {{banuka}}
But I don't know these:
1. How to get the shell command output to the variable in set_fact and refer it somewhere
2. Is it possible to have multiple hosts (as shown in the above playbook)
I would do it the following way:
---
- hosts: master01
tasks:
- name: Print the value
shell: |
echo "hi"
register: somevariablename
- name: set fact
set_fact:
myvar: "{{ somevariablename.stdout }}"
- hosts: kube-minions
tasks:
- name: Print the variable
shell: |
echo "{{ hostvars['master01'].myvar }}"
It's important to understand, that set_fact only set a variable on the host which it's executed. Since you have a group kube-master it could be executed on each. I had the same issue in a playbook with Kubernetes-Masters and i used one of them as a "primary" e.q. master01. Then the echo hi will only be executed on that one.
In the second hostgroup, you must refer to the hostvars of your kube-master host like the master01.
Do you have the need to run over all the hosts in the group kube-master?

Ansible set environment variable from a file and access it within the playbook

I have the below Ansible script which runs on localhost
- name: set env
shell: ". /tmp/testenv"
- name: get env
debug:
msg: "{{ lookup('env','TEST') }}"
In above script I'm trying to source the file and access the environment variables using the lookup. But it seems like environment variable is not set. Is there anyway I can get this to work?
The shell command is one process and the lookup looks in the environment of the Ansible process, which is a different one. You have to echo the environment variable in your shell command and register the result.
- hosts: localhost
connection: local
gather_facts: no
tasks:
- name: set env
shell: "echo 'export TEST=test' > /tmp/testenv"
- name: check env
shell: ". /tmp/testenv; echo $TEST"
register: result
- name: get env
debug:
msg: "{{ result.stdout }}"

How to permanently set environment variable?

Host is Ubuntu 16.04
I'm trying to set environment variable for user, with:
- hosts: all
remote_user: user1
tasks:
- name: Adding the path in the bashrc files
lineinfile: dest=/home/user1/.bashrc line='export MY_VAR=TEST' insertafter='EOF' state=present
- name: Source the bashrc file
shell: . /home/user1/.bashrc
- debug: msg={{lookup('env','MY_VAR')}}
Unfortunately it outputs:
TASK [debug] *******************************************************************
ok: [xxxxx.xxx] => {
"msg": ""
}
How can I export variable so next time I run some tasks on this machine I can use {{ lookup('env', 'MY_VAR') }} to get value of this variable?
Because lookups happen locally, and because each task runs in it's own process, you need to do something a bit different.
- hosts: all
remote_user: user1
tasks:
- name: Adding the path in the bashrc files
lineinfile: dest=/home/user1/.bashrc line='export MY_VAR=TEST' insertafter='EOF' state=present
- shell: . /home/user1/.bashrc && echo $MY_VAR
args:
executable: /bin/bash
register: myvar
- debug: var=myvar.stdout
In this example I am sourcing the .bashrc and checking the var in the same command, and storing the value with register
All lookups in Ansible are local. See documentation for details:
Note
Lookups occur on the local computer, not on the remote computer.

Ansible Set Dynamic Environment Variables

I know about Ansible's environment: command at the top of playbook, but I don't think that will work for me seeing how I don't know the variables value prior to the execution of the playbook. I'm trying to retrieve package versions and PHP Modules and log them to a file. I want to use regex to capture the version and store it to an environment variable. Then I want to write that variable equals that variable's value to an environment file with a shell command. I also want to pull an array from the environment and loop through that. Ansible doesn't seem to persist the shell environment and the environment variable gets wiped out between commands. This is simple in Bash. Is this possible in Ansible? I'm trying:
---
- hosts: all
become: yes
vars:
site_variables:
code_directory: /home/
dependency_versions:
WGET_VERSION: placeholder
PHP_MODULES: placeholder
tasks:
- name: Retrieve Environment
shell: export WGET_VERSION=$(wget --version | grep -o 'Wget [0-9]*.[0-9]*\+')
shell: export PHP_MODULES=$(php -m)
shell: echo "export {{ item }}={{ lookup('env', item ) }}" >> {{ site_variables.code_directory }}/.env.log
with_items:
- WGET_VERSION
- name: Write PHP Modules Out
shell: export PHP_MODULES=$(php -m)
shell: export PHP_MODULES=$(echo {{ lookup('env', 'PHP_MODULES') }} | sed 's/\[PHP Modules\]//g')
shell: export PHP_MODULES=$(echo {{ lookup('env', 'PHP_MODULES') }} | sed 's/\[Zend Modules\]//g')
shell: export PHP_MODULES=({{ lookup('env', 'PHP_MODULES') }})
shell: echo "# - {{ item.0 }}" >> {{ site_variables.code_directory }}/.env.log
with_items:
- "{{ lookup('env', 'PHP_MODULES') }}"
There's a lot going on here.
First, lookup always runs on the ansible control host, while the script that you pass to the shell module is running on the remote server. So you will never be able to get a remote environment variable using lookup.
For details: https://docs.ansible.com/ansible/playbooks_lookups.html
Secondly, environment variables don't propagate from a child to parent. If you have a script that does this...
export MYVARIABLE=foo
...and you run that script, your current environment will not suddenly have a variable named MYVARIABLE. This is just as true for processes spawned by Ansible as it is for processes spawned by your shell.
If you want to set an ansible variable, consider using the register keyword to get the value:
- hosts: localhost
gather_facts: false
tasks:
- name: get wget version
command: wget --version
register: wget_version_raw
- name: extract wget version
set_fact:
wget_version: "{{ wget_version_raw.stdout_lines[0].split()[2] }}"
- name: show wget version
debug:
msg: "wget version is: {{ wget_version }}"

Resources