Create request rate limiting for all API instances under APIM - azure

Is it possible to create a policy that limites request rate over a period for all API instances?
Can the policy below be used for the requirement?
Please note I want the policy to be define in one place (global, that is, "All APIs"), not repeated for every API instance.
<policies>
<inbound>
<base />
<rate-limit calls="20" renewal-period="90" />
</inbound>
<outbound>
<base />
</outbound>
</policies>
Policy sections: inbound
Policy scopes: product
https://learn.microsoft.com/en-us/azure/api-management/api-management-access-restriction-policies#LimitCallRate

yes. You can add this policy inside "ALL APIS" policy section. It will get effect for all the APIs. Its's correct

Related

Set Response Header With remaining-calls Azure API Management

I'm using Azure API Management with some rate limiting based on subscription. I need to send to the user in the response headers the number of remaining calls. I know that I should set some values in the outbound policy but I do not know how to do it exactly. This is my policy XML if any one can help.
<policies>
<inbound>
<base />
<set-variable name="remainingCalls" value="remaining-calls-variable-name" />
<quota-by-key calls="5" renewal-period="86400" counter-key="#(context.Subscription?.Key ?? "anonymous")" increment-condition="#(context.Response.StatusCode >= 200 && context.Response.StatusCode < 300)" />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
<set-header name="remainingCalls" exists-action="append">
<value>#(context.Response.Headers.GetValueOrDefault("remaining-calls-header-name","2"))</value>
</set-header>
</outbound>
<on-error>
<base />
</on-error>
</policies>
As per the Azure Documentation, You can set rate-limit by subscription only in inbound section & the policy scope should be either product, api or operation.
Here is the sample example, where the per subscription rate limit is 30 calls per 90 seconds. After each policy execution, the remaining calls allowed in the time period are stored in the variable remainingCallsPerSubscription.
<policies>
<inbound>
<base />
<rate-limit calls="30" renewal-period="90" remaining-calls-variable-name="remainingCallsPerSubscription"/>
</inbound>
<outbound>
<base />
</outbound>
</policies>
Note: This policy can be used only once per policy document.
Policy expressions cannot be used in any of the policy attributes for this policy.
I've contacted Microsoft Azure support for this request and they were able to guid me to a possible workaround that may be helpful and in my particular use case it is good solution. For quota policy and as mentioned by #Venkatesh-MAT it is not supported to retrieve remaining quota information in response header as rate-limit policy. However there is a separate REST API for this purpose. This is documentation for the same https://learn.microsoft.com/en-us/rest/api/apimanagement/current-ga/quota-by-counter-keys/list-by-service.
The API in this documentation requires bearer token as authentication. To be able to generate the bearer token you can simply use azure cli to get token for the resource using command az account get-access-token --resource https://management.azure.com or if you need to do it programmatically you have to follow below steps:
Set principle role using azure cli with subscription scope to create service principle that have access on this resource scope (az ad sp create-for-rbac -n "principle-1" --role contributor –scopes /subscriptions/{subscriptionID}/resourceGroups/{resourcegroup}/providers/Microsoft.ApiManagement/service/{API management Service name} /quotas/{subscription key})
Use Client ID, client secret & tenant ID generated from above step to call this API https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token with body type x-www-form-urlencoded and body key value as below
KEY: grant_type VALUE: client_credentials
KEY: client_id VALUE: appid generated from step number 1
KEY: scope VALUE: https://management.azure.com/.default
KEY: client_secret VALUE: password generated from step number 1
Then use the output access token to get quota policy consumption.

Can I call different backend on Azure API Management

I am trying to achieve that, when I call an APIM Endpoint based on the request headers It should different endpoint. for e.g when user call https://test.azure-api.net/testsvc-dev/api/test APIM should be able to send the request to https://testappv1:80/test or https://testappv2:80. right now I can see in the serviceURL, I can add only one. Is there any policy that I can use to do these kind of operations.
little more context: I am trying to access two different version of API on a single call. Instead of caller choosing which one to call,I am trying to make the APIM to decide based on the user.
You are probably looking for the set-backend-service policy.
Here an example from the Microsoft docs that changes the backend service based on a query parameter:
<policies>
<inbound>
<choose>
<when condition="#(context.Request.Url.Query.GetValueOrDefault("version") == "2013-05")">
<set-backend-service base-url="http://contoso.com/api/8.2/" />
</when>
<when condition="#(context.Request.Url.Query.GetValueOrDefault("version") == "2014-03")">
<set-backend-service base-url="http://contoso.com/api/9.1/" />
</when>
</choose>
<base />
</inbound>
<outbound>
<base />
</outbound>
</policies>
Certainly, you could adopt the sample and query for the desired headers ;-)

