はじめに
このブログ記事では、AWS Lambdaを使用してEC2インスタンスのhttpdサービスの状態を監視し、サービスの状態に応じてALB (Application Load Balancer) のリスナールールを動的に変更する方法を紹介します。
メンテナンスモードや通常モードへの切り替えを自動化することで、システムの可用性を高めることができます。
全体のコード
import boto3
def lambda_handler(event, context):
ec2_client = boto3.client('ec2')
ssm_client = boto3.client('ssm')
elbv2_client = boto3.client('elbv2')
# 監視対象のEC2インスタンスIDリスト
instance_ids = ["i-0458be1d8c980e8ec", "i-0b27db6a9b067f345"]
# httpdサービスの状態を確認するためのSSM Run Command
command = "systemctl is-active httpd"
# httpdサービスが停止しているインスタンス数をカウント
instances_stopped_count = 0
for instance_id in instance_ids:
try:
response = ssm_client.send_command(
InstanceIds=[instance_id],
DocumentName="AWS-RunShellScript",
Parameters={'commands': [command]}
)
command_id = response['Command']['CommandId']
output = ssm_client.get_command_invocation(
CommandId=command_id,
InstanceId=instance_id
)
# httpdサービスが停止している場合にカウント
if output['StandardOutputContent'].strip() != 'active':
instances_stopped_count += 1
except Exception as e:
print(f"Error checking httpd service on instance {instance_id}: {e}")
# インスタンスの状態に応じてALBリスナールールの優先度を変更
if instances_stopped_count == len(instance_ids):
# 全てのインスタンスでhttpdが停止している場合、メンテナンスモードへ切り替え
response = elbv2_client.set_rule_priorities(
RulePriorities=[
{
'RuleArn': 'arn:aws:elasticloadbalancing:ap-northeast-1:YOUR_SORRY_PAGE_RULE_ARN',
'Priority': 1
},
{
'RuleArn': 'arn:aws:elasticloadbalancing:ap-northeast-1:YOUR_NORMAL_RULE_ARN',
'Priority': 2
},
]
)
else:
# 少なくとも1台が稼働中の場合、通常モードに戻す
response = elbv2_client.set_rule_priorities(
RulePriorities=[
{
'RuleArn': 'arn:aws:elasticloadbalancing:ap-northeast-1:YOUR_NORMAL_RULE_ARN',
'Priority': 1
},
{
'RuleArn': 'arn:aws:elasticloadbalancing:ap-northeast-1:YOUR_SORRY_PAGE_RULE_ARN',
'Priority': 2
},
]
)
return {
'statusCode': 200,
'body': 'Lambda execution completed successfully'
}
プログラムの処理内容
1. EC2クライアントとNLBクライアントの作成
boto3 ライブラリを使用して、AWSのEC2、SSM、ELBのクライアントを作成します。このライブラリを使うことで、PythonからAWSリソースにアクセスできます。
2. EC2インスタンスの状態確認
監視するEC2インスタンスのIDをリストとして定義し、各インスタンスでsystemctl is-active httpdコマンドを実行します。このコマンドにより、httpdサービスが稼働しているかどうかを確認します。
3. インスタンスの停止状態を確認
各インスタンスのhttpdサービスが停止している場合、その数をカウントします。send_commandとget_command_invocationメソッドを使用して、コマンドの実行結果を取得します。
4. ALBリスナールールの切り替え
2台ともhttpdサービスが停止している場合には、ALBリスナールールの優先度を変更して、メンテナンスモード(Sorryページ)に切り替えます。少なくとも1台が稼働中の場合は、通常ページを優先します。
5. 処理の結果を返す
処理が完了したことを示すステータスコードとメッセージを返します。
必要な設定とIAMポリシー
EC2インスタンスの設定
SSMエージェントのインストール:
EC2インスタンスにSSMエージェントがインストールされていることを確認します。多くのAmazon Linux 2 AMIでは、デフォルトでSSMエージェントがインストールされています。
sudo yum install -y amazon-ssm-agent
sudo systemctl enable amazon-ssm-agent
sudo systemctl start amazon-ssm-agent
IAMロールの設定:
EC2インスタンスに以下のポリシーを持つIAMロールをアタッチします。
AmazonEC2RoleforSSM
AmazonSSMManagedInstanceCore
Lambda関数の設定
IAMロールの設定:
Lambda関数に以下のポリシーを持つIAMロールをアタッチします。
ssm:SendCommand
ssm:GetCommandInvocation
elasticloadbalancing:SetRulePriorities
elasticloadbalancing:DescribeRules
注意点
注意点は、以下になります。
リトライとエラーハンドリング:
実際の運用環境では、コマンド実行や結果取得が失敗する場合もあるため、リトライ処理やエラーハンドリングを追加することをお勧めします。
コマンド結果の取得タイミング:
コマンドの出力を取得するために、適切なポーリング間隔を設定してください。現在はシンプルにtime.sleep()で待機していますが、より適切な実装を行うと良いでしょう。
まとめ
この手法を使うことで、AWS LambdaとSSMを活用してEC2インスタンスの状態を詳細に監視し、動的にALBのリスナールールを変更することが可能になります。
メンテナンス作業やサーバーのダウンタイム時にも柔軟に対応できるため、より高い可用性とユーザー体験を提供することができます。
これで、EC2インスタンスの状態に応じたメンテナンスモードの切り替えを自動化する仕組みが完成です。