I needed options for restricting the surface area of the Elasticsearch API for clients. I wanted to ensure only the search API was permitted e.g. urls containing "/_search". I could have used NGINX's rewrite or redirect functionality however my customer wanted a managed service if possible. Azure API Management (APIM) was another option but we needed to deploy internally to a Virtual Network and that would require the Premium tier for Production which was a bit much for this particular workload. Instead, I found Azure App Gateway to be a good option so this post is about what I had to do to get it working.
I had to start with a couple of empty subnets in a Virtual Network. I needed a custom DNS server for my VNET to resolve the various endpoints and I decided to use a developer tier APIM instance to emulate Elasticsearch back-end. I used the default domains, azure-api.net for the back-end so I registered the following A records (mcapim is the APIM name and 10.100.3.5 is the private IP address for it in its own subnet).
I should point out that these DNS records should be CNAMEs since the IP address can change under certain circumstances but I'm only doing a PoC here.
Follow the guide for installing APIM in a VNET. You can find an example script that creates both the APIM and gateway here but you'll need to have a VNET with two empty subnets.
The App Gateway is an Internal Load Balanced (ILB) gateway configured to take incoming requests (1) in the form...
And change the URL (2) before requesting the APIM back-end pool. Anyone that knows APIM will probably recognise that the rewritten path (2) is the Echo API that comes out-of-the-box.
Any other paths default to a "blackhole" back-end pool which causes a 502 Bad Gateway but should really be a nice error page instead (this can be set on the gateway's path-based Rule).
This deployment is end-to-end SSL but I only needed to upload a (wildcard) certificate for the front-end, *.admuk.net, since the back-end is azure-api.net so it's already whitelisted (you'll see the authentication certificate is commented out). I've included commented code in the script if you need to create self-signed certs for the front-end. I've also commented some logic if the back-end APIM needs custom domains in case that's useful to someone.
I didn't want a public endpoint for the workload so in this case the V2 tier for App Gateway is not an option because it requires a public endpoint be configured. I had to use a V1 SKU so I chose one that gave me the WAF...
$sku = New-AzApplicationGatewaySku -Name "WAF_Medium" -Tier "WAF" -Capacity 1
A single instance App Gateway with Developer tier APIM deployed in North Europe cost me about $5.50 per day so pretty reasonable.
Please note that this is purely PoC based activity and the approach detailed above will need some testing to confirm its suitability for my scenario. But so far so good.