Search code examples
linuxserviceansiblesystemd

Ansible - Run playbooks using systemd (.service files)


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


Solution

  • 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.