I recently needed to add a cleanup service that runs at shutdown to a hundred AWS servers. My requirements were:
- Run the script
/usr/local/sbin/ec2-cleanup.shwhen a VM shuts down (poweroff or reboot).
- Send the output from the script to the
So I needed to create a
systemd service file that would call the script when the VM shuts down. This is the
ec2-cleanup.service file I created:
# ec2-cleanup.service [Unit] Description=Run cleanup at shutdown After=syslog.service network.target [Service] Type=oneshot RemainAfterExit=yes ExecStop=/usr/local/sbin/ec2-cleanup.sh Restart=on-failure RestartSec=1s [Install] WantedBy=multi-user.target
Type=oneshot means that the command runs once. Normally since this is a
oneshot service the service would exit after the
ExecStart command runs, but since I don’t want to do anything when the service starts, there is is no
ExecStart command. That’s why I use
RemainAfterExit=yes, which keeps the service running even though there’s no
Finally I use
ExecStop to run the command at shutdown time.
After=syslog.service network.target ensures that the
ec2-cleanup.service doesn’t start until after
syslog service is running and the network has started. More importantly, since
systemd stops services in the reverse order that they’re started, this also ensures that
syslog and the
network service are still running when
systemd runs the
Although there are many different available
syslog services, most use “
syslog” as a service alias, so
After=syslog.service should work regardless of which
syslog service you actually use. (e.g. If you use
rsyslog this still works, because
syslog as an alias.)
Finally, I just needed to install the service on my AWS VMs, so I added this to an Ansible playbook that runs on my AWS VMs:
- name: Install the ec2-cleanup.sh script copy: src: ec2-cleanup.sh dest: /usr/local/sbin/ec2-cleanup.sh owner: root group: root mode: 0755 - name: Install a service to run ec2-cleanup.sh at shutdown copy: src: ec2-cleanup.service dest: /lib/systemd/system/ec2-cleanup.service owner: root group: root mode: 0644 register: ec2_cleanup_service - name: Restart ec2-cleanup service if the service file changed systemd: name: ec2-cleanup daemon_reload: True state: restarted when: ec2_cleanup_service.changed - name: Enable ec2-cleanup service so it starts on boot systemd: name: ec2-cleanup enabled: True state: started
To verify that all of this works I ran the Ansible playbook on a VM, then logged in and checked the status of the service:
eruby@i-056ac231adeb1f930:~$ systemctl status ec2-cleanup ● ec2-cleanup.service - Run cleanup at shutdown Loaded: loaded (/lib/systemd/system/ec2-cleanup.service; enabled; vendor preset: enabled) Active: active (exited) since Tue 2023-03-14 17:04:37 UTC; 44s ago Mar 14 17:04:37 i-056ac221aceb1f830 systemd: Finished Run cleanup at shutdown.
The service is
active (exited), which I expected (
ExecStart has completed,
RemainAfterExit=yes is keeping the service running until shutdown.
If I reboot the VM and log back in I can check syslog with:
journalctl -u ec2-cleanup.service -n 20
… and see the last 20 lines of output from the script. The log output shows that the script ran when I rebooted.
Hope you find this useful.