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

Serverless配置现有S3桶触发Lambda部署报错排查

问题描述

需要配置Lambda函数,实现S3桶内产生对象创建事件时自动触发执行。

初始配置与首次报错

初始serverless.yml相关配置如下:

handleNewRawObjectInS3:
  handler: lambdas/handleNewRawObjectInS3/handleNewRawObjectInS3.handleS3Event
  events:
    - s3:
        bucket: ${file(../evn.${opt:stage, 'dev'}.json):RAW_IMAGE_BUCKET}
        event: s3:ObjectCreated:*

执行部署时返回错误:

Error:
CREATE_FAILED: S3Bucketxxxxxxxxxrawimages (AWS::S3::Bucket)
xxxxxxxxx-raw-images already exists in stack arn:aws:cloudformation:us-east-1:xxxx:stack/s3-xxxxxxxxx-raw-images/310e7010-xxx-xxx-xxxx-12f066874c93

报错原因:配置中指定的S3桶已经通过单独的CloudFormation模板提前创建完成,企业AWS环境限制不允许Serverless框架自动创建S3资源。新版本Serverless Framework支持通过S3事件配置中的existing: true参数关联已存在的S3桶,无需框架自动创建桶资源。

调整配置后二次报错

根据环境要求调整配置,添加existing: true参数,同时手动指定预先创建的部署桶、自定义IAM角色,完整serverless.yml配置如下:

service: my-service-events

provider:
  name: aws
  runtime: nodejs14.x
  region: ${file(../evn.${opt:stage, 'dev'}.json):REGION}
  stage: ${opt:stage, 'dev'}

  deploymentBucket: # 企业环境不允许自动创建桶,手动指定已创建的部署桶
    name: ${file(../evn.${opt:stage, 'dev'}.json):DEPLOYMENT_BUCKET}
  iam: # 企业环境不允许自动创建角色,手动指定自定义角色
    role: myServerlessRole
    deploymentRole:  ${file(../evn.${opt:stage, 'dev'}.json):DEPLOYMENT_ROLE}
resources:
  - ${file(../iam-roles.${opt:stage, 'dev'}.yml)}

functions:
  handleNewRawObjectInS3:
    handler: lambdas/handleNewRawObjectInS3/handleNewRawObjectInS3.handleS3Event
    events:
      - s3:
          bucket: ${file(../evn.${opt:stage, 'dev'}.json):RAW_IMAGE_BUCKET}
          event: s3:ObjectCreated:*
          existing: true

配置引用的自定义IAM角色文件内容如下:

Resources:
  myServerlessRole:
    Type: AWS::IAM::Role
    Properties:
      PermissionsBoundary: arn:aws:iam::xxx:policy/csr-Developer-Permissions-Boundary
      Path: /my/default/path/
      RoleName: myServerlessRole-${self:service}
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
      Policies:
        - PolicyName: myPolicyName
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource:
                  - 'Fn::Join':
                    - ':'
                    -
                      - 'arn:aws:logs'
                      - Ref: 'AWS::Region'
                      - Ref: 'AWS::AccountId'
                      - 'log-group:/aws/lambda/*:*:*'
    
              - Effect: "Allow"
                Action:
                  - "s3:*"
                Resource: "arn:aws:s3:::*"
              - Effect: "Allow"
                Action:
                  - "lambda:*"
                Resource: "*"               
              - Effect: "Allow"
                Action:
                  - cloudfront:CreateDistribution
                  - cloudfront:GetDistribution
                  - cloudfront:UpdateDistribution
                  - cloudfront:DeleteDistribution
                  - cloudfront:TagResource
                Resource: "arn:aws:cloudfront:::*"             

再次执行部署返回新错误:

Error:
CREATE_FAILED: CustomDashresourceDashexistingDashs3LambdaFunction (AWS::Lambda::Function)
Resource handler returned message: "The role defined for the function cannot be assumed by Lambda. (Service: Lambda, Status Code: 400, Request ID: 812c5384-1c26-42c9-bdef-1ce4a59f2be4)" (RequestToken: 9cdbb5af-3bc7-d6bf-384b-5126d1048ccd, HandlerErrorCode: InvalidRequest)

该错误指向Serverless框架自动生成的、用于管理现有S3资源触发器的自定义Lambda函数,无法承担配置中指定的IAM角色。

解决方案

报错根因是全局配置的IAM角色被默认分配给了所有Lambda(包括框架自动生成的自定义资源Lambda),但该角色要么存在信任策略限制、要么没有适配自定义资源Lambda的使用场景,按以下步骤调整即可完成部署:

  • 移除provider.iam.role的全局角色配置,改为在业务函数handleNewRawObjectInS3的配置块下单独添加role: myServerlessRole,仅给业务Lambda分配自定义业务角色,避免框架自动生成的自定义资源Lambda错误复用业务角色。
  • 提前创建专门给Serverless自定义资源使用的IAM角色:
    • 信任策略必须允许lambda.amazonaws.com服务执行sts:AssumeRole动作
    • 绑定企业要求的权限边界
    • 配置最小必要权限:S3桶通知配置权限(s3:GetBucketNotification、s3:PutBucketNotification)、Lambda触发器配置权限(lambda:AddPermission、lambda:RemovePermission)、CloudWatch日志基础写入权限
  • 在serverless.yml的provider.iam配置块下添加customResourceRole字段,值为上一步提前创建的自定义资源角色的完整ARN,指定框架生成的自定义资源Lambda使用该专属角色。
  • 若角色是刚创建完成,等待10秒左右待IAM角色全局传播完成后再执行部署,避免因角色传播延迟导致的无法承担错误。
  • (可选优化)当前业务角色配置了s3:*、lambda:*的全量权限,建议根据实际业务需求收缩为最小权限,避免权限过度开放。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 01:42:17