【運用自動化】Amazon Connectでシステム障害を即座に音声通知する仕組みを作ってみた
Amazon Connect アドベントカレンダー 2025、3日目の記事です!
クラスメソッドとギークフィードさん、AWS Japanさんの有志が募ってチャレンジしている企画になります。
(アドベントカレンダーのカレンダー一覧はこちら↓)
はじめに
システム障害は、緊急度によっては1分1秒を争う迅速な対応が必要になります。
しかし、運用担当者への連絡など、コミュニケーションに時間がかかる場合があります。
Amazon Connect を活用すると、音声通知が自動化できると思ったので試してみました!
アーキテクチャ図
以下の構成で、EC2の障害検知から自動通知までを実現します。
- CloudWatch Alarm が EC2 の CPU 使用率を監視
- アラーム状態になると EventBridge がトリガー
- Step Functions が DynamoDB から通知先情報を取得
- SNSでメール通知、Amazon Connect で電話発信

前提
- Amazon EC2
- Amazon Linux 2023 (ami-03852a41f1e05c8e4)
- Amazon Connect
- 構築や電話番号取得など、初期設定が完了していること
- Amazon SNS
- メールアドレスの紐付けが完了していること
本記事では作成手順については解説しません。
下記のリソースの設定値をご参考ください。
リソースの設定値
CloudWatch Alarm
インスタンスの CPU 使用率が 80% 以上の時にアラート状態になるように設定しました。

DynamoDB
CloudShell で、下記の AWS CLI コマンドを入力し、データを入れておきました。
インスタンス ID を基準に、電話番号と SNS ARN がマッピングされるイメージです。
aws dynamodb put-item \
--table-name <DynamoDBテーブル名> \
--item '{
"instance_id": {"S": "<EC2インスタンスID>"},
"phonenumber": {"S": "<電話番号>"},
"sns_arn": {"S": "<SNSトピックARN>"}
}'


Amazon Connect
日本語でプロンプトを読み上げるシンプルな構成で設定しました。


StepFunctions
全体的な StepFunctions の処理の流れは下記のイメージです。

