有識者からしたら、何言ってんだってタイトルになりそうだけど、多めに見てください…
※[追記] pprintをインポートしなくても標準出力でも行けそう・・・。
boto3 というモジュールを使うらしい
どうやってデータを引っ張るか調べると、boto3ってのを使うらしい
Boto3 documentation — Boto3 Docs 1.26.49 documentation (amazonaws.com)
ってことは、レイヤー使うのかもなー・・・。(。´・ω・)
でも、AWSサービスとして盛り込まれてるって線も・・・試してみようず!
lambdaでデフォで作成される関数に、boto3をインポートしてみた
※ブログじゃなくて、ドキュメント見てると、漁る時間がかかる
import json
import pprint
import boto3
def lambda_handler(event, context):
pprint.pprint(boto3.__version__)
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
実行してみたら、バージョンがちゃんと出てきた。

ってことは、レイヤー使わなくても大丈夫そうじゃん!!
コードでCloudwatchを利用しよう v0.1(本番はここから)
ドキュメントもちょろっと、サンプルコードあるし、インテリセンス使えはサクっといけそう!!
※この気持ちがダメ
cw = boto3.resource('cloudwatch')
cw. ### ん?出なくない?
ってことで素直に行こうぜ。(VSCodeで環境でコード作成してから実装しようと強く誓った)
この部分参照しながら、地味にやってみた
CloudWatch — Boto3 Docs 1.26.49 documentation (amazonaws.com)
それでも、[Namespace][MetricName][Dimensions:Name][Dimensions:Value]ってのは
何入れるか読み取れず不明だったのだが、たまたま別項目の設定をしてるときに、これじゃん?と。

ってことで書いてみたコード v0.1 で実行
import json
import boto3
import datetime
import pprint
def lambda_handler(event, context):
client = boto3.client('cloudwatch', region_name='us-east-1')
response = client.get_metric_statistics(
Namespace='AWS/Billing',
MetricName='EstimatedCharges',
Dimensions=[
{
'Name':'Currency',
'Value': 'USD'
},
],
Period=60,
# 日付は月末の課金が多かった時
StartTime = datetime.datetime(2022, 12, 29),
EndTime = datetime.datetime(2022, 12, 30),
Statistics=['Maximum']
)
pprint.pprint(response)
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
どん! エラーが発生!!

ちょっと細かすぎるのでエラー分だけ抽出したのが、これ↓
“An error occurred (AccessDenied) when calling the GetMetricStatistics operation: User: arn:aws:sts::<AWSID>:assumed-role/<role名>/<関数名> is not authorized to perform: cloudwatch:GetMetricStatistics because no identity-based policy allows the cloudwatch:GetMetricStatistics action”,
んー、、、権限ないらしい。なのでロールに権限を付与します。
ロールに権限を付与
lambda関数作成時に自動でIAMロール作成してもらったので、今回は勉強かねて
ポリシー作成 > ロールにアタッチをしました。
作成したポリシーのアクセス権限はこんな感じ。とりあえずエラー箇所だけ追加しようかね。

作成したポリシーをロールにアタッチして完成!!
※アタッチするHCは修正めんどくさかったので省きます。
再度実行+コード修正しよう v0.5
日付のところを、ちょっとだけ修正

実行したら・・・。

いやいや、情報多すぎるて( ;∀;) ww
これは、配列なんですかね?って try&err しまくってて、コード修正しました。
import json
import boto3
import datetime
import pprint
def lambda_handler(event, context):
client = boto3.client('cloudwatch', region_name='us-east-1')
response = client.get_metric_statistics(
Namespace='AWS/Billing',
MetricName='EstimatedCharges',
Dimensions=[
{
'Name':'Currency',
'Value': 'USD'
},
],
# Periodの理解が不安だけど、これが今一番ちょうどいい
Period=86400,
StartTime = datetime.datetime.now() - datetime.timedelta(days=1) ,
EndTime = datetime.datetime.now(),
Statistics=['Maximum']
)
pprint.pprint(response['Datapoints'][0]['Maximum'])
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
そしたら、こんな感じになったさ!!

出たけども、使ってないから面白みのない数字・・・
自分コード最終版 v1.0
最終的には実行したときに、数字が何を表してるか分からなくなるので、表示文字列を修正しました。
import json
import boto3
import datetime
import pprint
def lambda_handler(event, context):
client = boto3.client('cloudwatch', region_name='us-east-1')
response = client.get_metric_statistics(
Namespace='AWS/Billing',
MetricName='EstimatedCharges',
Dimensions=[
{
'Name':'Currency',
'Value': 'USD'
},
],
Period=86400,
StartTime = datetime.datetime.now() - datetime.timedelta(days=1) ,
EndTime = datetime.datetime.now(),
Statistics=['Maximum']
)
today = datetime.datetime.now()
str_today = (today.strftime('%Y/%m/%d'))
pprint.pprint(str_today + " AWS Billing : " + str(response['Datapoints'][0]['Maximum']))
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}

なんかそれっぽくなったじゃん! ※自己満足
料金部分はfloat型だったらしく、そのまま文字列結合したら怒られたので注意しようね
まとめ
公式ドキュメントが読みづらいのと、Pythonを知らんから、関係ないとこで引っかかってる感じ。
だけど、なんとなく分かると、使い道が広がるなこれも。
あとはプログラムの整理というか、メイン関数になんでも書きすぎなので修正したい。
おわり
コメント