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

使用Serverless Framework部署两个独立Lambda函数时遭遇CloudFormation资源冲突问题

Serverless Framework部署两个独立Lambda函数时遭遇CloudFormation资源冲突问题

最近我碰到一个特别头疼的问题:用Serverless Framework部署两个完全独立的Lambda函数(lambda-1和lambda-2),各自绑定不同S3桶的ObjectCreated事件触发器,结果每次部署其中一个的时候都会报错。

问题详情

每次部署lambda-1时,都会收到CloudFormation的创建失败提示:

CREATE_FAILED: CustomDashresourceDashexistingDashs3LambdaFunction (AWS::Lambda::Function)
-custom-resource-existing-s3 already exists in stack arn:aws:cloudformation:eu-central-1:xxx:stack/-/xxxsome-uuidxxxx

更奇怪的是,我把两个CloudFormation栈都删掉之后,能成功部署其中一个,但再部署另一个就会立刻触发同样的冲突错误。而且我完全没在serverless.yml里定义过这个叫<prefix-of-both-lambdas>-custom-resource-existing-s3的资源,两个S3桶的名字也和它完全不沾边。

两个函数的Serverless配置

lambda-1的serverless.yml关键部分:

functions:
  lambda-1:
    handler: src/lambda_handler.main
    environment:
      ENV: ${opt:stage}
    events:
      - s3:
          bucket: ${ssm:/panda/${opt:stage}/strings/lambda-1-bucket}
          event: s3:ObjectCreated:*
          rules:
            - prefix: <s3-prefix>/
            - suffix: .csv
          existing: true
    forceDeploy: true

resources:
  Outputs:
    ServerlessDeploymentBucketName:
      Export:
        Name: "${self:service}-${opt:stage}-${self:custom.serverless-aws-resource-names.variables.lambdaFunctionName}-sls-dpl"
    PythonRequirementsLambdaLayerHash:
      Export:
        Name: "${self:service}-${opt:stage}-${self:custom.serverless-aws-resource-names.variables.lambdaFunctionName}-requirements-LayerHash"
    PythonRequirementsLambdaLayerQualifiedArn:
      Export:
        Name: "${self:service}-${opt:stage}-${self:custom.serverless-aws-resource-names.variables.lambdaFunctionName}-requirements-LayerQualifiedArn"
    PythonRequirementsLambdaLayerS3Key:
      Export:
        Name: "${self:service}-${opt:stage}-${self:custom.serverless-aws-resource-names.variables.lambdaFunctionName}-requirements-LayerS3Key"

lambda-2的serverless.yml关键部分:

functions:
  lambda-2:
    package:
      artifact: ${env:MVN_ARTIFACT_RELATIVE_PATH}
    handler: lambda_handler.Handler
    events:
      - s3:
          bucket: ${ssm:/panda/${opt:stage}/strings/lambda-2-bucket}
          event: s3:ObjectCreated:*
          rules:
            - suffix: .xlsx
          existing: true
    logSubscription: true
    memorySize: 512
    timeout: 120

resources:
  Outputs:
    ServerlessDeploymentBucketName:
      Export:
        Name: "sls-${self:service}-${opt:stage}-${self:custom.serverless-aws-resource-names.variables.lambdaFunctionName}-ServerlessDeploymentBucketName"

问题根源

后来查了Serverless Framework的文档才明白:当我们给S3触发器设置existing: true(也就是绑定已存在的S3桶)时,框架会自动创建一个自定义Lambda资源,用来处理现有桶的事件通知配置(比如给Lambda加S3权限、配置桶的事件规则)。

这个自定义资源的默认命名规则是{服务前缀}-custom-resource-existing-s3,如果两个Lambda服务的前缀相同,就会生成完全一样的资源名,而AWS不允许同一区域下存在同名的Lambda函数,自然就触发冲突了。

解决办法

这里有几个可行的解决方案,按需选择:

  • 给两个服务设置不同的service名称
    在每个服务的serverless.yml顶层配置里,把service字段改成不一样的名字,比如:

    # lambda-1的serverless.yml
    service: lambda-1-service
    
    # lambda-2的serverless.yml
    service: lambda-2-service
    

    这样自定义资源的前缀会跟着service名称变,自然不会冲突。

  • 自定义资源名称规则
    在每个服务的custom字段里,覆盖默认的自定义资源命名,确保每个服务的资源唯一:

    custom:
      existingS3:
        resourceName: ${self:service}-${opt:stage}-custom-resource-existing-s3
    

    这个配置会让自定义资源的名字带上服务名和环境,彻底避免重复。

  • 手动管理S3触发器
    如果不想依赖Serverless自动创建资源,可以手动配置:

    1. 登录AWS控制台,找到对应的S3桶,手动添加事件通知,指向目标Lambda函数
    2. 在serverless.yml里去掉S3触发器的配置,同时给Lambda函数添加必要的S3权限(比如s3:GetObject、s3:ListBucket等)

验证步骤

不管用哪个方案,建议先把现有的冲突CloudFormation栈删掉,然后分别部署两个Lambda函数,确认不再出现资源冲突的错误。

备注:内容来源于stack exchange,提问作者Alex_Wlt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 15:59:52