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

AWS CloudFormation部署Lambda遇S3 NoSuchKey错误及相关技术疑问

问题与解答:AWS CloudFormation部署Lambda时S3 NoSuchKey错误

问题背景

我尝试通过AWS CloudFormation创建S3桶,并向其中上传JavaScript代码,以下是我的CloudFormation脚本:

MyLambdaFunction:
  Type: AWS::Lambda::Function
  Properties:
    Description: >
      Lambda function to call a Docker image
    FunctionName:
      !Sub
      - '${TheEnv}-${TheAppNameForResources}-v1'
      - TheEnv: !Ref Environment
        TheAppNameForResources: !Ref AppNameForResources
    EphemeralStorage:
      Size: 10240
    Code:
      S3Bucket: !Ref MyS3Bucket
      S3Key: "lambda-code.zip"
    Runtime: nodejs20.x
    Handler: index.handler
    Role: !GetAtt MyLambdaExecutionRole.Arn

MyLambdaExecutionRole:
  Type: AWS::IAM::Role
  Properties:
    RoleName:
      !Sub
      - "${TheAppNameForResources}-${TheEnvName}-lambda-execution-role"
      - TheAppNameForResources: !Ref AppNameForResources
        TheEnvName: !Ref Environment
    AssumeRolePolicyDocument:
      Statement:
        - Effect: Allow
          Principal:
            Service: lambda.amazonaws.com
          Action: ['sts:AssumeRole']
    Policies:
      - PolicyName:
          !Sub
          - "${TheAppNameForResources}-${TheEnvName}-lambda-execution-role-policy"
          - TheAppNameForResources: !Ref AppNameForResources
            TheEnvName: !Ref Environment
        PolicyDocument:
          Version: "2012-10-17"
          Statement:
            - Effect: Allow
              Action:
                - 'logs:CreateLogGroup'
                - 'logs:CreateLogStream'
                - 'logs:PutLogEvents'
              Resource: "*"

MyS3Bucket:
  Type: AWS::S3::Bucket
  Properties:
    BucketName:
      !Sub
      - '${TheEnv}-${TheAppNameForResources}-${TheBucketRegion}'
      - TheEnv: !Ref Environment
        TheAppNameForResources: !Ref AppNameForResources
        TheBucketRegion: !Ref AWS::Region

当我的CodePipeline运行时,出现以下错误:

资源处理程序返回消息:"获取对象时出错。S3错误代码:NoSuchKey。S3错误消息:指定的键不存在。(服务:Lambda,状态码:400,请求ID:6a1d0144-97ce-413a-8efe-94572ace7980)" (请求令牌:47866741-293b-8590-b5e8-508d9945265b,处理程序错误代码:InvalidRequest)

我的疑问:

  1. 向S3上传代码时,是否需要手动将文件压缩为ZIP包并手动上传?还是CloudFormation会自动完成此操作?
  2. 创建Lambda资源时,何时需要指定S3Key属性?该属性是否为必填项?
  3. 如果第一个问题的答案是需要手动操作,那么我是否无法在同一个CloudFormation模板中包含所有相关的S3资源?因为如果S3桶中没有ZIP包,MyLambdaFunction资源创建会失败。理想情况下,我是否需要先单独创建S3桶,上传ZIP包后再部署其余资源?

解答

1. ZIP包的处理方式

CloudFormation不会自动压缩代码并上传到S3。你需要自行将Lambda代码文件(如index.js等)打包成ZIP包,再上传到指定的S3桶。如果用CodePipeline部署模板,通常要在Pipeline中添加构建阶段(比如用CodeBuild),先完成代码打包,再上传到目标S3桶,最后执行CloudFormation部署。

2. S3Key的使用场景与必填性

当你通过S3存储Lambda代码时,S3Key是必填属性——它对应S3桶中代码ZIP包的对象键(即文件名称/路径)。Lambda代码配置有两种方式:

  • 用S3存储代码:必须同时指定S3Bucket和S3Key(若ZIP包有版本,还可添加S3ObjectVersion)。
  • 内嵌代码到模板:使用ZipFile属性(适合代码量小的场景,比如简单脚本),这种情况无需任何S3相关属性。

3. 同一模板部署S3桶与Lambda的解决方案

不需要拆分模板分两次部署,有几种可行方案:

  • 调整CodePipeline阶段顺序:先执行CloudFormation创建S3桶,接着用CodeBuild把代码ZIP包上传到该桶,最后再执行CloudFormation部署Lambda(此时S3桶已存在代码包)。
  • 使用自定义资源:编写Lambda自定义资源,在模板部署过程中自动完成代码打包并上传到新建的S3桶,适合复杂场景,但需要额外配置权限和代码。
  • 内嵌代码(小体量场景):如果Lambda代码较短,直接用ZipFile把代码写在模板里,无需依赖S3桶,示例如下:
    Code:
      ZipFile: |
        exports.handler = async (event) => {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello from Lambda!'),
          };
        };
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 01:19:54