はじめに
こんにちは。satyamです。
本記事では、AWS Systems Manager の Parameter Store と State Manager を組み合わせ、EC2 インスタンスの挙動を動的に制御する方法を紹介します。
多くの環境では、設定値をスクリプトにハードコードしているため、小さな変更でもスクリプト修正や再デプロイが必要となり、運用負荷の増加につながります。
そこで本記事では、設定値を Parameter Store に格納し、State Manager から実行されるスクリプトで取得することで、スクリプトを変更することなく EC2 の挙動を柔軟に切り替える仕組みを解説します。
具体例として、httpd の起動・停止制御やメンテナンスモードの切り替えを通じて、動的制御の方法を確認します。
目次
構成図
以下の図は、本記事で構築する構成を示しています。

【動作フロー】
- State Manager が、タグで指定した対象の EC2 に対して関連付けで定義したコマンドを実行します。
- EC2 上で実行されたスクリプトが Parameter Store から設定値を取得します。
- 取得した設定値に応じて、EC2 上でサービスの起動・停止やメンテナンスモードの制御を行います。
- EC2 は実行結果(Success / Failed)を State Manager に返します。
- 実行結果が Failed の場合は、必要に応じて EventBridge が検知し、SNS を通じてメール通知を送信できます。
【前提条件】
- 対象の EC2 インスタンスが SSM Managed Instance として登録されていること
- EC2 インスタンスの IAM ロールに
AmazonSSMManagedInstanceCoreが付与されていること - EC2 インスタンス上で、制御対象のサービス
httpdがインストールされていること
ワークフロー
- タグによる適用範囲の制御
- Parameter Store による設定値の管理
- State Manager による設定適用と実行ロジック
- 通知設定(任意)
- 動作確認
- Test 1: サービス制御の確認(enabled / disabled)
- Test 2: メンテナンスモードの確認(on / off)
- Test 3: エラー動作の確認
タグによる適用範囲の制御
AWS マネジメントコンソールから EC2 を選択します。
インスタンスを開き、対象のインスタンスを選択します。
次に、「タグ」タブを開き、
以下のタグを追加します。
- Key: ConfigControl
- Value: Enabled

Parameter Store の設定
コンソール画面から Systems Manager を選択します。
パラメータストア → [パラメータの作成] を選択します。
① サービス名の設定
名前:/app/config/service_name
タイプ:文字列
データ型:text
値:httpd

同様の手順で、以下のパラメータを作成します。
※ タイプおよびデータ型は①と同様に設定します。
② サービスモードの設定
名前:/app/config/service_mode
値:enabled
※ 設定可能な値:enabled / disabled
③ メンテナンスモードの設定
名前:/app/config/maintenance_mode
値:off
※ 設定可能な値:on / off
④ サービスポートの設定
名前:/app/config/service_port
値:80

※ 補足
サービス名およびポート番号は、利用環境に応じて変更できます。 サービス名には、EC2 上で systemctl により制御可能なサービスを指定してください。 また、パラメータ名を変更する場合は、State Manager で実行するスクリプト内の取得先と整合していることを確認してください。
State Manager による設定適用
コンソール画面から Systems Manager を選択します。
ステートマネージャー → [関連付けの作成] を選択します。
名前:任意
ドキュメント:AWS-RunShellScript

パラメータ:
Commands に、以下のスクリプトを貼り付けます。
#!/bin/bash
# エラー発生時は即終了し、未定義変数やパイプライン内の失敗も検知する
set -euo pipefail
REGION="ap-northeast-1"
# Parameter Store から指定したパラメータ値を取得する関数
get_param() {
aws ssm get-parameter \
--name "$1" \
--query "Parameter.Value" \
--output text \
--region "$REGION"
}
# Parameter Store から制御に必要な設定値を取得
SERVICE_NAME=$(get_param "/app/config/service_name")
SERVICE_MODE=$(get_param "/app/config/service_mode")
MAINTENANCE_MODE=$(get_param "/app/config/maintenance_mode")
SERVICE_PORT=$(get_param "/app/config/service_port")
# 取得した設定値を出力(実行結果確認用)
echo "Service: $SERVICE_NAME"
echo "Mode: $SERVICE_MODE"
echo "Maintenance mode: $MAINTENANCE_MODE"
echo "Service port: $SERVICE_PORT"
# メンテナンスモードの判定
# on の場合は通常の service_mode 制御より優先してサービスを停止する
if [ "$MAINTENANCE_MODE" = "on" ]; then
echo "Maintenance mode is ON. Stopping service and skipping normal control."
systemctl stop "$SERVICE_NAME"
systemctl disable "$SERVICE_NAME"
# サービスが停止状態になっていることを確認
if systemctl is-active --quiet "$SERVICE_NAME"; then
echo "Service is still active during maintenance mode"
exit 1
else
echo "Service is inactive due to maintenance mode"
exit 0
fi
# maintenance_mode には on / off 以外を許可しない
elif [ "$MAINTENANCE_MODE" != "off" ]; then
echo "Invalid maintenance_mode value"
exit 1
fi
# service_mode に応じたサービス制御
if [ "$SERVICE_MODE" = "enabled" ]; then
# サービスを自動起動対象にし、起動する
systemctl enable "$SERVICE_NAME"
systemctl start "$SERVICE_NAME"
# サービスが正常に起動したことを確認
if systemctl is-active --quiet "$SERVICE_NAME"; then
echo "Service is active"
else
echo "Service failed to become active"
exit 1
fi
elif [ "$SERVICE_MODE" = "disabled" ]; then
# サービスを停止し、自動起動対象から外す
systemctl stop "$SERVICE_NAME"
systemctl disable "$SERVICE_NAME"
# サービスが停止状態になっていることを確認
if systemctl is-active --quiet "$SERVICE_NAME"; then
echo "Service is still active after stop"
exit 1
else
echo "Service is inactive"
exit 0
fi
# service_mode には enabled / disabled 以外を許可しない
else
echo "Invalid service_mode value"
exit 1
fi
# 指定ポートでサービスが待ち受けしていることを確認
if ss -ltn | grep -q ":${SERVICE_PORT} "; then
echo "Port ${SERVICE_PORT} is listening"
else
echo "Port ${SERVICE_PORT} is NOT listening"
exit 1
fi

