広島吉川です。
[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'
]
},
"...(以下省略)..."
]