iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
⚠️

Creating AWS Budget Alerts for Slack Notifications with CloudFormation

に公開

Overview

When unexpected costs start to occur, you want to know as soon as possible, right?
Therefore, I created a mechanism that notifies a specified Slack channel when costs exceed n % of the daily budget.

While budgets can be set to a fixed value, in the project I'm handling, I used the "moving average of the past 30 days" as the daily budget.

I designed it to accept the following four parameters:

  • Environment name (used for resource naming)
  • Slack workspace ID
  • Slack channel ID
  • Percentage of the budget at which to trigger the alert

Full 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

References

https://docs.aws.amazon.com/ja_jp/cost-management/latest/userguide/sns-alert-chime.html

Discussion