无法在我部署的 Azure api 管理器中应用策略
Unable to apply a policy inside of the my deployed Azure api manager
在我的 apim 中尝试为我的操作部署策略时,我无法实施我的策略。
错误日志
Error: creating or updating API Policy (Resource Group "rg-opendata-dev" / API Management Service "apimopendata-dev" / API "apim-opendata-dev"): apimanagement.APIPolicyClient#CreateOrUpdate: Failure responding to request: StatusCode=400 -- Original Error: autorest/azure: Service returned an error. Status=400 Code="ValidationError" Message="Entity with specified identifier not found"
│
│ with azurerm_api_management_api_policy.apipolicy,
│ on main.tf line 78, in resource "azurerm_api_management_api_policy" "apipolicy":
│ 78: resource "azurerm_api_management_api_policy" "apipolicy" {
│
╵
我不明白这个,因为我很确定我写的变量是正确的,
还是我给变量取错了名字?
您是否也认为使用如下所示的 xml 代码添加策略是部署策略的正确方法?
main.tf 文件的一部分
resource "azurerm_api_management_api" "api" {
name = "apim-opendata-${var.env}"
resource_group_name = data.azurerm_resource_group.rg.name
api_management_name = azurerm_api_management.apim.name
revision = "1"
display_name = "${var.display_name}"
service_url = "${var.service_url}"
protocols = ["https"]
}
resource "azurerm_api_management_api_operation" "apioperation" {
operation_id = "get-data"
api_name = azurerm_api_management_api.api.name
api_management_name = azurerm_api_management.apim.name
resource_group_name = data.azurerm_resource_group.rg.name
display_name = "Get Data"
method = "GET"
url_template = "/"
description = "Get data inside of the container"
response {
status_code = 200
}
}
resource "azurerm_api_management_api_policy" "apipolicy" {
api_name = azurerm_api_management_api.api.name
api_management_name = azurerm_api_management.apim.name
resource_group_name = data.azurerm_resource_group.rg.name
xml_content = <<XML
<policies>
<inbound>
<set-variable name="ContainerName" value="@(context.Request.Headers.GetValueOrDefault("Container"))" />
<set-variable name="BlobName" value="@(context.Request.Headers.GetValueOrDefault("Blob"))" />
<base />
<set-header name="Blob" exists-action="delete" />
<set-header name="Container" exists-action="delete" />
<set-header name="x-ms-version" exists-action="override">
<value>@{string version = "2017-11-09"; return version;}</value>
</set-header>
<set-backend-service base-url="@{
string containerName = context.Variables.GetValueOrDefault<string>("ContainerName");
string blobName = context.Variables.GetValueOrDefault<string>("BlobName");
return String.Format("https://${var.storage_account_name}.blob.core.windows.net/{0}/{1}", containerName, blobName);
}" />
<authentication-managed-identity resource="https://storage.azure.com/" />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
XML
}
问题可能是因为没有设置 base-URL & Backend-id 属性,在这种情况下 API Manager 服务没有检测到使用 id 的后端组件.所以我们需要同时指定 base-URL 和 backend-id.
的解决方案
如果您仍然遇到问题,请检查以下步骤:
此策略将调用路由到两个后端服务中最近的一个,并在返回 HTTP 404 时故障转移到辅助服务。
假设 API 管理器部署在 'East US' 和 'West Europe'。类似地,策略(按原样)假设在相同区域有两个后端服务,可见:
https://hello-eus.azurewebsites.net/
(美国东部);和
https://hello-weu.azurewebsites.net/
(西欧)
如果后端服务返回失败 (HTTP 404),该策略会将调用重新路由到故障转移区域。
该策略使用缓存值来跟踪哪个服务在过去 10 秒内返回了错误,以避免将新请求路由到可能会失败的后端。
<retry condition="@(context.Response.StatusCode == 404)" count="2" interval="1" max-interval="10" delta="1" first-fast-retry="true">
使用重试策略中的逻辑参考here
参考here
在我的 apim 中尝试为我的操作部署策略时,我无法实施我的策略。
错误日志
Error: creating or updating API Policy (Resource Group "rg-opendata-dev" / API Management Service "apimopendata-dev" / API "apim-opendata-dev"): apimanagement.APIPolicyClient#CreateOrUpdate: Failure responding to request: StatusCode=400 -- Original Error: autorest/azure: Service returned an error. Status=400 Code="ValidationError" Message="Entity with specified identifier not found"
│
│ with azurerm_api_management_api_policy.apipolicy,
│ on main.tf line 78, in resource "azurerm_api_management_api_policy" "apipolicy":
│ 78: resource "azurerm_api_management_api_policy" "apipolicy" {
│
╵
我不明白这个,因为我很确定我写的变量是正确的, 还是我给变量取错了名字?
您是否也认为使用如下所示的 xml 代码添加策略是部署策略的正确方法?
main.tf 文件的一部分
resource "azurerm_api_management_api" "api" {
name = "apim-opendata-${var.env}"
resource_group_name = data.azurerm_resource_group.rg.name
api_management_name = azurerm_api_management.apim.name
revision = "1"
display_name = "${var.display_name}"
service_url = "${var.service_url}"
protocols = ["https"]
}
resource "azurerm_api_management_api_operation" "apioperation" {
operation_id = "get-data"
api_name = azurerm_api_management_api.api.name
api_management_name = azurerm_api_management.apim.name
resource_group_name = data.azurerm_resource_group.rg.name
display_name = "Get Data"
method = "GET"
url_template = "/"
description = "Get data inside of the container"
response {
status_code = 200
}
}
resource "azurerm_api_management_api_policy" "apipolicy" {
api_name = azurerm_api_management_api.api.name
api_management_name = azurerm_api_management.apim.name
resource_group_name = data.azurerm_resource_group.rg.name
xml_content = <<XML
<policies>
<inbound>
<set-variable name="ContainerName" value="@(context.Request.Headers.GetValueOrDefault("Container"))" />
<set-variable name="BlobName" value="@(context.Request.Headers.GetValueOrDefault("Blob"))" />
<base />
<set-header name="Blob" exists-action="delete" />
<set-header name="Container" exists-action="delete" />
<set-header name="x-ms-version" exists-action="override">
<value>@{string version = "2017-11-09"; return version;}</value>
</set-header>
<set-backend-service base-url="@{
string containerName = context.Variables.GetValueOrDefault<string>("ContainerName");
string blobName = context.Variables.GetValueOrDefault<string>("BlobName");
return String.Format("https://${var.storage_account_name}.blob.core.windows.net/{0}/{1}", containerName, blobName);
}" />
<authentication-managed-identity resource="https://storage.azure.com/" />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
XML
}
问题可能是因为没有设置 base-URL & Backend-id 属性,在这种情况下 API Manager 服务没有检测到使用 id 的后端组件.所以我们需要同时指定 base-URL 和 backend-id.
如果您仍然遇到问题,请检查以下步骤:
此策略将调用路由到两个后端服务中最近的一个,并在返回 HTTP 404 时故障转移到辅助服务。
假设 API 管理器部署在 'East US' 和 'West Europe'。类似地,策略(按原样)假设在相同区域有两个后端服务,可见:
https://hello-eus.azurewebsites.net/
(美国东部);和
https://hello-weu.azurewebsites.net/
(西欧)
如果后端服务返回失败 (HTTP 404),该策略会将调用重新路由到故障转移区域。
该策略使用缓存值来跟踪哪个服务在过去 10 秒内返回了错误,以避免将新请求路由到可能会失败的后端。
<retry condition="@(context.Response.StatusCode == 404)" count="2" interval="1" max-interval="10" delta="1" first-fast-retry="true">
使用重试策略中的逻辑参考here
参考here