Starting a long-running process in cloud-init on ec2 instance

amazon ec2cloud-init

I'm trying and failing to start a long-running command on launch of an EC2 (Amazon Linux). It needs to run under the ec2-user account. This was my first attempt:

#!/bin/bash
echo 'Woot 1!' > /home/ec2-user/woot1.txt
pushd /home/ec2-user/my-app-dir
nohup sudo -u ec2-user /home/ec2-user/my-app-dir/my_process.py &
echo 'Woot 2!' > /home/ec2-user/woot2.txt

The key command I'm trying to run is the "nohup" line, to run my_process.py.

The shell script works when I run it as root from a shell, but when I supply it in user-data to ec2-run-instances and login to the instance, I see both woot1.txt and woot2.txt, but my_process.py is not running. What's more, my_process.py creates a log file when it runs, but there is no log file there (and no nohup.out either) when I supply the script as user-data to ec2-run-instances.

I've tried putting the same things in a cloud-init form as well, with the same results:

#cloud-config
runcmd:
 - echo 'Woot 1!' > /home/ec2-user/woot1.txt
 - pushd /home/ec2-user/my-app-dir
 - nohup sudo -u ec2-user /home/ec2-user/my-app-dir/my_process.py &
 - echo 'Woot 2!' > /home/ec2-user/woot2.txt

If anyone can tell me where I'm going wrong, I'd appreciate it.

Best Answer

The reason the process was not running was that the Amazon EC2 Linux instance is Red-Hat like, and there is a bug/feature in those distros that a sudo command requires a tty. There is no tty attached to the environment when the cloud-init is processed, and so it fails.

One answer is to edit etc/sudoers and change the line

Defaults requiretty

to

Defaults !requiretty

There are other approaches, apparently, but this worked for me.