CONTACT
お問い合わせ

Lambdaを用いたEC2外形監視構成

前提

 アプリケーションの死活監視を実際にアプリケーションにアクセスして行うことを外形監視といいます。本記事では、Lambdaから定期的にシステムにアクセスし稼働状況を監視する構成について解説します。
 前提は以下の通りです。

  • Spring Bootを用いたWebアプリケーション
  • AWS EC2で稼働
  • アクセスをIPアドレスフィルタしている
  • できるだけ安価に実現する

全体構成図

Spring Boot Actuatorの導入

 まず、死活監視のためにアクセスする先をアプリケーションに用意します。今回はSpring Boot Actuatorを利用します。
 Spring Boot Actuatorとは、アプリケーションの監視・管理に有用なSpring Bootの依存関係です。
 pom.xmlの<dependencies>に以下の記載をすることで導入できます。

<dependency>	
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

 application.ymlに以下のように記載します。各設定値の詳細については割愛しますが、今回はアプリケーションが起動しているかの確認(ping)とDBとの接続が正常かの確認(db)のみ有効にしました。

management:               
  health:             
    defaults:           
      enabled: false        #デフォルトを不可に設定
    db:           
      enabled: true         #DB接続チェック有効
    ping:           
      enabled: true         #ping有効
  endpoint:             
    health:           
      show-details: always  #常に詳細表示
  endpoints:              
    web:            
      exposure:         
        include: health     #/healthパスだけ有効化

 上記の設定をしてアプリケーションを起動してみましょう。localhost:8080/[applicationName]/actuator/health のようにアクセスすると、以下のようなjsonが得られます。このjsonをLambdaで取得・解析することで死活監視ができます。

{"status":"UP","components":{"db":{"status":"UP","details":{"database":"MySQL","validationQuery":"isValid()"}},"ping":{"status":"UP"}}}

LambdaからのIP固定アクセス

 Lambdaのコードについて詳細は割愛しますが、簡単に言うと以下のような処理をします。

  1. /actuator/healthにアクセスしてjsonを取得
  2. jsonをパースして、”ping”と”db”の”status”値をチェック
  3. “UP”でない場合に、異常と判定する

 Lambdaを普通に起動すると、Lambdaには起動のたびに異なるIPアドレスが割り当てられます。ですが、ホワイトリストに登録されたIPアドレスからしかアクセスできないように制御している場合、LambdaのIPアドレスを固定してホワイトリストに登録する必要があります。
 IPv4を固定するにはNAT Gatewayを利用するといった方法がありますが、NAT Gatewayの利用は有料です。そこで、IPv4ではなくIPv6でアクセスするようにします。

 Lambdaの設定タブからVPC, サブネットを設定できます。
 IPv6のCIDRを設定したサブネットを紐づけます。これによりLambdaは必ずCIDRに指定した範囲のIPv6アドレスからアプリケーションにアクセスするようになります。
 IPv4はプライベートアドレスをNATでグローバルアドレスに変換して外部と通信しますが、IPv6は直接グローバルアドレスが割り当てられるため、サブネットに配置していてもそのまま通信が可能です。(※Internet Gatewayのルーティング設定は必要です)
 セキュリティグループではアウトバウンドルールでIPv6を許可しておきます。
 ホワイトリストにはCIDRに設定したIPアドレスを登録しておきましょう。

異常時のSlack通知

 ここまででLambdaからアプリケーションにアクセスする構成はできました。
 ですが、外形監視である以上は異常を検知するだけでなく、異常が検知された場合にそれを通知する必要があります。
 今回はSlackに通知する方法について記載します。
 Slackのchat.postMessage(https://docs.slack.dev/reference/methods/chat.postMessage/)というAPIを使うと任意のチャンネルに好きなメッセージを送信することができます。
 上記APIの使用方法については、他の詳しい記事に任せて割愛します。
 本題は、上記の構成でサブネットに配置したLambdaからはSlackのAPIを呼び出せない、という問題についてです。理由はSlackのAPIはIPv6に対応していないためです。(2026/03/27現在)
 なのでこちらはIPv4で呼び出す必要があります。そのためにSlack通知専用のVPC設定を行わないLambdaを用意します。
 以下はpythonのコードですが、このようにLambda関数からLambda関数を呼び出すことができます。

# 呼び出し時のイベントデータ
	payload = {
		"message": f"<!channel> ヘルスチェック異常を検知しました。確認してください。\nURL: {url}actuator/health\nStatus Code: {status_code}\nHealth Status: {health_status}\nMessage: {message}",
		"channel": channel_id
	}

	# Lambdaクライアントの作成
	client = boto3.client('lambda', endpoint_url='https://lambda.ap-northeast-1.api.aws')

	# Lambda関数の呼び出し
	response = client.invoke(
		FunctionName='noticeForSlack',  # 呼び出し先のLambda関数名
		InvocationType='RequestResponse',  # 同期的に呼び出す
		Payload=json.dumps(payload)  # ペイロードを渡す
	)

 LambdaはIPv6でも呼び出すことができます。呼び出された側のVPC設定をしていないLambdaではIPv4での通信が可能です。SlackのAPIについても問題なく叩くことができます。

 LambdaはEvent Bridgeを利用することで容易に定期実行が可能です。
 Lambda, Event Bridgeについては従量課金となりますが、安価に利用することができます。詳しい料金についてはAWSの公式ページをご確認ください。