AWSの料金を毎日Slackに通知する


クラウド破産が起きないようにAWSの料金を毎日通知するやつを作りたかったのですが忙しくて...
重い腰を上げてやっとです。LINEに通知してもでもいいのですが手軽なのでSlackで行きます。
Slackシリーズ結構やってきましたので他の記事も参考に

今回のアーキテクチャ

Lambdaを作成

今回動かすコードを貼り付けましょう


import datetime
import json
import urllib.request
import boto3
import os
import logging

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):

    url = "https://slack.com/api/chat.postMessage"

    headers = {
        "Content-type" : "application/json",
        "Authorization" : "Bearer "+ "< Token >"
    }

    response = boto3.client('cloudwatch', region_name='us-east-1')

    get_metric_statistics = response.get_metric_statistics(
        Namespace='AWS/Billing',
        MetricName='EstimatedCharges',
        Dimensions=[
            {
                'Name': 'Currency',
                'Value': 'USD'
            }
        ],
        StartTime=datetime.datetime.today() - datetime.timedelta(days=1),
        EndTime=datetime.datetime.today(),
        Period=86400,
        Statistics=['Maximum']
    )

    cost = get_metric_statistics['Datapoints'][0]['Maximum']
    date = get_metric_statistics['Datapoints'][0]['Timestamp'].strftime('%Y年%m月%d日')


    text = "%sまでのAWSの料金は、$%sです。" % (date, cost)

    payload = {
        "channel": "< 通知したいチャンネルID>",
        "text" : text
    }

    req = urllib.request.Request(url=url, headers=headers, data=json.dumps(payload).encode('utf-8'))

    with urllib.request.urlopen(req) as res:

        logger.info(res.read().decode("utf-8"))

LambdaにIAMロールをアタッチ

LambdaにCloudWatchの読み取り権限を付与します。IAMのページに遷移して先程作成したLambdaを選択します。

「ポリシーをアタッチします」をクリック

CloudWatchReadOnlyAccessを選択して「ポリシーのアタッチ」をクリックします。

Eventbridgeの設定

1日1回定期実行を行うにはEventbridgeをLambdaと連携して使います。

 cron(0 3 * * ? *)は毎日、日本時間の午前12時ということを表している。

 参考文献

・Rate または Cron を使用したスケジュール式