Azure APIM as pure proxy

I am trying to deal with an Backend API(REST) with no swagger documents to be accessed through Azure APIM.
I want all the calls directed to the Backend API with me not manually creating GET/PUT/POST for all the resources. My inbound policies for all operations is below
'
<policies>
<inbound>
<set-variable name="requestPath" value="#(context.Request.Url.Path)" />
<base/>
<set-backend-service base-url="https://*****/****/" />
<rewrite-uri template="#(context.Request.Url.Path)" copy-unmatched-params="true" />
</inbound>
<backend>
<base/>
</backend>
<outbound>
<base/>
</outbound>
</policies>
`
However when hit the APIM i was given
{
"statusCode": 404,
"message": "Resource not found"
}
Any help is appreciated Thanks
The easy way to do this is to create one operation for each HTTP method you support and use /* for the template. This will match any inbound path/query and forward it to the backend.

How can I modify Azure API base policy without completely overwriting it?

In Azure API Management, I'm trying to modify the CORS policy for a single route within the API. The problem I'm having is that I can't figure out how to modify the BASE policy. Azure seems to simply override it with the new policy.
Simple BASE policy:
<policies>
<inbound>
<cross-domain>
<cross-domain-policy>
<allow-http-request-headers-from domain="*" headers="*" />
</cross-domain-policy>
</cross-domain>
<cors>
<allowed-origins>
<origin>*</origin>
</allowed-origins>
<allowed-methods>
<method>*</method>
</allowed-methods>
<allowed-headers>
<header>*</header>
</allowed-headers>
</cors>
</inbound>
<backend>
<forward-request />
</backend>
<outbound>
</outbound>
</policies>
In the specific route, I want to modify the <cors> section to include one more policy, like this:
<policies>
<inbound>
<base />
<cors>
<expose-headers>
<header>Content-Disposition</header>
</expose-headers>
</cors>
</inbound>
</policies>
However, Azure wants to override the base CORS policy with this one. I can't find anything in the documentation about how to just modify/merge a policy rather than wholesale replacing it.
So, how would I inherit the base policy but just add this one additional <expose-headers> policy?
That is not possible at the moment. They way policies work is once request scope is defined (product, API and operation are matched) the policy is constructed by replacing all tags with a policy from the upper level. Resulting effective policy is just a flat list of statements that are executed one after another. In that sense you have no control over parent policy on lower level.
But you can always insert things before parent policy is executed. For that just place another fully specified CORS policy before tag and in resulting policy it will be executed first.
Having multiple CORS policies per effective policy is fine, they'll be executed one after another and first one that is capable of handling CORS call (origin, method, headers match) will take action.

Are there rest calls for these Api Management actions?

Say I want to automate API Management, I would want to
Create Api (https://learn.microsoft.com/en-us/rest/api/apimanagement/apis#Apis_CreateOrUpdate)
Create certificate (https://learn.microsoft.com/en-us/rest/api/apimanagement/certificates#Certificates_CreateOrUpdate)
Tie certificate to API (¿?)
Create API Policy (¿?)
I've went through all the calls one by one, and wasn't able to identify anything meaningful.
edit: or a confirmation that this is not yet possible with the API.
edit: looking at the swagger definition of ApiManagement, I don't think its there?
edit: exported configuration to Git, doesn't look like it contains the cert, so this also wouldn't help?
The client Certificate is not represented in the model of the ApiContract. When you want to tie a Certificate to an API, we create a policy authentication certificate policy in the API Scope.
<policies>
<inbound>
<base />
<authentication-certificate thumbprint="***19B22E********5E2E**820" />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
You can create an API Policy using https://learn.microsoft.com/en-us/rest/api/apimanagement/apimanagementrest/azure-api-management-rest-api-api-entity#SetAPIPolicy

Resources