以下はサンプルコードです。
"SourcePhoneNumber": "<AmazonConnectに登録した電話番号>", は、
例えば 050 の場合、+8150xxxxxxxx のような形で入力します。
{
"Comment": "EC2 インスタンス障害通知ワークフロー",
"StartAt": "DynamoDB から情報取得",
"States": {
"DynamoDB から情報取得": {
"Type": "Task",
"Resource": "arn:aws:states:::dynamodb:getItem",
"Parameters": {
"TableName": "<DynamoDBテーブル名>",
"Key": {
"instance_id": {
"S.$": "$.detail.configuration.metrics[0].metricStat.metric.dimensions.InstanceId"
}
}
},
"ResultPath": "$.dynamodb_result",
"Next": "インスタンス情報が存在するか確認",
"Catch": [
{
"ErrorEquals": [
"States.ALL"
],
"Next": "エラー処理",
"ResultPath": "$.error"
}
]
},
"インスタンス情報が存在するか確認": {
"Type": "Choice",
"Choices": [
{
"Variable": "$.dynamodb_result.Item",
"IsPresent": true,
"Next": "メッセージ作成"
}
],
"Default": "インスタンス情報なし"
},
"メッセージ作成": {
"Type": "Pass",
"Parameters": {
"instance_id.$": "$.detail.configuration.metrics[0].metricStat.metric.dimensions.InstanceId",
"alarm_name.$": "$.detail.alarmName",
"state.$": "$.detail.state.value",
"reason.$": "$.detail.state.reason",
"timestamp.$": "$.detail.state.timestamp",
"sns_arn.$": "$.dynamodb_result.Item.sns_arn.S"
},
"ResultPath": "$.message_data",
"Next": "SNS 通知送信"
},
"SNS 通知送信": {
"Type": "Task",
"Resource": "arn:aws:states:::sns:publish",
"Parameters": {
"TopicArn.$": "$.message_data.sns_arn",
"Subject": "【緊急】EC2 インスタンス障害通知",
"Message.$": "States.Format('EC2 インスタンスで障害が発生しました。\n\n【詳細情報】\nインスタンスID: {}\nアラーム名: {}\n状態: {}\n理由: {}\n発生時刻: {}\n\n至急ご確認ください。', $.message_data.instance_id, $.message_data.alarm_name, $.message_data.state, $.message_data.reason, $.message_data.timestamp)"
},
"ResultPath": "$.sns_result",
"Next": "Amazon Connect 発信"
},
"Amazon Connect 発信": {
"Type": "Task",
"Resource": "arn:aws:states:::aws-sdk:connect:startOutboundVoiceContact",
"Parameters": {
"InstanceId": "<AmazonConnectインスタンスID>",
"ContactFlowId": "<AmazonConnectフローID>",
"SourcePhoneNumber": "<AmazonConnectに登録した電話番号>",
"DestinationPhoneNumber.$": "$.dynamodb_result.Item.phonenumber.S"
},
"ResultPath": "$.connect_result",
"Next": "成功",
"Catch": [
{
"ErrorEquals": [
"States.ALL"
],
"Next": "成功",
"ResultPath": "$.connect_error"
}
]
},
"成功": {
"Type": "Succeed"
},
"インスタンス情報なし": {
"Type": "Fail",
"Error": "InstanceNotFound",
"Cause": "指定されたインスタンスIDが DynamoDB に登録されていません"
},
"エラー処理": {
"Type": "Fail",
"Error": "WorkflowError",
"Cause": "ワークフロー実行中にエラーが発生しました"
}
}
}
※ 注意
Step Functions の作成時に自動的に付与されるロールでは、権限が足りません。
以下のポリシーを必ず追加してください。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "connect:StartOutboundVoiceContact",
"Resource": "arn:aws:connect:ap-northeast-1:<AWSアカウントID>:instance/*/contact/*"
}
]
}
EventBridge
対象 CloudWatch Alarm が ALARM 状態の時にトリガーされるように設定しました。
{
"source": ["aws.cloudwatch"],
"detail-type": ["CloudWatch Alarm State Change"],
"detail": {
"alarmName": ["<CloudWatchアラーム名>"],
"state": {
"value": ["ALARM"]
}
}
}
ターゲットには、Step Functions を登録しています。

▼ Amazon_EventBridge_Invoke_Step_Functions_xxxxxxxxx IAM ロールのポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"states:StartExecution"
],
"Resource": [
"arn:aws:states:ap-northeast-1:<AWSアカウントID>:stateMachine:<StepFunctions名>"
]
}
]
}
▼ Amazon_EventBridge_Invoke_Step_Functions_xxxxxxxxx IAM ロールの信頼関係
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "events.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
障害発生からの流れ

EC2 インスタンスで stress コマンドで負荷をかけてみます。
$ stress --cpu 2 --timeout 300s
CloudWatch Alarm がアラーム状態になり、EventBridge がトリガーされます。

EventBridge → Step Functions
DynamoDB を確認し、SNS トピックにメール通知を実施した後、
phonenumber に電話をかけてアナウンスプロンプトを読み上げます。

結果
メール通知
下記のように、案内メールが届いていました。

電話連絡
実際に Amazon Connect の電話番号から電話がかかってきて、
下記の CloudWatch Logs のように案内アナウンスが流れてきました。
{
(...省略)
"Parameters": {
"TextToSpeechType": "text",
"Text": "只今、システム障害が発生しました。\n詳細はメールにてご案内しております。",
"Voice": "Kazuha"
}
}
まとめ
障害発生時には、速やかな対応が重要です。
今回は、EC2 の障害検知から自動連絡までの仕組みを作ってみました。
実際にアラート状態になってから、数秒程度でメール通知と電話連絡が来ました。
Amazon Connect の運用自動化で、障害発生時の初動対応を大幅に効率化できそうですね!
参考記事







