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

修改AWS API Gateway路径及source_arn报错的解决方案咨询

修改Terraform管理的API Gateway端点路径时的部署错误解决方案

错误现象

首次部署修改后的配置时出现Provider计划不一致错误:

│ Error: Provider produced inconsistent final plan
│ 
│ When expanding the plan for
│ aws_lambda_permission.lambdaApiGetStockPermission to include new values
│ learned so far during apply, provider "registry.terraform.io/hashicorp/aws"
│ produced an invalid new value for .source_arn: was
│ cty.StringVal("arn:aws:execute-api:eu-west-3:<account-id>:<api-id>/*/POST/stock"),
│ but now
│ cty.StringVal("arn:aws:execute-api:eu-west-3:<account-id>:<api-id>/*/POST/stockDispoOfArticle").
│ 
│ This is a bug in the provider, which should be reported in the provider's
│ own issue tracker.

后续部署触发API Gateway部署失败:

│ Error: Error creating API Gateway Deployment: BadRequestException: No integration defined for method
│ 
│   with aws_api_gateway_deployment.ApiDeployment,
│   on api.tf line 50, in resource "aws_api_gateway_deployment" "ApiDeployment":
│   50: resource "aws_api_gateway_deployment" "ApiDeployment" {

补充说明:本地执行terraform plan无报错,但GitLab CI部署时触发错误;无AWS控制台API Gateway访问权限,原路径仍可正常访问;使用AWS Provider版本4.23.0。

相关Terraform配置

API Gateway部署资源

resource "aws_api_gateway_deployment" "ApiDeployment" {
  depends_on = [
    ...
    aws_api_gateway_integration.lambdaApiGetStock,
    ...
  ]

  rest_api_id = aws_api_gateway_rest_api.Api.id
  stage_name  = "latest"

  variables     = {
      deployed_at = timestamp()
  }

  lifecycle {
    create_before_destroy = true
  }
}

API Gateway集成资源

resource "aws_api_gateway_integration" "lambdaApiGetStock" {
  rest_api_id             = aws_api_gateway_rest_api.Api.id
  resource_id             = local.lambdaApiGetStockRouteParent
  http_method             = aws_api_gateway_method.lambdaApiGetStock.http_method
  type                    = "AWS_PROXY"
  uri                     = aws_lambda_function.lambdaApiGetStock.invoke_arn
  integration_http_method = "POST"
}

API Gateway方法资源

resource "aws_api_gateway_method" "lambdaApiGetStock" {
  rest_api_id      = aws_api_gateway_rest_api.Api.id
  resource_id      = local.lambdaApiGetStockRouteParent
  http_method      = local.lambdaApiGetStockMethod
  api_key_required = false
  authorization = "CUSTOM"
  authorizer_id = aws_api_gateway_authorizer.ApiAuthorizer.id
}

Lambda权限资源

resource "aws_lambda_permission" "lambdaApiGetStockPermission" {
  statement_id  = "AllowExecutionFromAPIGateway"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.lambdaApiGetStock.arn
  principal     = "apigateway.amazonaws.com"
  source_arn    = "arn:aws:execute-api:${var.region}:${var.aws_account_id}:${aws_api_gateway_rest_api.Api.id}/*/${aws_api_gateway_method.lambdaApiGetStock.http_method}${local.lambdaApiGetStockRoutePath}"
}

本地变量定义

locals {
  ...
  lambdaApiGetStockMethod      = "POST"
  lambdaApiGetStockRouteParent = aws_api_gateway_resource.ApiResourceGetStock.id
  lambdaApiGetStockRoutePath   = aws_api_gateway_resource.ApiResourceGetStock.path
  ...
}

API Gateway路径资源

resource "aws_api_gateway_resource" "ApiResourceGetStock" {
  rest_api_id   = aws_api_gateway_rest_api.Api.id
  parent_id     = aws_api_gateway_rest_api.Api.root_resource_id
  path_part     = "stockDispoOfArticle"
}

AWS Provider配置

provider "registry.terraform.io/hashicorp/aws" {
  version = "4.23.0"
  hashes = [
    "h1:JDJLmKK61GLw8gHQtCzmvlwPNZIu46/M5uBg/TDlBa0=",
    "zh:17adbedc9a80afc571a8de7b9bfccbe2359e2b3ce1fffd02b456d92248ec9294",
    "zh:23d8956b031d78466de82a3d2bbe8c76cc58482c931af311580b8eaef4e6a38f",
    "zh:343fe19e9a9f3021e26f4af68ff7f4828582070f986b6e5e5b23d89df5514643",
    "zh:6b8ff83d884b161939b90a18a4da43dd464c4b984f54b5f537b2870ce6bd94bc",
    "zh:7777d614d5e9d589ad5508eecf4c6d8f47d50fcbaf5d40fa7921064240a6b440",
    "zh:82f4578861a6fd0cde9a04a1926920bd72d993d524e5b34d7738d4eff3634c44",
    "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425",
    "zh:a08fefc153bbe0586389e814979cf7185c50fcddbb2082725991ed02742e7d1e",
    "zh:ae789c0e7cb777d98934387f8888090ccb2d8973ef10e5ece541e8b624e1fb00",
    "zh:b4608aab78b4dbb32c629595797107fc5a84d1b8f0682f183793d13837f0ecf0",
    "zh:ed2c791c2354764b565f9ba4be7fc845c619c1a32cefadd3154a5665b312ab00",
    "zh:f94ac0072a8545eebabf417bc0acbdc77c31c006ad8760834ee8ee5cdb64e743",
  ]
}

问题

修改API Gateway端点路径(及对应的source_arn)是否可行?若可行,有哪些解决方案可以使修改生效?

解决方案

1. 升级AWS Provider版本

第一个错误是AWS Provider 4.23.0的已知bug,后续版本已修复。建议升级到4.30.0及以上版本:

provider "registry.terraform.io/hashicorp/aws" {
  version = ">= 4.30.0"
}

2. 强化部署资源的依赖关系

第二个错误是部署时method、integration资源未完全就绪导致的。需要:

  • 确保aws_api_gateway_deployment的depends_on包含所有相关资源:
    depends_on = [
      aws_api_gateway_resource.ApiResourceGetStock,
      aws_api_gateway_method.lambdaApiGetStock,
      aws_api_gateway_integration.lambdaApiGetStock,
      // 其他关联资源
    ]
    
  • 替换timestamp()为路径相关的唯一值,确保路径修改时强制触发重新部署:
    variables = {
      deployed_at = sha1(aws_api_gateway_resource.ApiResourceGetStock.path_part)
    }
    

3. 拆分CI部署步骤

在GitLab CI中拆分部署流程,避免资源时序冲突:

  1. 先更新路径资源:terraform apply -target=aws_api_gateway_resource.ApiResourceGetStock -auto-approve
  2. 再更新方法和集成:terraform apply -target=aws_api_gateway_method.lambdaApiGetStock -target=aws_api_gateway_integration.lambdaApiGetStock -auto-approve
  3. 接着更新Lambda权限:terraform apply -target=aws_lambda_permission.lambdaApiGetStockPermission -auto-approve
  4. 最后执行完整部署:terraform apply -auto-approve

4. 修正Lambda权限的source_arn生成逻辑

当前source_arn依赖动态路径属性,易导致计划与应用阶段值不一致。直接拼接路径部分:

source_arn    = "arn:aws:execute-api:${var.region}:${var.aws_account_id}:${aws_api_gateway_rest_api.Api.id}/*/${local.lambdaApiGetStockMethod}/${aws_api_gateway_resource.ApiResourceGetStock.path_part}"

5. 临时绕过:先清理旧路径资源(谨慎操作)

若上述方法无效,可先删除旧路径相关资源(会导致旧路径临时不可用):

terraform destroy -target=aws_api_gateway_resource.旧路径资源名 -target=aws_api_gateway_method.旧方法名 -target=aws_api_gateway_integration.旧集成名 -target=aws_lambda_permission.旧权限名 -auto-approve

执行完成后再运行terraform apply部署新路径。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 11:50:46