[AWS CDK] S3 バケットの autoDeleteObjects を有効化すると作成される Lambda 関数の実行ログ保持期間をエスケープハッチを使用して設定してみた
はじめに
CDK の S3 Bucket class には、バケット削除時にオブジェクトを削除してくれる autoDeleteObjects というオプションがあります。
仕組みとしては、このオプションの有効化によりタグ( aws-cdk:auto-delete-objects )の値が true になったバケットに対し、専用に作成される Lambda 関数を使用してオブジェクトを削除する、というものです。
autoDeleteObjects を有効化してデプロイすると、CDK は Custom Resource を使用して前述のオブジェクト削除用の Lambda 関数を自動的に作成します。
しかしながら S3 Bucket class には当該 Lambda 関数の実行ログの保存先であるロググループのログ保持期間を指定するオプションがなく、このままではログ保持期間を CDK で管理できません。
この問題に対して CDK の エスケープハッチを使用して Lambda 関数名を特定することでログ保持期間を変更する方法がありましたので、紹介いたします。
エスケープハッチとは
まず、エスケープハッチについて簡単に説明します。
抽象化度の高い L2 などのコンストラクトではプロパティの値がデフォルト値として設定されており変更できない場合があります。
この場合に、L2 コンストラクトが内包している L1 コンストラクトにアクセスするための手段がエスケープハッチです。
L1 コンストラクトは抽象度が一番低く、 CloudFormation テンプレートのリソースセクションと1対1で対応しているためプロパティを細かく設定できます。
AWS の公式ドキュメントの説明は以下のリンクからご覧になれます。
エスケープハッチを用いてどのように対処するか
今回は、CDK によって作成される Custom Resource の論理 ID から自動作成される Lambda 関数の名前を参照します。
ログループ名には Lambda 関数の名前が含まれていますので、これでロググループ名が特定できます。
ロググループ名と LogGroup class を使用してロググループを CDK 管理下に置きつつ、ログ保持期間を設定します。
エスケープハッチを使用したコード例
以下が実際のコード例です。
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { aws_s3,aws_logs,aws_lambda} from "aws-cdk-lib";
import { CustomResourceConfig } from 'aws-cdk-lib/custom-resources';
export class CustomResourceStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
CustomResourceConfig.of(this).addLogRetentionLifetime(aws_logs.RetentionDays.TWO_WEEKS);
const accountId = cdk.Stack.of(this).account;
const region = cdk.Stack.of(this).region;
const bucket = new aws_s3.Bucket(this, 'TestBucket', {
bucketName: `test-auto-delete-objects-bucket-${accountId}-${region}`,
versioned: true,
removalPolicy: cdk.RemovalPolicy.DESTROY,
autoDeleteObjects: true, // autoDeleteObjects を有効化
});
const customResourceProvider = this.node.findChild('Custom::S3AutoDeleteObjectsCustomResourceProvider');
const lambdaFunction = customResourceProvider.node.findChild('Handler') as aws_lambda.CfnFunction;
const logGroup = new aws_logs.LogGroup(this, 'logGroup', {
logGroupName: `/aws/lambda/${lambdaFunction.ref}`,
removalPolicy: cdk.RemovalPolicy.DESTROY,
retention: aws_logs.RetentionDays.ONE_WEEK,
});
}
}
コードの説明
autoDeleteObjects の有効化
Bucket クラスの autoDeleteObjects オプションの値を true に設定することで、オブジェクトの自動削除が有効になります[1]。
autoDeleteObjects: true,
Custom Resource で作成される Lambda 関数の参照
node.findChild メソッドを使用して、Custom Resource で作成される Lambda 関数を参照します。
まずは、論理 ID を使用して Custom Resource のリソース全体を参照します。
const customResourceProvider = this.node.findChild('Custom::S3AutoDeleteObjectsCustomResourceProvider');
Custom Resource で作成されるリソースの論理 ID は Custom::S3AutoDeleteObjectsCustomResourceProvider です。これはスタックのリソースタブから確認できます。
次に、Custom Resource のリソースに含まれる Lambda 関数を参照します。
const lambdaFunction = customResourceProvider.node.findChild('Handler') as aws_lambda.CfnFunction;
LogGroup の作成
LogGroup クラスを使用して、Lambda 関数のロググループを作成します。
その際に前述のとおり参照した Lambda 関数(lambdaFunction)に対して ref メソッドを使用して、Lambda 関数の名前を参照し、ロググループの設定を記述します。
その際に、retention プロパティを使用してログ保持期間を設定できます。
const logGroup = new aws_logs.LogGroup(this, 'logGroup', {
logGroupName: `/aws/lambda/${lambdaFunction.ref}`,
removalPolicy: cdk.RemovalPolicy.DESTROY,
retention: aws_logs.RetentionDays.ONE_WEEK, // ログ保持期間を1週間に設定
});
デプロイして確認
デプロイを行い、S3 バケットを作成します。
cdk deploy
デプロイ後、AWS マネジメントコンソールの CloudWatch Logs のロググループを確認します。
無事にログの保持期間が CDK に記述した通りに1週間に設定されていることを確認できます。
おわりに
今回は、CDK の S3 バケットの autoDeleteObjects オプションを有効化した際に自動的に作成される Lambda 関数のロググループのログ保持期間を変更するために、エスケープハッチを使用してみました。
このオプション以外にも、Lambda 関数を自動作成するものには流用できそうですので、参考にしていただければと思います。
参考リンク
[1] [AWS CDK] S3 Bucket class には、バケット削除時にオブジェクト自動削除もしてくれるオプション autoDeleteObjects がある! | DevelopersIO
以上。