You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CloudFormation栈部署后S3上传事件无法触发Lambda函数:如何正确引用已有S3桶实现触发?

Fixing S3-Lambda Trigger Association for Existing S3 Buckets in CloudFormation

Let's break down the issues with your current setup and fix them step by step to get your Lambda triggered when files are uploaded to your existing S3 bucket path.

Key Problems in Your Current Template

  1. You're trying to redefine an existing S3 bucket: Your StagingBucket resource attempts to create a bucket that already exists, which will either fail deployment or create an unintended duplicate.
  2. Missing S3 event notification configuration: You only set up Lambda permissions, but didn't tell S3 to send events to your Lambda function—this is why the console shows no association.
  3. Incorrect SourceArn in Lambda permission: You used the bucket path instead of the bucket's root ARN, which breaks the permission trust relationship.

Step-by-Step Fixes

1. Remove Unnecessary S3 Bucket Resource

Delete the StagingBucket and S3SourceBucket resource definition (you can keep S3SourceBucket as a parameter for reusability, but don't create a new bucket).

2. Configure S3 Event Trigger (via SAM)

Since you're using AWS::Serverless::Function (SAM), the easiest way to set up the trigger is using the Events property directly in your Lambda resource. This handles both the event notification and Lambda permissions automatically (though we'll still explicitly define the permission for clarity).

3. Fix Lambda Permissions and IAM Policies

Update the SourceArn to use your bucket's root ARN, and use dynamic references to avoid hardcoding bucket names.

Corrected Template

Parameters:
  LambdaModuleName:
    Type: String
    Default: MyTriggerFunction
  # Use this parameter to pass your existing bucket name, or replace with !ImportValue if it's exported from another stack
  S3SourceBucket:
    Type: String
    Default: bucket1

Resources:
  MyTrigger:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Ref LambdaModuleName
      CodeUri: src/my_module
      Handler: app.lambda_handler
      Runtime: python3.9
      MemorySize: 7500
      Timeout: 600
      ReservedConcurrentExecutions: 1
      Policies:
        - AWSLambdaExecute
        - AWSLambdaVPCAccessExecutionRole
        - Statement:
            - Sid: StagingS3DeleteCreate
              Effect: Allow
              Action:
                - s3:DeleteObject*
                - s3:PutObject*
              Resource: !Sub "arn:aws:s3:::${S3SourceBucket}/folder1/folder2/*"
            - Sid: StagingS3List
              Effect: Allow
              Action:
                - s3:List*
              Resource:
                - !Sub "arn:aws:s3:::${S3SourceBucket}"
                - !Sub "arn:aws:s3:::${S3SourceBucket}/*"
      # Add S3 trigger configuration here
      Events:
        S3UploadTrigger:
          Type: S3
          Properties:
            Bucket: !Ref S3SourceBucket
            # Trigger on all object creation events
            Events: s3:ObjectCreated:*
            # Filter to only trigger for files in your target path
            Filter:
              S3Key:
                Rules:
                  - Name: prefix
                    Value: folder1/folder2/

# Explicit Lambda permission for S3 (SAM generates this automatically, but defining it adds clarity)
AllowS3ToCallLambdaPermission:
  Type: AWS::Lambda::Permission
  Properties:
    Action: 'lambda:InvokeFunction'
    FunctionName: !Ref MyTrigger
    Principal: s3.amazonaws.com
    # Use the bucket's root ARN, not the path
    SourceArn: !Sub "arn:aws:s3:::${S3SourceBucket}"
    # Optional: Restrict to your AWS account for added security
    SourceAccount: !Ref AWS::AccountId

Using !ImportValue for Cross-Stack Bucket References

If your existing bucket is created in another CloudFormation stack and exported, replace the S3SourceBucket parameter with:

# In your Lambda's Events property
Bucket: !ImportValue ExistingBucketNameExport

# In the Lambda permission's SourceArn
SourceArn: !Sub
  - "arn:aws:s3:::${BucketName}"
  - BucketName: !ImportValue ExistingBucketNameExport

(Make sure the source stack exports the bucket name with Export: { Name: ExistingBucketNameExport })

Why This Works

  • No duplicate bucket: We're referencing your existing bucket directly instead of trying to create a new one.
  • S3 event notification: The Events property tells S3 to send object creation events from the specified path to your Lambda—this is what makes the association visible in the AWS console.
  • Correct permissions: The SourceArn uses the bucket's root ARN (required for S3 to invoke Lambda), and the IAM policies are scoped to your target path.

Verification Steps

After deploying the updated stack:

  1. Go to your S3 bucket's Event notifications tab—you should see a trigger linked to your Lambda.
  2. Go to your Lambda's Configuration > Triggers tab—the S3 bucket trigger will be listed.
  3. Upload a file to bucket1/folder1/folder2/ and check Lambda's CloudWatch logs to confirm it's triggered.

内容的提问来源于stack exchange,提问作者pymat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 23:19:06