GitHub Actions矩阵策略替代方案:降低Terraform多部门部署成本
降低GitHub Actions多部门Terraform部署成本方案
我们组织采用Terraform作为基础设施即代码(IaC)工具,需要为多个组及部门部署相同资源集(例如ABC组下包含1、2、3、4、5号部门)。此前使用GitHub Actions的matrix功能部署,但该功能会创建独立任务,导致计费成本偏高,现需优化方案降低运行成本。
单Runner内并行部署脚本
以下bash脚本可在单个GitHub Actions runner实例中,控制并发数执行多部门的Terraform部署,避免启动多个独立runner带来的额外成本:
group=${GROUPS} divisions=${DIVISIONS} divisions=${divisions#\[} divisions=${divisions%\]} IFS=',' read -r -a array <<< "$divisions" task () { echo "Starting task for the $2 division" cd ./infra/terraform/scheduleQueryStack terraform workspace select -or-create "${1}_${2}_schedulequery_stack_test" export TF_VAR_environment=${{ inputs.Stage }} export TF_VAR_group=$1 export TF_VAR_region=${{ inputs.Region }} export TF_VAR_division=$2 terraform apply --auto-approve echo "Task for the $2 division completed" } # 存储后台任务PID的数组 pids=() # 最大并发后台任务数 max_concurrent=4 remove_empty_pids() { local new_pids=() for pid in "${pids[@]}"; do if [ -n "$pid" ]; then new_pids+=("$pid") fi done pids=("${new_pids[@]}") } # 列出所有运行中的后台任务 list_background_tasks() { echo "PIDs of background running tasks: ${pids[@]}" echo "Current total number of PIDs: ${#pids[@]}" for pid in "${pids[@]}"; do if kill -0 "$pid" 2>/dev/null; then echo "Task with PID $pid is running" else echo "Task with PID $pid has completed" # 从数组中移除已完成任务的PID pids=("${pids[@]/$pid}") remove_empty_pids echo "$pid PID removed from the PIDs array" fi done } # 并行运行任务并保存PID for division in "${array[@]}"; do # 检查后台任务数是否达到上限 while [ ${#pids[@]} -ge $max_concurrent ]; do list_background_tasks sleep 60 echo "等待1分钟,待部分后台任务完成" done # 后台运行任务 task "$group" "$division" & # 将任务PID加入数组 pids+=($!) done # 等待所有后台任务完成 wait_for_background_tasks() { for pid in "${pids[@]}"; do wait "$pid" done } wait_for_background_tasks echo "所有任务已完成"
脚本核心逻辑
- 变量解析:将传入的部门列表字符串(格式如
[1,2,3,4,5])转换为bash数组,便于循环处理每个部门 - 任务封装:
task函数封装了单个部门的Terraform部署流程,包括切换工作区、设置环境变量、执行apply操作 - 并发控制:通过PID数组跟踪后台任务,限制最大并发数(当前设为4),定期检查任务状态并清理已完成的PID,确保不会超出runner的资源承载能力
- 任务等待:所有任务启动后,等待所有后台进程执行完毕,确保部署全量完成
额外成本优化建议
- Terraform缓存复用:在GitHub Actions workflow中配置
actions/cache,缓存Terraform的provider和模块,避免每次部署重复下载,缩短运行时间 - 选择合适的Runner规格:根据部署任务的资源消耗,选择最小规格的托管runner;或使用自托管runner,进一步降低长期运行成本
- 增量部署触发:通过Terraform的
plan结果判断是否需要执行apply,避免无资源变更时的无效运行 - Terraform模块批量处理:将多部门的通用部署逻辑封装为Terraform模块,通过输入变量批量生成资源,减少重复执行的任务数量
内容的提问来源于stack exchange,提问作者chethankumar MV
相关产品推荐
相关产品推荐

