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

GitLab CI运行Lambda旧版本清理Python脚本报错如何解决

报错根因

CI配置中使用了shell的source语法(. 命令)执行Python脚本,该语法会将文件内容作为shell命令解析,而不是调用Python解释器运行代码,因此shell读到首行的import关键字时会抛出command not found错误。
另外原配置和脚本还存在几个隐性问题:

  • 未确认运行环境是否安装boto3依赖
  • 未处理Lambda API的分页逻辑,函数/版本数量超过API单次返回上限时会漏清理
  • 未提前过滤被别名绑定的版本,触发删除时会直接抛异常中断任务
  • 原脚本中删除逻辑的代码是注释状态,实际执行不会真的删除版本
正确配置方法

按照以下步骤调整即可正常运行:

  1. 修正脚本执行命令,不要使用. 前缀调用Python脚本,优先直接指定Python解释器执行,兼容性最好:
    修正后的.gitlab-ci.yml片段参考:
    delete-lambda-versions-nonprod:
      stage: import
      image: "someimage/confidential"
      <<: *nonprod
      variables:
        ENV_TAG: "alpha1"
        AWS_DEFAULT_REGION: "ap-southeast-1" # 替换为实际Lambda所在区域
      script:
        # 先安装依赖,如果你的自定义镜像已经预装boto3可以跳过这行
        - pip3 install boto3
        # 调用Python解释器执行脚本,不要加.前缀
        - python3 clean_old_lambda_versions.py
      when: manual
    
  2. 修复原Python脚本的逻辑缺陷,补充分页、别名过滤逻辑,参考修正后的代码:
    #!/usr/bin/env python3
    from __future__ import absolute_import, print_function, unicode_literals
    import boto3
    
    def clean_old_lambda_versions():
        client = boto3.client('lambda')
        # 处理函数列表分页
        function_paginator = client.get_paginator('list_functions')
        for function_page in function_paginator.paginate():
            for function in function_page['Functions']:
                func_name = function['FunctionName']
                print(f"Processing function: {func_name}")
                # 先查询所有别名绑定的版本,加入保留列表
                alias_paginator = client.get_paginator('list_aliases')
                reserved_versions = set()
                for alias_page in alias_paginator.paginate(FunctionName=func_name):
                    for alias in alias_page['Aliases']:
                        reserved_versions.add(alias['FunctionVersion'])
                # 拉取全量版本列表
                version_paginator = client.get_paginator('list_versions_by_function')
                all_versions = []
                for ver_page in version_paginator.paginate(FunctionName=func_name):
                    all_versions.extend(ver_page['Versions'])
                # 过滤掉$LATEST,按版本号排序取最大的那个作为最新发布版本加入保留列表
                published_versions = [v for v in all_versions if v['Version'] != '$LATEST']
                published_versions.sort(key=lambda x: int(x['Version']), reverse=True)
                if published_versions:
                    reserved_versions.add(published_versions[0]['Version'])
                reserved_versions.add('$LATEST')
                # 遍历删除不在保留列表里的版本
                for version in all_versions:
                    ver_num = version['Version']
                    if ver_num not in reserved_versions:
                        arn = version['FunctionArn']
                        print(f"Deleting old version: {arn}")
                        # 测试没问题后再取消下面这行的注释执行实际删除
                        # client.delete_function(FunctionName=arn)
                print(f"{func_name}: cleanup completed")
    
    if __name__ == '__main__':
        clean_old_lambda_versions()
    
  3. 确认GitLab Runner配置的AWS凭证有权限执行Lambda的lambda:ListFunctions、lambda:ListVersionsByFunction、lambda:ListAliases、lambda:DeleteFunction权限,否则会报权限不足错误。
可选替代方案
  • 方案一:基于AWS CLI实现清理逻辑,无需Python依赖,只要运行镜像预装AWS CLI即可,通过shell循环完成版本遍历、过滤、删除操作,逻辑更轻量。
  • 方案二:将保留版本数做成CI可配置变量,比如通过KEEP_VERSIONS_COUNT变量控制保留最近N个发布版本,而不是硬编码只保留1个最新版本,适配不同环境的版本保留需求。
  • 方案三:如果是多账号环境,在CI脚本中加入STS跨账号角色扮演逻辑,通过GitLab存储的对应环境凭证获取临时访问密钥后再执行清理,避免给Runner服务账号开放过宽的权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 23:18:19