はじめに
AWS Systems Manager (SSM) の Run Command は、AWS環境内のEC2インスタンスなどをリモート操作できる強力なツールです。
Run Commandの基本的な使い方については、前回の記事でも詳しく説明していますので、興味がある方はぜひご覧ください。
この記事では、EventBridgeを使用してEC2インスタンスの起動を検知し、Lambda関数をトリガーとしてSSMコマンドを実行します。
さらに、指定のインスタンスにApacheのサービスを自動起動させる自動化の流れを解説します。
前提条件
この手順では、AWSの各種サービスを活用して、インスタンスの起動を動的に検知し、Apacheサービスの起動を自動化するフローを構築します。
IAM Roleの設定:
EC2インスタンスには「AmazonSSMManagedInstanceCore」ポリシーがアタッチされたIAMロールが必要です。
Lambda関数には「AmazonSSMFullAccess」ポリシーがアタッチされたIAMロールが必要です。
SSMエージェントのインストール:
最新のAmazon LinuxやWindows ServerにはSSMエージェントがプリインストールされていますが、インストールされていない場合は手動でのインストールが必要です。
AWS CLIのセットアップ:
コマンドを実行するマシンにAWS CLIがインストールされ、適切に設定されていることを確認してください。
IAMロールに必要なポリシーが付与されていないと処理が正しく動作しないことがあるため、実装時には十分に確認してください。
構成/検証の流れ
ここでは、すでにEC2インスタンスが構築されていることを前提とします。
インスタンスの構築やIAMロールの設定に関しては、前回の記事でも解説していますので、こちらも参考にしてください。
Apache HTTP Serverのインストール手順
使用するLinuxディストリビューションによって異なりますが、ここではAmazon Linux 2 / CentOS / RHELの場合の手順を紹介します。
まず、パッケージリストを更新し、Apacheをインストールします。
sudo yum update -y
sudo yum install httpd -y
Apacheサービスを起動し、ファイアウォールでHTTPおよびHTTPSのトラフィックを許可します。
※ここでは、後続の検証のために、あえてApacheサービスの自動起動設定は行っていません。
sudo systemctl start httpd
# HTTP (ポート 80) を許可
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# HTTPS (ポート 443) を許可
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# 変更を保存します
sudo service iptables save
サーバーのIPアドレスまたはドメイン名をブラウザに入力します。デフォルトのApacheのテストページが表示されれば、インストールは成功です。
デフォルトのApacheのテストページが表示されない場合は、セキュリティグループのインバウンドルールで「HTTP(80):0.0.0.0/0」を許可する必要があります。
EventBridgeルールの作成
まず、EC2インスタンスの起動を検知するために、EventBridgeルールを設定します。
AWS Management ConsoleからEventBridgeに移動し、新しいルールを作成します。
イベントソースを「EC2」から選択し、イベントタイプを「EC2インスタンスの状態変更通知」とします。
次に、EC2インスタンスの起動(state: running)を検知するため、以下のカスタムイベントパターンJSONを使用します。
{
"source": [
"aws.ec2"
],
"detail-type": [
"EC2 Instance State-change Notification"
],
"detail": {
"instance-id": [
"i-xxx"
],
"state": [
"running"
]
}
}
このように「state: running」と設定することで、特定のインスタンスの起動イベントをキャプチャできます。
設定内容に問題がないことを確認したら、ルールを作成します。
Lambda関数の作成
次に、EventBridgeからトリガーされるLambda関数を作成します。AWS Lambdaに移動し、新しい関数を作成します。
Lambda関数に使用する実行ロールには、「AmazonSSMFullAccess」ポリシーを必ずアタッチしてください。
次に、既存のLambda関数にApacheの自動起動コマンドを追加し、起動が成功した場合にメッセージを/tmp/instance_status.txtに記録する処理を追加します。
import boto3
import datetime
def lambda_handler(event, context):
# SSMクライアントの作成
ssm = boto3.client('ssm')
# インスタンスIDを取得
instance_id = event['detail']['instance-id']
# 現在のタイムスタンプを取得
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# Apacheサービスの自動起動と成功メッセージの記録コマンド
commands = [
"sudo systemctl start httpd", # Apacheの起動コマンド (Amazon Linuxの場合)
"if systemctl is-active --quiet httpd; then", # Apacheが起動しているか確認
f"echo '{timestamp} - Apacheサービスが正常に起動しました' >> /tmp/instance_status.txt", # 起動成功時のメッセージ
"else",
f"echo '{timestamp} - Apacheサービスの起動に失敗しました' >> /tmp/instance_status.txt", # 起動失敗時のメッセージ
"fi"
]
# SSM Run Commandを使用してApacheを起動し、メッセージを出力
response = ssm.send_command(
InstanceIds=[instance_id],
DocumentName="AWS-RunShellScript",
Parameters={'commands': commands},
)
return {
'statusCode': 200,
'body': response
}
このLambda関数は、EC2インスタンスが起動した際にApache(httpd)サービスを自動的に開始します。
また、起動結果は/tmp/instance_status.txtにタイムスタンプ付きで記録されます。
Lambdaトリガーの設定
Lambda関数を作成した後、EventBridgeルールのターゲットとしてこの関数を指定します。
これにより、EC2インスタンスの起動が検知されるたびに、Lambda関数が自動で呼び出されます。
検証方法
EC2インスタンスを起動または再起動して、EventBridgeがインスタンスの状態変化を検知し、LambdaをトリガーとしてSSM Run Commandを実行し、Apacheが自動的に起動されるか確認します。
検証結果として、/tmp/instance_status.txtに以下のようにタイムスタンプ付きのメッセージが出力されていることが確認できました。
[ec2-user@ip-10-0-7-121 ~]$ cd /tmp/
[ec2-user@ip-10-0-7-121 tmp]$ cat instance_status.txt
2024-10-12 10:35:15 - Apacheサービスが正常に起動しました
[ec2-user@ip-10-0-7-121 tmp]$ sudo systemctl status httpd
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
Active: active (running) since Sat 2024-10-12 10:35:16 UTC; 1min 55s ago
Docs: man:httpd.service(8)
Main PID: 3214 (httpd)
Status: "Total requests: 0; Idle/Busy workers 100/0;Requests/sec: 0; Bytes served/sec: 0 B/sec"
CGroup: /system.slice/httpd.service
├─3214 /usr/sbin/httpd -DFOREGROUND
├─3219 /usr/sbin/httpd -DFOREGROUND
├─3220 /usr/sbin/httpd -DFOREGROUND
├─3221 /usr/sbin/httpd -DFOREGROUND
├─3222 /usr/sbin/httpd -DFOREGROUND
└─3223 /usr/sbin/httpd -DFOREGROUND
Oct 12 10:35:16 ip-10-0-7-121.ap-northeast-1.compute.internal systemd[1]: Starting The Apache HTTP Server...
Oct 12 10:35:16 ip-10-0-7-121.ap-northeast-1.compute.internal systemd[1]: Started The Apache HTTP Server.
[ec2-user@ip-10-0-7-121 tmp]$
OS起動後、デフォルトのApacheのテストページが正常に表示されることも確認できました。
Apacheのhttpd.serviceも正常に起動していることが確認でき、検証は成功です!
おわりに
この記事では、EC2インスタンスの起動イベントをEventBridgeで検知し、LambdaをトリガーとしてSSM Run Commandを実行してApacheを自動的に起動する手順を紹介しました。
この方法を使うことで、インスタンス起動時のApacheサービスの管理が簡単になります。
少し難しい内容でしたが、期待通りの結果が得られ、非常に有意義な検証となりました!
参考文献