AWS Budgetsの予算超過アラートを構築ハンズオン

## はじめに
昨年は部内で利用できるAWS検証環境を超過してしまったので、月々の予算に敏感になるためにも、今まで利用しなかったAWS Budgetsを利用していこうと思い立ち構築を考えました。
まずは後続の処理はSNSで通知するだけの、スモールステップで構築します。

------------

## 構成図
![](https://cloud5.jp/wp-content/uploads/2023/01/スクリーンショット-2023-01-29-7.29.05.png)


------------

## ハンズオン
### 構築のながれ
#### 1.SNS作成：予算超過通知が送られる先の構築
#### 2.AWS Budgets作成：予算・予算に対するアラートを構築

-----------

### 1.SNS作成：予算超過通知が送られる先の構築
##### 1.1 SNSを構築する
署名付きURLを通知する、SNSトピックを構築します。
`TopicPolicy`部分は、検証のため制限していません。

```yaml
AWSTemplateFormatVersion: "2010-09-09"
Description: SNS Create

# ------------------------------------------------------------#
#  Metadata
# ------------------------------------------------------------#
Metadata:
  "AWS::CloudFormation::Interface":
    ParameterGroups:
      - Label:
          default: "SNS Configuration"
        Parameters:
        - TopicName
        - Endpoint
        - TagsValueUserName

    ParameterLabels:
      TopicName:
        default: "TopicName"
      Endpoint:
        default: "MailAddress"
      Endpoint:
        default: "UserName"

# ------------------------------------------------------------#
#  InputParameters
# ------------------------------------------------------------#
Parameters:
  TopicName:
    Type: String
    Default: "【各自TopicName】"
  Endpoint:
    Type: String
    Default: "【各自メールアドレス】"
  TagsValueUserName:
    Type: String
    Default: "【各自タグ名】"

# ------------------------------------------------------------#
#  Resources
# ------------------------------------------------------------#
Resources:
  SNSTopic:
    Type: AWS::SNS::Topic
    Properties:
      TopicName: !Ref TopicName
      Subscription:
        - Endpoint: !Ref Endpoint
          Protocol: email
      Tags:
        - Key: "User"
          Value: !Ref TagsValueUserName    

  TopicPolicy:
    Type: AWS::SNS::TopicPolicy
    Properties:
      Topics:
        - !Ref SNSTopic
      PolicyDocument:
        Id: !Ref SNSTopic
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              AWS: "*"
            Action: SNS:Publish
            Resource: !Ref SNSTopic

# ------------------------------------------------------------#
# Output Parameters
# ------------------------------------------------------------#                
Outputs:
  SNSArn:
    Value: !Ref SNSTopic
    Export:
      Name: !Sub "${TopicName}-arn"
  SNSTopicName:
    Value: !Ref TopicName
    Export:
      Name: !Ref TopicName
```

#### 1.2 上記設定後に、SNSから送られてきたメールのサブスクリプションを押下する
①送られてきたメールの赤枠部分をクリックする
![](https://cloud5.jp/wp-content/uploads/2022/11/スクリーンショット-2022-11-26-14.13.42-640x157.png)

②画面が遷移して下記画面が表示されると、サブスクリプションが開始される
![](https://cloud5.jp/wp-content/uploads/2022/11/スクリーンショット-2022-11-26-14.15.17.png)
※上記青枠部分をクリックすると、サブスクリプションが解除される

<br>

### 2.AWS Budgets作成：予算・予算に対するアラートを構築
・`Ammount`に全体の予算金額を入力
・`ThrshouldHigh`は 予算を100%を超過した場合、メール通知をする
・`ThrshouldMid`は 予算を80%を超過した場合、メール通知をする
・`ThrshouldMid`は 予算を50%を超過した場合、メール通知をする

```yaml
AWSTemplateFormatVersion: '2010-09-09'
Description:
  Create Budgets
# ------------------------------------------------------------#
#  Metadata
# ------------------------------------------------------------#
Metadata:
  "AWS::CloudFormation::Interface":
    ParameterGroups:
      - Label:
          default: "AWS Budget Configuration"
        Parameters:
          - BudgetName
          - Ammount
          - ThreshouldHigh
          - ThreshouldMid
          - ThreshouldLow

# ------------------------------------------------------------#
#  InputParameters
# ------------------------------------------------------------#
Parameters:
  BudgetName:
    Type: String
    Default: 【各自設定したい予算書の名前】
    Description: Budget Name
  Ammount:
    Type: String
    Default: 【各自設定したい予算金額】
    Description: Budget Limit Amount
  ThreshouldHigh:
    Type: Number
    Default: 100
    MinValue: 50
    MaxValue: 100
    Description: 50-100 % of budgeted AmountHigh
  ThreshouldMid:
    Type: Number
    Default: 80
    MinValue: 50
    MaxValue: 100
    Description: 50-100 % of budgeted AmountMiddle
  ThreshouldLow:
    Type: Number
    Default: 50
    MinValue: 5
    MaxValue: 100
    Description: 50-100 % of budgeted AmountLow

# ------------------------------------------------------------#
#  Resources
# ------------------------------------------------------------#
Resources:
# ------------------------------------------------------------#
#  BudgetAlarts
# ------------------------------------------------------------#    
  BudgetAlarts:
    Type: "AWS::Budgets::Budget"
    Properties:
      Budget:
        BudgetName: !Ref BudgetName
        BudgetLimit:
          Amount: !Ref Ammount
          Unit: USD
        TimeUnit: MONTHLY
        BudgetType: COST
      NotificationsWithSubscribers:
        - Notification:
            NotificationType: ACTUAL
            ComparisonOperator: GREATER_THAN
            Threshold: !Ref ThreshouldHigh
          Subscribers:
            - SubscriptionType: SNS
              Address: !ImportValue cfn-sns-topic-inamura-arn
        - Notification:
            NotificationType: ACTUAL
            ComparisonOperator: GREATER_THAN
            Threshold: !Ref ThreshouldMid
          Subscribers:
          - SubscriptionType: SNS
            Address: !ImportValue cfn-sns-topic-inamura-arn
        - Notification:
            NotificationType: ACTUAL
            ComparisonOperator: GREATER_THAN
            Threshold: !Ref ThreshouldLow
          Subscribers:
          - SubscriptionType: SNS
            Address: !ImportValue cfn-sns-topic-inamura-arn
```
<br />

### 挙動の確認
#### 予算に対して50,80,100%を超過すると、SNSが通知される
設定した時点で50,80,100％を超過していた場合それぞれメール通知が届く(※100%の場合ならば、50%のメール、80％のメール、100％のメールと3通受信)
![](https://cloud5.jp/wp-content/uploads/2023/01/スクリーンショット-2023-01-29-6.53.09-640x101.png)

<br />

------------

## さいごに
さくっと構築できましたが、これでは`SNS`で登録している自分にしか通知がこないので、`Lambda`を挟み込んで部署内で利用しているチャットツールに連絡をするなど運用的には考えなければいけなさそうです。