Unable to fetch existing file. Error: "the remote file does not exist, not transferring, ignored" - file

I want ansible to read a csv file in test server (10.15.170.22), but keep getting this error : "the remote file does not exist, not transferring, ignored".
This is how I structured my playbooks:
- name: Find files in sub-folders
hosts: testserverhost
tasks:
- name: Search for files in folder
win_find:
paths: C:\folder\data\
register: file
- name: set_fact
set_fact:
filename: "{{ file | json_query('files[0].filename') }}"
Since there seems to be no way for ansible to directly read the file in test server 10.15.170.22, I had to include a fetch file task before the read_csv task.
- name: Fetching file and reading data
hosts: localhost
tasks:
- name: Set fact
set_fact:
filename: "{{ hostvars['10.15.170.22']['filename'] }}"
- name: Fetch file from test server to ansible controller server
fetch:
src: C:\folder\data\{{ filename }}
dest: /var/lib/awx/projects/ansibleproject/testproject/
flat: yes
- name: Read file
read_csv:
path: /var/lib/awx/projects/ansibleproject/testproject/{{ filename }}
key: FirstName
fieldnames: FirstName,LastName
delimiter: ','
register: userdata
Output of playbooks:
TASK [Search for files in folder] ********************************************************************************************
ok: [10.15.170.22] => {"changed": false, "examined": 1, "files": [{"attributes": "Archive", "checksum": "b86f10b0f2305c6c97a1464c19d9f53dce6b0367", "creationtime": 1676388747.9286883, "exists": true, "extension": ".csv", "filename": "testdata.csv", "hlnk_targets": [], "isarchive": true, "isdir": false, "ishidden": false, "isjunction": false, "islnk": false, "isreadonly": false, "isreg": true, "isshared": false, "lastaccesstime": 1676388747.9504724, "lastwritetime": 1676301040, "lnk_source": null, "lnk_target": null, "nlink": 1, "owner": "BUILTIN\\Administrators", "path": "C:\\folder\\data\\testdata.csv", "sharename": null, "size": 1225}], "matched": 1}
TASK [set_fact] ********************************************************************************************
ok: [10.15.170.22] => {
"ansible_facts": {
"filename": "testdata.csv"
},
"changed": false
}
TASK [Set fact] ********************************************************************************************
ok: [localhost] => {
"ansible_facts": {
"filename": "testdata.csv"
},
"changed": false
}
TASK [Fetch file from test server to ansible controller server] ********************************************************************************************
fatal: [localhost]: FAILED! => {
"changed": false,
"invocation": {
"module_args": {
"src": "C:\\folder\\data\\testdata.csv"
}
},
"msg": "the remote file does not exist, not transferring, ignored"
}
I tried switching testserverhost to localhost, and also tried C:\folder\data\testdata.csv and C:/folder/data/testdata.csv for src, but I still get errors. I don't understand where did it go wrong.

Related

Bad file descriptor in Ansible when read JSON content is numeric

