systemdでEC2の起動時・停止時にコマンドを実行してみる

2022.04.25

データアナリティクス事業本部の鈴木です。

EC2インスタンスの開始時およびAMI取得時などの停止時に、一緒にインスタンス内で稼働しているプログラムを決まった手順で開始・停止したいことがありました。今回はsystemdを使って実現できるか検証しました。Linuxにお詳しい方だと当たり前かもしれませんが、参考までにご共有します。

準備

前提条件

以下のAMIを使ってEC2インスタンスを作成し、検証を行いました。

  • AMI ID: ami-0ab0bbbd329f565e6

用意したファイル

ec2-userのホームディレクトリに、起動時・停止時に実行するための2つのスクリプトを作成しました。これらは実行されると同じディレクトリにあるtest.logに時間を追記します。

まずは起動時です。

start.sh

#!/bin/sh
echo `date` >> test.log
echo "start" >> test.log

次に停止時です。停止時用は、停止がコマンド実行を待ってくれているか確認するため、30秒の待機を含んでいます。

stop.sh

#!/bin/sh
echo `date` >> test.log
sleep 30
echo `date` >> test.log
echo "stop" >> test.log

ホームディレクトリ配置した後は、実行権限をつけておきました。

chmod +x ./start.sh 
chmod +x ./stop.sh

次にサービスファイルを準備しました。EC2起動時にサービスが開始されExecStartで設定したコマンドを実行し、終了時にExecStopで設定したコマンドを実行します。 start.shを実行してからstop.shを実行するまでをサービスの起動状態とした方が自然と思ったので、Typeoneshotとして、RemainAfterExityesとしました。

sample.service

[Unit]
Description=Start&stop sample service.
After=syslog.target network-online.target

[Service]
User=ec2-user
Type=oneshot
RemainAfterExit=yes
KillMode=none
ExecStart=/bin/bash -c 'cd /home/ec2-user; ./start.sh'
ExecStop=/bin/bash -c 'cd /home/ec2-user; ./stop.sh'

[Install]
WantedBy=multi-user.target

ExecStartExecStopでは、あえてbash -cでディレクトリ移動とスクリプト実行の複数のコマンドを実行しています。これは必須ではなく、以下のような特定のディレクトリに移動してからコマンドを実行する必要があるケースを想定しました。もちろん、単一のコマンドで済む場合は、普通にコマンドを書いて問題ありません。

サービスの有効化

systemctlコマンドでサービスの有効化をしておきます。また、動作確認のためサービスの開始もしておきました。

# サービスの有効化
sudo systemctl enable sample

# サービスの開始
sudo systemctl start sample

test.logを確認すると、開始用のスクリプトが動いていることを確認できました。

動作確認

やってみる

停止を伴う3つのケースで、期待通りにスクリプトが実行されるか確認してみました。

停止・起動した場合

まずインスタンスを停止しました。

インスタンスが停止状態になったことを確認して、インスタンスを開始しました。

インスタンスを開始

30秒待機してから停止していることが確認できました。

停止→起動

再起動した場合

インスタンスを再起動しました。

インスタンスを再起動

このときも30秒待機してから停止していることが確認できました。

再起動

静止点AMIを作成した場合

アクション > イメージとテンプレート > イメージを作成からイメージを作成しました。

AMIの作成1

このとき、再起動しないは無効にしておきました(有効化にチェックは入れないままにしておきました)。

AMIの作成2

このときも30秒待機してから停止していることが確認できました。

静止点バックアップ

最後に

今回はsystemdを使ってEC2の起動時・停止時にコマンドを実行できるか検証しました。特に停止時は不定期に停止を行っても決まったコマンドを実行してくれるので役立つケースが多そうです。参考になれば幸いです。