ターゲットの選択 では、インスタンスタグを指定 を選択します。
以下のタグを設定します。
- タグキー:ConfigControl
- タグの値:Enabled

スケジュールを指定
CRON/Rate 式 を選択します。
例:cron(0 00 18 ? * * *)
※ 毎日 18:00 に実行されます

必要に応じてスケジュールを調整します。
※ 注意点
関連付けを作成すると、作成後まもなく一度自動的に実行されます。その後は、設定したスケジュールに従って継続的に自動実行されます。
そのほかの設定はデフォルトのままとし、[関連付けの作成]を選択します。
通知設定(任意)
SNS および EventBridge を利用した通知設定は任意です。通知設定を行わなくても、本記事の構成のみで動作確認は可能です。実行失敗時のアラートを設定したい場合は、前回の記事の「通知設定(SNS + EventBridge)」を参照してください。
これにより、State Manager の実行が失敗した際にメール通知を受け取り、迅速に検知・対応することが可能になります。
動作確認
Test 1: サービス制御の確認(enabled / disabled)
インスタンス上で現在の状態を確認します。
systemctl is-active httpd
systemctl is-enabled httpd
結果: inactive / disabled

コンソール画面から Systems Manager を選択します。
パラメータストア → /app/config/service_mode
値:enabled

コンソール画面から Systems Manager を選択します。
ステートマネージャー → 関連付け を選択します。
作成した関連付けを開き、[Apply association now] を選択します。
その後、[実行履歴] を開き、実行結果とコマンド出力内容を確認します。


実行完了後、インスタンス上で確認します。
systemctl is-active httpd
systemctl is-enabled httpd
結果: active / enabled

※ 補足
service_mode を disabled に設定した場合も同様に、サービスが停止(inactive)かつ無効化(disabled)されることを確認できます。
Test 2: メンテナンスモードの確認(on / off)
インスタンス上で現在の状態を確認します。
systemctl is-active httpd
systemctl is-enabled httpd
結果: active / enabled

コンソール画面から Systems Manager を選択します。
パラメータストア → /app/config/maintenance_mode
値:on

Test 1 と同様に[Apply association now]を実行し、
[実行履歴] を開き、実行結果および出力内容を確認します。


実行完了後、インスタンス上で確認します。
systemctl is-active httpd
systemctl is-enabled httpd
結果: inactive / disabled
メンテナンスモードが優先され、サービスが停止することを確認できます。

※ 補足
maintenance_mode を off に戻すことで、service_mode に従った通常動作に復帰します。
Test 3: エラー動作の確認
コンソール画面から Systems Manager を選択します。
パラメータストア → /app/config/service_port
値:9999

Test 1 と同様に[Apply association now]を実行し、
[実行履歴] を開き、実行結果および出力内容を確認します。
結果: Failed


※ SNS および EventBridge による通知設定を行っている場合は、実行失敗時に以下のようなメール通知を受け取ることができます。

まとめ
本記事では、Parameter Store と State Manager を組み合わせることで、EC2 の設定値を外部化し、運用を動的に制御する方法を紹介しました。
今回は、サービス制御やメンテナンスモードを例に取り上げましたが、同様の考え方は、より幅広い設定値や実行時制御にも応用できます。
シンプルな構成でありながら拡張性にも優れており、運用の柔軟性向上や設定管理の標準化を進めるうえで、有効なアプローチです。




