I'm adding policy for APIs, I have many APIs onboarded and want to add API specific policies. I am adding rate limit as per the API owner request sent in a config file, Some APIs provide rate limit and some not. At the same time APIs use different authontication too(JWT ot subscription_id). I want to add condition in policy that if rate limit is given by API owner and API is validated by jwt/subscription_id then add given rate limit if not then dont do anything. I tried below code
<policies>
<inbound>
<set-variable name="isjwt" value="@(context.Request.Headers.GetValueOrDefault('Authorization', '').AsJwt()?.Subject)" />
<set-variable name="isSubId" value="@(context.Subscription.Id)" />
<choose>
<when condition="(${var.api.rate_limit} != "" and (context.Variables["isjwt"] != null or context.Variables["isSubId"] != null))">
<rate-limit-by-key calls=${var.api.rate_limit} renewal-period="60" counter-key="@(context.Variables["isjwt"] ?? context.Variables["isSubId"])" />
</when>
</choose>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
variable "api" {
type = object({
name = string
rate_limit = string
})
}
The terraform plan looks like this
+ <set-variable name="isAuthenticated" value="@(context.Request.Headers.GetValueOrDefault('Authorization', '').AsJwt()?.Subject)" />
+ <set-variable name="hasSubscriptionId" value="@(context.Subscription.Id)" />
+
+ <choose>
+ <when condition="( != "" and (context.Variables["isjwt"] != null or context.Variables["isSubId"] != null))">
+ <rate-limit-by-key calls="" renewal-period="60" counter-key="@(context.Variables["isjwt"] ?? context.Variables["isSubId"])" />
+ </when>
+ </choose>
I get error at condition var.api.rate_limit != ""
I tried adding single quates it doesn't help,
Error: creating/updating Api Policy: (Policy Name "xml" / Api Name "APINAME" / Service Name "SERVICENAME" / Resource Group "RGNAME"): apimanagement.APIPolicyClient#CreateOrUpdate: Failure responding to request: StatusCode=400 -- Original Error: autorest/azure: Service returned an error. Status=400 Code="ValidationError" Message="One or more fields contain incorrect values:" Details=[{"code":"ValidationError","message":"Name cannot begin with the '"' character, hexadecimal value 0x22. Line 36, position 52.","target":"representation"}]
Azure API Management Policy: Unable to add condition to check it the string is empty: -
Use below modified policy to resolve your conflict on quotes("
).
resource "azurerm_api_management_api_operation_policy" "example" {
api_name = azurerm_api_management_api_operation.example.api_name
api_management_name = azurerm_api_management_api_operation.example.api_management_name
resource_group_name = azurerm_api_management_api_operation.example.resource_group_name
operation_id = azurerm_api_management_api_operation.example.operation_id
xml_content = <<XML
<policies>
<inbound>
<set-variable name="isjwt" value="@(context.Request.Headers.GetValueOrDefault('Authorization', '').AsJwt()?.Subject)" />
<set-variable name="isSubId" value="@(context.Subscription.Id)" />
<choose>
<when condition='(${var.api.rate_limit} != "" and (context.Variables["isjwt"] != null or context.Variables["isSubId"] != null))'>
<rate-limit-by-key calls="${var.api.rate_limit}" renewal-period="60" counter-key="@(context.Variables["isjwt"] ?? context.Variables["isSubId"])" />
</when>
</choose>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
XML
}
Referring to the template of azurerm_api_management_api_operation_policy
from terraform registry, I tried deploying your requirement by adding the above policy and it worked successfully as shown below.