I am still working on an API Manager DR scenario for a client. After automating the backup and restore process, to make sure that the APIM instances are always in sync, I needed to setup Traffic Manager in priority mode to distribute the calls between the main and secondary instances.
Traffic Manager setup seemed quite straightforward. You just need to create a traffic manager endpoint for each API Manager Instance, using the external endpoint.
Creating that for each endpoint should do the trick… Or so I thought. After that setup was complete, testing the endpoint always returned 503, even though access each individual endpoint was returning the correct result.
Searching for this error, took me to a MSDN Forum question, where I found that API Manager will only reply to an endpoint with a hostname that is registered on it (probably to avoid man in the middle kind of attacks).
So in order to get this working, I would need a custom domain and a valid certificate associated to that certificate. Once I had that, what I needed to do was:
- Create a CNAME entry on my domain DNS Server that redirected the custom domain to the traffic manager profile.
- Create a custom domain for the proxy endpoint for each APIM instance.
Again, second part looked quite straighforward, right? It was, until I found that the Add functionality is not enable in the portal (or at least is not enabled to my DEV instances – at this stage I am not sure if it is a bug in the portal or a restriction on that particular instance, since the option is there, but unavailable).
That is where powershell comes to the rescue. The following script allow you to create a proxy endpoint, as long as you have a valid certificate to associate to it:
#Azure specific details
$resourceGroupName = "<APIM_Resource_Group>"
$subscriptionId = "<APIM_Resource_Group>"
# Api Management service specific details
$apimServiceName = "<APIM_Service Intance>"
# Certificate related details
$proxyHostname = "<proxy hostname e.g. myapim.mydomain.com>"
# Certificate for your custom domain
$proxyCertificatePath = "<location of proxy certificate on local computer in pfx format>"
$proxyCertificatePassword = "<pfx certificate password>"
$proxyCertThumbprint = "<certificate thumbprint>"
#Guarantee that the correct subscription is selected as context
Select-AzureRmSubscription -SubscriptionID $subscriptionId
# Upload the custom ssl certificate to be applied to Proxy endpoint / Api Gateway endpoint
$proxyCertUploadResult = Import-AzureRmApiManagementHostnameCertificate -Name $apimServiceName -ResourceGroupName $resourceGroupName `
-HostnameType "Proxy" -PfxPath $proxyCertificatePath -PfxPassword $proxyCertificatePassword
$ProxyHostNameConf = New-AzureRmApiManagementHostnameConfiguration -Hostname $proxyHostname -CertificateThumbprint $proxyCertThumbprint
Set-AzureRmApiManagementHostnames -Name $apimServiceName -ResourceGroupName $resourceGroupName -PortalHostnameConfiguration $PortalHostnameConf -ProxyHostnameConfiguration $ProxyHostnameConf
Using the script above will allow you to create a custom domain hostname for your APIM instance proxy endpoint, while maintaining the original endpoint (which is not possible to do using the portal).
You should run this script for each endpoint, so both instances will accept the calls when it is redirected to it.
Once I had this setup, I was then able to send messages to each endpoint.
To make sure I could test the setup, I created a probe API endpoint using mock to return a 200 OK response. To simulate a failure, I simply changed the mock response to 500, degrading that endpoint and routing the traffic to the secondary endpoint.
If you are setting up a traffic manage solution for your API Management instances and got stuck on a 503 response, remember that you need to wrap the whole solution with a custom domain, by:
- Adding a custom domain for the proxy endpoint on each API Management instance.
- Setup a CNAME entry on your DNS Server to point the custom domain to your traffic management endpoint.