1

I would like to start an ansible playbook through a service.

Problem is that there is an exception occurring if i try to start a specific playbook with the help of a .service file.

Normal execution via the command line doesn't throw any exceptions.

The exact error is as follows:

ESTABLISH LOCAL CONNECTION FOR USER: build

EXEC /bin/sh -c '( umask 77 && mkdir -p "echo /tmp"&& mkdir "echo /tmp/ansible-tmp-1628159196.970389-90181-42979741793270" && echo ansible-tmp-1628159196.970389-90181-42979741793270="echo /tmp/ansible-tmp-1628159196.970389-90181-42979741793270" ) && sleep 0' fatal: [Ares]: UNREACHABLE! => changed=false

msg: 'Failed to create temporary directory.In some cases, you may have been able to authenticate and did not have permissions on the target directory. Consider changing the remote tmp path in ansible.cfg to a path rooted in "/tmp", for more error information use -vvv. Failed command was: ( umask 77 && mkdir -p "echo /tmp"&& mkdir "echo /tmp/ansible-tmp-1628159196.970389-90181-42979741793270" && echo ansible-tmp-1628159196.970389-90181-42979741793270="echo /tmp/ansible-tmp-1628159196.970389-90181-42979741793270" ), exited with result 127'

unreachable: true'

I've tried the following:

  1. Authentication or permission failure, did not have permissions on the remote directory
  2. https://github.com/ansible/ansible/issues/43830
  3. Generally searching for an answer, but all i could find is to change remote_config to /tmp
  4. Changing the permissions to 777 for the /tmp folder
  5. Changing the user for the service to both build and root
  6. Changing the group for the service to both build and root

Current configuration:

The remote_tmp is set to /tmp

The rights for /tmp are: drwxrwxrwt. 38 root root

This is the service i am starting:

[Unit]
Description=Running vmware in a service
After=network.target

[Service]
User=build
Group=build
WorkingDirectory=/home/build/dev/sol_project_overview/ansible-interface
Environment="PATH=/home/build/dev/sol_project_overview/ansible-interface/venv/bin"
ExecStart=/home/build/dev/sol_project_overview/ansible-interface/venv/bin/ansible-playbook ./playbooks/get_vm_data_playbook.yml --vault-password-file password.txt -vvv

[Install]
WantedBy=multi-user.target

The exact ansible task that throws this exception:

- name: Write Disks Data to file
  template:
    src: template.j2
    dest: /home/build/dev/sol_project_overview/tmp/vm_data
  delegate_to: localhost
  run_once: yes

Also normally I would run a python script via this service file, that would call ansible when special conditions are met. But the same error occurs with a python script started by the service.

All of this lets me think that the problem is with the .service file... i just don't know what.

Any help is appreciated.

EDIT: SELinux is disabled

Strawl
  • 33
  • 9
  • 1
    Random idea off my hat: do you have selinux enabled and enforcing on this machine ? If yes what happens (just for testing...) if you switch it to permissive mode or disable it ? Side note: running an ansible playbook as a service looks like a quite awkward idea... – Zeitounator Aug 05 '21 at 13:01
  • Selinux is disabled, i already checked with the command sestatus. My plan isn't to run ansible as a service. I want to run it via a python script, which can be started/ stopped as a service. But the exact same error occurs, if i start my python script as a service – Strawl Aug 05 '21 at 13:14
  • Should i try to upgrade to ansible 4.0? Currently using 2.9.23 – Strawl Aug 05 '21 at 13:20
  • 2
    IMHO this is not the ideal use of a service, services are typically processes that run until they are asked to stop. Have you considered using cron jobs instead? – seshadri_c Aug 05 '21 at 14:02
  • @seshadri_c my goal would be to listen for incoming requests with a python script. Which would run 24/7 until stopped. The request would be for example to execute a command via ansible-playbook on a remote machine. Currently this python script runs fine with nohup. But that is no good longterm solution, neither is putting it into rc.local for ex. – Strawl Aug 05 '21 at 14:16
  • 1
    May I suggest you stop re-inventing the wheel and have a look at (non exhaustive single element list) [awx](https://github.com/ansible/awx) (which is the development version of Ansible Tower)? – Zeitounator Aug 05 '21 at 15:21
  • @Zeitounator Okay, you have a point. but do you perhaps have any suggestions on installing awx? Docker and Kubernetes are not an option, since i am already working on a Virtual Machine with CentOs 8 installed. I've tried [this](https://awx.wiki/installation), but the installation doesn't seem to work – Strawl Aug 06 '21 at 07:53
  • `Docker and Kubernetes are not an option, since I am already working on a Virtual Machine with CentOs 8 installed` <= Although I can understand you can be reluctant to installing Kube for a simple service because of the overall complexity if you don't need it, what is the actual issue with installing docker-ce in a vm to run awx? The overhead is very small and it just works (and most docker/kube services are today deployed on vms inside IaaS platforms anyway) – Zeitounator Aug 06 '21 at 09:18
  • And please note I stated `non exhaustive single element list` :) Depending on what you really want to do, there are tons of other alternatives that you can research: semaphore, jenkins, gitlab-ci, github actions, travis-ci, rundeck..... the choice is actually yours. – Zeitounator Aug 06 '21 at 09:25
  • @Zeitounator Thanks for everything, i ended up trying rundeck, but it was too big of an application and I didn't want to run multiple web servers on a virtual machine. Then decided to use celery+flask to schedule my playbooks, which is kind of reinventing the wheel, but with little overhead honestly. Ran in to the same problem with the services+ansible, but luckily found the solution after an hour :) – Strawl Aug 17 '21 at 13:55

1 Answers1

1

So i found the problem:

When debugging with -vvvv => 4 * verbose you get an even more precise error message:

"msg": "Failed to create temporary directory.In some cases, you may have been able to authenticate and did not have permissions on the target directory. Consider changing the remote tmp path in ansible.cfg to a path rooted in "/tmp", for more error information use -vvv. Failed command was: ( umask 77 && mkdir -p "echo /tmp/.ansible/tmp"&& mkdir "echo /tmp/.ansible/tmp/ansible-tmp-1629205650.8804808-397364-56399467035196" && echo ansible-tmp-1629205650.8804808-397364-56399467035196="echo /tmp/.ansible/tmp/ansible-tmp-1629205650.8804808-397364-56399467035196" ), exited with result 127**, stderr output: /bin/sh: mkdir: command not found\n",**

and in the last part there is this information:, stderr output: /bin/sh: mkdir: command not found\n",

So after googling i realized the problem was with that "PATH" variable I am setting in my .service file.

This was the problem:

Environment="PATH=/home/build/dev/sol_project_overview/ansible-interface/venv/bin"

it couldn't find mkdir because the "bin" folder, where "mkdir" is located at, wasn't specified in the "PATH" variable

What was left to do is to change the PATH variable of the service correctly. In order to do so I took the the PATH variable from the corresponding virtual environment when it was active.

Lesson: If you are working with virtual environments and want to use services using their environments, then change the PATH variable to that of the virtual machine.

Strawl
  • 33
  • 9