[AWS CDK] CloudWatchアラームをChatbotからSlackに連携してみた
みなさんこんにちは! 第4開発事業部のAKIHISAです!
DevOpsが叫ばれる今、監視情報は開発者にとっても有益な情報です
システムの重大な異常の検知→調査・改修が迅速にできたら言うことはありません
監視情報をメールや監視ダッシュボードだけでは無く、普段目にしているチャットに通知したら監視情報の連携はよりスムーズになります
そこで、今回はAWSの監視サービスであるCloudWatchアラームから、一般的に使われているチャットツールであるSlackへの連携方法を紹介します!
やること
CloudWatchアラームにてアラーム状態となったメトリクスを、Slackに通知を行います
アーキテクチャ
前提条件
AWS CDKをデプロイできる状態
参考
Slackのワークスペースが存在する状態
参考
作業概要
AWS ChatbotとSlackの事前設定
AWS CDKデプロイ
動作確認
AWS ChatbotとSlackの事前設定
AWS Chatbotの事前設定
Chatbotは2024年2月現在、CLI及びIaCでのチャットクライアントの設定を行うことができません
ChatbotコンソールからSlackワークスペースとの連携を行います
チャットクライアントからSlackを選択してクライアントを設定を押下します
ChatbotがSlackワークスペースにアクセスする権限をリクエストされるので、許可するを押下します
SlackのワークスペースにAWS Chatbotアプリが追加されています
Slackの設定
チャンネルを作成します
作成したチャンネルへ以下のメッセージを送信(スラッシュコマンドの実行)し、AWS Chatbotをチャンネルに追加します
/invite @aws
Slack情報の取得
ワークスペースIDとチャンネルIDが必要なのでそれぞれ取得します
ワークスペースのIDはChatbotのコンソール上から取得するのが簡単です
(Tから始まる番号)
チャンネルIDは、Slackにて作成したチャンネルのチャンネル情報の最下部に表示されています
(Cから始まる番号)
AWS CDKデプロイ
作成するスタックは以下の2つのL3コンストラクタからなっています
CloudWatchアラームが設定されているサンプルリソース(Lmabda)のコンストラクタ
アラームをモニタリングしているコンストラクタ
lib/construct/sample-resource.ts
import * as cdk from 'aws-cdk-lib';
import { aws_cloudwatch as cw, aws_cloudwatch_actions as cwa, aws_lambda as lambda, aws_sns as sns } from 'aws-cdk-lib';
import { Construct } from 'constructs';
export interface sampleResourceProps {
topic: sns.Topic;
}
export class sampleResource extends Construct {
constructor(scope: Construct, id: string, props: sampleResourceProps) {
super(scope, id);
const func = new lambda.Function(this, 'Function', {
functionName: 'SampleFunction',
runtime: lambda.Runtime.PYTHON_3_11,
handler: 'index.lambda_handler',
code: lambda.Code.fromInline(
`def lambda_handler(event, context):
message = "Hello, World!"
return message`,
),
});
const errorsAlarm = new cw.Metric({
dimensionsMap: {
FunctionName: func.functionName,
},
namespace: 'AWS/Lambda',
metricName: 'Errors',
period: cdk.Duration.minutes(5),
statistic: cw.Stats.SUM,
}).createAlarm(this, 'SampleFunctionErrors', {
alarmName: 'SampleFunctionAlarm-Erros',
evaluationPeriods: 1,
threshold: 1,
comparisonOperator: cw.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
});
errorsAlarm.addAlarmAction(new cwa.SnsAction(props.topic));
const throttlesAlarm = new cw.Metric({
dimensionsMap: {
FunctionName: func.functionName,
},
namespace: 'AWS/Lambda',
metricName: 'Throttles',
period: cdk.Duration.minutes(5),
statistic: cw.Stats.SUM,
}).createAlarm(this, 'SampleFunctionThrottles', {
alarmName: 'SampleFunctionAlarm-Throttles',
evaluationPeriods: 1,
threshold: 1,
comparisonOperator: cw.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
});
throttlesAlarm.addAlarmAction(new cwa.SnsAction(props.topic));
}
}
lib/construct/monitoring.ts
import { aws_chatbot as chatbot, aws_sns as sns } from 'aws-cdk-lib';
import { Construct } from 'constructs';
export class monitoring extends Construct {
public readonly topic: sns.Topic;
constructor(scope: Construct, id: string) {
super(scope, id);
const topic = new sns.Topic(this, 'Topic', {
topicName: 'SampleTopic',
});
this.topic = topic;
new chatbot.SlackChannelConfiguration(this, 'Channel', {
slackChannelConfigurationName: 'SampleMonitoringChannel',
slackWorkspaceId: '[ワークスペースID]',
slackChannelId: '[チャンネルID]',
notificationTopics: [topic],
});
}
}
lib/stack/sample-app-stack.ts
import { Stack } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { monitoring } from '../construct/monitoring';
import { sampleResource } from '../construct/sample-resource';
export class SampleAppStack extends Stack {
constructor(scope: Construct, id: string) {
super(scope, id);
const monitor = new monitoring(this, 'AlarmNortification');
new sampleResource(this, 'SampleResource', {
topic: monitor.topic,
});
}
}
CDKデプロイを行います
cdk deploy
スタックが作成されました!
CloudFormationコンソール
動作確認
CloudWatchアラームをアラーム状態にさせます
CloudShellを開き、以下のコマンドを実行します
CloudShellコンソール
aws cloudwatch set-alarm-state --alarm-name "SampleFunctionAlarm-Erros" --state-value "ALARM" --state-reason "test"
参考
SlackチャンネルにCloudWatchアラームの通知が送信されていました!
もう一つのCloudWatchアラームもアラーム状態にします
aws cloudwatch set-alarm-state --alarm-name "SampleFunctionAlarm-Throttles" --state-value "ALARM" --state-reason "test"
こちらもアラームの通知が送信されています
まとめ
CloudWatchアラームをSlackへ迅速へ通知することができました
CDKのコードから分かる通り、CloudWatchアラームをSNSトピックへ送信するだけで追加のアラームを通知することもできるため、拡張性も高いです
errorsAlarm.addAlarmAction(new cwa.SnsAction(props.topic));
是非、ChatOpsを推進させて、対インシデント耐性の高いシステムを構築していきましょう!
ALHについて知る
↓ ↓ ↓ 採用サイトはこちら ↓ ↓ ↓
↓ ↓ ↓ コーポレートサイトはこちら ↓ ↓ ↓
↓ ↓ ↓ もっとALHについて知りたい? ↓ ↓ ↓