一、为什么要把AWS Lambda和GitLab CI/CD绑一起?

很多开发者用AWS Lambda做后端接口、定时任务或者小工具时,都绕不开手动部署的麻烦:改了代码要本地打包,还要打开AWS控制台找对应的Lambda函数,上传新代码,偶尔还要调整层的配置,步骤多还容易出错。尤其是团队协作时,好几个人改同一个Lambda,手动操作很容易传错版本;要是有好几个Lambda要维护,每次迭代都花半小时在上传上,效率低到心疼。GitLab CI/CD就是来解决这个问题的,把代码提交、测试、打包、部署全流程自动化,省时间还靠谱。

1.1 适合的开发场景

最常见的场景是:用Lambda做前端请求的后端接口,每次改了接口逻辑,想直接推代码就能生效;或者做定时执行的工具,比如每日给团队发周报、定时统计数据,不用手动触发任务;还有微服务里的多个Lambda函数,需要统一更新依赖,用层管理更方便。这些场景里,自动化部署能把重复的手动操作砍掉,减少人工失误。

1.2 手动部署的痛点

手动部署的坑主要有三个:第一,慢,每次从打包到上传至少要10分钟,碰到网络差的时候更久;第二,错,比如上传时选了错误的压缩包,或者漏了更新层的版本,上线后才发现bug;第三,乱,没有版本记录,万一上线出问题,回滚要找很久之前的备份,不如自动化的流水线清晰。

二、整体流程拆解(测试、打包、层上传、函数更新)

要把Lambda和GitLab CI/CD连起来,核心是把四个步骤串成流水线:首先是代码提交后先跑单元测试,确保代码能正常跑;然后把Lambda的依赖打包成“层”(这个层相当于公共依赖包,所有用这个依赖的Lambda都可以用,不用每个函数都装一遍),再把Lambda的业务代码打包;最后把层上传到AWS,更新Lambda函数的代码和对应的层版本。整个流程只要有人把代码合并到主分支,就自动跑,不用人工干预。

2.1 用到的核心工具

不用装复杂的东西,只要有GitLab账号、AWS账号,还有Python环境就行(本文选Python当示例,因为Lambda对Python的支持最完善,代码也简单好懂)。GitLab自带的CI功能会帮你跑流水线,AWS的CLI命令会帮你操作Lambda和层,不用写复杂的脚本,配置好就自动跑。

2.2 要注意的基础准备

首先得在AWS里给GitLab的流水线配个专用的账号,这个账号只给Lambda相关的权限,不能开太大,安全最重要;然后在GitLab项目里加几个私密变量,把AWS的账号信息存进去,防止泄露。

三、详细实现步骤(带完整示例)

整个示例用Python栈,技术栈明确标注,代码都带注释,保证新手也能看懂。

3.1 第一步:准备项目基础文件

先建一个简单的Lambda项目,结构很简单:

  • lambda_function.py:Lambda的业务代码
  • requirements.txt:Lambda要用的依赖,比如requests(用来发请求)
  • tests/:单元测试的文件夹
  • .gitlab-ci.yml:GitLab流水线的配置文件,是核心

3.2 第二步:写项目代码

先写业务代码,比如做一个给指定用户发消息的Lambda:

# lambda_function.py
import requests

def lambda_handler(event, context):
    # 从事件里拿要发的消息内容
    message = event.get("message", "你好!这是Lambda自动发的消息")
    # 用requests发请求,这个依赖会打包到层里
    response = requests.post("https://example.com/send", json={"content": message})
    return {"statusCode": 200, "body": "消息发送成功"}

再写依赖文件requirements.txt,只要一行:

# requirements.txt
requests==2.31.0

然后写单元测试,测一下函数能不能正常返回:

# tests/test_lambda.py
import lambda_function

def test_lambda_success():
    # 模拟Lambda事件
    test_event = {"message": "测试消息"}
    result = lambda_function.lambda_handler(test_event, None)
    # 检查返回状态
    assert result["statusCode"] == 200

3.3 第三步:写GitLab流水线配置(核心)

这个配置文件是整个自动化的关键,分三个阶段:测试、打包、部署,只有合并到主分支才会跑,避免特性分支乱触发。代码里的变量都是GitLab里设的私密变量,安全又方便:

# 技术栈:Python 3.9、AWS CLI 2.0、GitLab CI/CD
stages:
  - test    # 第一阶段:跑单元测试,确保代码没问题
  - package # 第二阶段:打包层和Lambda代码
  - deploy  # 第三阶段:部署到AWS Lambda

# 第一阶段:单元测试
test:
  stage: test
  # 用Python的轻量镜像,不用装多余的东西
  image: python:3.9-slim
  before_script:
    - pip install --upgrade pip pytest
  script:
    # 跑单元测试,-v显示详细结果,方便看哪里错
    - pytest tests/ -v
  # 只在主分支合并时跑,其他分支不触发,省时间
  only:
    - main