Below is my JSON file:
[
{
"?xml": {
"attributes": {
"encoding": "UTF-8",
"version": "1.0"
}
}
},
{
"domain": [
{
"name": "mydom"
},
{
"domain-version": "12.2.1.3.0"
},
{
"server": [
{
"name": "AdminServer"
},
{
"ssl": {
"name": "AdminServer"
}
},
{
"listen_port": "12400"
},
{
"listen_address": "mydom.host1.bank.com"
}
]
},
{
"server": [
{
"name": "myserv1"
},
{
"ssl": [
{
"name": "myserv1"
},
{
"login-timeout-millis": "25000"
}
]
},
{
"listen_port": "22421"
}
]
}
]
}
]
Here is the code to get the listen port number form the json
---
- name: ReadJsonfile
hosts: localhost
tasks:
- name: Display the JSON file content
shell: "cat this.json"
register: result
- name: save the Json data to a Variable as a Fact
set_fact:
jsondata: "{{ result.stdout | from_json }}"
- name: create YML for server name with Listen port
shell: "echo {{ server.0.name }}_httpport: {{ httpport[0].listen_port }}>>{{ playbook_dir }}/wlsdatadump.yml"
loop: "{{ jsondata[1].domain }}"
vars:
server: "{{ item.server | selectattr('name', 'defined') }}"
httpport: "{{ item.server | selectattr('listen_port', 'defined') | list }}"
when: item.server is defined and (item.server | selectattr('listen_port', 'defined')) != []
I get the below error when executing the play
TASK [create YML for server name with Listen port] ************************************************************
skipping: [localhost] => (item={'name': 'mydom'})
skipping: [localhost] => (item={'domain-version': '12.2.1.3.0'})
failed: [localhost] (item={'server': [{'name': 'AdminServer'}, {'ssl': {'name': 'AdminServer'}}, {'listen_port': '12400'}, {'listen_address': 'mydom.host1.bank.com'}]}) => {"ansible_loop_var": "item", "changed": true, "cmd": "echo AdminServer_httpport: 12400>>/web/aes/admin/playbooks/dump.yml", "delta": "0:00:00.007706", "end": "2022-03-17 04:43:24.665832", "item": {"server": [{"name": "AdminServer"}, {"ssl": {"name": "AdminServer"}}, {"listen_port": "12400"}, {"listen_address": "mydom.host1.bank.com"}]}, "msg": "non-zero return code", "rc": 1, "start": "2022-03-17 04:43:24.658126", "stderr": "/bin/sh: 12400: Bad file descriptor", "stderr_lines": ["/bin/sh: 12400: Bad file descriptor"], "stdout": "", "stdout_lines": []}
If i change the port number from numeric to non-numeric say change "12400" to "portfirst" the playbook works fine.
This issue may have to do with the data type.
Can you please suggest how can i overcome this error?
you create a file listenport.j2 in folder templates:
{% for item in jsondata[1].domain if item.server is defined and (item.server | selectattr('listen_port', 'defined')) != [] %}
{{ item.server.0.name }}_httpport: {{ (item.server | selectattr('listen_port', 'defined')| list).0.listen_port }}
{% endfor %}
playbook:
- name: ReadJsonfile
hosts: localhost
tasks:
- name: Display the JSON file content
shell: "cat ./file2.json"
register: result
- name: save the Json data to a Variable as a Fact
set_fact:
jsondata: "{{ result.stdout | from_json }}"
- name: template
template:
src: listenport.j2
dest: "{{ playbook_dir }}/wlsdatadump.yml"
result in file wlsdatadump.yml:
AdminServer_httpport: 12400
myserv1_httpport: 22421
if you are working on lot of hosts (not only on localhost) and just want to create the file on localhost, use delegate_to: localhost inside the task

How to loop through set_fact attributes in another task of ansible playbook

I am struggling with the looping using with_items from the set_fact results in my ansible playbook.
- set_fact:
TAGNAME: "TEST-EC2-0{{item}}"
TAGOWNER: LOGIN
TAGROLE: DB
with_sequence: start=01 end="{{ count }}"
register: tagname
Below is the result of set_fact using debug I got this.
"results": [
{
"_ansible_ignore_errors": null,
"_ansible_item_label": "1",
"_ansible_item_result": true,
"_ansible_no_log": false,
"ansible_facts": {
"TAGNAME": "TEST-EC2-01",
"TAGOWNER": "LOGIN",
"TAGROLE": "DB"
},
"changed": false,
"failed": false,
"item": "1"
},
{
"_ansible_ignore_errors": null,
"_ansible_item_label": "2",
"_ansible_item_result": true,
"_ansible_no_log": false,
"ansible_facts": {
"TAGNAME": "TEST-EC2-02",
"TAGOWNER": "LOGIN",
"TAGROLE": "DB"
},
"changed": false,
"failed": false,
"item": "2"
}
]
With this given output, I want to use all the "TAGNAME" in the below ec2 task for tagging purpose whenever I create multiple instances using COUNT module.
ec2:
....
....
....
instance_tags:
Name: "{{ item.TAGNAME }}"
Owner: "LOGIN"
with_items: "{{ tagname.results }}"
But when I trigger the playbook I am getting below error
fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'item' is undefined\n\nThe error appears to have been in 'local/apps/roles/EC2_Deploy/tasks/ec2_creation.yml': line 217, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: Create Instances\n ^ here\n"}
I am not sure what and where I am missing. Could someone help me on this ?

