2

I launch m5.large (nitro-based) EC2 instance from Ubuntu AMI and attach EBS volume. There is systemd as a default init system. As AWS documentation "Making an Amazon EBS Volume Available for Use on Linux" stands, I mount EBS volume within user data:

#!/bin/bash

# Sleep gives the SSD drive a chance to mount before the user data script completes.
sleep 15

mkdir /application

mount /dev/nvme1n1 /application

I need Nginx and provide site configuration for it at EBS volume. For default nginx package with systemd unit file I declare a dependency on the mount with RequiresMountsFor directive within drop-in:

# /lib/systemd/system/nginx.service

[Unit]
Description=A high performance web server and a reverse proxy server
After=network.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t -q -g 'daemon on; master_process on;'
ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;'
ExecReload=/usr/sbin/nginx -g 'daemon on; master_process on;' -s reload
ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid
TimeoutStopSec=5
KillMode=mixed

[Install]
WantedBy=multi-user.target
# /etc/systemd/system/nginx.service.d/override.conf

[Unit]
RequiresMountsFor=/application

[Service]
Restart=always

But this doesn't help to run Nginx only after mount will be completed (in user data) for some reason. I can see the mount unit for /application path, but I don't see Required=application.mount as I'd expect:

$ sudo systemctl show -p After,Requires nginx
Requires=system.slice sysinit.target -.mount
After=sysinit.target -.mount systemd-journald.socket basic.target application.mount system.slice network.target

Nginx service still tries to run before cloud-init completes user data execution, exhausts all attempts to run the service and fails:

Apr 08 15:34:32 hostname nginx[1303]: nginx: [emerg] open() "/application/libexec/etc/nginx/nginx.site.conf" failed (2: No such file or directory) in /etc/nginx/sites-e
Apr 08 15:34:32 hostname nginx[1303]: nginx: configuration file /etc/nginx/nginx.conf test failed
Apr 08 15:34:32 hostname systemd[1]: nginx.service: Control process exited, code=exited status=1
Apr 08 15:34:32 hostname systemd[1]: Failed to start A high performance web server and a reverse proxy server.

I assume the service should be started by systemd on mount notification for the specified path /application. What am I missing?

What is the most flexible and correct way to mount EBS volumes at Ubuntu + systemd?

  • Keep reading that document you linked to. The next section, "Automatically Mount an Attached Volume After Reboot" explains what you need to do. This should NOT be in user data, that's not what the documentation says to do, and of course it does not work. – Michael Hampton Apr 8 at 18:59
  • @MichaelHampton, Thank you for your answer. That's not quite what I want. The main idea behind this – phoenix server, that is always built from scratch and easy to recreate (or "rise from the ashes") through automated procedures. Ideally, it should never be rebooted. Terraform launches an EC2 instance within Autoscale Group from a golden AMI and attaches EBS volume with the application code and some configuration. So I just want to mount the EBS volume on the first boot and then run Nginx server. – Tensho Apr 8 at 19:22
  • Then it should already be in the /etc/fstab in the AMI. – Michael Hampton Apr 9 at 0:47
  • It's hard to predict what the device name should be in /etc/fstab, because it depends on the EC2 instance type. For old generation it's /dev/xvdb and for new one – /dev/nvme0n1. – Tensho Apr 9 at 16:19
  • 1
    I suppose you could put them both in. One will fail and the other will succeed, but either way you get your mount. – Michael Hampton Apr 9 at 16:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.