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.テンプレートをデプロイしてスタック作成(ロググループが含まれている)
2.Lambda関数を手動でテスト実行
↓
3.CFn管理下のロググループにログが保存されていたことが確認できました。
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関数名>
とはならず、
<スタック名>-<ロググループ名>-<ランダムな英数字>
となります。
②ロググループを作成し、ロググループ名に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関数名>
になります。