Not able to gather facts of ansible host machine - ansible

Set up module in ansible gives an error when i tried to set custom facts on host machine using control machine
---
- hosts: test-servers
gather_facts: false
tasks:
- name: deleting Facts directory
file:
path: /etc/ansible/facts.d/
state: absent
- name: Creates a directiory
file:
path: /etc/ansible/facts.d/
recurse: yes
state: directory
- name: Copy custom date facts to host machine
copy:
src: /app/ansible_poc/roles/custom_facts/templates/facts.d/getdate.fact
dest: /etc/ansible/facts.d/getdate.fact
mode: 0755
- name: Copy custom role facts to host machine
copy:
src: /app/ansible_poc/roles/custom_facts/templates/facts.d/getrole.fact
dest: /etc/ansible/facts.d/getrole.fact
mode: 0755
- name: Reloading facts
setup:
- name: Display message
debug:
msg: "{{ ansible_local.getdate.date.date }}"
- name: Display message
debug:
msg: "{{ ansible_local.getrole.role.role }}"
I get following error when i tried to collect facts of ansible host machine. I have set up a file getdate.fact and getrole.fact which has code respectively
#############getdate.fact###############
echo [date]
echo date= `date`
########################################
#############getrole.fact###############
echo [role]
echo role= `whoami`
########################################
and when i tried to run the playbook main.yml then it following error.
[root#ansibletower tasks]# ansible -m setup test-servers
192.168.111.28 | FAILED! => {
"changed": false,
"cmd": "/etc/ansible/facts.d/getdate.fact",
"msg": "[Errno 8] Exec format error",
"rc": 8
}
192.168.111.27 | FAILED! => {
"changed": false,
"cmd": "/etc/ansible/facts.d/getdate.fact",
"msg": "[Errno 8] Exec format error",
"rc": 8
}

If I recall correctly, executables are expected to return JSON:
#!/bin/bash
echo '{ "date" : "'$( date )'" }'

You probably need to add "shebang" line to your fact scripts. I.e., getdate.fact should look like:
#!/bin/sh
echo [date]
echo date=`date`

Related

Save ansible variable in local file

I am executing a PS script on a windows host and want to store its stdout in a file on an ansible local machine. I have a playbook like following:
---
- name: Check Antivirus software
hosts: all
become: false
gather_facts: no
tasks:
- name: Get AV details
win_shell: |
echo "script printing data on stdout"
register: result
- name: save response
copy:
content: '{{ result.stdout }}'
dest: '{{ response_file }}'
delegate_to: localhost
From the above playbook, 1st task gets executed without any issues. But 2nd task gives the following error.
TASK [save response] *******************************************************************************************************************************************
fatal: [20.15.102.192 -> localhost]: UNREACHABLE! => {"changed": false, "msg": "ntlm: HTTPSConnectionPool(host='localhost', port=5986): Max retries exceeded with url: /wsman (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x7f4940760208>: Failed to establish a new connection: [Errno 111] Connection refused',))", "unreachable": true}
I also tried local_action which is also giving the same error.

ansible copy module AnsibleUndefined error

I have below task to copy the content of file difference and there is no error but it output "AnsibleUndefined " into destination file
- name: dff tesk
local_action: shell diff -s --unified=0 /src/path/{{ item }} /dest/path/{{ item }}
with_items:
- file1.yml
- file2.yml
register: file_cmp
- name: copy
copy:
content: "{{ file_cmp.results | map(attribute='stdout') | list }}"
dest: "/path/to_dest/file_cmp.log
remote_src: yes
The task do not result in any error and create output file with content
AnsibleUndefined,AnsibleUndefined,AnsibleUndefined,AnsibleUndefined,AnsibleUndefined
The same playbook works and generate correct when executed locally.
"results": [
{
"ansible_loop_var" : "item"
"changed": "false"
"failed": "false"
"failed_when_result":"false"
"item": "fail1.yml"
"module_stderr":"sudo : effective uid is not 0 is /bin/sudo on a file system with the nosuid option set or an NFS file system without root priviledges ?" "msg": "MODULE FAILURE"
"rc": "1"

Edit excel file locally based on remote host condition ansible playbook

I am trying to update a XLSX file locally using this module : https://github.com/mohameosam/open_excel
I have succeed to update the XLSX file when running a task without "Conditional Variables". But when I try to run it with "When" variable. It shows error below :
TASK [Update predepchk] ****************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Unsupported parameters for (open_excel) module: when Supported parameters include: attributes, backup, cell_style, content, delimiter, dest, directory_mode, follow, force, group, index_by_name, mode, op, owner, read_range, regexp, remote_src, selevel, serole, setype, seuser, sheet_name, src, unsafe_writes, updates_matrix"}
Here is my ansible yml file :
---
- hosts: all
tasks:
- name: Ping all hosts
ping:
- name: Print a message
debug:
msg: 'All set'
- name: Show facts available on the system
ansible.builtin.debug:
var: ansible_facts
- name: PredepCHK
hosts: localhost
connection: local
gather_facts: no
tasks:
- name: Update predepchk
open_excel:
src: "/root/Documents/Ansible/XLSX/predepchk.xlsx"
dest: "/root/Documents/Ansible/XLSX/predepchk_updated.xlsx"
sheet_name: "predepchk"
op: "w"
updates_matrix: "{{ [{'cell_row': 21, 'cell_col': 1, 'cell_value': 1}] }}"
when: ansible_facts['distribution'] == "Debian" and ansible_facts['distribution_major_version'] == "9"
My question will be:
Can I pass this remote host condition to my local tasks?
As answered by #Zeitounator .
It's because I have my when: conditional statement where was not the same level as "name: / open_excel:"

group_names variable in ansible

I am running some issues when I execute this playbook:
- hosts: all
connection: local
tasks:
- template: src=/etc/ansible/{{group_names}}/common.j2 dest=/etc/ansible/configs/{{inventory_hostname}}.txt
name: create common config snippets
the error that I am getting is:
fatal: [R1]: FAILED! => {"changed": false, "failed": true, "msg": "Unable to find '/etc/ansible/[u'ios']/common.j2' in expected paths."}
fatal: [R2]: FAILED! => {"changed": false, "failed": true, "msg": "Unable to find '/etc/ansible/[u'ios1']/common.j2' in expected paths."}
and here are my groups:
/etc/ansible# cat hosts | grep ios
[ios]
[ios1]
and here are my common.j2 files:
/etc/ansible# ls ios1/
common.j2
/etc/ansible# ls ios/
common.j2
Could someone elaborate why the group_names returns [u'group_names] please?
Because group_names a list (that's why it is surrounded by [ ]) -- a host can belong to multiple groups.
You need to decide, what is your objective:
If you wanted to include files for all groups, you have to add a loop:
- hosts: all
connection: local
tasks:
- name: create common config snippets
template:
src: /etc/ansible/{{item}}/common.j2
dest: /etc/ansible/configs/{{inventory_hostname}}.txt
with_items: "{{group_names}}"
If you wanted to add a single group, you could refer to a single element (group_names[0]), but that doesn't seem practical...

Ansible set_fact across plays

I have to run an ansible playbook to execute the following tasks
1) Calculate date in YYYY_MM_DD format and then use this prefix to download some file from aws to my local machine. The filename is of the following format 2015_06_04_latest_file.csv
2) I have to then create a folder by the name 2015_06_04 into multiple hosts and upload this file there.
This is my current playbook -
---
- hosts: 127.0.0.1
connection: local
sudo: yes
gather_facts: no
tasks:
- name: calculate date
shell: date "+%Y_%m_%d" --date="1 days ago"
register: output
- name: set date variable
set_fact: latest_date={{ item }}
with_items: output.stdout_lines
- local_action: command mkdir -p /tmp/latest_contracts/{{ latest_date }}
- local_action: command /root/bin/aws s3 cp s3://primarydatafolder/data/{{ latest_date }}_latest_data.csv /tmp/latest_contracts/{{ latest_date }}/ creates=/tmp/latest_contracts/{{ latest_date }}/latest_data.csv
register: result
ignore_errors: true
- local_action: command /root/bin/aws s3 cp s3://secondarydatafolder/data/{{ latest_date }}_latest_data.csv /tmp/latest_contracts/{{ latest_date }}/ creates=/tmp/latest_contracts/{{ latest_date }}/latest_data.csv
when: result|failed
# remove the date prefix from the downloaded file
- local_action: command ./rename_date.sh {{ latest_date }}
ignore_errors: true
- hosts: contractsServers
sudo: yes
gather_facts: no
tasks:
- name: create directory
file: path={{item.path}} state=directory mode=0775 owner=root group=root
with_items:
- {path: '/var/mukul/contracts/{{ latest_date }}' }
- {path: '/var/mukul/contracts/dummy' }
- name: copy dummy contracts
copy: src=dummy dest=/var/mukul/contracts/
- name: delete previous symlink
shell: unlink /var/mukul/contracts/latest
ignore_errors: true
- name: upload the newly created latest date folder to the host
copy: src=/tmp/latest_contracts/{{ latest_date }} dest=/var/mukul/contracts/
- name: create a symbolic link to the folder on the host and call it latest
action: file state=link src=/var/mukul/contracts/{{ latest_date }} dest=/var/mukul/contracts/latest
As per ansible's documentation on set_fact variable, this variable latest_date should be available across plays. However, ansible fails with the following message
failed: [192.168.101.177] => (item={'path': u'/var/mukul/contracts/{# latest_date #}'}) => {"failed": true, "item": {"path": "/var/mukul/contracts/{# latest_date #}"}}
msg: this module requires key=value arguments (['path=/var/mukul/contracts/{#', 'latest_date', '#}', 'state=directory', 'mode=0775', 'owner=root', 'group=root'])
It looks as if the second playbook is unable to get the value of the latest_date fact. Can you please tell me where i'm making a mistake?
Facts are host specific. As the documentation about set_fact says, "[v]ariables [set with set_fact] are set on a host-by-host basis".
Instead, I'd try using run_once as defined in Delegation, rolling updates, and local actions, like this:
- hosts: contractsServers
tasks:
- name: Determine date
local_action: shell: date "+%Y_%m_%d" --date="1 days ago"
register: yesterday
always_run: True
changed_when: False
run_once: True
- name: Do something else locally
local_action: ...
register: some_variable_name
always_run: True
changed_when: False
run_once: True
- name: Do something remotely using the variables registered above
...
You could enable fact-caching. You will need to set up a local redis instance where facts then will be stored.

Resources