Deploy Azure Self Hosted Gateway to Docker

Deploy Azure Self Hosted Gateway to Docker
A self hosted gateway through Azure APIM allows to more strictly control where clients send their traffic to when consuming APIs - Photo by Tianshu Liu / Unsplash

The Azure API Management service allows you to host an API Gateway on your own infrastructure on premises without API requests going into Azure first. You might want to do so for compliance reasons, minimising request traffic into Azure itself and related costs, or simply streamlining how you operate your API systems and giving you finer control.

Self hosting a gateway in the context of Azure presents itself as a Docker container that you run on your own servers and your request traffic goes there. However the management of the API service (Management Plane) remains in the Azure Portal. The APIs themselves can live on premises, in Azure or even other clouds (almost anywhere). Let's observe how we can set up an Azure self hosted API gateway to use on our own environment on premises. In this blog post, we will be focussing on deploying to Docker and using APIs that run in Azure. After completion, we will remember to DELETE the unused resources in Azure (APIM resource).

Create APIM Resource

First, create a Developer Tier APIM Service in Azure which will give us access to the Self Hosted Gateway feature (also available on the Premium Tier). Next we will pull, configure and run the container for the self hosted gateway. Then we will need to add and expose APIs to consume under our gateway.

Pull official Self Hosted Gateway Docker Image

After creating our APIM resource, pull the latest image from Microsoft with the following docker pull command to have ready locally on your machine:

docker pull mcr.microsoft.com/azure-api-management/gateway:latest
Pull the image from Microsoft's repository

The pull command should complete.

Create Azure Self Hosted Gateway Deployment Template

In the Azure Portal, go to your Developer Tier or Premium Tier API Management resource. Then go to Gateways under Deployments and Infrastructure and Click Add, and set your deployment Name and Location (don't add APIs just yet, discussed shortly), then click Add. This will shortly assist Azure identify and recognise our gateway on premises in the cloud:

Give a name for your self hosted gateway for Azure to identify (the location here does not need to be an Azure region name)

After creating this Deployment template in Azure, drill down into the deployment instance you just made by clicking on the name. You should now see a blade with an access Token (that uses the alias we set previously) and also for a docker run command to connect and authorise your self hosted gateway container .. to the APIM instance in Azure. We will use this in the next section. Also focussing on the Docker Tab on this page, you will see the contents to add to a env.conf file to set some configuration values for the container:

Deployment blade for a self hosted gateway with docker Run command

Create and Run Docker Container

Before you can run the Docker container you need to place or create/save a env.conf file with the contents shown in the your Environment box, at the same folder location where you will be executing your docker run command. So for example if I am intending to build and run the docker run command at C:/Batsirai/Dev, I will need to create C:/Batsirai/Dev/env.conf as the docker run command references a env.conf file at the same path.

After creating and saving the file, now run the docker run command shown in your Deployment page, making sure that no other applications are using the stated ports (if you are running other applications on these ports, you may a get a 'Ports not available Error'). I always like to just change it to another port (8077 in my case) to avoid any conflicts (the https port mapping (443) is not necessary for this demo):

docker run -d -p 8077:8080 --name nameofyourGateWay --env-file env.conf mcr.microsoft.com/azure-api-management/gateway:v2

docker run command for self hosted gateway (without https port mapping)

Your container should start running your gateway

If you set the env.conf details as outlined in your Deployment page and run the container successfully, you should then see 1 instance alive in your Azure portal in the Gateways section upon refreshing. Be careful and avoid re-using the same env.conf file for different instances of gateways like I did 😐:

You should see this upon running the container and refreshing Azure

Add and Expose APIs

Once the self hosted gateway is running as a docker container, you are now free to Add then Expose specific APIs you want to be used under the gateway. If your APIs are running in Azure, you can add them as you would normally would under APIM instance> APIs>Add API.

In my case I added an existing Azure Function as an API (which I wrote about in a previous post here dealing with the Monitor Pattern in Azure Functions).When adding your API, you can use any of the options available as you would normally such as OpenAPI APIs. I then changed the URL Scheme to HTTP(S) from the default HTTPS to match the requirements of the container which was only mapped on the http port as shown before. Then I purposefully removed the requirement for an Ocp-Apim-Subcription-Key to make testing within a web browser slightly easier (if set to ON, this key can be sent as a request parameter). Below, notice the self hosted gateway tag added on Gateways(more on this shortly). And finally I saved the configuration, making the Function available for the self hosted gateway (but not yet exposed for use):

Adding and Configuring the API settings in the APIM Configurator

Now to properly make sure the APIs that you added are properly exposed on the self hosted gateway, go to Gateways, then click on your gateway instance, then APIs, Add , then select your API you added in the APIM configuration before (the echo-api is added by default). In my case, it's my Azure Function that I added:

Adding custom APIs for exposure for the self hosted gateway

Testing and Result

By going to the localhost on the host port we set during the docker run command, we can allow a local client to consume our API without the client's outbound traffic going out to Azure. Here is my example with a browser (Postman works too) using port 8077 and consuming my Function API that lives in Azure through the self hosted gateway.

using a self hosted gateway to consume an API in Azure

Conclusions

It is important to remember that when using the Self hosted gateway, the APIs themselves can be hosted on premises, in Azure or in other clouds. We use a self hosted gate way to have stricter control over how and where our clients send their traffic. Happy learning!!.