一、为什么要把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的权限配置
这一步是踩坑最多的地方,要仔细弄:
- 先在AWS IAM里建一个用户,名字比如
gitlab-lambda-deploy,只给这个用户开三个权限:lambda:PublishLayerVersion(上传层)、lambda:UpdateFunctionCode(更新Lambda代码)、lambda:UpdateFunctionConfiguration(关联层),绝对不能开管理员权限,安全第一。 - 把这个用户的Access Key和Secret Key存到GitLab项目的
Settings -> CI/CD -> Variables里,变量名分别叫AWS_ACCESS_KEY_ID和AWS_SECRET_ACCESS_KEY,还要加两个变量:AWS_REGION(比如us-east-1)、LAYER_NAME(你要的层名字)、FUNCTION_NAME(你在AWS建的Lambda函数名字),这些都是公用变量,私密的要选“Protected”和“Masked”,防止泄露。 - AWS那边要先建好对应的Lambda函数,名字和GitLab变量里的
FUNCTION_NAME一致,层的名字也要对应,不然流水线跑不起来。
四、技术优缺点分析
4.1 优点
- 省时间:每次代码合并到主分支,自动跑完整流程,不用手动操作,从上传到生效最多1分钟,比手动快很多。
- 减少失误:有测试阶段挡着,代码有bug就通不过测试,不会上线出问题;版本记录清晰,回滚只要用之前的commit就行。
- 灵活可控:GitLab的分支规则可以限制,比如只有主分支合并才能部署生产,开发分支不会乱上线,安全有保障。
- 分层管理:层和函数分开,更新依赖不用改业务代码,只要更新层的版本就行,适合多个函数用同一个依赖的情况。
4.2 缺点
- 入门要花点时间:新手可能在IAM权限配置、GitLab变量设置上卡壳,不过按步骤来都能搞定。
- 适合小项目,大项目要优化:如果有几十个Lambda函数,流水线会变长,不过可以用并行阶段或者拆分流水线解决,不影响核心流程。
五、注意事项(避坑指南)
很多人第一次配置会踩这些坑,提前避开:
- 权限要最小:GitLab用的IAM账号只开需要的Lambda权限,别给
lambda:CreateFunction这种没用的权限,更不能开*,不然泄露了会被人乱改你的AWS资源。 - 层的兼容要对:Lambda用Python3.9,层的
--compatible-runtimes一定要写python3.9,不然函数启动会报错,找不到依赖。 - 变量别暴露:AWS的Access Key绝对不能写到代码里,GitLab里的变量要设成“Masked”,防止被其他项目偷拿到。
- 测试不能跳过:哪怕改个小标点,也要跑单元测试,比如把
message写成messag,测试会发现,不然上线后函数报错,用户用不了。 - 版本回滚要做好:如果部署出问题,比如传错代码,Lambda可以选“Publish new version”,GitLab可以通过commit版本回滚,所以每次修改尽量用小分支,好回滚。
六、总结
把AWS Lambda集成到GitLab CI/CD的自动化部署,是Serverless开发里最实用的技巧之一。不管是个人做小工具,还是企业维护多个Lambda,这套流程都能帮你节省大量手动操作的时间,还能保证代码质量,减少失误。只要按步骤配置好权限和流水线,哪怕是刚接触CI/CD的新手,也能快速搭建起稳定的自动化部署流程,把精力放在写业务代码上,而不是反复上传文件上。
评论
围绕“将AWS Lambda集成到GitLab CI/CD流水线的自动化部署:测试、打包、层上传与函数更新的最佳实践”参与讨论