CDK Custom Resourceでカスタム AWS 設定を実現する
公開日
2025年4月25日
更新日
2025年4月25日
12
分で読める
AWS
本記事では、CDK の Custom Resource 機能を使って、CDK がネイティブにサポートしていない AWS リソースや機能に対してカスタム設定を追加する方法を紹介します。
たとえば、CDK は既存の S3 バケットに対してイベント通知(Notification)を追加する機能を標準では持っていません。以下の例では、既存の S3 バケットに対して Custom Resource 経由で Notification を動的に設定し、指定したファイル拡張子でオブジェクトがアップロードされたときに自動的に Lambda を呼び出す仕組みを実装します。
1. S3 Notification を設定する Lambda の実装
まず、S3 バケットに Notification 設定を行う専用の Lambda 関数を用意します。この関数は、受け取った拡張子リスト(suffixList)を元に PutBucketNotificationConfigurationCommand を組み立て、S3 に送信します。
// lambda/s3-notification-setting/index.ts
import { LambdaFunctionConfiguration, PutBucketNotificationConfigurationCommand, S3Client } from '@aws-sdk/client-s3';
import { CdkCustomResourceEvent, Context } from 'aws-lambda';
const createUpdateCommand = (suffixList: string[]) => {
const configurations: LambdaFunctionConfiguration[] = suffixList.map((suffix) => ({
LambdaFunctionArn: process.env.INVOKE_FUNC_ARN!,
Events: ['s3:ObjectCreated:*'],
Filter: {
Key: {
FilterRules: [{ Name: 'suffix', Value: suffix }],
},
},
}));
return new PutBucketNotificationConfigurationCommand({
Bucket: process.env.TARGET_BUCKET_NAME!,
NotificationConfiguration: {
LambdaFunctionConfigurations: configurations,
},
});
};
export const handler = async (event: CdkCustomResourceEvent, context: Context) => {
const suffixList = event.ResourceProperties.suffixList as string[];
const bucketName = process.env.TARGET_BUCKET_NAME!;
const s3Client = new S3Client({});
// Delete 時用の空設定
let command = new PutBucketNotificationConfigurationCommand({
Bucket: bucketName,
NotificationConfiguration: {},
});
// Create / Update 時は実際の設定を作成
if (event.RequestType === 'Create' || event.RequestType === 'Update') {
command = createUpdateCommand(suffixList);
}
await s3Client.send(command);
return { PhysicalResourceId: `${bucketName}-notification` };
};
ポイント:
INVOKE_FUNC_ARNに、S3 イベント発行時に呼び出す Lambda の ARN を設定します。TARGET_BUCKET_NAMEに、設定対象の S3 バケット名を指定します。CreateおよびUpdateリクエストでは同じロジックを使い、Deleteでは空設定を送信して通知設定を削除します。
2. CDK スタックへの Custom Resource 統合
次に、CDK スタック内で次の 2 つの Lambda を定義します。
- S3 アップロードイベントを処理する
s3-notification-invoke - Notification 設定を行う
s3-notification-setting
そして、custom-resources.Provider を使って設定用 Lambda を Custom Resource のハンドラとして登録します。
import * as cdk from 'aws-cdk-lib';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import { Provider } from 'aws-cdk-lib/custom-resources';
import { Construct } from 'constructs';
export class S3NotificationSettingStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// 1. S3 アップロードイベントを処理する Lambda
const s3NotificationInvokeFunc = new lambda.Function(this, 's3-notification-invoke', {
runtime: lambda.Runtime.NODEJS_22_X,
code: lambda.Code.fromAsset('lambda/s3-notification-invoke'),
handler: 'index.handler',
functionName: 's3-notification-invoke',
});
// 2. Notification 設定を行う Lambda
const s3NotificationSettingFunc = new lambda.Function(this, 's3-notification-setting', {
runtime: lambda.Runtime.NODEJS_22_X,
code: lambda.Code.fromAsset('lambda/s3-notification-setting'),
handler: 'index.handler',
functionName: 's3-notification-setting',
environment: {
INVOKE_FUNC_ARN: s3NotificationInvokeFunc.functionArn,
TARGET_BUCKET_NAME: 'your-existing-bucket-name', // 対象バケット名に置き換えてください
},
});
// S3 から通知ハンドラ Lambda への呼び出し権限を付与
s3NotificationInvokeFunc.addPermission('AllowS3Invoke', {
action: 'lambda:InvokeFunction',
principal: new iam.ServicePrincipal('s3.amazonaws.com'),
sourceArn: `arn:aws:s3:::your-existing-bucket-name`, // 対象バケット ARN に置き換えてください
});
// 3. Custom Resource Provider の定義
const provider = new Provider(this, 'S3NotificationProvider', {
onEventHandler: s3NotificationSettingFunc,
});
// 4. Custom Resource の作成と suffixList の指定
new cdk.CustomResource(this, 'S3NotificationCustomResource', {
serviceToken: provider.serviceToken,
properties: {
suffixList: ['.jpg', '.pdf'], // 必要に応じて拡張子を追加・変更
},
});
}
}
手順概要:
- 通知処理用 Lambda (
s3-notification-invoke) をデプロイ - 設定用 Lambda (
s3-notification-setting) をデプロイ - S3 が通知処理 Lambda を呼び出せるように権限を付与
- Custom Resource を登録し、
deploy時に設定用 Lambda を呼び出して通知の作成/更新/削除を実行
3. まとめ
このパターンにより、CDK の Custom Resource 機能を活用して、CDK 単体では対応できない既存リソースへの追加設定や、ネイティブ SDK API 呼び出しをプログラマブルに実行できます。必要に応じて他の AWS リソースや機能にも応用し、CDK の適用範囲を拡張してください。