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

多Git仓库通过Terraform向同一API Gateway Dev阶段部署Lambda的问题

解决方案:多仓库共享API Gateway Stage的Terraform实践

针对多Git仓库部署Lambda到同一API Gateway dev 阶段的问题,核心思路是拆分资源管理边界,将共享的Stage资源独立管理,业务仓库仅负责自身API变更与Deployment生成,具体实现如下:

1. 独立管理API Gateway核心资源

创建单独的「API Gateway基础设施仓库」,专门负责管理rest_api和dev Stage资源,彻底避免多仓库重复创建/删除Stage:

# 定义API Gateway主资源
resource "aws_api_gateway_rest_api" "my_api" {
  name = "MySharedAPI"
  # 可添加描述、版本等自定义配置
}

# 唯一的dev Stage资源
resource "aws_api_gateway_stage" "dev" {
  rest_api_id   = aws_api_gateway_rest_api.my_api.id
  stage_name    = "dev"
  deployment_id = var.latest_deployment_id # 接收外部传入的最新部署ID
  
  # 可选:配置访问日志、缓存、环境变量等
  access_log_settings {
    destination_arn = aws_cloudwatch_log_group.api_access_log.arn
    format          = "{\"requestId\":\"$context.requestId\",\"ip\":\"$context.identity.sourceIp\",\"method\":\"$context.httpMethod\",\"path\":\"$context.resourcePath\",\"status\":\"$context.status\"}"
  }
}

# 输出API基础信息,供业务仓库引用
output "api_rest_api_id" {
  value = aws_api_gateway_rest_api.my_api.id
}

output "root_resource_id" {
  value = aws_api_gateway_rest_api.my_api.root_resource_id
}

output "dev_stage_name" {
  value = aws_api_gateway_stage.dev.stage_name
}

该仓库需配置Terraform远程状态(如S3+DynamoDB)存储状态,确保其他业务仓库可读取输出信息。

2. 业务仓库(Lambda)改造

每个业务仓库不再创建aws_api_gateway_stage资源,仅负责自身API路径、Lambda集成及对应Deployment的生成:

# 读取API基础设施仓库的远程状态
data "terraform_remote_state" "api_core" {
  backend = "s3"
  config = {
    bucket = "your-terraform-state-bucket"
    key    = "path/to/api-infra/terraform.tfstate"
    region = "cn-north-1" # 替换为你的AWS区域
  }
}

# 创建业务专属API路径
resource "aws_api_gateway_resource" "user_service" {
  rest_api_id = data.terraform_remote_state.api_core.outputs.api_rest_api_id
  parent_id   = data.terraform_remote_state.api_core.outputs.root_resource_id
  path_part   = "user"
}

# 配置Lambda集成
resource "aws_api_gateway_integration" "user_lambda" {
  rest_api_id = data.terraform_remote_state.api_core.outputs.api_rest_api_id
  resource_id = aws_api_gateway_resource.user_service.id
  http_method = aws_api_gateway_method.user_get.http_method
  type        = "AWS_PROXY"
  uri         = aws_lambda_function.user_handler.invoke_arn
}

# 生成当前业务变更的Deployment
resource "aws_api_gateway_deployment" "user_deployment" {
  depends_on = [
    aws_api_gateway_integration.user_lambda,
    aws_api_gateway_method.user_get
  ]
  rest_api_id = data.terraform_remote_state.api_core.outputs.api_rest_api_id

  # 触发器:每次API资源变更时强制生成新Deployment
  triggers = {
    resource_change = sha1(jsonencode([
      aws_api_gateway_resource.user_service,
      aws_api_gateway_integration.user_lambda
    ]))
  }
}

# 输出当前Deployment ID,用于更新Stage
output "deployment_id" {
  value = aws_api_gateway_deployment.user_deployment.id
}

3. 更新Stage指向最新Deployment

业务仓库部署完成后,将输出的deployment_id传入基础设施仓库的var.latest_deployment_id变量,执行terraform apply即可更新dev Stage到最新的API快照:

  • 手动方式:复制业务仓库输出的Deployment ID,修改基础设施仓库的变量值后执行部署。
  • 自动化方式:通过CI/CD工具(如GitHub Actions),在业务仓库部署完成后自动触发基础设施仓库的部署,传递最新的Deployment ID作为变量。

替代方案:无仓库拆分的临时解决(不推荐)

如果暂时无法拆分仓库,可通过数据资源引用已存在的Stage,并用AWS CLI更新Deployment ID,但会导致Terraform状态与实际资源不一致,仅作为临时过渡方案:

# 引用已存在的dev Stage
data "aws_api_gateway_stage" "dev" {
  rest_api_id = data.aws_api_gateway_rest_api.my_api.id
  stage_name  = "dev"
}

# 创建Deployment后,用CLI更新Stage
resource "null_resource" "update_stage" {
  depends_on = [aws_api_gateway_deployment.deployment]

  provisioner "local-exec" {
    command = <<EOT
      aws apigateway update-stage \
        --rest-api-id ${data.aws_api_gateway_rest_api.my_api.id} \
        --stage-name dev \
        --patch-operations op=replace,path=/deploymentId,value=${aws_api_gateway_deployment.deployment.id}
    EOT
  }
}

关键注意事项

  • 权限控制:确保业务仓库的Terraform有读取基础设施仓库远程状态的权限,基础设施仓库有修改API Gateway Stage的权限。
  • Deployment唯一性:每个业务仓库的Deployment必须设置triggers,避免重复使用旧的Deployment快照。
  • 状态一致性:优先采用仓库拆分方案,确保Terraform状态与实际云资源一致,避免手动操作带来的风险。

内容的提问来源于stack exchange,提问作者PackedUp

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 12:41:00