AWS CDK 通过 EventBridge 接收对象创建事件并触发 Lambda

问题描述 投票:0回答:2

每当新对象上传到特定存储桶时,我尝试使用 EventBridge 触发 Lambda 函数。我的 CDK 代码是:

import { StackProps } from "aws-cdk-lib";
import * as s3 from "aws-cdk-lib/aws-s3";
import * as iam from "aws-cdk-lib/aws-iam";
import * as lambda from "aws-cdk-lib/aws-lambda";
import * as events from "aws-cdk-lib/aws-events";
import * as targets from "aws-cdk-lib/aws-events-targets";
import * as lambdaEventSources from "aws-cdk-lib/aws-lambda-event-sources";

import { Construct } from "constructs";

export interface TServiceStackProps {
  bucketName: string;
}

export class TranscriptionServiceStack extends Construct {
  // Allow access to the counter function
  public readonly inputBucket: s3.Bucket;
  public readonly outputBucket: s3.Bucket;

  constructor(scope: Construct, id: string, props: TServiceStackProps) {
    super(scope, id);
    /**
     * Create input bucket where videos TO BE transcribed get uploaded.
     */
    this.inputBucket = new s3.Bucket(this, "InputBucket", {
      bucketName: props.bucketName + "-inputs",
      eventBridgeEnabled: true,
    });
    /**
     * Create output bucket where transcribe results get stored.
     */
    this.outputBucket = new s3.Bucket(this, "OutputBucket", {
      bucketName: props.bucketName + "-outputs",
    });
    /**
     * Create iam statement for transcribe admin policy.
     */
    const adminTranscribePolicyStatement = new iam.PolicyStatement({
      effect: iam.Effect.ALLOW,
      actions: ["transcribe:*"],
      resources: ["*"],
    });
    /**
     * Handler function for QUEUING jobs, handling status updates, and saving results.
     */
    const transcribeHandler = new lambda.Function(this, "TranscribeHandler", {
      runtime: lambda.Runtime.NODEJS_14_X,
      code: lambda.Code.fromAsset("lambda/transcribe-service"),
      handler: "transcribe.handler",
      environment: {
        INPUT_BUCKET_NAME: this.inputBucket.bucketName,
        OUTPUT_BUCKET_NAME: this.outputBucket.bucketName,
      },
    });
    /**
     * Associate transcribe policy with lambda handler
     */
    transcribeHandler.role?.attachInlinePolicy(
      new iam.Policy(this, "TranscribeAdminPolicy", {
        statements: [adminTranscribePolicyStatement],
      })
    );
    /**
     * Rule for detecting a new object uploaded to input bucket.
     */
    new events.Rule(this, "InputBucketUploadRule", {
      description: "Watches for s3 object:put events.",
      eventPattern: {
        source: ["aws.s3"],
        detailType: events.Match.equalsIgnoreCase("object created"),
        detail: {
          bucket: {
            name: [this.inputBucket.bucketName],
          },
        },
      },
      targets: [new targets.LambdaFunction(transcribeHandler)],
    });
    /**
     * Rule for detecting status updates from Transcribe service.
     */
    new events.Rule(this, "TranscribeEventRule", {
      description: "Watches for Transcribe state events.",
      eventPattern: {
        source: ["aws.transcribe"],
        detailType: events.Match.equalsIgnoreCase(
          "Transcribe Job State Change"
        ),
        detail: {
          TranscriptionJobStatus: [
            "COMPLETED",
            "FAILED",
            "QUEUED",
            "IN_PROGRESS",
          ],
        },
      },
      targets: [new targets.LambdaFunction(transcribeHandler)],
    });
    /**
     * Handler gets to read and delete objects from inputBucket
     */
    this.inputBucket.grantReadWrite(transcribeHandler);
    this.inputBucket.grantDelete(transcribeHandler);
    /**
     * Handler gets to read objects from inputBucket
     */
    this.outputBucket.grantReadWrite(transcribeHandler);
  }
}

每当我将新对象上传到 inputBucket 时,CloudWatch(或特定的 EventBridge 资源)都不会触发或观察到任何事件。

知道我错过了什么吗?

typescript amazon-web-services amazon-s3 aws-cloudformation aws-cdk
2个回答
2
投票

深入研究文档后,我发现您需要创建一个 CloudTrail 资源来收集这些事件,然后将相关事件源添加到跟踪中。

    /**
     * Create a CloudTrail resource for capturing events.
     */
    const eventsTrail = new cloudtrail.Trail(this, "TranscriptionServiceTrail");
    /**
     * Add S3 selector for input bucket's object created events.
     */
    eventsTrail.addS3EventSelector(
      [
        {
          bucket: this.inputBucket,
        },
      ],
      {
        readWriteType: cloudtrail.ReadWriteType.WRITE_ONLY,
      }
    );

将以下内容添加到我的堆栈中,使 EventBridge 能够开始接收事件并触发我的 lambda。


0
投票

如果有人不想启用 CloudTrail,另一个选择是 s3 事件通知。目前支持 Lambda、SNS 和 SQS

示例

this.inputBucket.bucket.addEventNotification(
     s3.EventType.OBJECT_CREATED_PUT,
     new s3n.LambdaDestination(transcribeHandler )
    )

参考:https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3_notifications-readme.html

© www.soinside.com 2019 - 2024. All rights reserved.