dshimizu/blog

アルファ版

AWS Budgets を設定して日々の利用料金が一定額を超えたら AWS Chatbot で Slack 通知させる CloudFormation テンプレートのサンプルを作ってみた

AWS Budgets を設定して、料金が一定額を超えたら AWS Chatbot で Slack へ通知させるような設定ができる CloudFormation テンプレートを作った。

AWS Budgets とは

AWS のコスト管理サービスの1つで、日別や月別などでAWSの利用料を予算として定義する事ができ、それによって可視化が可能となり、また、設定した予算に対して閾値を設定することができ、それを超えるとアラート通知を行うことができる。(と言った感じの理解。詳細はドキュメントを参照のこと)

docs.aws.amazon.com

設定

Slack と AWS Chatbot の連携

Chatbot で Slacke WorkSpace の連携をしていない場合は、マネジメントコンソールで AWS Chatbot の画面から Slack WorkSpace の連携を行う。

マネジメントコンソールで AWS Chatbot の画面から、画面右の「チャットクライアントを設定」で 「Slack」 を選択して、「クライアントを設定」ボタンをクリックする。

認証画面が出てくるので、連携したいワークスペースにログインし、連携する。

AWS Budgets、Amazon SNSAWS Chatbot の設定

手動での設定手順は探せば出てくるので、とりあえず CloudFormation テンプレートを作った。 Slack のワークスペースIDとチャンネルIDは、Slackの画面等から確認してセットする必要がある。

下記は毎日の利用料を $10 として、それに対して実際の利用料が 120% を超えるとアラート通知する、というような設定になっている。

AWSTemplateFormatVersion: 2010-09-09
Description: >
    Template AWS Budgets, Amazon SNS, AWS Chatbot

Resources:
  # ----------------------------------------------------------------
  # SNS Topic and Topic Policy
  # ----------------------------------------------------------------
  SNSTopicForAWSChatbot:
    Type: AWS::SNS::Topic
    Properties: 
      TopicName: !Sub ${AWS::StackName}-sns-topic

  SNSTopicPolicyForEventBridgeToSNSTopicForAWSChatbot:
    Type: AWS::SNS::TopicPolicy
    DependsOn: SNSTopicForAWSChatbot
    Properties: 
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Sid: SNSTopicPolicyForEventBridgeToSNSTopicForAWSChatbot
            Effect: Allow
            Principal:
              Service: events.amazonaws.com
            Action:
              - SNS:Publish
            Resource: !Ref SNSTopicForAWSChatbot
      Topics: 
        - !Ref SNSTopicForAWSChatbot

  # ----------------------------------------------------------------
  # IAM Role For AWS Chatbot
  # ----------------------------------------------------------------
  IAMRoleForAWSChatbot:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub ${AWS::StackName}-chatbot-iam-role
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: chatbot.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: !Sub ${AWS::StackName}-chatbot-iam-policy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - cloudwatch:Describe*
                  - cloudwatch:Get*
                  - cloudwatch:List*
                Resource:
                  - "*"

  # ----------------------------------------------------------------
  # Chatbot Slack Channel
  # ----------------------------------------------------------------
  ChatbotSlackChannelConfiguration:
    Type: AWS::Chatbot::SlackChannelConfiguration
    DependsOn:
      - IAMRoleForAWSChatbot
      - SNSTopicForAWSChatbot
    Properties: 
      ConfigurationName: !Sub ${AWS::StackName}-chatbot
      IamRoleArn: !GetAtt IAMRoleForAWSChatbot.Arn
      LoggingLevel: ERROR
      SlackChannelId: **********  # 連携したいチャンネルのID
      SlackWorkspaceId: ********   # Slack ワークスペースのID 
      SnsTopicArns: 
        - !Ref SNSTopicForAWSChatbot

  # ----------------------------------------------------------------
  # AWS Budgets
  # ----------------------------------------------------------------
  DailyBudgets:
    Type: AWS::Budgets::Budget
    DependsOn: SNSTopicForAWSChatbot
    Properties: 
      Budget:
        BudgetLimit: # 予算設定
          Amount: 10  # 毎日 $10 ドルを予算として設定
          Unit: USD
        BudgetType: COST
        BudgetName: !Sub ${AWS::StackName}-daily
        TimeUnit: DAILY
      NotificationsWithSubscribers:   # 通知設定
        - Notification:
            NotificationType: ACTUAL
            ComparisonOperator: GREATER_THAN
            Threshold: 120  # 予算として設定した値(ここでは $100 )の超過率が 120% を超えたら SNS へ通知(Chatbot から Slack へ通知)
            ThresholdType: PERCENTAGE
          Subscribers:
          - SubscriptionType: SNS
            Address:
              !Ref SNSTopicForAWSChatbot