修改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中拆分部署流程,避免资源时序冲突:
- 先更新路径资源:
terraform apply -target=aws_api_gateway_resource.ApiResourceGetStock -auto-approve - 再更新方法和集成:
terraform apply -target=aws_api_gateway_method.lambdaApiGetStock -target=aws_api_gateway_integration.lambdaApiGetStock -auto-approve - 接着更新Lambda权限:
terraform apply -target=aws_lambda_permission.lambdaApiGetStockPermission -auto-approve - 最后执行完整部署:
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
相关产品推荐
相关产品推荐