# 第二阶段:打包层和业务代码
package:
  stage: package
  image: python:3.9-slim
  before_script:
    # 把依赖装到当前目录的python文件夹里,符合Lambda层的格式要求
    - pip install --target ./python -r requirements.txt
  script:
    # 把依赖打包成zip,这个zip就是Lambda的层文件
    - zip -r layer.zip python/
    # 把Lambda的业务代码打包成zip
    - zip function.zip lambda_function.py
  # 把打包好的文件传给下一个部署阶段,不用重新生成
  artifacts:
    paths:
      - layer.zip
      - function.zip
  only:
    - main

# 第三阶段:部署到AWS Lambda
deploy:
  stage: deploy
  # 用带AWS CLI的镜像,避免自己装AWS工具,方便又稳定
  image: amazon/aws-cli:latest
  before_script:
    # 配置AWS凭证,用GitLab的私密变量,不会泄露
    - aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID
    - aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY
    - aws configure set region $AWS_REGION
  script:
    # 上传层到AWS,如果层不存在会自动创建,存在就新增版本
    - aws lambda publish-layer-version \
      --layer-name $LAYER_NAME \
      --zip-file fileb://layer.zip \
      --compatible-runtimes python3.9
    # 获取刚上传的层的最新版本号,用来更新Lambda函数
    - LATEST_LAYER_VERSION=$(aws lambda list-layer-versions \
      --layer-name $LAYER_NAME \
      --query 'LayerVersions[0].Version' \
      --output text)
    # 更新Lambda函数的业务代码
    - aws lambda update-function-code \
      --function-name $FUNCTION_NAME \
      --zip-file fileb://function.zip
    # 把层关联到Lambda函数,这样函数就能用到层里的requests依赖了
    - aws lambda update-function-configuration \
      --function-name $FUNCTION_NAME \
      --layers $LAYER_NAME:$LATEST_LAYER_VERSION
  only:
    - main

3.4 第四步:AWS和GitLab的权限配置

这一步是踩坑最多的地方,要仔细弄:

  1. 先在AWS IAM里建一个用户,名字比如gitlab-lambda-deploy,只给这个用户开三个权限:lambda:PublishLayerVersion(上传层)、lambda:UpdateFunctionCode(更新Lambda代码)、lambda:UpdateFunctionConfiguration(关联层),绝对不能开管理员权限,安全第一。
  2. 把这个用户的Access Key和Secret Key存到GitLab项目的Settings -> CI/CD -> Variables里,变量名分别叫AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY,还要加两个变量:AWS_REGION(比如us-east-1)、LAYER_NAME(你要的层名字)、FUNCTION_NAME(你在AWS建的Lambda函数名字),这些都是公用变量,私密的要选“Protected”和“Masked”,防止泄露。
  3. AWS那边要先建好对应的Lambda函数,名字和GitLab变量里的FUNCTION_NAME一致,层的名字也要对应,不然流水线跑不起来。

四、技术优缺点分析

4.1 优点

  • 省时间:每次代码合并到主分支,自动跑完整流程,不用手动操作,从上传到生效最多1分钟,比手动快很多。
  • 减少失误:有测试阶段挡着,代码有bug就通不过测试,不会上线出问题;版本记录清晰,回滚只要用之前的commit就行。
  • 灵活可控:GitLab的分支规则可以限制,比如只有主分支合并才能部署生产,开发分支不会乱上线,安全有保障。
  • 分层管理:层和函数分开,更新依赖不用改业务代码,只要更新层的版本就行,适合多个函数用同一个依赖的情况。

4.2 缺点

  • 入门要花点时间:新手可能在IAM权限配置、GitLab变量设置上卡壳,不过按步骤来都能搞定。
  • 适合小项目,大项目要优化:如果有几十个Lambda函数,流水线会变长,不过可以用并行阶段或者拆分流水线解决,不影响核心流程。

五、注意事项(避坑指南)

很多人第一次配置会踩这些坑,提前避开:

  1. 权限要最小:GitLab用的IAM账号只开需要的Lambda权限,别给lambda:CreateFunction这种没用的权限,更不能开*,不然泄露了会被人乱改你的AWS资源。
  2. 层的兼容要对:Lambda用Python3.9,层的--compatible-runtimes一定要写python3.9,不然函数启动会报错,找不到依赖。
  3. 变量别暴露:AWS的Access Key绝对不能写到代码里,GitLab里的变量要设成“Masked”,防止被其他项目偷拿到。
  4. 测试不能跳过:哪怕改个小标点,也要跑单元测试,比如把message写成messag,测试会发现,不然上线后函数报错,用户用不了。
  5. 版本回滚要做好:如果部署出问题,比如传错代码,Lambda可以选“Publish new version”,GitLab可以通过commit版本回滚,所以每次修改尽量用小分支,好回滚。

六、总结

把AWS Lambda集成到GitLab CI/CD的自动化部署,是Serverless开发里最实用的技巧之一。不管是个人做小工具,还是企业维护多个Lambda,这套流程都能帮你节省大量手动操作的时间,还能保证代码质量,减少失误。只要按步骤配置好权限和流水线,哪怕是刚接触CI/CD的新手,也能快速搭建起稳定的自动化部署流程,把精力放在写业务代码上,而不是反复上传文件上。