azureazure-api-managementterraform-provider-azurepolicy

Azure API Management Policy: Unable to add condition to check it the string is empty


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"}]


Solution

  • 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.

    enter image description here

    enter image description here