Terraform渲染OpenAPI JSON配置AWS API网关时出现非预期变更
问题根因
出现非预期变更的核心原因有3个:
- 模板文件
routes.tpl写的是Terraform HCL对象结构,不是合法的OpenAPI JSON格式,templatefile渲染后输出的是HCL语法的普通字符串,根本不符合API网关要求的JSON结构 - 资源定义中对已经是字符串的模板渲染结果额外做了一次
jsonencode,等于把HCL格式的字符串二次编码成转义的JSON字符串,和云上现存的合法OpenAPI结构完全不匹配 - 模板里直接写了
var.rest_api_name,templatefile不会自动解析Terraform变量,你也没把这个变量传入模板渲染参数,最终渲染结果里直接保留了字面量var.rest_api_name,不会替换成实际的API名称
从plan输出可以看到,当前云上已存的资源body是包含/path1路径的合法OpenAPI结构,你传入的是未正确渲染的HCL字符串,所以Terraform判定要全量替换body内容。
修复步骤
1. 把routes.tpl改成合法的JSON模板
替换原有HCL结构的内容,所有待替换变量用${}占位,严格遵循JSON语法:
{ "openapi": "3.0.1", "info": { "title": "${rest_api_name}", "version": "1.0" }, "paths": { "/v1/alerts": { "get": { "x-amazon-apigateway-integration": { "httpMethod": "GET", "payloadFormatVersion": "1.0", "type": "HTTP_PROXY", "uri": "${url}" } } } } }
注意:JSON的键和字符串值必须用双引号包裹,不能用HCL的无引号写法
2. 修改main.tf的模块调用,补全模板参数
调用templatefile时把模板用到的rest_api_name变量一并传入:
module "api_gateway_new" { source = "../../../modules/api-gateway/new/" routes = templatefile("${path.module}/routes.tpl",{ url = "https://ip-ranges.amazonaws.com/ip-ranges.json" rest_api_name = "dev-api-gateway-fargate" }) }
3. 修改resource.tf,去掉多余的jsonencode
templatefile渲染后已经是合法的JSON字符串,直接传给body参数即可,不需要二次编码:
resource "aws_api_gateway_rest_api" "default" { body = var.routes name = "dev-api-gateway-fargate" endpoint_configuration { types = ["REGIONAL"] } }
验证说明
改完后重新执行terraform plan,body的变更会符合预期:
- 路径配置从原有
/path1更新为你配置的/v1/alerts - info.title会显示你传入的实际API名称,不会再出现字面量
var.rest_api_name - 不会再出现把HCL结构当字符串传入的异常
如果你需要保留原有已部署的
/path1路径,要把该路径的配置也加到routes.tpl的paths节点下,否则Terraform会删除这个路径的相关配置。
内容的提问来源于stack exchange,提问作者mohit
相关产品推荐
相关产品推荐

