iku8blog

Webエンジニアのタダのメモ。

AWS Lambdaから「node.js+CloudWatch API」でBilling取得時の権限周りメモ

AWS LambdaからCloudwatchのAPIをキックしたかったが、権限周りでて手こずったのでそのへんのメモ。

CloudWatchのBillingを取得はリージョン設定が必要

Lambda関数でCloudWatchAPIをコールするとき、Billing情報がほしいのであればリージョンを変える必要がある

const AWS = require('aws-sdk');
const cw = new AWS.CloudWatch({region: 'us-east-1'}); // us-east-1にしなければならない

CloudWatchでBilling情報を見るとき管理画面に行けばわかるのだが、リージョンが東京だと見れない。 どうやらBillingはバージニア北部(us-east-01)である必要がある。バージニア北部にBillingメトリクスは貯まるとのこと

https://t.co/EDegw1OeSv?amp=1

適切なIAMロールをLambda関数にアタッチする

APIを使うので、勝手にIAMユーザ(プログラム)のアクセスキーとシークレットキーを使うものだと思いこんでいたが、Lambda関数に適切なIAMロールをアタッチするだけで、CloudWatchのAPIを叩くことができた。

適切なIAMロールを作成

以下ポリシーをアタッチしたロールを作成する。

f:id:iku8:20201025164710p:plain

  • CloudWatchReadOnlyAccess
  • AWSLambdaBasicExecutionRole

Lambda関数にロールをアタッチ

f:id:iku8:20201025164658p:plain

コストを取得するコード

const AWS = require('aws-sdk');
const moment = require('moment');
const cw = new AWS.CloudWatch({region: 'us-east-1'});

exports.handler = function(event, context) {
  // startとendは当日で良い。一月分の料金が取得されるため
  const start = moment().subtract(1, 'days').toISOString();
  const end = moment().toISOString();

  const params = {
    StartTime: start,
    EndTime: end,
    MetricName:'EstimatedCharges',
    Namespace:'AWS/Billing',
    Period:86400,
    Dimensions:[
      {
        Name:'Currency',
        Value:'USD'
      }
    ],
    Statistics:['Maximum']
  };

  const getMetricStatistics = () => {
    return new Promise(resolve => {
      cw.getMetricStatistics(params, (err, data) => {
        if (err){
          console.log(err, err.stack);
        }
        resolve(data);
      });
    })
  }

  getMetricStatistics().then(res => {
    let message = moment().format("YYYY年MM月DD日").toString() + "時点での料金: $" + res.Datapoints[0].Maximum
    console.log(message);
  });
}