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

如何构建CI/CD流水线更新控制台创建的现有AWS Lambda代码?

解决控制台创建的AWS Lambda代码更新的CI/CD方案

我来帮你梳理几个针对「仅更新控制台创建的Lambda函数代码、禁止新建函数」需求的可行方案,完美避开你遇到的CloudFormation和CodeDeploy的坑:

方案1:CodePipeline + CodeBuild + AWS CLI(最直接省心)

这个方案完全绕开CloudFormation的资源归属限制,直接用AWS CLI命令更新代码,简单粗暴但有效。

具体配置步骤:

  1. CodePipeline源码阶段:连接你的代码仓库(GitHub/CodeCommit/GitLab都行),拉取最新的Lambda源码。
  2. 添加CodeBuild阶段:
    • 写一个buildspec.yml放在代码根目录,负责打包代码并调用CLI更新Lambda:
      version: 0.2
      phases:
        install:
          runtime-versions:
            python: 3.9 # 替换成你的Lambda运行时,比如nodejs18.x
        build:
          commands:
            # 把源码打包成zip(排除.git和buildspec.yml这些无关文件)
            - zip -r lambda-update-package.zip . -x "*.git*" "buildspec.yml"
            # 核心命令:更新指定的Lambda函数代码
            - aws lambda update-function-code --function-name 你的现有Lambda名称 --zip-file fileb://lambda-update-package.zip
      artifacts:
        files:
          - lambda-update-package.zip
      
    • 给CodeBuild的服务角色加上lambda:UpdateFunctionCode权限,确保它能操作目标Lambda。
  3. 无需额外部署阶段:CodeBuild跑完就已经完成代码更新了,直接结束流水线就行。

优势:

  • 完全适配控制台创建的Lambda,绝对不会触发新建函数的操作。
  • 配置成本极低,不需要写复杂的CloudFormation模板。

方案2:CodePipeline + 自定义Lambda动作(更灵活)

如果不想用CodeBuild,可以搞个辅助Lambda来做代码更新的事儿,把它作为CodePipeline的一个自定义动作。

具体操作:

  1. 写一个辅助Lambda函数:这个函数的任务是从CodePipeline的输出 artifact(存在S3里的代码包)拉取内容,然后调用Lambda的更新API。示例代码(Python):
    import boto3
    import os
    from io import BytesIO
    
    s3 = boto3.client('s3')
    lambda_client = boto3.client('lambda')
    codepipeline = boto3.client('codepipeline')
    
    def lambda_handler(event, context):
        # 从CodePipeline事件里拿到S3的代码包位置
        job_details = event['CodePipeline.job']
        input_artifact = job_details['data']['inputArtifacts'][0]['location']['s3Location']
        bucket = input_artifact['bucketName']
        key = input_artifact['objectKey']
    
        # 下载S3里的代码包
        s3_response = s3.get_object(Bucket=bucket, Key=key)
        zip_content = BytesIO(s3_response['Body'].read())
    
        # 更新目标Lambda函数
        try:
            lambda_client.update_function_code(
                FunctionName=os.environ['TARGET_LAMBDA'],
                ZipFile=zip_content.getvalue()
            )
            # 告诉CodePipeline任务成功
            codepipeline.put_job_success_result(jobId=job_details['id'])
        except Exception as e:
            # 失败的话也要通知CodePipeline
            codepipeline.put_job_failure_result(
                jobId=job_details['id'],
                failureDetails={'message': str(e), 'type': 'JobFailed'}
            )
        return {'statusCode': 200}
    
  2. 配置CodePipeline的自定义动作:
    • 在流水线里加一个“Lambda”类型的动作,选择刚才创建的辅助Lambda。
    • 给辅助Lambda设置环境变量TARGET_LAMBDA,值就是你要更新的现有Lambda名称。
    • 给辅助Lambda的角色加上s3:GetObject、lambda:UpdateFunctionCode和codepipeline:PutJobSuccessResult这几个权限。

方案3:修复CodeDeploy的BundleType错误(如果想继续用CodeDeploy)

你遇到的BundleType must be either YAML or JSON错误,本质是CodeDeploy找不到正确的appspec.yml配置文件,或者代码包结构不对。针对控制台创建的Lambda,调整代码包结构就能解决:

正确的代码包结构:

lambda-deploy-package/
├── appspec.yml
└── src/
    └── 你的Lambda代码文件(比如index.js、requirements.txt等)

appspec.yml的正确写法:

version: 0.0
Resources:
  - TargetLambda:
      Type: AWS::Lambda::Function
      Properties:
        Name: 你的现有Lambda名称
        CodeUri: src/
        Runtime: python3.9 # 匹配你的Lambda运行时

把整个lambda-deploy-package目录打包成zip,上传给CodeDeploy,就能正常识别BundleType了。


不管用哪个方案,记得给流水线/辅助服务的IAM角色配置足够的权限,避免出现权限不足的报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 16:57:48