|
| 1 | +--- |
| 2 | +title: Deploy a self-hosted gateway to Azure Container Apps - Azure API Management |
| 3 | +description: Learn how to deploy a self-hosted gateway component of Azure API Management to an Azure Container Apps environment. |
| 4 | +author: dlepow |
| 5 | +ms.service: api-management |
| 6 | +ms.topic: article |
| 7 | +ms.date: 03/04/2024 |
| 8 | +ms.author: danlep |
| 9 | +--- |
| 10 | + |
| 11 | +# Deploy an Azure API Management self-hosted gateway to Azure Container Apps |
| 12 | + |
| 13 | +This article provides the steps to deploy the [self-hosted gateway](self-hosted-gateway-overview.md) component of Azure API Management to [Azure Container Apps](../container-apps/overview.md). |
| 14 | + |
| 15 | +Deploy a self-hosted gateway to a container app to access APIs that are hosted in the same Azure Container Apps environment. |
| 16 | + |
| 17 | +[!INCLUDE [api-management-availability-premium-dev](../../includes/api-management-availability-premium-dev.md)] |
| 18 | + |
| 19 | +## Prerequisites |
| 20 | + |
| 21 | +- Complete the following quickstart: [Create an Azure API Management instance](get-started-create-service-instance.md). |
| 22 | + |
| 23 | +- For Azure CLI: |
| 24 | + [!INCLUDE [include](~/articles/reusable-content/azure-cli/azure-cli-prepare-your-environment-no-header.md)] |
| 25 | + |
| 26 | + > [!NOTE] |
| 27 | + > The Azure CLI command examples in this article require the `containerapp` Azure CLI extension. If you haven't used `az containerapp` commands, the extension is installed dynamically when you run your first `az containerapp` command. Learn more about [Azure CLI extensions](/cli/azure/azure-cli-extensions-overview). |
| 28 | +
|
| 29 | +## Provision gateway in your API Management instance |
| 30 | + |
| 31 | +Before deploying a self-hosted gateway, provision a gateway resource in your Azure API Management instance. For steps, see [Provision a self-hosted gateway](api-management-howto-provision-self-hosted-gateway.md). In the examples in this article, the gateway is named `my-gateway`. |
| 32 | + |
| 33 | +## Get gateway deployment settings from API Management |
| 34 | + |
| 35 | +To deploy the gateway, you need the gateway's **Token** and **Configuration endpoint** values. You can find them in the Azure portal: |
| 36 | + |
| 37 | +1. Sign in to the [Azure portal](https://portal.azure.com), and navigate to your API Management instance. |
| 38 | +1. In the left menu, under **Deployment and infrastructure**, select **Gateways**. |
| 39 | +1. Select the gateway resource you provisioned, and select **Deployment**. |
| 40 | +1. Copy the **Token** and **Configuration endpoint** values. |
| 41 | + |
| 42 | +## Deploy the self-hosted gateway to a container app |
| 43 | + |
| 44 | +You can deploy the self-hosted gateway [container image](https://aka.ms/apim/shgw/registry-portal) to a container app using the [Azure portal](../container-apps/quickstart-portal.md), [Azure CLI](../container-apps/get-started.md), or other tools. This article shows steps using the Azure CLI. |
| 45 | + |
| 46 | +### Create a container apps environment |
| 47 | + |
| 48 | +First, create a container apps environment using the [az containerapp env create](/cli/azure/containerapp#az-containerapp-env-create) command: |
| 49 | + |
| 50 | +# [Bash](#tab/bash) |
| 51 | +```azurecli-interactive |
| 52 | +#!/bin/bash |
| 53 | +az containerapp env create --name my-environment --resource-group myResourceGroup \ |
| 54 | + --location centralus |
| 55 | +``` |
| 56 | + |
| 57 | +# [PowerShell](#tab/psh) |
| 58 | +```azurecli |
| 59 | +# PowerShell syntax |
| 60 | +az containerapp env create --name my-environment --resource-group myResourceGroup ` |
| 61 | + --location centralus |
| 62 | +``` |
| 63 | +--- |
| 64 | + |
| 65 | +This command creates: |
| 66 | +* A container app environment named `my-environment` that you use to group container apps. |
| 67 | +* A log analytics workspace |
| 68 | + |
| 69 | +### Create a container app for the self-hosted gateway |
| 70 | + |
| 71 | +To deploy the self-hosted gateway to a container app in the environment, run the [az containerapp create](/cli/azure/containerapp#az-containerapp-create) command. |
| 72 | + |
| 73 | +First set variables for the **Token** and **Configuration endpoint** values from the API Management gateway resource. |
| 74 | + |
| 75 | +# [Bash](#tab/bash) |
| 76 | +```azurecli-interactive |
| 77 | +#!/bin/bash |
| 78 | +endpoint="<API Management configuration endpoint>" |
| 79 | +token="<API Management gateway token>" |
| 80 | +``` |
| 81 | +# [PowerShell](#tab/psh) |
| 82 | +```azurecli |
| 83 | +# PowerShell syntax |
| 84 | +$endpoint="<API Management configuration endpoint>" |
| 85 | +$token="<API Management gateway token>" |
| 86 | +``` |
| 87 | +--- |
| 88 | + |
| 89 | +Create the container app using the `az containerapp create` command: |
| 90 | + |
| 91 | +# [Bash](#tab/bash) |
| 92 | +```azurecli-interactive |
| 93 | +#!/bin/bash |
| 94 | +az containerapp create --name my-gateway \ |
| 95 | + --resource-group myResourceGroup --environment 'my-environment' \ |
| 96 | + --image "mcr.microsoft.com/azure-api-management/gateway:2.5.0" \ |
| 97 | + --target-port 8080 --ingress external \ |
| 98 | + --min-replicas 1 --max-replicas 3 \ |
| 99 | + --env-vars "config.service.endpoint"="$endpoint" "config.service.auth"="$token" "net.server.http.forwarded.proto.enabled"="true" |
| 100 | +``` |
| 101 | + |
| 102 | +# [PowerShell](#tab/psh) |
| 103 | +```azurecli |
| 104 | +# PowerShell syntax |
| 105 | +az containerapp create --name my-gateway ` |
| 106 | + --resource-group myResourceGroup --environment 'my-environment' ` |
| 107 | + --image "mcr.microsoft.com/azure-api-management/gateway:2.5.0" ` |
| 108 | + --target-port 8080 --ingress external ` |
| 109 | + --min-replicas 1 --max-replicas 3 ` |
| 110 | + --env-vars "config.service.endpoint"="$endpoint" "config.service.auth"="$token" "net.server.http.forwarded.proto.enabled"="true" |
| 111 | +``` |
| 112 | +--- |
| 113 | + |
| 114 | +This command creates: |
| 115 | +* A container app named `my-gateway` in the `myResourceGroup` resource group. In this example, the container app is created using the `mcr.microsoft.com/azure-api-management/gateway:2.5.0` image. Learn more about the self-hosted gateway [container images](self-hosted-gateway-overview.md#packaging). |
| 116 | +* Support for external ingress to the container app on port 8080. |
| 117 | +* A minimum of 1 and a maximum of 3 replicas of the container app. |
| 118 | +* A connection from the self-hosted gateway to the API Management instance using configuration values passed in environment variables. For details, see the self-hosted gateway [container configuration settings](self-hosted-gateway-settings-reference.md). |
| 119 | + |
| 120 | + > [!NOTE] |
| 121 | + > Azure Container Apps ingress forwards HTTPS requests to the self-hosted gateway container app as HTTP. Here, the `net.server.http.forwarded.proto.enabled` environment variable is set to `true` so that the self-hosted gateway uses the `X-Forwarded-Proto` header to determine the original protocol of the request. |
| 122 | +
|
| 123 | +### Confirm that the container app is running |
| 124 | + |
| 125 | +1. Sign in to the [Azure portal](https://portal.azure.com), and navigate to your container app. |
| 126 | +1. On the container app's **Overview** page, check that the **Status** is **Running**. |
| 127 | +1. Send a test request to the status endpoint on `/status-012345678990abcdef`. For example, use a `curl` command similar to the following. |
| 128 | + |
| 129 | + ```bash |
| 130 | + curl -i https://my-gateway.happyvalley-abcd1234.centralus.azurecontainerapps.io/status-012345678990abcdef |
| 131 | + ``` |
| 132 | + |
| 133 | + A successful request returns a `200 OK` response. |
| 134 | + |
| 135 | +> [!TIP] |
| 136 | +> Using the CLI, you can also run the [az containerapp show](/cli/azure/containerapp#az-containerapp-show) command to check the status of the container app. |
| 137 | + |
| 138 | +### Confirm that the gateway is healthy |
| 139 | + |
| 140 | +1. Sign in to the [Azure portal](https://portal.azure.com), and navigate to your API Management instance. |
| 141 | +1. In the left menu, under **Deployment and infrastructure**, select **Gateways**. |
| 142 | +1. On the **Overview** page, check the **Status** of your gateway. If the gateway is healthy, it reports regular gateway heartbeats. |
| 143 | + |
| 144 | + :::image type="content" source="media/how-to-deploy-self-hosted-gateway-container-apps/gateway-heartbeat.png" alt-text="Screenshot of gateway status in the portal." lightbox="media/how-to-deploy-self-hosted-gateway-container-apps/gateway-heartbeat.png"::: |
| 145 | + |
| 146 | +## Example scenario |
| 147 | + |
| 148 | +The following example shows how you can use the self-hosted gateway to access an API hosted in a container app in the same environment. As shown in the following diagram, the self-hosted gateway can be accessed from the internet, while the API is only accessible within the container apps environment. |
| 149 | + |
| 150 | +:::image type="content" source="media/how-to-deploy-self-hosted-gateway-container-apps/scenario.png" alt-text="Diagram of example scenario with self-hosted gateway."::: |
| 151 | + |
| 152 | +1. Deploy a container app hosting an API in the same environment as the self-hosted gateway |
| 153 | +1. Add the API to your API Management instance |
| 154 | +1. Call the API through the self-hosted gateway |
| 155 | + |
| 156 | +### Deploy a container app hosting an API in the same environment as the self-hosted gateway |
| 157 | + |
| 158 | +For example, deploy an example music album API to a container app. For later access to the API using the self-hosted gateway, deploy the API in the same environment as the self-hosted gateway. For detailed steps and information about the resources used in this example, see [Quickstart: Build and deploy from local source code to Azure Container Apps](../container-apps/quickstart-code-to-cloud.md). Abbreviated steps follow: |
| 159 | + |
| 160 | +1. Download [Python source code](https://codeload.github.com/azure-samples/containerapps-albumapi-python/zip/refs/heads/main) to your local machine. If you prefer, download the source code in another language of your choice. |
| 161 | +1. Extract the source code to a local folder and change to the *containerapps-albumapi-python-main/src* folder. |
| 162 | +1. Run the following [az containerapp up](/cli/azure/containerapp#az-containerapp-up) command to deploy the API to a container app in the same environment as the self-hosted gateway. Note the `.` at the end of the command, which specifies the current folder as the source for the container app. |
| 163 | + |
| 164 | + # [Bash](#tab/bash) |
| 165 | + ```azurecli-interactive |
| 166 | + #!/bin/bash |
| 167 | + az containerapp up --name albums-api \ |
| 168 | + --resource-group myResourceGroup --location centralus \ |
| 169 | + --environment my-environment --source . |
| 170 | + ``` |
| 171 | + |
| 172 | + # [PowerShell](#tab/psh) |
| 173 | + ```azurecli |
| 174 | + # PowerShell syntax |
| 175 | + az containerapp up --name albums-api ` |
| 176 | + --resource-group myResourceGroup --location centralus ` |
| 177 | + --environment my-environment --source . |
| 178 | + ``` |
| 179 | + --- |
| 180 | + |
| 181 | +1. Confirm that the container app is running and accessible externally at the FQDN returned in the command output. By default the API is accessible at the `/albums` endpoint. Example: `https://albums-api.happyvalley-abcd1234.centralus.azurecontainerapps.io/albums/albums`. |
| 182 | + |
| 183 | +### Configure the API for internal ingress |
| 184 | + |
| 185 | +Now update the container app hosting the sample API to enable ingress only in the container environment. This setting restricts access to the API only from the self-hosted gateway that you deployed. |
| 186 | + |
| 187 | +1. Sign in to the [Azure portal](https://portal.azure.com), and navigate to your container app. |
| 188 | +1. In the left menu, select **Ingress**. |
| 189 | +1. Set **Ingress** to **Enabled**. |
| 190 | +1. In **Ingress traffic**, select **Limited to Container Apps Environment**. |
| 191 | +1. Review the remaining settings and select **Save**. |
| 192 | + |
| 193 | +### Add the API to your API Management instance |
| 194 | + |
| 195 | +The following are example steps to add an API to your API Management instance and configure an API backend. For more information, see [Add an API to Azure API Management](add-api-manually.md). |
| 196 | + |
| 197 | +#### Add the API to your API Management instance |
| 198 | + |
| 199 | +1. In the portal, navigate to the API Management instance where you configured the self-hosted gateway. |
| 200 | +1. In the left menu, select **APIs** > **+ Add API**. |
| 201 | +1. Select **HTTP** and select **Full**. Enter the following settings: |
| 202 | + 1. **Display name**: Enter a descriptive name. Example: *Albums API*. |
| 203 | + 1. **Web service URL**: Enter the *internal* FQDN of the container app hosting the API. Example: `http://albums-api.internal.happyvalley-abcd1234.centralus.azurecontainerapps.io`. |
| 204 | + 1. **URL scheme**: Select **HTTP(S)**. |
| 205 | + 1. **API URL suffix**: Enter a suffix of your choice. Example: *albumapi*. |
| 206 | + 1. **Gateways**: Select the self-hosted gateway you provisioned. Example: *my-gateway*. |
| 207 | +1. Configure other API settings according to your scenario. Select **Create**. |
| 208 | + |
| 209 | +#### Add an API operation |
| 210 | + |
| 211 | +1. In the left menu, select **APIs** > **Albums API**. |
| 212 | +1. Select **+ Add operation**. |
| 213 | +1. Enter operation settings: |
| 214 | + 1. **Display name**: Enter a descriptive name for the operation. Example: *Get albums*. |
| 215 | + 1. **URL**: Select **Get** and enter `/albums` for the endpoint. |
| 216 | + 1. Select **Save**. |
| 217 | + |
| 218 | +### Call the API through the self-hosted gateway |
| 219 | + |
| 220 | +Call the API using the FQDN of the self-hosted gateway running in the container app. Find the FQDN on the container app's **Overview** page in the Azure portal, or run the following `az containerapp show` command. |
| 221 | +
|
| 222 | +# [Bash](#tab/bash) |
| 223 | +
|
| 224 | +```azurecli-interactive |
| 225 | +#!/bin/bash |
| 226 | +az containerapp show --name my-gateway --resource-group myResourceGroup \ |
| 227 | + --query "properties.configuration.ingress.fqdn" --output tsv |
| 228 | +``` |
| 229 | +
|
| 230 | +# [PowerShell](#tab/psh) |
| 231 | +```azurecli |
| 232 | +# PowerShell syntax |
| 233 | +az containerapp show --name my-gateway --resource-group myResourceGroup ` |
| 234 | + --query "properties.configuration.ingress.fqdn" --output tsv |
| 235 | +``` |
| 236 | +--- |
| 237 | +
|
| 238 | +
|
| 239 | +For example, run the following `curl` command to call the API at the `/albumapi/albums` endpoint. If your API requires a subscription key, pass a valid subscription key for your API Management instance as a header in the request: |
| 240 | +
|
| 241 | +```bash |
| 242 | +curl -i https://my-gateway.happyvalley-abcd1234.centralus.azurecontainerapps.io/albumapi/albums -H "Ocp-Apim-Subscription-Key: <subscription-key>" |
| 243 | +``` |
| 244 | +When the test is successful, the backend responds with a successful HTTP response code and some data. |
| 245 | +
|
| 246 | +```output |
| 247 | +HTTP/1.1 200 OK |
| 248 | +content-length: 751 |
| 249 | +content-type: application/json |
| 250 | +date: Wed, 28 Feb 2024 22:45:09 GMT |
| 251 | +[...] |
| 252 | +
|
| 253 | +[{"id":1,"title":"You, Me and an App Id","artist":"Daprize","price":10.99,"image_url":"https://aka.ms/albums-daprlogo"},{"id":2,"title":"Seven Revision Army","artist":"The Blue-Green Stripes","price":13.99,"image_url":"https://aka.ms/albums-containerappslogo"},{"id":3,"title":"Scale It Up","artist":"KEDA Club","price":13.99,"image_url":"https://aka.ms/albums-kedalogo"},{"id":4,"title":"Lost in Translation","artist":"MegaDNS","price":12.99,"image_url":"https://aka.ms/albums-envoylogo"},{"id":5,"title":"Lock Down Your Love","artist":"V is for VNET","price":12.99,"image_url":"https://aka.ms/albums-vnetlogo"},{"id":6,"title":"Sweet Container O' Mine","artist":"Guns N Probeses","price":14.99,"image_url":"https://aka.ms/albums-containerappslogo"}] |
| 254 | +``` |
| 255 | +
|
| 256 | +> [!TIP] |
| 257 | +> If you've enabled [logging of your API to Application insights](api-management-howto-app-insights.md), you can query the logs to see the requests and responses. |
| 258 | +
|
| 259 | +
|
| 260 | +## Related content |
| 261 | +
|
| 262 | +* [Connected microservices with Azure Container Apps](https://techcommunity.microsoft.com/t5/apps-on-azure-blog/connected-microservices-with-azure-container-apps/ba-p/3072158) |
| 263 | +* [Azure API Management's Self-Hosted Gateway on Azure Container Apps](https://github.com/tomkerkhove/azure-apim-on-container-apps) |
0 commit comments