I’m new to using Ansible and was hoping to be able to write basic python scripts then run them on remote machines. I have tried the various execution methods (raw, command, script) but seem to be getting stuck with an error where it seems like ansible is trying to read in my python file as a JSON rather than just executing it like normal. There are no modules involved with this just these two files and the hosts/cfg file.
If I run the script alone locally it gives the desired output but when trying to run it remotely with ansible I get the following:
ERROR! We were unable to read either as JSON nor YAML, these are the errors we got from each:
JSON: Expecting value: line 1 column 1 (char 0)
Syntax Error while loading YAML.
did not find expected <document start>
The error appears to be in '/etc/ansible/playbooks/splunk/splunk.py': line 8, column 1, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
#Function that gets stored as the splunkDNS variable then used in the first try/except
def get_ip(hostname):
^ here
My splunk.yml file here I am trying to just use as a method to run the script file remotely.
---
- hosts: local
become: False
- name: Copy local python script copy to remote
ansible.builtin.copy:
src: /etc/ansible/playbooks/splunk/splunk.py
dest: /root/splunk.py
- name: Execute Python Script using the raw module
ansible.builtin.raw: python3 /root/splunk.py
register: result
- debug:
msg: "{{ result }}"
Script I want to run remotely to test ports:
#!/bin/python
from contextlib import closing
import os, subprocess, sys, socket
import ipaddress, random, struct
#Function that gets stored as the splunkDNS variable then used in the first try/except
def get_ip(hostname):
return list(
i
[4]
[0]
for i in
socket.getaddrinfo(
hostname,
80
)
if i[0] is socket.AddressFamily.AF_INET
and i[1] is socket.SocketKind.SOCK_RAW
)
def get_ip_from_subnet(ip_subnet):
ips=ipaddress.ip_network(ip_subnet)
ip_list=[str(ip) for ip in ips]
return ip_list
splunkDNS=get_ip('splunk.com') #Uses the function above to get the IP of the splunk-local domain
hostname=os.getenv('HOSTNAME')
ip_subnet="1.5.1.128/25"
ip_list= get_ip_from_subnet(ip_subnet)
randIp = ip_list[random.randint(0,len(ip_list))]
print("Hostname: " + str(hostname))
#Check DNS resolution
try:
if '1.5.1.95' in splunkDNS: #If that .95 IP is anywhere in the output of the get_ip function this returns True.
print("DNS Resolution to Splunk is working!")
else:
print("DNS resolution to splunk.com has failed!\nPlease verify that /etc/resolv.conf contains the following entries: ")
except Exception as e:
print("Something went wrong! - DNS Step")
print(e)
#Check if the current machine can send traffic on 1.5.1.95:8089
try:
def check_socket(host, port):
with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
if sock.connect_ex((host, port)) == 0:
print("Can send traffic on 1.5.1.95:8089")
else:
print("Cannot connect to 1.5.1.95:8089!\n\n")
splunkPort=check_socket('1.5.1.95', 8089)
except Exception as e:
print("Something went wrong! - 8089 Traffic Step")
print(e)
try:
print("Testing the IP: "+randIp)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = sock.connect_ex((randIp,9997))
if result == 0:
print("Port 9997 is open on " + randIp)
else:
print("Port 9997 is not open on " + randIp)
sock.close()
except Exception as e:
print("Something went wrong! - Random IP Step")
print(e)
My hosts file only has the following in it:
[local]
localhost
>Solution :
I’m unable to reproduce your problem. As I noted in a comment, your playbook as posted in your question is invalid. If I correct that, it seems to just work.
Simplifying things a bit, if I start with the following in splunk.py
:
print('hello i am splunk.py')
And this in playbook.yaml
:
- hosts: remotehost
become: false
gather_facts: false
tasks:
- name: Execute Python Script using the raw module
script: splunk.py
args:
executable: python3
register: result
- debug:
msg: "{{ result }}"
And I run it like this:
ansible-playbook playbook.yaml
Then I get the following output:
PLAY [remotehost] **************************************************************
TASK [Execute Python Script using the raw module] ******************************
changed: [remotehost]
TASK [debug] *******************************************************************
ok: [remotehost] => {
"msg": {
"changed": true,
"failed": false,
"rc": 0,
"stderr": "Shared connection to raspberrypi.local closed.\r\n",
"stderr_lines": [
"Shared connection to raspberrypi.local closed."
],
"stdout": "hello i am splunk.py\r\n",
"stdout_lines": [
"hello i am splunk.py"
]
}
}
PLAY RECAP *********************************************************************
remotehost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0