EC2の稼働台数をCloudWatchメトリクスに記録する

社内で検証用環境等を持っていると、いろんな人EC2を立てていて管理が難しかったりします。
気づいたら立っていて、いつの間にか削除されていたり。
請求書を見ても、その月の各EC2インスタンスタイプの稼働時間は見えますが、細かくいつ増えたのか、何台あったのかがわかりません。

ということで定期的にEC2インスタンス台数をチェックして記録させてみようと思い立ちました。
最初はDynamoDBに記録させようかなと思いましたが、折れ線グラフとかで遷移が見えたらわかりやすいなと思って、CloudWatchメトリクスに記録することにしました。

使用例

このページのLambdaとCloudWatchメトリクス、EventBridgeを使用することで以下のようなことが実現できます。
  • インスタンスタイプ別の台数カウント
  • 過去の台数記録チェック
  • 台数の遷移確認
Lambdaの定期実行にはEventBridgeの設定が必要となります。
※AWS EventBridgeの解説は、本ページでは省略いたします。
 作成方法は、こちらをご確認下さい。

構成図

本ページにて紹介するLambdaは、存在しているEC2インスタンスの台数をカウントして、CloudWatchメトリクスに記録します。
boto3関数は、EC2の「describe_instances」とCloudWatchの「put_metric_data」を使用します。

Lambdaソースコード

import boto3
import json

cw_client = boto3.client('cloudwatch')
ec2_client = boto3.client('ec2')
ec2_paginator = ec2_client.get_paginator('describe_instances')
def lambda_handler(event, context):
    type_count = {}
    sum_count = 0
    
    for page in ec2_paginator.paginate():
        for ec2_info in page["Reservations"]:
            instance_type = ec2_info["Instances"][0]["InstanceType"]
            instance_state = ec2_info["Instances"][0]["State"]["Code"]
            if instance_state != 48:
                sum_count += 1
                if instance_type in type_count:
                    type_count[instance_type] += 1
                else:
                    type_count[instance_type] = 1
    type_count["Sum"] = sum_count
                
    for type in type_count:
        cw_client.put_metric_data(
            Namespace='EC2Count',
            MetricData=[
                {
                    'MetricName': 'InstanceTypeCount',
                    'Dimensions': [
                        {
                            'Name': 'InstanceType',
                            'Value': type 
                        }
                    ],
                    'Value': type_count[type],
                    'Unit': 'Count'
                }
            ]
        )
    return 0                  

権限(IAMロール設定)

LambdaにアタッチするIAMロールに「ec2:DescribeInstances」、「cloudwatch:PutMetricData」の権限を付与してください。

解説

紹介したLambdaのフローは以下の通りです。
  1. EC2インスタンスの検索
  2. インスタンスタイプ別にカウント
  3. CloudWatchメトリクスに記録
boto3のdescribe_instances関数をPaginatorsで使用することで、アカウント内のEC2を全て検索します。
検索した結果からEC2インスタンスの情報を1台ずつ処理し、インスタンスタイプ毎にカウントします。

カウントが完了したら、その結果をput_metric_data関数でCloudWatchメトリクスに記録します。
記録先のCloudWatchメトリクスは、「EC2Count」のカスタム名前空間にインスタンスタイプ毎に数値を記録します。

使い方

紹介したLambdaを作成し、EventBridgeにて定期実行するように設定してください。
(5分間隔くらいがおすすめです。)

定期実行でEC2の台数が以下の画像のように記録されます。