3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Lambda実行ログ用のCloudWatch LogsをCloudFormation / CDKで管理する

Last updated at Posted at 2024-11-18

Lambda用のCloudWatch LogsをIaC管理下に置きたい

CloudFormation(以下CFn)やCDKでログ書き込み権限のあるLambdaを作成すると、
Lambda実行時にログが自動でCloudWatch Logsに書き込まれます。
しかしこの時作成されたロググループはIaC管理外となるため、

  • ロググループの保持期間やDeletionPolicy等の設定ができない
  • スタック削除してもロググループが残ってしまう

といったもどかしさがあります。
当記事ではCFn, CDKそれぞれでLambda実行ログ用のCloudWatch Logsをコード管理する方法をご紹介します。

CFnでのCloudWatch Logs管理方法

CFnでLambda用のCloudWatch Logsを管理する場合は、以下のテンプレートのように
ロググループ名にLambda関数名を含めるようにして作成します。

AWSTemplateFormatVersion: "2010-09-09"

Resources:
  LambdaRole:
    # Lambdaの実行に必要なIAMロール
    Type: AWS::IAM::Role
    Properties:
      RoleName: lambda-role
      AssumeRolePolicyDocument:
        Statement:
          - Action:
              - sts:AssumeRole
            Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
        Version: "2012-10-17"
      ManagedPolicyArns:
        # CloudWatch Logsへのログ書き込み権限があるIAMポリシー
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      Path: /

  # Lambda関数
  LambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: lambda-function
      Description: LambdaFunction using python3.12.
      Runtime: python3.12
      Code:
        ZipFile: |
          import json

          def handler(event, context):
              return {
                  'statusCode': 200,
                  'body': json.dumps({
                      'message': 'hello world!'
                  })
              }
      Handler: index.handler
      MemorySize: 128
      Timeout: 10
      Role: !GetAtt LambdaRole.Arn

  ### ⭐️Lambda関数のCloudWatchロググループ ###
  LambdaFunctionLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      # ${LambdaFunction}では、上記で定義したLambda関数の"FunctionName"を参照しています
      LogGroupName: !Sub /aws/lambda/${LambdaFunction} 

一番下にCloudWatch Logsのロググループを定義しました。
Lambda関数を実行した時に作成されるロググループ名は、デフォルトだと
/aws/lambda/<Lambda関数名>となるため、
同じ名前になるように以下のようにロググループ名を定義しています。

LogGroupName: !Sub /aws/lambda/${LambdaFunction} 

これにより、Lambda用のロググループをCFnで管理できるようになります。
また、DeletionPolicyやログの保持期間を設定することも可能になります。

  # イメージ
  LambdaFunctionLogGroup:
    Type: AWS::Logs::LogGroup
    DeletionPolicy: Delete      # DeletionPolicyを設定
    UpdateReplacePolicy: Delete # UpdateReplacePolicyを設定
    Properties:
      LogGroupName: !Sub /aws/lambda/${LambdaFunction}
      RetentionInDays: 14       # ログの保持期間を指定

デモ

1.テンプレートをデプロイしてスタック作成(ロググループが含まれている)

スクリーンショット 2024-11-04 21.31.44.png

2.Lambda関数を手動でテスト実行

3.CFn管理下のロググループにログが保存されていたことが確認できました。

スクリーンショット 2024-11-04 21.00.44.png

CDKでのCloudWatch Logs管理方法(2パターン)

CDK実行環境

  • CDKのバージョン:2.158.0
  • 言語:TypeScript

CDKでLambda用のCloudWatch Logsを管理する方法は以下の2パターンあります。

①ロググループを作成し、FunctionのlogGroupプロパティで指定する

1つ目の方法:

以下のようにまずLogGroupコンストラクトを定義し、続いてFunctionコンストラクトのlogGroupプロパティに指定することで
Lambda関数とロググループを関連づけられます。

import { RemovalPolicy, Stack, type StackProps } from "aws-cdk-lib";
import {
	Code,
	Function,
	Runtime,
} from "aws-cdk-lib/aws-lambda";
import * as logs from "aws-cdk-lib/aws-logs";
import type { Construct } from "constructs";

export class CdkWorkshopStack extends Stack {
	constructor(scope: Construct, id: string, props?: StackProps) {
		super(scope, id, props);

		// ⭐️ まずLambda用のロググループを作成
		const helloLogGroup = new logs.LogGroup(this, "HelloLogGroup", {
			retention: logs.RetentionDays.ONE_WEEK, // ログの保持期間を指定(必要に応じて)
			removalPolicy: RemovalPolicy.DESTROY,   // RemovalPolicyを設定(必要に応じて)
		});

		// Lambda関数を作成
		new Function(this, "HelloHandler", {
			logGroup: helloLogGroup, // ⭐️ ここで、上記で作成したロググループを指定
			runtime: Runtime.NODEJS_20_X,
			code: Code.fromAsset("lambda"),
			handler: "hello.handler",
		});
	}
}

参考コード:AWS公式CDKワークショップ

なお、この方法で作成したロググループ名はデフォルトの
/aws/lambda/<Lambda関数名>とはならず、
<スタック名>-<ロググループ名>-<ランダムな英数字>となります。

スクリーンショット 2024-11-17 20.55.45.png

②ロググループを作成し、ロググループ名にLambda関数名を含める

2つ目の方法:

ロググループを作成し、以下のように
ロググループ名に作成したLambda関数名を含めることで
Lambda関数とロググループを関連づけられます。

import { RemovalPolicy, Stack, type StackProps } from "aws-cdk-lib";
import {
	Code,
	Function,
	Runtime,
} from "aws-cdk-lib/aws-lambda";
import * as logs from "aws-cdk-lib/aws-logs";
import type { Construct } from "constructs";

export class CdkWorkshopStack extends Stack {
	constructor(scope: Construct, id: string, props?: StackProps) {
		super(scope, id, props);

		// まずLambda関数を作成
		const helloHandler = new Function(this, "HelloHandler", {
			runtime: Runtime.NODEJS_20_X,
			code: Code.fromAsset("lambda"),
			handler: "hello.handler",
		});

		// ⭐️ Lambda用のロググループを作成
		new logs.LogGroup(this, "HelloLogGroup", {
			// ⭐️ ロググループ名を`/aws/lambda/<Lambda関数名>`にする
			logGroupName: `/aws/lambda/${helloHandler.functionName}`,
			retention: logs.RetentionDays.ONE_WEEK, // ログの保持期間を指定(必要に応じて)
			removalPolicy: RemovalPolicy.DESTROY,   // RemovalPolicyを設定(必要に応じて)
		});
	}
}

作成されたロググループは、
デフォルトの/aws/lambda/<Lambda関数名>になります。

スクリーンショット 2024-11-17 21.19.24.png

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?