CloudFormationテンプレートをクラウドシェルからワンライナーで実行し、AWS Budgetsを作成する

# 概要

特定アカウントで閾値を超える課金が発生した場合に通知を受けるBudget設定をCloudFormationで作成しました。

# 設計

クラウドシェルからシェルスクリプトを実行して、CloudFormationでBudgetsアラートを作成します。
最終的にYAMLテンプレートとシェルスクリプトを公開されたS3に置いて、curlでシェルスクリプトを取得して、アカウントごとにシェルスクリプトをアップロードしなくても、クラウドシェルから1行のコマンドで実行できるようにします。

## YAMLテンプレート

```YAML
AWSTemplateFormatVersion: "2010-09-09" 

Description: "Budget"

Parameters:
  Amount:
    Type: String
    Default: 0.5
    Description: Budgeted amount
  EmailAddress:
    Type: String
    Description: Notification email address
  Actual:
    Type: Number
    Default: 100
    MinValue: 1
    MaxValue: 100
    Description: "% of budgeted amount (Actual Costs)"

Resources:
  Budget:
    Type: AWS::Budgets::Budget
    Properties:
      Budget:
        BudgetLimit:
          Amount: !Ref Amount
          Unit: USD
        TimeUnit: MONTHLY
        BudgetType: COST
      NotificationsWithSubscribers:
        - Notification:
            NotificationType: ACTUAL
            ComparisonOperator: GREATER_THAN
            Threshold: !Ref Actual
          Subscribers:
          - SubscriptionType: EMAIL
            Address: !Ref EmailAddress
```

## パラメータ

### Amount
設定する金額。予算額をUSDで指定します。
※金額の単位は日本円で設定することはできません。1ドル未満 (0.5ドルなど) は設定可能です。
例）0.5

### EmailAddress
送信先のメールアドレス。アラートを通知するメールアドレスを指定します。
例）xxx@yyy.slack.com

### Actual
しきい値のパーセント。実際の使用料のアラートの割合を指定します。
※YAMLファイルの ComparisonOperator で <= は設定できません。許容値は EQUAL_TO、GREATER_THANまたはLESS_THAN の3パターンです。
例）100

## シェルスクリプト

S3にアップロードするYAMLテンプレートのURLをtemplate-urlに指定します。公開するバケットなので、名前の頭にpublicをつけています。YAMLテンプレートのパラメータの値はparametersでクラウドシェルのコマンドから受け取るようにします。

```create_budget.sh
aws cloudformation create-stack  \ 
    --stack-name "BudgetAlert-PayerAccount"  \
    --template-url https://public-xxx.s3.ap-northeast-1.amazonaws.com/sample-template.yml  \
    --parameters ParameterKey=Amount,ParameterValue=$1 ParameterKey=Actual,ParameterValue=$2 ParameterKey=EmailAddress,ParameterValue=$3

aws cloudformation wait stack-create-complete \
    --stack-name "BudgetAlert-PayerAccount"
```
 
## S3

S3バケットを作成して、公開設定をします。
[Amazon S3 バケットの一部のオブジェクトにパブリック読み取りアクセス権を付与するにはどうすればよいですか?](https://aws.amazon.com/jp/premiumsupport/knowledge-center/read-access-objects-s3-bucket/)
YAMLテンプレートとシェルスクリプトをS3にアップロードします。

## クラウドシェルで実行するコマンド

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599875/c5db4141-d0fc-d1c3-ae6d-249712fd8053.png)


YAMLテンプレートのパラメータに指定したい値を引数に渡します。

```sh
curl https://public-xxx.s3.ap-northeast-1.amazonaws.com/sample-script.sh > sample-script.sh && sh sample-script.sh <<設定する金額>> <<しきい値のパーセント>> <<送信先のメールアドレス>>
```

# 参考

## Slackにメールを送信する手順

チャンネルまたは DM 用メールアドレスを作成し、Slack にメールを送信できます。xxxxx@cloudpack.slack.comのメールアドレスが発行されます。
[チャンネルまたは DM 用メールアドレスを作成する](https://slack.com/intl/ja-jp/help/articles/206819278-Slack-%E3%81%AB%E3%83%A1%E3%83%BC%E3%83%AB%E3%82%92%E9%80%81%E4%BF%A1%E3%81%99%E3%82%8B#u12513u12540u12523u12450u12489u12524u12473u12434u20316u25104u12377u12427)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599875/3bc500bf-f721-328a-f2bb-7aa968fcbc82.png)

## AWS CLI Command Reference

[create-stack](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/create-stack.html)
[stack-create-complete](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/wait/stack-create-complete.html)