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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 00:52:03