AWS BudgetsアラートをSlack通知する仕組みをCDKで構築
はじめに
AWS CDKv2(TypeScript)を使用し、AWS Budgetsで予算の監視とアラート通知を自動化し、Amazon SNSとAWS Chatbotを介してSlackにアラート通知を送信する設定を行いました。
今回の記事ではそれらの構築の解説とハマったところの紹介を行います。
対象読者
- AWSのコストアラートをslackやメールに通知したい
- CDKv2でインフラ構築を試してみたい
サービスの構成
以下のような構成のサービスを構築します。SNSをすでに100万回くらい動かしているとかでない限り、基本的に無料で運用できると思います。
各サービスについての補足
-
AWS Budgets
AWS Budgetsは、AWSリソースの使用量とコストを監視し、管理するためのサービスです。ユーザーはAWS Budgetsを使用して、特定の期間のコストと使用量に対する予算を設定できます。予算を超えると、AWS Budgetsはアラートを発生させ、設定された通知チャネルを通じてユーザーに通知します。 -
Amazon SNS
Amazon SNSは、パブリッシュ/サブスクライブモデルに基づくフルマネージドなメッセージングサービスです。SNSを使用すると、テキストメッセージ、Eメール、Slack通知、AWS Lambda関数など、複数のエンドポイントやクライアントに対してメッセージを即座に送信することができます。AWS Budgetsと組み合わせて使用することで、コストに関連するアラートを自動的に通知することができます。 -
AWS Chatbot
AWS Chatbotは、Amazon ChimeまたはSlackに対して安全かつ簡単に通知が送れるサービスです。
SNSから通知イベントを受け取り、各種AWSサービスからアラームの内容を取得します。その後、アラームの内容をslackに送信することができます。
実装
前提になる設定
CDKのコードを書く前に、AWS Management ConsoleでAWS ChatbotサービスにアクセスしSlackワークスペースとの接続は事前に行なっておく必要があります。
CDKのコード
今回はCDKv2(TypeScript)で行います。CDKのinstallやsetupの方法などについては割愛します。
import * as cdk from "aws-cdk-lib";
import * as budgets from "aws-cdk-lib/aws-budgets";
import * as chatbot from "aws-cdk-lib/aws-chatbot";
import * as iam from "aws-cdk-lib/aws-iam";
import * as sns from "aws-cdk-lib/aws-sns";
import { Construct } from "constructs";
export class AwsBudgetsNotifyStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// SNSトピックを先に作成
const topic = new sns.Topic(this, "MyBudgetTopic", {
topicName: "Budgets-Alert-Topic",
});
// budgetからのSNS通知を許可
topic.addToResourcePolicy(
new iam.PolicyStatement({
actions: ["sns:Publish"],
principals: [new iam.ServicePrincipal("budgets.amazonaws.com")],
resources: [topic.topicArn],
effect: iam.Effect.ALLOW,
}),
);
// 予算を作成し、SNSトピックを指定
new budgets.CfnBudget(this, "MyBudget", {
budget: {
budgetName: "SandBox-Alert-Budget",
budgetLimit: {
amount: 4, // 予算の金額 例なので4ドルで設定
unit: "USD",
},
timeUnit: "MONTHLY",
budgetType: "COST",
},
notificationsWithSubscribers: [
{
subscribers: [
{
subscriptionType: "SNS",
address: topic.topicArn, // ここでSNSトピックARNを指定
},
// メールでも通知したい場合ここで設定
{
subscriptionType: "EMAIL",
address: "あなたのメールアドレス",
},
],
notification: {
notificationType: "ACTUAL",
comparisonOperator: "GREATER_THAN",
threshold: 50, // 予算の50%を超えた時点で通知
},
},
],
});
// AWS Chatbot設定(Slackに通知)
new chatbot.SlackChannelConfiguration(this, "MySlackChannel", {
slackChannelConfigurationName: "COST_ALERT_CHANNEL",
slackWorkspaceId: "SLACK_WORKSPACE_ID", // SlackワークスペースID
slackChannelId: "SLACK_CHANNEL_ID", // SlackチャンネルID
notificationTopics: [topic],
loggingLevel: chatbot.LoggingLevel.NONE, // ログレベルを設定(必要に応じて変更)
});
}
}
上記のインフラコードでデプロイし、設定した予算を超えたとき場合以下のような通知がslackに送られてきます。
ハマったポイント
AWS BudgetsからSNSへののPublish操作の明示的無許可の不足
最初に試した時はChatbotがSNSトピックからの通知を受け取り、Slackに転送するためのIAMロールに関する具体的な設定は含まれおらず、デプロイ時にリソースは正しく作成されていましたが実行に失敗しました。
Chatbotを使用してSlackに通知を送信するためには、AWS BudgetsからSNSへのPublish操作を許可するための権限が設定されたIAMロールを明示的に関連付けてあげる必要がありました。
// budgetからのSNS通知を許可
topic.addToResourcePolicy(
new iam.PolicyStatement({
actions: ["sns:Publish"],
principals: [new iam.ServicePrincipal("budgets.amazonaws.com")],
resources: [topic.topicArn],
effect: iam.Effect.ALLOW,
}),
);
デプロイ時に予算がすでに超えている場合slackに即時通知されない
デプロイ時(アラームと通知設定が行われた瞬間)に予算をすでに超えていた場合、メールへの予算アラート通知はdeployと同時に通知されるがslack通知は来ないという事象が発生しました。
アラート作ったあとに予算を超えた場合はメール通知もslack通知も正常に動作しました。本番運用では既に超えているアラートを設定することはほとんどないはずなので問題ないと思いますが、検証時にはそういったことも起こる可能性は高いと思います。今後似たような作業をして同じ事象に遭遇する方がいるかもしれないのでハマったポイントとして記述しておきます。
最後に
今回のような設定を行うことでAWSのコスト管理を自動化し、指定した予算を超えた場合にSlackを通じて即時に通知を受け取ることができます。コストの急増を迅速に察知し、適切な対応を取ることが可能になるので安心してAWSを利用した開発ができるようになります。
みなさんもぜひ設定してみてください。
ユーザーファーストなサービスを伴に考えながらつくる、デザインとエンジニアリングの会社です。エンジニア積極採用中です!hrmos.co/pages/funteractive/jobs
Discussion