Terraform部署AWS API Gateway报Invalid model identifier:Empty错误
报错Invalid model identifier specified: Empty是因为模块硬编码在response_models中引用了名为Empty的API Gateway模型,但当前正在创建的REST API实例下不存在该模型,AWS API侧校验不通过。squidfunk/api-gateway-enable-cors/aws 0.3.3版本默认给OPTIONS预检响应的200状态码配置了application/json映射到Empty模型的规则,存在两个明显问题:
- 如果你是通过OpenAPI声明(
aws_api_gateway_rest_api资源的body参数)创建的API,AWS不会自动生成Empty、Error这类内置默认模型 - CORS预检的OPTIONS响应本身只需要返回跨域头,不需要携带JSON格式响应体,默认绑定模型的逻辑本身是冗余的
其他同配置项目能正常部署,一般是因为那些API是通过控制台/纯Terraform资源方式创建,AWS自动初始化了内置Empty模型,或是之前的部署流程已经提前创建过该模型。
按优先级选择以下方案即可:
方案1(优先推荐,无侵入)
直接给模块传入response_models参数覆盖默认的错误硬编码配置,去掉冗余的模型绑定,修改后的模块配置如下:
module "corslambdaApiHelloWorld" { source = "squidfunk/api-gateway-enable-cors/aws" version = "0.3.3" api_id = aws_api_gateway_rest_api.Api.id api_resource_id = aws_api_gateway_resource.ApiResourceHelloWorld.id allow_methods = ["GET"] # 覆盖默认配置,移除冗余的Empty模型引用 response_models = {} }
修改后OPTIONS方法响应将不会绑定多余的JSON模型,完全符合CORS预检响应的规范,不会影响跨域逻辑。
方案2(需要保留响应模型时使用)
如果业务确实需要给OPTIONS响应绑定JSON模型,手动在配置中定义缺失的Empty模型,再让模块依赖该模型即可:
# 手动补全API Gateway的Empty默认模型 resource "aws_api_gateway_model" "empty" { rest_api_id = aws_api_gateway_rest_api.Api.id name = "Empty" description = "Default empty response model" content_type = "application/json" schema = jsonencode({ "$schema" = "http://json-schema.org/draft-04/schema#" title = "Empty Schema" type = "object" }) } module "corslambdaApiHelloWorld" { source = "squidfunk/api-gateway-enable-cors/aws" version = "0.3.3" api_id = aws_api_gateway_rest_api.Api.id api_resource_id = aws_api_gateway_resource.ApiResourceHelloWorld.id allow_methods = ["GET"] # 确保模型创建完成后再部署CORS配置 depends_on = [aws_api_gateway_model.empty] }
方案3
升级cors模块到0.4.0及以上版本,新版本已经修复了硬编码Empty模型的问题,升级前注意核对模块变量的兼容性即可。
配置修改完成后,本地执行terraform plan,查看输出中module.corslambdaApiHelloWorld.aws_api_gateway_method_response._资源的response_models字段:
- 如果用方案1,该字段值为空map
- 如果用方案2,该字段能正确引用已存在的Empty模型
确认计划无异常后再执行apply即可正常完成部署。
内容的提问来源于stack exchange,提问作者prout

