CloudFormation栈部署后S3上传事件无法触发Lambda函数:如何正确引用已有S3桶实现触发?
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
- You're trying to redefine an existing S3 bucket: Your
StagingBucketresource attempts to create a bucket that already exists, which will either fail deployment or create an unintended duplicate. - 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.
- Incorrect
SourceArnin 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
Eventsproperty 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
SourceArnuses 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:
- Go to your S3 bucket's Event notifications tab—you should see a trigger linked to your Lambda.
- Go to your Lambda's Configuration > Triggers tab—the S3 bucket trigger will be listed.
- Upload a file to
bucket1/folder1/folder2/and check Lambda's CloudWatch logs to confirm it's triggered.
内容的提问来源于stack exchange,提问作者pymat

