How to set environment variables of remote hosts - linux

I am having problems working with the environment variables of a remote host. For example, when I try {{ lookup('env', 'PATH') }} this returns the path of my guest machine not of the remote host.
How to pick up / change environment variables of the remote host?
my playbook :
---
- name : playbook
hosts : webservers
gather_facts: yes
remote_user: user1
vars:
Path: "{{lookup('ansible_env','PATH')}}"
roles :
- task1
- task2
- task3
that's return the path of my machine not the path of remote host named user1
i'm a beginner in ansible need some help .
thank you in advance.

You can set the PATH for a task or a playbook by using the environment keyword.
environment:
PATH: "{{ ansible_env.PATH }}:/thingy/bin"
SOME: value
The Ansible FAQ mentions this near the top http://docs.ansible.com/ansible/faq.html
So in your case try something like the following:
- name: Set Path for java
environment:
PATH: "$JAVA_HOME/bin:{{ ansible_env.PATH }}"
Setting the environment reference: http://docs.ansible.com/ansible/playbooks_environment.html

Related

Ansible: How to add Linux modul command path (opkg not in path)

My Linux box (busybox) using read-only filesystems mostly. I have option to install my programs different path like PATH=/opt/bin:/opt/sbin. The package manager also sitting in this folder (exec. file name: /opt/bin/opkg) .
When I want to use Ansible opkg module I got the following error:
"Failed to find required executable opkg in paths: /bin:/usr/bin:/bin:/usr/sbin:/sbin"
Question: How can I say to my Ansible to look for opkg package in different path?
Any ideas are welcome!
Thank you!
I found some useful link:
https://docs.ansible.com/ansible/latest/reference_appendices/faq.html
Ansible - Set environment path as inventory variable
And here is my example:
---
- hosts: CBOX-0001
gather_facts: True
gather_subset:
- "!all"
environment:
PATH: "/opt/bin:/opt/sbin:/usr/bin:/usr/sbin:{{ ansible_env.PATH }}"
collections:
- community.general
tasks:
- name: "install opkg packages"
opkg:
name: "{{ item }}"
state: present
with_items:
- screen
- mc
- rclone

Ansible-AWX get file from remote Windows to local linux

Hello to all stack overflow community.
I'm seeking you help because I've been trying to accomplish the task of getting a file from remote Windows to local linux using Ansible-AWX and I can't get it to work. Bellow I shared the playbook and most of tests I've done but none of them worked.
I'm getting latest file in a windows directory and trying to transfer that file to local AWX either inside the docker or in the linux server where AWX is running.
Test_1: Said file was copied but when I go inside the docker nothing there. I can't find an answer and couldn't find any on Google.
Test_2: Didn't work. It says can't authenticate to linux server
Test_3: Task became idle and I have to restart the docker to be able to stop it. It gets crazy. No idea why.
Test_4: It says connection unexpectedly closed.
I didn't want to provide output to reduce noise and because I can't share the information. I removed names and ips from playbook as well.
I'm connecting to Windows server using AD.
Please, I don't know what else to do. Thanks for your help in advance.
---
- name: Get file from Windows to Linux
hosts: all # remote windows server ip
gather_facts: true
become: true
vars:
local_dest_path_test1: \var\lib\awx\public\ # Inside AWX docker
local_dest_path_test2: \\<linux_ip>\home\user_name\temp\ # Outside AWX docker in the linux server
local_dest_path_test3: /var/lib/awx/public/ # Inside AWX docker
# Source file in remote windows server
src_file: C:\temp\
tasks:
# Getting file information to be copied
- name: Get files in a folder
win_find:
paths: "{{ src_file }}"
register: found_files
- name: Get latest file
set_fact:
latest_file: "{{ found_files.files | sort(attribute='creationtime',reverse=true) | first }}"
# Test 1
- name: copy files from Windows to Linux
win_copy:
src: "{{ latest_file.path }}"
dest: "{{ local_dest_path_test1 }}"
remote_src: yes
# Test 2
- name: copy files from Windows to Linux
win_copy:
src: "{{ latest_file.path }}"
dest: "{{ local_dest_path_test2 }}"
remote_src: yes
become: yes
become_method: su
become_flags: logon_type=new_credentials logon_flags=netcredentials_only
vars:
ansible_become_user: <linux_user_name>
ansible_become_pass: <linux_user_password>
ansible_remote_tmp: <linux_remote_path>
# Test 3
- name: Fetch latest file to linux
fetch:
src: "{{ latest_file.path }}"
dest: "{{ local_dest_path_test3 }}"
flat: yes
fail_on_missing: yes
delegate_to: 127.0.0.1
# Test 4
- name: Transfer file from Windows to Linux
synchronize:
src: "{{ latest_file.path }}"
dest: "{{ local_dest_path_test3 }}"
mode: pull
delegate_to: 127.0.0.1

