EventBridgeとLambdaを使用して、CloudWatchカスタムメトリクスを定期的に配信する

EventBridgeとLambdaを使用して、CloudWatchカスタムメトリクスを定期的に配信する

EventBridgeとLambdaを使用して、CloudWatchカスタムメトリクスを定期的に配信する

CloudWatchにカスタムメトリクスをプッシュする方法は、以下の2通りあります。

統合 CloudWatch エージェントまたは API を使用して、カスタムメトリクスを CloudWatch にプッシュできます。

CloudWatchにカスタムメトリクスをプッシュするにはどうすればよいですか?

本ページでは、Lambda関数からAPIを使用します。
そしてEventBridgeを使用することで、CloudWatchカスタムメトリクスを定期的に配信する方法をご紹介します。

構築する環境

Diagram of using EventBridge and Lambda to deliver CloudWatch Custom Metrics on a regular basis.

Lambda関数を作成します。
この関数の働きは、CloudWatchカスタムメトリクスとして、0から9の数字をランダムにプッシュすることです。

EventBridgeルールで、この関数を定期的に実行します。
実行間隔は1分間とします。

CloudFormationテンプレートファイル

上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。

https://github.com/awstut-an-r/awstut-fa/tree/main/123

テンプレートファイルのポイント解説

Lambda関数

Resources:
  Function:
    Type: AWS::Lambda::Function
    Properties:
      Architectures:
        - !Ref Architecture
      Environment:
        Variables:
          DIMENSION_NAME: !Ref CloudWatchMetricDimensionName
          DIMENSION_VALUE: !Ref CloudWatchMetricDimensionValue
          METRIC_NAME: !Ref CloudWatchMetricName
          NAMESPACE: !Ref CloudWatchMetricNamespace
      Code:
        ZipFile: |
          import boto3
          import datetime
          import os
          import random

          dimension_name = os.environ['DIMENSION_NAME']
          dimension_value = os.environ['DIMENSION_VALUE']
          metric_name = os.environ['METRIC_NAME']
          namespace = os.environ['NAMESPACE']

          client = boto3.client('cloudwatch')

          def lambda_handler(event, context):
            response = client.put_metric_data(
              Namespace=namespace,
              MetricData=[
                {
                  'MetricName': metric_name,
                  'Dimensions': [
                    {
                      'Name': dimension_name,
                      'Value': dimension_value
                    }
                  ],
                  'Timestamp': datetime.datetime.now(),
                  'Value': random.randint(0, 9),
                  'Unit': 'Count',
                  'StorageResolution': 60
                }
              ]
            )
            print(response)
      FunctionName: !Sub "${Prefix}-function"
      Handler: !Ref Handler
      Runtime: !Ref Runtime
      Role: !GetAtt FunctionRole.Arn
Code language: YAML (yaml)

Lambda関数で実行するコードをインライン形式で記載します。
詳細につきましては、以下のページをご確認ください。

https://awstut.com/2022/02/02/3-patterns-for-creating-lambda-with-cloudformation

コードの内容ですが、boto3でCloudWatch用のクライアントオブジェクトを作成後、put_metric_dataメソッドを実行して、カスタムメトリクスを配信するものとなっています。

以下がカスタムメトリクスを配信する上でポイントとなる情報です。

  • 名前空間:test
  • メトリック名:randomnum
  • ディメンション名:lambda
  • ディメンションの値:fa-123
  • 配信する値:0から9でランダムの値

以下は本関数用のIAMロールです。

Resources:
  FunctionRole:
    Type: AWS::IAM::Role
    DeletionPolicy: Delete
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action: sts:AssumeRole
            Principal:
              Service:
                - lambda.amazonaws.com
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      Policies:
        - PolicyName: CreateThumbnailPolicy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - cloudwatch:PutMetricData
                Resource: "*"
Code language: YAML (yaml)

CloudWatchにカスタムメトリクスを配信するための権限を与えます。

EventBridgeルール

Resources:
  Rule:
    Type: AWS::Events::Rule
    Properties:
      Name: !Sub "${Prefix}-EventsRule"
      ScheduleExpression: rate(1 minute)
      State: ENABLED
      Targets:
        - Arn: !Ref FunctionArn
          Id: !Ref Function
Code language: YAML (yaml)

1分ごとに先述のLambda関数を実行するルールです。

EventBridgeルールを使用してLambda関数を定期的に実行する場合、EventBridgeがLambda関数を呼び出すという挙動になります。
そのためEventBridgeに関数を呼び出す権限を与える必要があります。

Resources:
  EventsRulePermission:
    Type: AWS::Lambda::Permission
    Properties:
      FunctionName: !Ref Function
      Action: lambda:InvokeFunction
      Principal: events.amazonaws.com
      SourceArn: !GetAtt Rule.Arn
Code language: YAML (yaml)

以下のAWS公式ページを参考に設定しました。

https://docs.aws.amazon.com/ja_jp/eventbridge/latest/userguide/eb-use-resource-based.html#eb-lambda-permissions

環境構築

CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。

CloudFormationスタックを作成し、スタック内のリソースを確認する

CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。

https://awstut.com/2021/12/02/cloudformation-nested-stacks

各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。

  • Lambda関数:fa-123-function
  • EventBridgeルール:fa-123-EventRule

AWSマネージメントコンソールから各種リソースを確認します。

Lambda関数を確認します。

Detail of Lambda 1.

正常に関数が作成されています。

EventBridgeルールを確認します。

Detail of EventBridge 1.
Detail of EventBridge 2.

こちらも正常に作成されています。
1分ごとにLambda関数が実行される内容です。

動作確認

準備が整いました。

まずLambda関数の実行ログを確認します。

Detail of Lambda 2.

EventBridgeルールによって、自動的にLambda関数が実行されました。
既に3回実行されていることがわかります。

続いてCloudWatchメトリクスを確認します。

Detail of CloudWatch 1.

確かにカスタムメトリクスとして、Lambda関数によって生成された数値が配信されていることがわかります。

このようにLambda関数とEventBridgeを使用することで、CloudWatchカスタムメトリクスを定期的に配信することができます。

まとめ

Lambda関数とEventBridgeを使用することで、CloudWatchカスタムメトリクスを定期的に配信する方法をご紹介しました。