Execute detached process with Ansible

How to execute long running process on remote host with Ansible?
There are several ways to achieve this. Let's look into them:

Async task

You can use async option for your task with huge value:

- name: long running task
  shell: /usr/bin/myscript.sh
  async: 2592000               # 60*60*24*30 – 1 month
  poll: 0

This will spawn async_wrapper process that is detached from Ansible ssh session and your script will continue to run until 1 month is passed (or script is terminated by other means: normal exit, reboot, etc).
Your process tree will look like this:

init
  └─async_wrapper /ansible/async_wrapper 872305235772 2592000...
      └─async_wrapper /ansible/async_wrapper 872305235772 2592000...
          └─command /ansible/command
              └─python /tmp/ansible_W8WEYJ/ansible_module_command.py
                  └─/usr/bin/myscript.sh
Background shell job

You may use & to run your script as shell background job, but there are some quirks:

  • detach your process' stdin/stdout/stderr from your terminal;
    if you don't do this, your process may suspend or fail during input/output attempt
  • catch SIGHUP signal to prevent exit when shell exits

Let's run Python Simple HTTP server for /tmp/www path:

- name: start simple http server in background
  shell: cd /tmp/www; nohup python -mSimpleHTTPServer </dev/null >/dev/null 2>&1 &

This will spawn background shell job and exit signals will be ignored by nohup wrapper.

You can also use raw module to prevent command module's code copying. But we need to add a tiny sleep in this case, because ssh shell will disconnect to quickly, that job scheduler will have no time to start our nohup process:

- name: start simple http server in background
  raw: cd /tmp; nohup python -mSimpleHTTPServer </dev/null >/dev/null 2>&1 & sleep 1