1. はじめに
- 前回の記事「AWS DevOps Agent を使ってみる (Getting started with AWS DevOps Agent の実施)」では、DevOps Agentの初期設定および基本的な使用方法を確認した。
- 前回は、ユーザが DevOps AgentのOperatorアクセス画面を開いて、手動(チャット)で調査を依頼する必要があったが、今回は、CloudWatch アラームが出たら、それをトリガにDevOps Agentが自動で調査を開始するように改良する。
2. やったこと
- 以下のパイプラインを作成し、CloudWatch アラームが出たら自動的に調査が始まることを確認する。
- CloudWatch アラームを発生させる
- EventBridgeで該当のアラーム発生をフィルタし、アラーム発生時にLambdaを起動させる
- Lambdaがアラーム情報をDevOps AgentのWebhookに送信し、DevOps Agentに調査開始依頼する
- DevOps Agentが自動で調査を開始する
3. 構成図
4. 先輩の手順
既にやりたいことを実現している記事がいくつかあったが、あらためて自分でやってみることで仕組みを理解する。
5. 手順
5.1 前提条件
- DevOps Agent のエージェントスペースが作成済であること。
- 特定のインスタンスでCPUが70%以上になるとアラームになるCloudWatchアラームが作成済であること。
5.2 Webhookの設定
- 公式ドキュメント「Invoking DevOps Agent through Webhook」に従い、Webhookを作成する。
- 設定画面を進めると、URL(エンドポイント)と、Secretkeyが発行されるのでメモする。
5.3 Lambda関数の作成
-
アラームが発生した時に、「アラームの内容を調べて!」とDevOps Agentに調査依頼するLambda関数を作成する。
-
機能
- CloudWatchアラーム名をメッセージに含め、そのアラームについて調査を依頼できるようにする。
- DevOps Agent Webhookのお作法(内容をHMAC SHA256署名して正当性の確認)に従ってメッセージを作成・送信する。
-
備考
- Lambda Layersなどを使用しなくてよいように、標準ライブラリのみを使用する。
- httpsのリクエストを出すだけなので、標準のLambda実行用IAMロールでよい。
- Webhook URLやSecretkeyは本来安全な場所(Secret Managerなど)に保存すべきだが、今回は検証のため環境変数に保存(マネコンから見える状態)。
- Priorityを指定できるが、今回はMediumで固定。
-
具体的なPythonコードは以下(Kiroで自動作成したものであまり精査はできていない)。
Lambdaコード(押すと表示)
send-investigation-request.py
import json
import hashlib
import hmac
import os
import base64
import uuid
import urllib.request
import urllib.error
from datetime import datetime, timezone
def lambda_handler(event, context):
webhook_url = os.environ["WEBHOOK_URL"]
secret_key = os.environ["WEBHOOK_SECRET_KEY"]
timestamp = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.000Z")
alarm_name = event.get("detail", {}).get("alarmName", "unknown-alarm")
incident_payload = {
"eventType": "incident",
"incidentId": str(uuid.uuid4()),
"action": "created",
"priority": "MEDIUM",
"title": f"CloudWatch Alarm: {alarm_name}",
"description": f"{alarm_name} の直近のアラートの原因調査してください",
"timestamp": timestamp,
}
payload = json.dumps(incident_payload)
# timestamp:payload の形式で署名を計算し、base64エンコード
message = f"{timestamp}:{payload}"
signature = base64.b64encode(
hmac.new(
key=secret_key.encode("utf-8"),
msg=message.encode("utf-8"),
digestmod=hashlib.sha256,
).digest()
).decode("utf-8")
req = urllib.request.Request(
url=webhook_url,
data=payload.encode("utf-8"),
headers={
"Content-Type": "application/json",
"x-amzn-event-signature": signature,
"x-amzn-event-timestamp": timestamp,
},
method="POST",
)
try:
with urllib.request.urlopen(req, timeout=10) as response:
status_code = response.status
body = response.read().decode("utf-8")
print(f"Webhook response: status={status_code}, body={body}")
except urllib.error.HTTPError as e:
print(f"HTTP error: {e.code} {e.reason}")
raise
except urllib.error.URLError as e:
print(f"URL error: {e.reason}")
raise
return {"statusCode": status_code, "body": body}
5.4 EventBridgeの設定
- インスタンスのCPU70%超過を検知するアラーム(アラーム名:mksamba-devops-agent-cpuload-alarm)が発生した時に、上記のLambda関数を呼び出すように、EventBridgeルールを作成する。
- イベントバス(default)に対して以下のイベントパターンを設定し、5.3項で作成したLambda関数を実行するように指定する。
イベントパターン.json
{
"source": ["aws.cloudwatch"],
"detail-type": ["CloudWatch Alarm State Change"],
"detail": {
"alarmName": ["mksamba-devops-agent-cpuload-alarm"],
"state": {
"value": ["ALARM"]
},
"previousState": {
"value": ["OK"]
}
}
}
5.5 一連の動作確認
-
検証用のEC2インスタンスでスクリプトを実行し、CPU使用率を高騰させ、CloudWatchアラームが出て、Lambda関数が実行されて、DevOps Agentが調査開始することを確認する。
-
Lambda関数のWebhookへのPOSTが成功すると、DevOps Agentから以下の正常応答がある。
Webhook response: status=200, body={"message": "Webhook received"}
- DevOps Agentのオペレータアクセス画面にアクセスし、調査が自動開始されていることを確認する。
- 今回は5分程度で調査が完了していた。(私が負荷スクリプトを実行したという原因も判明)
6. 所感
- CloudWatch アラームが出たら自動で調査開始する方法が確認できた。次回は、調査結果を自動で外部送信する仕組みを確認し、調査を全自動化したい。



