AWS Budgets を Slack と LINE に通知してみた

2021.05.21

こんにちは、森田です。 AWSの勉強を始めて様々なサービスを利用していますが、利用するにあたってもちろん利用料が発生します!

現在の利用料が知らない間にとんでもないことにならないよう、AWS Budgetsを利用しデバイスに通知させます。

またデバイスへの通知は、Slack通知とLINEもよく利用するので、Lambdaを使用してLINEにも通知を行います。

やりたいこと

Slack、LINEへ通知を行います。 LINEでの通知は、ボタンテンプレートのメッセージを通知します。

下図のように構成し、デバイスへの通知を実現します。

やってみた

【Slackへの通知】AWS SNS トピック + AWS Chatbot  作成

こちらを参考に行いました。この通り進めていくことで、Slackの通知設定まで行えます!

終えると下記の画面のようにSlackのサブスクリプション1つのみが確認できます。

 

【準備】LINE Channel access tokenの取得

LINEで通知を行うにあたってaccess token必要です。

こちらでコンソールにログインし、BOTを作成します。

ログイン後、プロバイダーを作成します。

プロバイダー作成後、 Messaging APIでBOTを作成していきます。

BOTの設定がありますので、好きな画像や名前を設定して作成します。

作成後、 Messaging APIの下部にIssueボタンがありますので、access tokenを発行します。

後ほど作成する、lambda_function.pyで使用しますので、メモしておきましょう。

【LINEへの通知】Lambda 作成、SNSトリガーの追加

エディタは、VSCodeを使用していきます。

まず、Lambdaで動作させるためのプロジェクトを作成します。(今回はdemoという名前で作成しています)

続いてPythonにてボタンメッセージを送るlambda_function.pyを以下のように作成しました。 先ほど発行したaccess_tokenをXXXに入れます。

import json, requests

access_token = "XXX"

url = 'https://api.line.me/v2/bot/message/broadcast'
headers = {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer {}'.format(access_token)
}

message = {
  "type": "template",
  "altText": "This is a buttons template",
  "template": {
      "type": "buttons",
      "title": "Menu",
      "thumbnailImageUrl": "https://cdn-ssl-devio-img.classmethod.jp/wp-content/uploads/2019/04/aws-budgets-960x504.png",
      "imageAspectRatio": "rectangle",
      "imageSize": "cover",
      "imageBackgroundColor": "#FFFFFF",
      "text": "Please select",
      "actions": [
          {
            "type": "uri",
            "label": "View detail",
            "uri": "https://console.aws.amazon.com/billing/home#/budgets"
          }
      ]
  }
}



def lambda_handler(event, context):
    
    data = str(event['Records'][0]["Sns"]["Message"])
    text = [text.replace("[1]","") for text in data.split("\n") if ":" in text]
    message["altText"] = "AWS Budget"
    message["template"]["title"] = text[0]
    message["template"]["text"] = '\n'.join(text[4:-1])
    message["template"]["actions"][0]["uri"] = text[-1].replace(" ","")
    
    payload = { 'messages': [ message ] }
    
    r = requests.post(url, data=json.dumps(payload), headers=headers)
    print(r.text)
    # TODO implement
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!'),
        "get-data": str(event['Records'])
    }

また、requestsライブラリを使用するので、下記コマンドを作業ディレクトリで実行し、保存します。

pip install -t ./ requests

現在のディレクトリは以下のような構成となっています。

demo内のファイルを圧縮します。

zip -r demo.zip ./*

zipファイルが作成されましたら、Lambdaへアップロードしていきます。 Lambdaにて以下のようにデフォルトで作成します。 Lambdaが作成されますと、以下の画面になりますので、先ほど作成したzipファイルのアップロードを行います。

アップロード後は、以下のように圧縮したファイルが確認できます。

最後に、メッセージのテストとして下記のJSONを送信します。

{
	"Records": [
		{
			"EventSource": "aws:sns",
			"EventVersion": "1.0",
			"EventSubscriptionArn": "XXX",
			"Sns": {
				"Type": "Notification",
				"MessageId": "5a13e080-b90b-516a-ba62-b995433effce",
				"TopicArn": "XXX",
				"Subject": "AWS Budgets: line-demo has exceeded your alert threshold",
				"Message": "AWS Budget Notification May 12, 2021\nAWS Account XXXX\n\nDear AWS Customer,\n\nYou requested that we alert you when the ACTUAL Cost associated with your line-demo budget is greater than $0.24 for the current month. The ACTUAL Cost associated with this budget is $1.65. You can find additional details below and by accessing the AWS Budgets dashboard [1].\n\nBudget Name: line-demo\nBudget Type: Cost\nBudgeted Amount: $0.30\nAlert Type: ACTUAL\nAlert Threshold: > $0.24\nACTUAL Amount: $1.65\n\n[1] https://console.aws.amazon.com/billing/home#/budgets\n",
				"Timestamp": "2021-05-12T15:44:53.116Z",
				"SignatureVersion": "1",
				"Signature": "XXX",
				"SigningCertUrl": "XXX",
				"UnsubscribeUrl": "XXX",
				"MessageAttributes": {}
			}
		}
	]
}

テストの後、LINEへと通知が来れば問題ありません。

そして最後にLambdaのトリガーをSNSに設定します。

これでSNSからLambdaへ処理が流れるようになりました!

 

AWS Budgets 作成

最後に、Budgetsで予算のアラートを作成します。

今回は動作確認のため、すでに現在の利用料よりも少ない$1を設定しました。

 

しきい値を設定するを選択しますと、下記の画面になりますので、

しきい値SNSのARNを設定し、予算の確認作成を順に選択します。

 

すると、予算を超えていればすぐに通知が来ます。

 

最後に

個人的には、SNSのアクセスポリシーでつまづきました。

アクセスポリシーはこれから勉強していきます。