How to run a playbook task based on OS type in ansible?

I have written a playbook task in ansible. I am able to run the playbook on linux end.
- name: Set paths for go
blockinfile:
path: $HOME/.profile
backup: yes
state: present
block: |
export PATH=$PATH:/usr/local/go/bin
export GOPATH=$HOME/go
export FABRIC_CFG_PATH=$HOME/.fabdep/config
- name: Load Env variables
shell: source $HOME/.profile
args:
executable: /bin/bash
register: source_result
become: yes
As in linux we have .profile in home directory but in Mac there is no .profile and .bash_profile in macOS.
So I want to check if os is Mac then path should be $HOME/.bash_profile and if os is linux based then it should look for $HOME/.profile.
I have tried adding
when: ansible_distribution == 'Ubuntu' and ansible_distribution_release == 'precise'
But it does not work firstly and also it is length process. I want to get path based on os in a variable and use it.
Thanks
I found a solution this way. I added gather_facts:true at top of yaml file and it started working. I started using variable as ansible_distribution.
Thanks
An option would be to include_vars from files. See example below
- name: "OS specific vars (will overwrite /vars/main.yml)"
include_vars: "{{ item }}"
with_first_found:
- files:
- "{{ ansible_distribution }}-{{ ansible_distribution_release }}.yml"
- "{{ ansible_distribution }}.yml"
- "{{ ansible_os_family }}.yml"
- "default.yml"
paths: "{{ playbook_dir }}/vars"
skip: true
- name: Set paths for go
blockinfile:
path: "$HOME/{{ my_profile_file }}"
[...]
In the playbooks' directory create directory vars and create files
# cat var/Ubuntu.yml
my_profile_file: ".profile"
# cat var/macOS.yml
my_profile_file: ".bash_profile"
If you have managed hosts with different OS, group them by OS in your inventory:
[Ubuntu]
ubu1
ubu2
[RHEL6]
RH6_1
[RHEL7]
RH7_1
RH7_2

How can I set NODE_ENV permanently with ansible?

I have 2 machines for my two environments.
The first one hosts a staging environment. It needs to have NODE_ENV set to dev.
The second one hosts a production environment. It needs to have NODE_ENV set to prod.
I provision my servers with Ansible.
How can I do this ?
Another option is set NODE_ENV at /etc/environment file.
In ansible tasks:
- lineinfile: dest=/etc/environment line="NODE_ENV=dev"
I solved the problem like so.
In roles/node-env/tasks/main.yml :
---
- name: Configure NODE_ENV
lineinfile: dest=/etc/environment regexp="^NODE_ENV=" line="NODE_ENV={{ node_env }}"
when: node_env is defined
In hosts/staging:
[webserver]
staging-server-hostname
[webserver:vars]
node_env=dev
In hosts/production:
[webserver]
production-server-hostname
[webserver:vars]
node_env=prod
In playbook.yml:
---
- name: Provision web server
hosts: webserver
sudo: true
roles:
- { role: Stouts.nodejs, tags: nodejs }
- ...
- { role: node-env, tags: nodejs }
Then I provision my staging environment with:
ansible-playbook -i hosts/staging playbook.yml
And my production environment with:
ansible-playbook -i hosts/production playbook.yml
Note that I stored my environment variable in /etc/environment because I wanted this variable set one for all and for every users.
This can also be stored in ~/.profile or in /etc/profile.d according to your needs. See this answer for more information.
It might be overkill, but it's flexible. If anyone has a simplier suggestion don't hesitate to share!

How can I access templated variables for another host in Ansible?

Background
I am deploying to a system containing multiple hosts along with a monitoring host. The monitoring host needs to use information about the other hosts to configure its monitoring checks. However, variables defined as Jinja templates in host_vars/group_vars do not work when accessed through hostvars on the monitoring host.
Example
inventory.ini
my_host ansible_connection=local
monitoring_host ansible_connection=local
host_vars/my_host
---
my_var: "{{ inventory_hostname }}"
playbook.yml
---
- hosts: my_host
tasks:
- debug: var=my_var
- hosts: monitoring_host
tasks:
- debug: var="hostvars['my_host']['my_var']"
The expectation is that the two debug task will output the same value, "my_host". In Ansible 1.7, the second debug task outputs "{{ inventory_hostname }}" (i.e. the template is not expanded). In Ansible 1.8, the second debug task outputs "monitoring_host" (i.e. the template is expanded in the wrong context).
Is this a known bug? Is there a good workaround?
I'm pretty sure this is buggy behaviour. Possible workaround:
---
- hosts: my_host
tasks:
- debug: var=my_var
- set_fact: my_var="{{ my_var }}" # Expanded in my_host context
- hosts: monitoring_host
tasks:
- debug: var="hostvars['my_host']['my_var']"

Resources