use ansible api to push files to remote hosts

Hello,

i am looking to create a tool that pushes sudoers file to remote file using the ansible api

it is a tool for some non technical users

this is what I have

`
from ansible.parsing.dataloader import DataLoader
from ansible.module_utils.common.collections import ImmutableDict
from ansible.inventory.manager import InventoryManager
from ansible.cli import CLI
from ansible.vars.manager import VariableManager
from ansible.executor.playbook_executor import PlaybookExecutor
from ansible.playbook.play import Play
from ansible import context

from sudo_manager.objects import Host
from sudo_manager import render_sudoers
from sudo_manager.objects import HostGroup

def get_arguments():
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument(“–hostnames”, dest=‘hosts’, help=‘list of hosts seperated by comma or a file name (one hostname per line)’)
group.add_argument(“–hostgroup”, dest=‘hostgrp’, help=‘enter hostgroup name’)
parser.add_argument(“–dest_dir”, dest=‘dest_dir’, help='where to store the sudoers file, dafault is the current directory ', default=“.”)

return parser

def get_hosts(hostgroup):
hostgrp = HostGroup.get_hostgroup(hostgroup)
hosts = hostgrp.hosts
output =
for host in hosts:
output.append(host.hostname)
return output

arguments = get_arguments().parse_args()
hostnames =

if arguments.hosts:
hostnames = arguments.hosts.strip().split(‘,’)

hostnames = [x.strip() for x in list(hostnames)]
hostnames = filter(None, hostnames)
hostnames = set(hostnames)

if arguments.hostgrp:
hostnames = get_hosts(arguments.hostgrp)

for hostname in hostnames:
sudoers_content = render_sudoers(hostname, ‘sudoers.j2’)
sudoers = os.path.join(arguments.dest_dir, 'sudoers%s’ % hostname)

with open(_sudoers, ‘w’) as sudoers_file:
sudoers_file.write(sudoers_content)

my_inv = ‘,’.join(hostnames)+ ‘,’
print (my_inv)

loader = DataLoader()

context.CLIARGS = ImmutableDict(tags={}, listtags=False, listtasks=False, listhosts=False, syntax=False, connection=‘ssh’,
module_path=None, forks=100, private_key_file=None,
ssh_common_args=None, ssh_extra_args=None, sftp_extra_args=None, scp_extra_args=None,
verbosity=True, check=False, start_at_task=None)

Inventory = InventoryManager(loader=loader, sources=my_inv)

variable_manager = VariableManager(loader=loader, inventory=Inventory)

pbex = PlaybookExecutor(playbooks=[‘/usr/home/secops_ansible/ansible/test.yml’], inventory=Inventory, variable_manager=variable_manager, loader=loader,passwords={})

results = pbex.run()
`

the purpose of this is that user will call a script with a list of hosts or a hostgroup name…then our "sudo_manager will get the hosts, generate the sudoers files… write them to disk and then ansible will push them to all the hosts that were passed as argument.

this is the test,yml contents:

`

  • name: deploy sudoers files to remote hosts
    hosts: all
    become: yes

tasks:

  • name: push files
    copy:
    src: “{{ playbook_dir }}/sudoers_{{ ansible_nodename}}”
    dest: /etc/sudoers3x
    validate: /usr/sbin/visudo -cf %s

`

when i call the script with some debuging info like show os version it works…

but when i call it with the copy or template module i get an error like this:

an exception occurred during task execution. To see the full traceback, use -vvv. The error was: TypeError: expected string or buffer
fatal: [vm]: FAILED! => {“msg”: “Unexpected failure during module execution.”, “stdout”: “”}

thank you for your assistance.