CloudWatch+Lambdaでawsの料金を毎朝9時に送信する

今回行ったこと

以前、boto3を使ってawsの料金を表示することができました。そして今回は、「Lambdaでメールを送信する」方法を使い、毎朝9時にawsの料金をメールで送られるようにしました。

実際の請求額と相違があり原因もまだわかっていないので、実際に利用する場合はこちらで試すほうが良いかもしれません。

Lambdaの設定

カスタムロールの作成

cloudwatch,Cloudwatch及びsnsの権限を追加するためにカスタムロールを作成します。

Lambda にある 「関数」、その後の「一から作成」から、以下のように設定してください。(名前は任意)

ロール名も任意に変えたあと、ポリシードキュメントを表示してください。デフォルトでは「CloudWatch logs」のみなので、今回使うものを追加するために以下をコピペしてください。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": "arn:aws:logs:*:*:*"
    },
     {
      "Effect": "Allow",
      "Action": "cloudwatch:*",
     "Resource": "*"
     },  
     {
      "Effect": "Allow",
      "Action": "sns:*",
     "Resource": "*"
    } 
  ]
}

許可を押した後、作ったロールと同じ名前が選択されていることを確認ししてください。その後、関数の作成を押すと以下の様になっているはずです。

スクリプトを書く

boto3を使ってawsの料金を表示する方法、boto3を使ってAmazon SNSでメールを送信する方法についてはリンク先にあるので説明は省きます。今回はロールの作成をしているのでアクセスキーやシークレットキーの設定は必要ありません。下記にあるコードを写してください。

import boto3
import datetime
import dateutil.tz
import re

def lambda_handler(event,context):
        region1 = "ap-northeast-1"
        region2 = "us-east-1"
        topic_arn = "********************"

        sns = boto3.resource(
                "sns",
                region_name=region1
                )

        cloud_watch = boto3.client(
                "cloudwatch",
                region_name=region2
                )

        get_metric_statistics_max = cloud_watch.get_metric_statistics(
                Namespace='AWS/Billing',
                MetricName='EstimatedCharges',
                Dimensions=[
                {
                        'Name': 'Currency',
                        'Value': 'USD'
                }
                ],
                StartTime=datetime.datetime.now() - datetime.timedelta(hours=36),
                EndTime=datetime.datetime.now() - datetime.timedelta(hours=9),
                Period=86400,
                Statistics=['Maximum']
        )

        get_metric_statistics_min = cloud_watch.get_metric_statistics(
                Namespace='AWS/Billing',
                MetricName='EstimatedCharges',
                Dimensions=[
                {
                        'Name': 'Currency',
                        'Value': 'USD'
                }
                ],
                StartTime=datetime.datetime.now() - datetime.timedelta(hours=33),
         EndTime=datetime.datetime.now() - datetime.timedelta(hours=9),
                Period=86400,
                Statistics=['Minimum']
        )

        max = re.findall('[0-9]{2}.[0-9]{1}',str(get_metric_statistics_max))
        min = re.findall('[0-9]{2}.[0-9]{1}',str(get_metric_statistics_min))
        answer = float(max[1]) -float(min[1])
        mail = sns.Topic(topic_arn).publish(
                Message=str(answer) + "$",
                Subject="fee"
        )

        return str(answer)

トリガーの設定

あとは先ほど作ったスクリプトを毎朝9時に実行できれば完成です。

CloudWatchからルール、その後にルールの作成を選択します。 その後、囲われている場所を設定してください。

これで完成です。cron式についてはAWSの公式から確認してください。 また、cron式で設定するタイムゾーンはUTCであるため、注意してください。