⚠️
「AWSのコストが設定した閾値以上になったらSlackに通知するリソース群」をCloudFormationで作成する
概要
予想外のコストがかかり出したら一刻も早く知りたいですよね。
というわけで、その日の予算に対して n
%を超えたらSlackの指定チャンネルに通知してくれる仕組みを作りました。
予算には固定値も設定できるのですが、担当しているプロジェクトでは「過去30日の移動平均」をその日の予算としました。
パラメータとして以下の4つを受け取る仕様にしました。
- 環境名(リソースへの命名に使用)
- SlackワークスペースID
- SlackチャンネルID
- 予算の何%でアラートを鳴らすか
yamlの全貌
billing-alert.yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Alert via Slack when AWS cost increases
Parameters:
EnvironmentName:
Description: An environment name that will be prefixed to resource names
Type: String
Default: stg
AllowedValues:
- stg
- prd
SlackWorkspaceID:
Description: Workspace ID to send billing alert
Type: String
SlackChannelID:
Description: Channel ID to send billing alert
Type: String
AlertThresholdPerBudget:
Type: Number
Default: 110
Resources:
SlackNotificationTopic:
Type: AWS::SNS::Topic
Properties:
TopicName: !Sub ${EnvironmentName}-billing-alert-topic
TopicPolicyForBilling:
Type: AWS::SNS::TopicPolicy
Properties:
Topics:
- !Ref SlackNotificationTopic
PolicyDocument:
Statement:
- Sid: "AWSBudgetsSNSPublishingPermissions"
Effect: Allow
Principal:
Service: budgets.amazonaws.com
Action: SNS:Publish
Resource: !Ref SlackNotificationTopic
Condition:
StringEquals:
aws:SourceAccount: !Sub ${AWS::AccountId}
ArnLike:
aws:SourceArn: !Sub arn:aws:budgets::${AWS::AccountId}:*
Budget:
Type: AWS::Budgets::Budget
Properties:
Budget:
BudgetName: !Sub ${EnvironmentName}-budget
BudgetType: COST
TimeUnit: DAILY
AutoAdjustData:
AutoAdjustType: HISTORICAL
HistoricalOptions:
BudgetAdjustmentPeriod: 30
CostTypes:
IncludeTax: false
NotificationsWithSubscribers:
- Notification:
NotificationType: ACTUAL
ComparisonOperator: GREATER_THAN
Threshold: !Ref AlertThresholdPerBudget
ThresholdType: PERCENTAGE
Subscribers:
- SubscriptionType: SNS
Address: !GetAtt SlackNotificationTopic.TopicArn
BillingSlackChannelConfig:
Type: AWS::Chatbot::SlackChannelConfiguration
Properties:
ConfigurationName: !Sub ${EnvironmentName}-billing-alert-configuration
IamRoleArn: !GetAtt BillingAlertIAMRole.Arn
SlackChannelId: !Ref SlackChannelID
SlackWorkspaceId: !Ref SlackWorkspaceID
SnsTopicArns:
- !Ref SlackNotificationTopic
BillingAlertIAMRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: chatbot.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: !Sub ${EnvironmentName}-BillingAlertPolicy
PolicyDocument:
Statement:
- Effect: Allow
Action:
- sns:Publish
Resource: !Ref SlackNotificationTopic
参考
Discussion