Skip to content

Commit 94858fb

Browse files
authored
Merge pull request #180480 from dlepow/apimpriendp
[APIM] Private endpoint preview
2 parents 770a608 + a40fcad commit 94858fb

9 files changed

+253
-10
lines changed

articles/api-management/TOC.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@
181181
href: api-management-using-with-internal-vnet.md
182182
- name: Integrate Application Gateway in an internal virtual network
183183
href: api-management-howto-integrate-internal-vnet-appgateway.md
184+
- name: Connect privately using private endpoint
185+
href: private-endpoint.md
184186
- name: Mutual Certificate authentication
185187
href: api-management-howto-mutual-certificates.md
186188
- name: Manage CA certificates

articles/api-management/api-management-policy-expressions.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ author: dlepow
77

88
ms.service: api-management
99
ms.topic: article
10-
ms.date: 10/25/2021
10+
ms.date: 02/07/2022
1111
ms.author: danlep
1212
---
1313
# API Management policy expressions
@@ -203,7 +203,7 @@ The `context` variable is implicitly available in every policy [expression](api-
203203
|<a id="ref-context-lasterror"></a>context.LastError|Source: string<br /><br /> Reason: string<br /><br /> Message: string<br /><br /> Scope: string<br /><br /> Section: string<br /><br /> Path: string<br /><br /> PolicyId: string<br /><br /> For more information about context.LastError, see [Error handling](api-management-error-handling-policies.md).|
204204
|<a id="ref-context-operation"></a>context.Operation|Id: string<br /><br /> Method: string<br /><br /> Name: string<br /><br /> UrlTemplate: string|
205205
|<a id="ref-context-product"></a>context.Product|Apis: IEnumerable<[IApi](#ref-iapi)\><br /><br /> ApprovalRequired: bool<br /><br /> Groups: IEnumerable<[IGroup](#ref-igroup)\><br /><br /> Id: string<br /><br /> Name: string<br /><br /> State: enum ProductState {NotPublished, Published}<br /><br /> SubscriptionLimit: int?<br /><br /> SubscriptionRequired: bool|
206-
|<a id="ref-context-request"></a>context.Request|Body: [IMessageBody](#ref-imessagebody) or `null` if request does not have a body.<br /><br /> Certificate: System.Security.Cryptography.X509Certificates.X509Certificate2<br /><br /> [Headers](#ref-context-request-headers): IReadOnlyDictionary<string, string[]><br /><br /> IpAddress: string<br /><br /> MatchedParameters: IReadOnlyDictionary<string, string><br /><br /> Method: string<br /><br /> OriginalUrl: [IUrl](#ref-iurl)<br /><br /> Url: [IUrl](#ref-iurl)|
206+
|<a id="ref-context-request"></a>context.Request|Body: [IMessageBody](#ref-imessagebody) or `null` if request does not have a body.<br /><br /> Certificate: System.Security.Cryptography.X509Certificates.X509Certificate2<br /><br /> [Headers](#ref-context-request-headers): IReadOnlyDictionary<string, string[]><br /><br /> IpAddress: string<br /><br /> MatchedParameters: IReadOnlyDictionary<string, string><br /><br /> Method: string<br /><br /> OriginalUrl: [IUrl](#ref-iurl)<br /><br /> Url: [IUrl](#ref-iurl)<br /><br /> PrivateEndpointConnection: [IPrivateEndpointConnection](#ref-iprivateendpointconnection) or `null` if request does not come from a private endpoint connection.|
207207
|<a id="ref-context-request-headers"></a>string context.Request.Headers.GetValueOrDefault(headerName: string, defaultValue: string)|headerName: string<br /><br /> defaultValue: string<br /><br /> Returns comma-separated request header values or `defaultValue` if the header is not found.|
208208
|<a id="ref-context-response"></a>context.Response|Body: [IMessageBody](#ref-imessagebody)<br /><br /> [Headers](#ref-context-response-headers): IReadOnlyDictionary<string, string[]><br /><br /> StatusCode: int<br /><br /> StatusReason: string|
209209
|<a id="ref-context-response-headers"></a>string context.Response.Headers.GetValueOrDefault(headerName: string, defaultValue: string)|headerName: string<br /><br /> defaultValue: string<br /><br /> Returns comma-separated response header values or `defaultValue` if the header is not found.|
@@ -212,6 +212,7 @@ The `context` variable is implicitly available in every policy [expression](api-
212212
|<a id="ref-iapi"></a>IApi|Id: string<br /><br /> Name: string<br /><br /> Path: string<br /><br /> Protocols: IEnumerable<string\><br /><br /> ServiceUrl: [IUrl](#ref-iurl)<br /><br /> SubscriptionKeyParameterNames: [ISubscriptionKeyParameterNames](#ref-isubscriptionkeyparameternames)|
213213
|<a id="ref-igroup"></a>IGroup|Id: string<br /><br /> Name: string|
214214
|<a id="ref-imessagebody"></a>IMessageBody|As<T\>(preserveContent: bool = false): Where T: string, byte[],JObject, JToken, JArray, XNode, XElement, XDocument<br /><br /> The `context.Request.Body.As<T>` and `context.Response.Body.As<T>` methods are used to read either a request and response message body in specified type `T`. By default, the method:<br /><ul><li>Uses the original message body stream.</li><li>Renders it unavailable after it returns.</li></ul> <br />To avoid that and have the method operate on a copy of the body stream, set the `preserveContent` parameter to `true`, as in [this example](api-management-transformation-policies.md#SetBody).|
215+
|<a id="ref-iprivateendpointconnection"></a>IPrivateEndpointConnection|Name: string<br /><br /> GroupId: string<br /><br /> MemberName: string<br /><br />For more information, see the [REST API](/rest/api/apimanagement/current-ga/private-endpoint-connection/list-private-link-resources).|
215216
|<a id="ref-iurl"></a>IUrl|Host: string<br /><br /> Path: string<br /><br /> Port: int<br /><br /> [Query](#ref-iurl-query): IReadOnlyDictionary<string, string[]><br /><br /> QueryString: string<br /><br /> Scheme: string|
216217
|<a id="ref-iuseridentity"></a>IUserIdentity|Id: string<br /><br /> Provider: string|
217218
|<a id="ref-isubscriptionkeyparameternames"></a>ISubscriptionKeyParameterNames|Header: string<br /><br /> Query: string|

articles/api-management/api-management-using-with-internal-vnet.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ For configurations specific to the *external* mode, where the service endpoints
4444

4545
1. Go to the [Azure portal](https://portal.azure.com) to find your API management instance. Search for and select **API Management services**.
4646
1. Choose your API Management instance.
47-
1. Select **Virtual network**.
47+
1. Select **Network** > **Virtual network**.
4848
1. Select the **Internal** access type.
4949
1. In the list of locations (regions) where your API Management service is provisioned:
5050
1. Choose a **Location**.

articles/api-management/api-management-using-with-vnet.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ For configurations specific to the *internal* mode, where the endpoints are acce
3232

3333
1. Go to the [Azure portal](https://portal.azure.com) to find your API management instance. Search for and select **API Management services**.
3434
1. Choose your API Management instance.
35-
1. Select **Virtual network**.
35+
1. Select **Network**.
3636
1. Select the **External** access type.
3737
:::image type="content" source="media/api-management-using-with-vnet/api-management-menu-vnet.png" alt-text="Select VNet in Azure portal.":::
3838

@@ -43,7 +43,7 @@ For configurations specific to the *internal* mode, where the endpoints are acce
4343

4444
:::image type="content" source="media/api-management-using-with-vnet/api-management-using-vnet-select.png" alt-text="VNet settings in the portal.":::
4545

46-
1. Select **Apply**. The **Virtual network** page of your API Management instance is updated with your new VNet and subnet choices.
46+
1. Select **Apply**. The **Network** page of your API Management instance is updated with your new VNet and subnet choices.
4747

4848
1. Continue configuring VNet settings for the remaining locations of your API Management instance.
4949

56.4 KB
Loading
96.7 KB
Loading
Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
---
2+
title: Set up private endpoint for Azure API Management
3+
description: Learn how to restrict access to an Azure API Management instance by using an Azure private endpoint and Azure Private Link.
4+
ms.service: api-management
5+
author: dlepow
6+
ms.author: danlep
7+
ms.topic: how-to
8+
ms.date: 02/23/2022
9+
10+
---
11+
12+
# Connect privately to API Management using a private endpoint
13+
14+
You can configure a [private endpoint](../private-link/private-endpoint-overview.md) for your API Management instance to allow clients in your private network to securely access the instance over [Azure Private Link](../private-link/private-link-overview.md).
15+
16+
* The private endpoint uses an IP address from your Azure VNet address space.
17+
18+
* Network traffic between a client on your private network and API Management traverses over the VNet and a Private Link on the Microsoft backbone network, eliminating exposure from the public internet.
19+
20+
* Configure custom DNS settings or an Azure DNS private zone to map the API Management hostname to the endpoint's private IP address.
21+
22+
With a private endpoint and Private Link, you can:
23+
24+
- Create multiple Private Link connections to an API Management instance.
25+
26+
- Use the private endpoint to send inbound traffic on a secure connection.
27+
28+
- Use policy to distinguish traffic that comes from the private endpoint.
29+
30+
- Limit incoming traffic only to private endpoints, preventing data exfiltration.
31+
32+
> [!IMPORTANT]
33+
> * API Management support for private endpoints is currently in preview.
34+
> * To enable private endpoints, the API Management instance can't already be configured with an external or internal [virtual network](virtual-network-concepts.md).
35+
> * A private endpoint connection supports only incoming traffic to the API Management instance.
36+
37+
[!INCLUDE [premium-dev-standard-basic.md](../../includes/api-management-availability-premium-dev-standard-basic.md)]
38+
39+
## Limitations
40+
41+
* Only the API Management instance's Gateway endpoint currently supports Private Link connections.
42+
* Each API Management instance currently supports at most 100 Private Link connections.
43+
* Connections are not supported on the [self-hosted gateway](self-hosted-gateway-overview.md).
44+
45+
## Prerequisites
46+
47+
- An existing API Management instance. [Create one if you haven't already](get-started-create-service-instance.md).
48+
- The API Management instance must be hosted on the [`stv2` compute platform](compute-infrastructure.md). For example, create a new instance or, if you already have an instance in the Premium service tier, enable [zone redundancy](zone-redundancy.md).
49+
- Do not deploy (inject) the instance into an [external](api-management-using-with-vnet.md) or [internal](api-management-using-with-internal-vnet.md) virtual network.
50+
- A virtual network and subnet to host the private endpoint. The subnet may contain other Azure resources.
51+
- (Recommended) A virtual machine in the same or a different subnet in the virtual network, to test the private endpoint.
52+
53+
## Approval method for private endpoint
54+
55+
Typically, a network administrator creates a private endpoint. Depending on your Azure role-based access control (RBAC) permissions, a private endpoint that you create is either *automatically approved* to send traffic to the API Management instance, or requires the resource owner to *manually approve* the connection.
56+
57+
58+
|Approval method |Minimum RBAC permissions |
59+
|---------|---------|
60+
|Automatic | `Microsoft.Network/virtualNetworks/**`<br/>`Microsoft.Network/virtualNetworks/subnets/**`<br/>`Microsoft.Network/privateEndpoints/**`<br/>`Microsoft.Network/networkinterfaces/**`<br/>`Microsoft.Network/locations/availablePrivateEndpointTypes/read`<br/>`Microsoft.ApiManagement/service/**`<br/>`Microsoft.ApiManagement/service/privateEndpointConnections/**` |
61+
|Manual | `Microsoft.Network/virtualNetworks/**`<br/>`Microsoft.Network/virtualNetworks/subnets/**`<br/>`Microsoft.Network/privateEndpoints/**`<br/>`Microsoft.Network/networkinterfaces/**`<br/>`Microsoft.Network/locations/availablePrivateEndpointTypes/read` |
62+
63+
## Steps to configure private endpoint
64+
65+
1. [Get available private endpoint types in subscription](#get-available-private-endpoint-types-in-subscription)
66+
1. [Disable network policies in subnet](#disable-network-policies-in-subnet)
67+
1. [Create private endpoint - portal](#create-private-endpoint---portal)
68+
1. [List private endpoint connections to the instance](#list-private-endpoint-connections-to-the-instance)
69+
1. [Approve pending private endpoint connections](#approve-pending-private-endpoint-connections)
70+
1. [Optionally disable public network access](#optionally-disable-public-network-access)
71+
72+
### Get available private endpoint types in subscription
73+
74+
Verify that the API Management private endpoint type is available in your subscription and location. In the portal, find this information by going to the **Private Link Center**. Select **Supported resources**.
75+
76+
You can also find this information by using the [Available Private Endpoint Types - List](/rest/api/virtualnetwork/available-private-endpoint-types) REST API.
77+
78+
```rest
79+
GET https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.Network/locations/{region}/availablePrivateEndpointTypes?api-version=2021-03-01
80+
```
81+
82+
Output should include the `Microsoft.ApiManagement.service` endpoint type:
83+
84+
```JSON
85+
[...]
86+
87+
"name": "Microsoft.ApiManagement.service",
88+
"id": "/subscriptions/{subscriptionId}/providers/Microsoft.Network/AvailablePrivateEndpointTypes/Microsoft.ApiManagement.service",
89+
"type": "Microsoft.Network/AvailablePrivateEndpointTypes",
90+
"resourceName": "Microsoft.ApiManagement/service",
91+
"displayName": "Microsoft.ApiManagement/service",
92+
"apiVersion": "2021-04-01-preview"
93+
}
94+
[...]
95+
```
96+
97+
### Disable network policies in subnet
98+
99+
Network policies such as network security groups must be disabled in the subnet used for the private endpoint.
100+
101+
If you use tools such as Azure PowerShell, the Azure CLI, or REST API to configure private endpoints, update the subnet configuration manually. For examples, see [Manage network policies for private endpoints](../private-link/disable-private-endpoint-network-policy.md).
102+
103+
When you use the Azure portal to create a private endpoint, as shown in the next section, network policies are disabled automatically as part of the creation process
104+
105+
### Create private endpoint - portal
106+
107+
1. Navigate to your API Management service in the [Azure portal](https://portal.azure.com/).
108+
109+
1. In the left-hand menu, select **Network**.
110+
111+
1. Select **Private endpoint connections** > **+ Add endpoint**.
112+
113+
:::image type="content" source="media/private-endpoint/add-endpoint-from-instance.png" alt-text="Add a private endpoint using Azure portal":::
114+
115+
1. In the **Basics** tab of **Create a private endpoint**, enter or select the following information:
116+
117+
| Setting | Value |
118+
| ------- | ----- |
119+
| **Project details** | |
120+
| Subscription | Select your subscription. |
121+
| Resource group | Select an existing resource group, or create a new one. It must be in the same region as your virtual network.|
122+
| **Instance details** | |
123+
| Name | Enter a name for the endpoint such as **myPrivateEndpoint**. |
124+
| Region | Select a location for the private endpoint. It must be in the same region as your virtual network. It may differ from the region where your API Management instance is hosted. |
125+
126+
1. Select the **Resource** tab or the **Next: Resource** button at the bottom of the page. The following information about your API Management instance is already populated:
127+
* Subscription
128+
* Resource group
129+
* Resource name
130+
131+
1. In **Resource**, in **Target sub-resource**, select **Gateway**.
132+
133+
:::image type="content" source="media/private-endpoint/create-private-endpoint.png" alt-text="Create a private endpoint in Azure portal":::
134+
135+
1. Select the **Configuration** tab or the **Next: Configuration** button at the bottom of the screen.
136+
137+
1. In **Configuration**, enter or select this information:
138+
139+
| Setting | Value |
140+
| ------- | ----- |
141+
| **Networking** | |
142+
| Virtual network | Select your virtual network. |
143+
| Subnet | Select your subnet. |
144+
| **Private DNS integration** | |
145+
| Integrate with private DNS zone | Leave the default of **Yes**. |
146+
| Subscription | Select your subscription. |
147+
| Resource group | Select your resource group. |
148+
| Private DNS zones | Leave the default of **(new) privatelink.azure-api.net**.
149+
150+
1. Select **Review + create**.
151+
152+
1. Select **Create**.
153+
154+
### List private endpoint connections to the instance
155+
156+
After the private endpoint is created, it appears in the list on the API Management instance's **Private endpoint connections** page in the portal.
157+
158+
You can also use the [Private Endpoint Connection - List By Service](/rest/api/apimanagement/current-ga/private-endpoint-connection/list-by-service) REST API to list private endpoint connections to the service instance.
159+
160+
161+
Note the endpoint's **Connection status**:
162+
163+
* **Approved** indicates that the API Management resource automatically approved the connection.
164+
* **Pending** indicates that the connection must be manually approved by the resource owner.
165+
166+
### Approve pending private endpoint connections
167+
168+
If a private endpoint connection is in pending status, an owner of the API Management instance must manually approve it before it can be used.
169+
170+
If you have sufficient permissions, approve a private endpoint connection on the API Management instance's **Private endpoint connections** page in the portal.
171+
172+
You can also use the API Management [Private Endpoint Connection - Create Or Update](/rest/api/apimanagement/current-ga/private-endpoint-connection/create-or-update) REST API.
173+
174+
```rest
175+
PATCH https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ApiManagement/service/{apimServiceName}privateEndpointConnections/{privateEndpointConnectionName}?api-version=2021-08-01
176+
```
177+
178+
### Optionally disable public network access
179+
180+
To optionally limit incoming traffic to the API Management instance only to private endpoints, disable public network access. Use the [API Management Service - Create Or Update](/rest/api/apimanagement/current-ga/api-management-service/create-or-update) REST API.
181+
182+
```rest
183+
PATCH https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ApiManagement/service/{apimServiceName}?api-version=2021-08-01
184+
Authorization: Bearer {{authToken.response.body.access_token}}
185+
Content-Type: application/json
186+
187+
```
188+
Use the following JSON body:
189+
190+
```json
191+
{
192+
[...]
193+
"properties": {
194+
"publicNetworkAccess": "Disabled"
195+
}
196+
}
197+
```
198+
199+
## Validate private endpoint connection
200+
201+
After the private endpoint is created, confirm its DNS settings in the portal:
202+
203+
1. In the portal, navigate to the **Private Link Center**.
204+
1. Select **Private endpoints** and select the private endpoint you created.
205+
1. In the left-hand navigation, select **DNS configuration**.
206+
1. Review the DNS records and IP address of the private endpoint. The IP address is a private address in the address space of the subnet where the private endpoint is configured.
207+
208+
### Test in virtual network
209+
210+
Connect to a virtual machine you set up in the virtual network.
211+
212+
Run a utility such as `nslookup` or `dig` to look up the IP address of your default Gateway endpoint over Private Link. For example:
213+
214+
```
215+
nslookup my-apim-service.azure-api.net
216+
```
217+
218+
Output should include the private IP address associated with the private endpoint.
219+
220+
API calls initiated within the virtual network to the default Gateway endpoint should succeed.
221+
222+
### Test from internet
223+
224+
From outside the private endpoint path, attempt to call the API Management instance's default Gateway endpoint. If public access is disabled, output will include an error with status code `403` and a message similar to:
225+
226+
```
227+
Request originated from client public IP address xxx.xxx.xxx.xxx, public network access on this 'Microsoft.ApiManagement/service/my-apim-service' is disabled.
228+
229+
To connect to 'Microsoft.ApiManagement/service/my-apim-service', please use the Private Endpoint from inside your virtual network.
230+
```
231+
232+
## Next steps
233+
234+
* Use [policy expressions](api-management-policy-expressions.md#ref-context-request) with the `context.request` variable to identify traffic from the private endpoint.
235+
* Learn more about [private endpoints](../private-link/private-endpoint-overview.md) and [Private Link](../private-link/private-link-overview.md).
236+
* Learn more about [managing private endpoint connections](../private-link/manage-private-endpoint.md).
237+
* Use a [Resource Manager template](https://azure.microsoft.com/resources/templates/api-management-private-endpoint/) to create an API Management instance and a private endpoint with private DNS integration.

0 commit comments

Comments
 (0)