Ansible Reading Python Script as JSON

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   

Leave a Reply