如何在单个Git仓库中管理多个Lambda函数并构建单配置CI/CD流水线
单Git仓库多Lambda函数统一CI/CD实现方案
1. 先统一仓库目录结构
所有Lambda函数统一存放在根目录下的functions/文件夹中,每个函数对应一个独立子目录,子目录名称与Lambda函数名保持一致,公共依赖、通用层代码可以放在根目录的common/文件夹下复用,目录结构参考:
. ├── deploy.yml # 唯一的CI/CD配置文件 ├── common/ # 全局公共依赖、工具代码 └── functions/ ├── lambda-order/ # 订单处理Lambda,目录名即函数名 │ ├── index.py │ └── requirements.txt ├── lambda-payment/ # 支付处理Lambda │ ├── index.js │ └── package.json └── lambda-notify/ # 通知推送Lambda └── index.go
2. 编写动态识别变更的统一CI/CD配置
核心逻辑是在流水线中自动识别本次提交改动的Lambda函数,只部署变更的函数,也支持手动触发全量部署,以下是GitHub Actions场景的deploy.yml示例,GitLab CI等其他CI工具逻辑完全一致,仅语法略有差异:
name: 多Lambda统一部署流水线 on: push: branches: [ main ] # main分支推送时自动触发 workflow_dispatch: # 支持手动触发部署 jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 # 拉取全量提交记录用于对比代码变更 - name: 配置云厂商凭证 uses: aws-actions/configure-aws-credentials@v4 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: ap-southeast-1 # 替换为你的实际区域 - name: 生成待部署Lambda列表 run: | # 自动识别本次提交改动的Lambda git diff --name-only ${{ github.event.before }} ${{ github.sha }} | grep '^functions/' | awk -F/ '{print $2}' | uniq > deploy_list.txt # 手动触发时默认部署所有Lambda,不需要可以删掉这段 if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then ls -d functions/*/ | awk -F/ '{print $2}' > deploy_list.txt fi echo "待部署函数列表:$(cat deploy_list.txt | tr '\n' ' ')" - name: 循环执行部署 run: | while read lambda_name; do # 跳过空行 if [ -z "$lambda_name" ]; then continue; fi # 进入对应函数目录执行构建 cd functions/$lambda_name # 各语言自定义构建逻辑,示例为Python安装依赖后打包 pip install -r requirements.txt -t . zip -r ${lambda_name}.zip . # 调用AWS CLI部署函数 aws lambda update-function-code --function-name $lambda_name --zip-file fileb://${lambda_name}.zip cd ../.. done < deploy_list.txt
3. Serverless框架适配方案
如果要使用Serverless Framework实现单配置文件部署,只需要编写一份serverless.yml,通过动态脚本加载所有函数配置即可,不需要为每个函数单独编写配置:
- 根目录新增
load_functions.js文件,用于遍历functions目录自动生成函数配置 - 在
serverless.yml中引入该动态生成的配置即可,核心示例代码:
// load_functions.js const fs = require('fs'); const functionNames = fs.readdirSync('./functions').filter(name => fs.statSync(`./functions/${name}`).isDirectory()); module.exports = functionNames.reduce((config, name) => { config[name] = { handler: `functions/${name}/index.handler`, name: name, runtime: 'python3.10' // 可以各函数单独配置,或统一指定 } return config; }, {});
# serverless.yml service: multi-lambda-service provider: name: aws region: ap-southeast-1 functions: ${file(./load_functions.js)}
内容的提问来源于stack exchange,提问作者Tanishk
相关产品推荐
相关产品推荐