Loop ansible_host stuck with first item

I am using the module csv-source-of-truth (https://github.com/joelwking/csv-source-of-truth) to get the IP and OS information from a csv file. I was able to register these info into a vsheet and using debug, I can see that I can loop through the contents of the vsheet.
However, when I use ios_command and try to loop through the vsheet, it seems that it gets stuck at the first entry of the vsheet.
This are the contents of the Inventory.csv file:
192.168.68.201,ios
192.168.68.202,ios
Code:
---
- hosts: localhost
gather_facts: false
tasks:
- name: Block
block:
- name: Use CSV
csv_to_facts:
src: '{{playbook_dir}}/NEW/Inventory.csv'
vsheets:
- INFO:
- IP
- OS
- debug:
msg: '{{item.IP}}'
loop: '{{INFO}}'
- name: Show Version
vars:
ansible_host: '{{item.IP}}'
ansible_network_os: '{{item.OS}}'
ansible_user: cisco
ansible_ssh_pass: cisco
ansible_connection: network_cli
ansible_become: yes
ansible_become_method: enable
ios_command:
commands: show version
register: output
loop: '{{INFO}}'
- name: Show the output of looped Show Version
debug:
var: output
- name: Show just the stdout_lines
debug:
var: output.results.{{item}}.stdout_lines
with_sequence: "0-{{output|length - 2}}"
You will notice on the output that it only has results for R1 when you look at the uptime information. i.e. R1 has an uptime of such and such.
PLAY [localhost] **********************************************************************************************************************************************
TASK [Use CSV] ************************************************************************************************************************************************
ok: [localhost]
TASK [debug] **************************************************************************************************************************************************
ok: [localhost] => (item={u'IP': u'192.168.68.201', u'OS': u'ios'}) => {
"msg": "192.168.68.201"
}
ok: [localhost] => (item={u'IP': u'192.168.68.202', u'OS': u'ios'}) => {
"msg": "192.168.68.202"
}
TASK [Show Version] *******************************************************************************************************************************************
ok: [localhost] => (item={u'IP': u'192.168.68.201', u'OS': u'ios'})
ok: [localhost] => (item={u'IP': u'192.168.68.202', u'OS': u'ios'})
TASK [Show the output of looped Show Version] *****************************************************************************************************************
ok: [localhost] => {
"output": {
"changed": false,
"msg": "All items completed",
"results": [
{
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"invocation": {
"module_args": {
"auth_pass": null,
"authorize": null,
"commands": [
"show version"
],
"host": null,
"interval": 1,
"match": "all",
"password": null,
"port": null,
"provider": null,
"retries": 10,
"ssh_keyfile": null,
"timeout": null,
"username": null,
"wait_for": null
}
},
"item": {
"IP": "192.168.68.201",
"OS": "ios"
},
"stdout": [
-- Output removed for brevity
],
"stdout_lines": [
[
"-- Output removed for brevity
"R1 uptime is 1 hour, 34 minutes",
]
]
},
{
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"invocation": {
"module_args": {
"auth_pass": null,
"authorize": null,
"commands": [
"show version"
],
"host": null,
"interval": 1,
"match": "all",
"password": null,
"port": null,
"provider": null,
"retries": 10,
"ssh_keyfile": null,
"timeout": null,
"username": null,
"wait_for": null
}
},
"item": {
"IP": "192.168.68.202",
"OS": "ios"
},
"stdout": [
-- Output removed for brevity
],
"stdout_lines": [
[
-- Output removed for brevity
"R1 uptime is 1 hour, 34 minutes",
]
]
}
]
}
}
TASK [Show just the stdout_lines] *****************************************************************************************************************************
ok: [localhost] => (item=0) => {
"ansible_loop_var": "item",
"item": "0",
"output.results.0.stdout_lines": [
[
-- Output removed for brevity
"R1 uptime is 1 hour, 34 minutes",
]
]
}
ok: [localhost] => (item=1) => {
"ansible_loop_var": "item",
"item": "1",
"output.results.1.stdout_lines": [
[
-- Output removed for brevity
"R1 uptime is 1 hour, 34 minutes",
]
]
}
PLAY RECAP ****************************************************************************************************************************************************
localhost : ok=5 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Try to create an inventory
- name: Create inventory
add_host:
hostname: '{{ item.IP }}'
groups: temp_group_01
ansible_network_os: '{{ item.OS }}'
ansible_user: cisco
ansible_ssh_pass: cisco
ansible_connection: network_cli
ansible_become: yes
ansible_become_method: enable
loop: '{{ INFO }}'
and delegate to the hosts
- name: Show Version
ios_command:
commands: show version
register: output
delegate_to: '{{ item }}'
loop: '{{ groups['temp_group_01'] }}'
Explanation
From the play below can be seen that the connection does not obey the changed ansible_host and keeps using the first item in the loop.
- hosts: test_01
tasks:
- command: hostname
register: result
vars:
ansible_host: "{{ item }}"
loop:
- test_02
- test_03
- debug:
msg: "{{ result.results|map(attribute='stdout')|list }}"
gives
TASK [command] ******************************************************************************
changed: [test_01] => (item=test_02)
changed: [test_01] => (item=test_03)
TASK [debug] ********************************************************************************
ok: [test_01] => {
"msg": [
"test_02",
"test_02"
]
}
This behavior is very probably caused by the connection plugin because vars works as expected. The play below
- hosts: test_01
tasks:
- command: echo "{{ ansible_host }}"
register: result
vars:
ansible_host: "{{ item }}"
loop:
- test_02
- test_03
- debug:
msg: "{{ result.results|map(attribute='stdout')|list }}"
gives
TASK [command] ******************************************************************************
changed: [test_01] => (item=test_02)
changed: [test_01] => (item=test_03)
TASK [debug] ********************************************************************************
ok: [test_01] => {
"msg": [
"test_02",
"test_03"
]
}
As a result, it's not possible to loop ansible_host. Instead, delegate_to shall be used.

How to access register variable in task

This is my output of EC2 instance. I am trying to access "instance_type".
And here is my task.
ec2:
key_name: redhat
group: MY_EC2
instance_type: t2.micro
image: ami-cfe4b2b0
region: us-east-1
zone: us-east-1a
wait: true
exact_count: 1
count_tag:
name: MyProjectInstances
instance_tags:
name: Ansible
register: ec2
- set_fact:
inst: "{{ ec2 }}"
- debug:
msg: "{{ inst }}"
I can reach Instances block through trying this.
debug:
msg: "{{ inst.instances }}" but cannot go further, getting error of undefined variable.
#
Output:
ok: [localhost] => {
"msg": {
"changed": true,
"failed": false,
"instance_ids": [
"i-0be089202b191769e"
],
"instances": [
{
"ami_launch_index": "0",
"architecture": "x86_64",
"block_device_mapping": {
"/dev/xvda": {
"delete_on_termination": true,
"status": "attached",
"volume_id": "vol-02b129004f1a5fb89"
}
},
"dns_name": "ec2-34-204-84-170.compute-1.amazonaws.com",
"ebs_optimized": false,
"groups": {
"sg-06c09a2c83d7b1a96": "MY_EC2"
},
"hypervisor": "xen",
"id": "i-0be089202b191769e",
"image_id": "ami-cfe4b2b0",
"instance_type": "t2.micro",
"kernel": null,
"key_name": "redhat",
"launch_time": "2018-07-15T14:34:43.000Z",
"placement": "us-east-1a",
"private_dns_name": "ip-172-31-35-24.ec2.internal",
"private_ip": "172.31.35.24",
"public_dns_name": "ec2-34-204-84-170.compute-1.amazonaws.com",
"public_ip": "34.204.84.170",
"ramdisk": null,
"region": "us-east-1",
"root_device_name": "/dev/xvda",
"root_device_type": "ebs",
"state": "running",
"state_code": 16,
"tags": {
"name": "Ansible"
},
"tenancy": "default",
"virtualization_type": "hvm"
}
Please try as below::
- name: Get instance Type
debug: msg={{ inst | json_query('instances[].instance_type') }}

ansible: how to iterate over all registered results?

Given the following playbook:
---
- name: Check if log directory exists - Step 1
stat: path="{{ wl_base }}/{{ item.0.name }}/{{ wl_dom }}/servers/{{ item.1 }}/logs" get_md5=no
register: log_dir
with_subelements:
- wl_instances
- servers
- name: Check if log directory exists - Step 2
fail: msg="Log directory does not exists or it is not a symlink."
failed_when: >
log_dir.results[0].stat.islnk is not defined
or log_dir.results[0].stat.islnk != true
or log_dir.results[0].stat.lnk_source != "{{ wl_base }}/logs/{{ wl_dom }}/{{ item.1 }}"
with_subelements:
- wl_instances
- servers
that is using the following vars:
---
wl_instances:
- name: aservers
servers:
- AdminServer
- name: mservers
servers:
- "{{ ansible_hostname }}"
the second task currently only uses one of the two possible results (results[0]).
My question is: how could I iterate over all available items stored in log_dir.results?
A sample output debug:hostvars[inventory_hostname] follows:
"log_dir": {
"changed": false,
"msg": "All items completed",
"results": [
{
"changed": false,
"invocation": {
"module_args": "path=\"/path/to/servers/aservers/domain/AdminServer/logs\" get_md5=no",
"module_name": "stat"
},
"item": [
{
"name": "aservers"
},
"AdminServer"
],
"stat": {
...
"lnk_source": "/path/to/logs/domain/AdminServer",
...
}
},
{
"changed": false,
"invocation": {
"module_args": "path=\"/path/to/servers/mservers/domain/servers/some_hostname/logs\" get_md5=no",
"module_name": "stat"
},
"item": [
{
"name": "mservers"
},
"some_hostname"
],
"stat": {
...
"lnk_source": "/path/to/logs/domain/some_hostname",
...
Looping over the results in an array (denoted by the []), would be done as
with_items: somelist
or if it's a dict that contains a list, as in this case
with_items: log_dir.results
note this can also be written
with_items: log_dir['results']
so in your task
- name: Check if log directory exists - Step 2
fail: msg="Log directory does not exists or it is not a symlink."
failed_when: >
item.stat.islnk is not defined
or item.stat.islnk != true
or item..stat.lnk_source != "{{ wl_base }}/logs/{{ wl_dom }}/{{ item.1 }}"
with_items: log_dir.results
More information and examples is available in http://docs.ansible.com/playbooks_loops.html#standard-loops.
The main thing here is that you're wanting to access only part of the registered variable.
My debug output:
{
"dkim_key.results": [
{
"changed": false,
"invocation": {
"module_args": "path=/etc/opendkim/keys/accept.example.com/mail.private get_md5=no",
"module_name": "stat"
},
"item": "accept.example.com",
"stat": {
"atime": 1427461574.5667424,
"checksum": "c882abaabvc66257555929f6290480a409d1",
"ctime": 1427461575.0307424,
"dev": 64770,
"exists": true,
"gid": 119,
"inode": 521115,
"isblk": false,
"ischr": false,
"isdir": false,
"isfifo": false,
"isgid": false,
"islnk": false,
"isreg": true,
"issock": false,
"isuid": false,
"mode": "0600",
"mtime": 1427461574.5947425,
"nlink": 1,
"pw_name": "opendkim",
"rgrp": false,
"roth": false,
"rusr": true,
"size": 887,
"uid": 110,
"wgrp": false,
"woth": false,
"wusr": true,
"xgrp": false,
"xoth": false,
"xusr": false
}
},
{
"changed": false,
"invocation": {
"module_args": "path=/etc/opendkim/keys/test.example.com/mail.private get_md5=no",
"module_name": "stat"
},
"item": "test.example.com",
"stat": {
"exists": false
}
}
]
}
Found the solution for a similar problem as follows:
- name: DKIM | Generate signing key
shell: opendkim-genkey -s {{ postfix.dkim_selector }} -d {{ item.item }} -D /etc/opendkim/keys/{{ item.item }}
with_items: dkim_key.results
when: not item.stat.exists
notify: restart opendkim
tags:
- postfix
- dkim
Using the dkim_key.results and a list to iterate over and then check against that list with item.stat.exists. Lastly getting the actual item via item.item

Resources