我们正在通过Terraform创建API管理实例和相关端点。我们所有的API端点(接近100个)共享相同的策略逻辑,将请求路由到Azure函数。
策略示例如下-
resource "azurerm_api_management_api_operation_policy"
"api_put_policy" {
api_name = azurerm_api_management_api.my_api.name
resource_group_name = azurerm_resource_group.main.name
api_management_name = azurerm_api_management.my_api.name
operation_id = azurerm_api_management_api_operation.my_api.operation_id
xml_content = <<XML
<policies>
<inbound>
<base />
<choose>
<when condition="@(context.Request.Headers.GetValueOrDefault("Key") == "password")">
<set-backend-service base-url="${data.azurerm_function_app.MyFunctionApp.default_hostname}" />
</when>
<when condition="@(context.Request.Headers.GetValueOrDefault("Key") != null)">
<return-response>
<set-status code="400" reason="Bad Request" />
<set-body>An incorrect Key header has been passed in the request</set-body>
</return-response>
</when>
<otherwise>
<set-backend-service base-url="${other-route-variable}" />
</otherwise>
</choose>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
所以我们在每个API端点上使用相同的XML_content,只是变量的设置不同,这取决于应用程序将被路由到的函数。
是否有一种方法可以将此xml内容移动到一个文件中,其中参数可以通过,然后为每个API策略生成xml,以便我们将逻辑存储在一个地方?
我看了各种各样的文件()函数的使用但什么也看不见,可以实现我所需要的东西。
感谢是的,您可以使用templatefile
函数[1]。templatefile
函数的工作方式如下:
templatefile(路径,var)
其中path
表示文件位置,vars
是将用于替换文件本身中的占位符的变量映射。我将根据您拥有的XML文件给出一个示例。首先,您可能会在同一目录中创建模板文件(例如,xml_content.tpl
):
<policies>
<inbound>
<base />
<choose>
<when condition="@(context.Request.Headers.GetValueOrDefault("Key") == ${password})">
<set-backend-service base-url="${hostname_url}" />
</when>
<when condition="@(context.Request.Headers.GetValueOrDefault("Key") != null)">
<return-response>
<set-status code="400" reason="Bad Request" />
<set-body>An incorrect Key header has been passed in the request</set-body>
</return-response>
</when>
<otherwise>
<set-backend-service base-url="${other-route-variable}" />
</otherwise>
</choose>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
注意,我删除了password
值和url
中的数据源输出。那些将现在预期password
这样的变量名和hostname_url
提供当使用templatefile
功能:
resource "azurerm_api_management_api_operation_policy" "api_put_policy" {
api_name = azurerm_api_management_api.my_api.name
resource_group_name = azurerm_resource_group.main.name
api_management_name = azurerm_api_management.my_api.name
operation_id = azurerm_api_management_api_operation.my_api.operation_id
xml_content = templatefile("${path.root}/xml_content.tpl",
password = var.password
hostname_url = data.azurerm_function_app.MyFunctionApp.default_hostname
)
}
无论何时调用,它都会查找占位符值并替换它们。还有两件事需要注意:
在当前的设置中,
"${other-route-variable}"
需要在templatefile
函数调用中提供,否则会失败。path.root
选项是内置在Terraform[2]。
从理论上讲,如果您要以此为基础创建一个模块以使其更具可移植性,那么您只需将path
更改为文件,以便可能通过变量提供它。
[1] https://www.terraform.io/language/functions/templatefile
[2] https://www.terraform.io/language/expressions/references filesystem-and-workspace-info