[Node.js] AWSアカウント内にデプロイされているS3イベントトリガーのLambda関数を列挙するスクリプト
広島吉川です。
[Node.js] AWSアカウント内にデプロイされているCloudWatch EventsトリガーのLambda関数を列挙するスクリプト | DevelopersIO
先日のこちらの記事の続編として、今回はS3イベントトリガーのLambda関数一覧を取得してみたいと思います。
環境
- node 16.13.0
- npm 8.1.4
- typescript 3.9.7
- aws-cdk 2.20.0
- aws-cdk-lib 2.20.0
- constructs 10.0.115
- @aws-sdk/* 3.67.0
- markdown-table 3.0.2
S3イベントトリガーのLambda関数を準備
import * as cdk from 'aws-cdk-lib' import { Construct } from 'constructs' export class AwsPlaygroundStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props) // Lambda関数 for (let i = 0; i < 30; i++) { new cdk.aws_lambda.Function(this, `sampleFn${i}`, { functionName: `sampleFn${i}`, runtime: cdk.aws_lambda.Runtime.NODEJS_14_X, code: cdk.aws_lambda.AssetCode.fromInline( `export const handler = () => console.log('Hello lambda.')` ), handler: 'handler', }) } // S3イベントトリガーのLambda関数 for (let i = 0; i < 10; i++) { const lambdaFn = new cdk.aws_lambda.Function(this, `sampleBatchFn${i}`, { functionName: `sampleBatchFn${i}`, runtime: cdk.aws_lambda.Runtime.NODEJS_14_X, code: cdk.aws_lambda.AssetCode.fromInline( `export const handler = () => console.log('Hello lambda.')` ), handler: 'handler', }) const s3Bucket = new cdk.aws_s3.Bucket(this, `s3Bucket${i}`, { removalPolicy: cdk.RemovalPolicy.DESTROY, }) lambdaFn.addEventSource( new cdk.aws_lambda_event_sources.S3EventSource(s3Bucket, { events: [cdk.aws_s3.EventType.OBJECT_CREATED], }) ) } } }
上のCDKコードで
- トリガーなしのLambda関数 30個
- S3イベントトリガーのLambda関数 10個
を準備しました。
AWS SDKでS3バケットに紐づくLambda関数を取得
S3クライアントの getBucketNotificationConfiguration()
を使うことでバケットに紐づくLambda関数を取得できるようです。
import { S3 } from '@aws-sdk/client-s3' const region = 'ap-northeast-3' // 大阪リージョン const s3 = new S3({ region }) ;(async () => { const output = await s3.getBucketNotificationConfiguration({ Bucket: 'S3_BUCKET_NAME', }) console.log(output.LambdaFunctionConfigurations) })()
出力は以下となります。
[ { Id: 'XXXXXXXXXXXXXXXXXXXX', LambdaFunctionArn: 'arn:aws:lambda:ap-northeast-3:AWS_ACCOUNT_ID:function:sampleBatchFn6', Events: [ 's3:ObjectCreated:*' ], Filter: undefined }
注意点として、S3クライアントを new
する際に渡す region
と取得対象のS3バケットのリージョンは一致させるようにしましょう。不一致の場合、下記のエラーが発生するようです。
PermanentRedirect: The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint.
S3イベントをトリガーとしているLambda関数一覧を取得
では、
- すべてのS3バケット一覧を取得
- 大阪リージョンにあるバケット一覧に絞り込む
- 各バケットに紐づくLambda関数を確認する
という方針でS3イベントトリガーのLambda関数ARN一覧を取得するコードを書いていきます。
import { S3 } from '@aws-sdk/client-s3' const region = 'ap-northeast-3' // 大阪リージョン const s3 = new S3({ region }) ;(async () => { const listBucketsOutput = await s3.listBuckets({}) // 全バケット名を取得 const bucketNames = listBucketsOutput.Buckets!.map((bucket) => bucket.Name!) // 大阪リージョンのバケットに絞り込む const filteredBucketNames = ( await Promise.all( bucketNames.map(async (bucketName) => { const getBucketLocationOutput = await s3.getBucketLocation({ Bucket: bucketName, }) if (getBucketLocationOutput.LocationConstraint !== region) { return undefined } return bucketName }) ) ).filter((bucketName) => bucketName != null) as string[] const result: { bucketName: string lambdaFnArns: string[] }[] = ( await Promise.all( filteredBucketNames!.map(async (bucketName) => { const getBucketNotificationConfigurationOutput = await s3.getBucketNotificationConfiguration({ Bucket: bucketName, }) return { bucketName, lambdaFnArns: getBucketNotificationConfigurationOutput.LambdaFunctionConfigurations?.map( (lambdaFunctionConfiguration) => lambdaFunctionConfiguration.LambdaFunctionArn! ) ?? [], } }) ) ).filter((item) => item.lambdaFnArns.length > 0) // 紐づくLambda関数が1つ以上あるバケットに絞り込む console.log(result) })()
出力は以下のようになります。
[ { bucketName: 'S3_BUCKET_NAME_0' lambdaFnArns: [ 'arn:aws:lambda:ap-northeast-3:AWS_ACCOUNT_ID:function:sampleBatchFn0' ] }, { bucketName: 'S3_BUCKET_NAME_1', lambdaFnArns: [ 'arn:aws:lambda:ap-northeast-3:AWS_ACCOUNT_ID:function:sampleBatchFn1' ] }, { bucketName: 'S3_BUCKET_NAME_2', lambdaFnArns: [ 'arn:aws:lambda:ap-northeast-3:AWS_ACCOUNT_ID:function:sampleBatchFn2' ] }, "...(以下省略)..." ]