|
| 1 | +--- |
| 2 | +title: Secure outbound traffic to Private Link Service through shared private endpoints |
| 3 | +titleSuffix: Azure Web PubSub |
| 4 | +description: Learn how to secure Azure Web PubSub outbound traffic to Azure Private Link Service by using shared private endpoints. |
| 5 | +author: ArchangelSDY |
| 6 | +ms.service: azure-web-pubsub |
| 7 | +ms.custom: devx-track-azurecli |
| 8 | +ms.topic: how-to |
| 9 | +ms.date: 09/23/2025 |
| 10 | +ms.author: dayshen |
| 11 | +--- |
| 12 | + |
| 13 | +# Secure outbound traffic to Azure Private Link service through shared private endpoints |
| 14 | + |
| 15 | +If you're using an [event handler](concept-service-internals.md#event-handler) in Azure Web PubSub, you might have outbound traffic to upstream endpoints backed by a [private link service](../private-link/private-link-service-overview.md). To secure such outbound traffic, you can create an outbound [private endpoint connection](../private-link/private-endpoint-overview.md) in your Web PubSub services to reach these endpoints in a private way. |
| 16 | + |
| 17 | +:::image type="content" alt-text="Diagram showing architecture of shared private endpoint." source="media\howto-secure-shared-private-endpoints-private-link-service\shared-private-endpoint-overview.png" border="false" ::: |
| 18 | + |
| 19 | +Azure Private Link Service can be backed by any application running behind Azure Standard Load Balancer. That means you can host your event handler in Virtual Machine, Virtual Machine Scale Set or Azure Kubernetes Service. |
| 20 | + |
| 21 | +This outbound method is subject to the following requirements: |
| 22 | + |
| 23 | +- The Private Link Service visibility must be configured ["visible to anyone"](../private-link/private-link-service-overview.md#control-service-exposure) |
| 24 | +- The Web PubSub resource must be on the Standard tier or the Premium tier. |
| 25 | + |
| 26 | +Private endpoints of secured resources that are created by using Azure Web PubSub APIs are called *shared private link resources*. You're "sharing" access to the Private Link Service. These private endpoints are created inside the Web PubSub service execution environment and aren't directly visible to you. |
| 27 | + |
| 28 | +## Prerequisites |
| 29 | + |
| 30 | +- An Azure account with an active subscription. [Create an account for free](https://azure.microsoft.com/free/?WT.mc_id=A261C142F). |
| 31 | +- An Azure Web PubSub instance. |
| 32 | +- An Azure Private Link Service. [Create a Private Link Service](../private-link/create-private-link-service-portal.md). |
| 33 | + |
| 34 | +> [!NOTE] |
| 35 | +> The examples in this article use the following values: |
| 36 | +> |
| 37 | +> - The resource ID of this Azure Web PubSub resource is `/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/contoso/providers/Microsoft.SignalRService/webPubSub/contoso-webpubsub`. |
| 38 | +> - The resource ID of the Azure Private Link Service resource is `/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/contoso/providers/Microsoft.Network/privateLinkServices/contoso-pls`. |
| 39 | +> - We'd like to use the domain `pls.contoso.com` to call the Private Link Service endpoint. |
| 40 | +> |
| 41 | +> To use the steps in the following examples, replace these values with your own subscription ID, the name of your Web PubSub resource, and the name of your Private Link Service. |
| 42 | +> |
| 43 | +> If you plan to use HTTPS for `pls.contoso.com` in event handler settings, make sure the application behind Azure Private Link Service is configured with correct certificate. |
| 44 | +
|
| 45 | +## Create a shared private link resource to a Private Link Service |
| 46 | + |
| 47 | +### [Azure portal](#tab/azure-portal) |
| 48 | + |
| 49 | +1. In the Azure portal, go to your Azure Web PubSub resource. |
| 50 | +1. On the left menu, select **Networking**. |
| 51 | +1. Select **Private access**. |
| 52 | +1. Select **Add shared private endpoint**. |
| 53 | + |
| 54 | + :::image type="content" alt-text="Screenshot that shows managing shared private endpoints." source="media\howto-secure-shared-private-endpoints-private-link-service\portal-shared-private-endpoints-management.png" lightbox="media\howto-secure-shared-private-endpoints-private-link-service\portal-shared-private-endpoints-management.png" ::: |
| 55 | + |
| 56 | +1. Enter a name for the shared private endpoint. |
| 57 | +1. To set your target linked sources, either choose **Select from your resources** or enter your resource ID in **Specify resource ID**. |
| 58 | + |
| 59 | + Optionally, you can enter text in **Request message** to send a request to the target resource owner. |
| 60 | +1. Enter **FQDN** as `pls.contoso.com`. |
| 61 | +1. Select **Add**. |
| 62 | + |
| 63 | + :::image type="content" alt-text="Screenshot that shows adding a shared private endpoint." source="media\howto-secure-shared-private-endpoints-private-link-service\portal-shared-private-endpoints-add.png" ::: |
| 64 | + |
| 65 | +The value for **Provisioning state** in the shared private endpoint resource is **Succeeded**. **Connection state** is **Pending** until the endpoint is approved at the target resource. |
| 66 | + |
| 67 | +:::image type="content" alt-text="Screenshot that shows an added shared private endpoint pending approval." source="media\howto-secure-shared-private-endpoints-private-link-service\portal-shared-private-endpoints-added.png" lightbox="media\howto-secure-shared-private-endpoints-private-link-service\portal-shared-private-endpoints-added.png" ::: |
| 68 | + |
| 69 | +### [Azure CLI](#tab/azure-cli) |
| 70 | + |
| 71 | +Use the following API call with the [Azure CLI](/cli/azure/) to create a shared private link resource. Replace the values in the following example with the values from your scenario. |
| 72 | + |
| 73 | +```bash |
| 74 | +az rest --method put --uri https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/contoso/providers/Microsoft.SignalRService/webPubSub/contoso-webpubsub/sharedPrivateLinkResources/pls-pe?api-version=2024-08-01-preview --body @create-pe.json --debug |
| 75 | +``` |
| 76 | + |
| 77 | +The *create-pe.json* file contains the request body to the API. It's similar to the following example: |
| 78 | + |
| 79 | +```json |
| 80 | +{ |
| 81 | + "name": "pls-pe", |
| 82 | + "properties": { |
| 83 | + "privateLinkResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/contoso/providers/Microsoft.Network/privateLinkServices/contoso-pls", |
| 84 | + "fqdns": [ |
| 85 | + "pls.contoso.com" |
| 86 | + ], |
| 87 | + "requestMessage": "please approve" |
| 88 | + } |
| 89 | +} |
| 90 | +``` |
| 91 | + |
| 92 | +The process of creating an outbound private endpoint is a long-running (asynchronous) operation. As in all asynchronous Azure operations, the PUT call returns an `Azure-AsyncOperation` header value that's similar to the following example: |
| 93 | + |
| 94 | +```plaintext |
| 95 | +"Azure-AsyncOperation": "https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/contoso/providers/Microsoft.SignalRService/webPubSub/contoso-webpubsub/operationStatuses/c0786383-8d5f-4554-8d17-f16fcf482fb2?api-version=2024-08-01-preview" |
| 96 | +``` |
| 97 | + |
| 98 | +To poll this URI periodically to get the status of the operation, manually query the `Azure-AsyncOperationHeader` value. Here's an example: |
| 99 | + |
| 100 | +```bash |
| 101 | +az rest --method get --uri https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/contoso/providers/Microsoft.SignalRService/webPubSub/contoso-webpubsub/operationStatuses/c0786383-8d5f-4554-8d17-f16fcf482fb2?api-version=2024-08-01-preview |
| 102 | +``` |
| 103 | + |
| 104 | +Wait until the status changes to "Succeeded" before you go to the next step. |
| 105 | + |
| 106 | +----- |
| 107 | + |
| 108 | +## Approve the private endpoint connection |
| 109 | + |
| 110 | +When the shared private endpoint connection has a **Pending** status, the connection request must be approved at the target resource. |
| 111 | + |
| 112 | +### [Azure portal](#tab/azure-portal) |
| 113 | + |
| 114 | +1. In the Azure portal, go to your Azure Private Link Service. |
| 115 | +1. On the left menu, select **Settings - Private endpoint connections**. |
| 116 | +1. Select the pending connection that you created in your Web PubSub resource. |
| 117 | +1. Select **Approve**, and then select **Yes** to confirm. |
| 118 | + |
| 119 | +:::image type="content" alt-text="Screenshot of approving a private endpoint connection." source="media\howto-secure-shared-private-endpoints-private-link-service\portal-private-link-service-approve-private-endpoint.png" lightbox="media\howto-secure-shared-private-endpoints-private-link-service\portal-private-link-service-approve-private-endpoint.png" ::: |
| 120 | + |
| 121 | +You can select **Refresh** to check the status. It might take a few minutes for the status **Connection state** to update to **Approved**. |
| 122 | + |
| 123 | +:::image type="content" alt-text="Screenshot of the Azure portal, showing an Approved status on the Private endpoint connections pane." source="media\howto-secure-shared-private-endpoints-private-link-service\portal-private-link-service-approved-private-endpoint.png" lightbox="media\howto-secure-shared-private-endpoints-private-link-service\portal-private-link-service-approved-private-endpoint.png" ::: |
| 124 | + |
| 125 | +### [Azure CLI](#tab/azure-cli) |
| 126 | + |
| 127 | +1. List private endpoint connections: |
| 128 | + |
| 129 | + ```bash |
| 130 | + az network private-endpoint-connection list -n <private-link-service-resource-name> -g <private-link-service-resource-group-name> --type 'Microsoft.Network/privateLinkServices' |
| 131 | + ``` |
| 132 | + |
| 133 | + Check for a pending private endpoint connection. Note the connection ID. |
| 134 | + |
| 135 | + ```json |
| 136 | + [ |
| 137 | + { |
| 138 | + "id": "<ID>", |
| 139 | + "location": "", |
| 140 | + "name": "", |
| 141 | + "properties": { |
| 142 | + "privateLinkServiceConnectionState": { |
| 143 | + "actionRequired": "None", |
| 144 | + "description": "Please approve", |
| 145 | + "status": "Pending" |
| 146 | + } |
| 147 | + } |
| 148 | + } |
| 149 | + ] |
| 150 | + ``` |
| 151 | + |
| 152 | +1. Approve the private endpoint connection: |
| 153 | + |
| 154 | + ```bash |
| 155 | + az network private-endpoint-connection approve --id <private-endpoint-connection-ID> |
| 156 | + ``` |
| 157 | + |
| 158 | +----- |
| 159 | + |
| 160 | +## Query the status of the shared private link resource |
| 161 | + |
| 162 | +It takes a few minutes for the approval to be reflected in Web PubSub. You can check the state by using either the Azure portal or the Azure CLI. |
| 163 | + |
| 164 | +### [Azure portal](#tab/azure-portal) |
| 165 | + |
| 166 | +:::image type="content" alt-text="Screenshot of an approved shared private endpoint." source="media\howto-secure-shared-private-endpoints-private-link-service\portal-shared-private-endpoints-approved.png" lightbox="media\howto-secure-shared-private-endpoints-private-link-service\portal-shared-private-endpoints-approved.png" ::: |
| 167 | + |
| 168 | +### [Azure CLI](#tab/azure-cli) |
| 169 | + |
| 170 | +```bash |
| 171 | +az rest --method get --uri https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/contoso/providers/Microsoft.SignalRService/webPubSub/contoso-webpubsub/sharedPrivateLinkResources/pls-pe?api-version=2024-08-01-preview |
| 172 | +``` |
| 173 | + |
| 174 | +This command returns JSON. The connection state is indicated in `status` under `properties`. |
| 175 | + |
| 176 | +```json |
| 177 | +{ |
| 178 | + "name": "pls-pe", |
| 179 | + "properties": { |
| 180 | + "privateLinkResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/contoso/providers/Microsoft.Network/privateLinkServices/contoso-pls", |
| 181 | + "fqdns": [ |
| 182 | + "pls.contoso.com" |
| 183 | + ], |
| 184 | + "requestMessage": "please approve", |
| 185 | + "status": "Approved", |
| 186 | + "provisioningState": "Succeeded" |
| 187 | + } |
| 188 | +} |
| 189 | +
|
| 190 | +``` |
| 191 | + |
| 192 | +When `properties.provisioningState` is `Succeeded` and `properties.status` (connection state) is `Approved`, the shared private link resource is functional, and Web PubSub can communicate over the private endpoint. |
| 193 | + |
| 194 | +----- |
| 195 | + |
| 196 | +At this point, the private endpoint between Azure Web PubSub and Azure Private Link Service is established. You can use URL like `http://pls.contoso.com/eventhandler` in event handler settings. When Azure Web PubSub sends event handler requests, `pls.contoso.com` is internally resolved to a private address and traffic go through private network. |
| 197 | + |
| 198 | +## Related content |
| 199 | + |
| 200 | +- [What is a private endpoint?](../private-link/private-endpoint-overview.md) |
| 201 | +- [What is a private link service?](../private-link/private-link-service-overview.md) |
0 commit comments