Create systemd service in AWS Elastic Beanstalk on new Amazon Linux 2

Viewed 1460

I'm currently trying to create a worker on AWS Elastic Beanstalk which is pulling messages from a specific SQS queue (with the help of the Symfony messenger). I don't want to use dedicated worker instances for this task. After some research, I found out that systemd can help here which is enabled by default on the new Amazon Linux 2 instances.

However, I'm not able to create a running systemd service. Here is my .ebextensions/03_workers.config file:

files:
    /etc/systemd/system/my_worker.service:
        mode: "000755"
        owner: root
        group: root
        content: |
            [Unit]
            Description=My worker

            [Service]
            User=nginx
            Group=nginx
            Restart=always
            ExecStart=/usr/bin/nohup /usr/bin/php /var/app/current/bin/console messenger:consume integration_incoming --time-limit=60

            [Install]
            WantedBy=multi-user.target

services:
    systemd:
        my_worker:
            enabled: "true"
            ensureRunning: "true"

I can't see my service running if I'm running this command:

systemctl | grep my_worker

What am I doing wrong? :)

2 Answers

systemd is not supported in Services. The only correct is sysvinit:

services:
  sysvinit:
    my_worker:
      enabled: "true"
      ensureRunning: "true"

But I don't think it will even work, as this is for Amazon Linux 1, not for Amazon Linux 2.

In Amazon Linux 2 you shouldn't be even using much of .ebextensions. AWS docs specifically write:

On Amazon Linux 2 platforms, instead of providing files and commands in .ebextensions configuration files, we highly recommend that you use Buildfile. Procfile, and platform hooks whenever possible to configure and run custom code on your environment instances during instance provisioning.

Thus, you should consider using Procfile which does basically what you want to achieve:

Use a Procfile for long-running application processes that shouldn't exit. Elastic Beanstalk expects processes run from the Procfile to run continuously. Elastic Beanstalk monitors these processes and restarts any process that terminates. For short-running processes, use a Buildfile.

Alternative

Since you already have created a unit file /etc/systemd/system/my_worker.service for systemd, you can enable and start it yourself.

For this container_commands in .ebextensions can be used. For example:

container_commands:
   10_enable_worker:
     command: systemctl enable worker.service
   20_start_worker:
     command: systemctl start worker.service

It's not officially documented, but you can use a systemd service in Amazon Linux 2.

A block like the following should work:

services: 
    systemd:
        __SERVICE_NAME__:
            enabled: true
            ensureRunning: true

Support for a "systemd" service is provided by internal package /usr/lib/python3.7/site-packages/cfnbootstrap/construction.py which lists recognized service types: sysvinit, windows, and systemd

class CloudFormationCarpenter(object):
    _serviceTools = {"sysvinit": SysVInitTool, "windows": WindowsServiceTool, "systemd": SystemDTool}

Note that a systemd service must support chkconfig and in particular your launch script at /etc/init.d/__SERVICE_NAME__ must include a "chkconfig" and "description" line similar to:

# chkconfig: 2345 70 60
# description: Continuously logs Nginx status.

If you don't support chkconfig correctly then chkconfig --list __SERVICE_NAME__ will print an error, and attempting to deploy to Elastic Beanstalk will log a more detailed error in /var/log/cfn-init.log when it tries to start the service.

Related