Skip to content
Get Started for Free

Private Endpoint

Azure Private Endpoint is a network interface that connects you privately and securely to a service powered by Azure Private Link. Private endpoints use a private IP address from your virtual network, effectively bringing the service into your virtual network and eliminating exposure to the public internet. They are commonly used to access Azure PaaS services, such as Storage or Cosmos DB, from within a private network without internet connectivity. For more information, see What is Azure Private Endpoint?.

LocalStack for Azure provides a local environment for building and testing applications that make use of Private Endpoints. The supported APIs are available on our API Coverage section, which provides information on the extent of Private Endpoint’s integration with LocalStack.

This guide is designed for users new to Private Endpoint and assumes basic knowledge of the Azure CLI and our azlocal wrapper script.

Launch LocalStack using your preferred method. For more information, see Introduction to LocalStack for Azure. Once the container is running, enable Azure CLI interception by running:

Terminal window
azlocal start-interception

This command points the az CLI away from the public Azure management REST API and toward the LocalStack for Azure emulator API. To revert this configuration, run:

Terminal window
azlocal stop-interception

This reconfigures the az CLI to send commands to the official Azure management REST API.

Create a resource group, virtual network, and subnet

Section titled “Create a resource group, virtual network, and subnet”

Private endpoints are assigned a private IP from a subnet. Create the prerequisites first:

Terminal window
az group create \
--name rg-pe-demo \
--location westeurope
Output
{
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-pe-demo",
"location": "westeurope",
"managedBy": null,
"name": "rg-pe-demo",
"properties": {
"provisioningState": "Succeeded"
},
"tags": null,
"type": "Microsoft.Resources/resourceGroups"
}

Create a virtual network for the private endpoint:

Terminal window
az network vnet create \
--name vnet-pe-demo \
--resource-group rg-pe-demo \
--location westeurope \
--address-prefixes 10.0.0.0/16
Output
{
"newVNet": {
"addressSpace": { "addressPrefixes": [ "10.0.0.0/16" ] },
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-pe-demo/providers/Microsoft.Network/virtualNetworks/vnet-pe-demo",
"location": "westeurope",
"name": "vnet-pe-demo",
"provisioningState": "Succeeded",
"resourceGroup": "rg-pe-demo",
"subnets": [],
"type": "Microsoft.Network/virtualNetworks",
...
}
}

Create a subnet within the virtual network to host the private endpoint:

Terminal window
az network vnet subnet create \
--name subnet-pe \
--resource-group rg-pe-demo \
--vnet-name vnet-pe-demo \
--address-prefixes 10.0.1.0/24
Output
{
"addressPrefix": "10.0.1.0/24",
"delegations": [],
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-pe-demo/providers/Microsoft.Network/virtualNetworks/vnet-pe-demo/subnets/subnet-pe",
"name": "subnet-pe",
"provisioningState": "Succeeded",
"resourceGroup": "rg-pe-demo",
"type": "Microsoft.Network/virtualNetworks/subnets"
...
}

Create a storage account (target resource)

Section titled “Create a storage account (target resource)”

Private endpoints connect to a specific Azure resource. Create a storage account as the target:

Terminal window
az storage account create \
--name stpedemo \
--resource-group rg-pe-demo \
--location westeurope \
--sku Standard_LRS
Output
{
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-pe-demo/providers/Microsoft.Storage/storageAccounts/stpedemo",
"kind": "StorageV2",
"location": "westeurope",
"name": "stpedemo",
"primaryEndpoints": {
"blob": "https://stpedemo.blob.core.azure.localhost.localstack.cloud:4566",
"file": "https://stpedemo.file.core.azure.localhost.localstack.cloud:4566",
"queue": "https://stpedemo.queue.core.azure.localhost.localstack.cloud:4566",
"table": "https://stpedemo.table.core.azure.localhost.localstack.cloud:4566",
...
},
"provisioningState": "Succeeded",
"resourceGroup": "rg-pe-demo",
"sku": { "name": "Standard_LRS", "tier": "Standard" },
"type": "Microsoft.Storage/storageAccounts",
...
}

Retrieve the storage account resource ID and create a private endpoint targeting the blob sub-resource:

Terminal window
STORAGE_ID=$(az storage account show \
--name stpedemo \
--resource-group rg-pe-demo \
--query id \
--output tsv)
az network private-endpoint create \
--name pe-storage-blob \
--resource-group rg-pe-demo \
--location westeurope \
--vnet-name vnet-pe-demo \
--subnet subnet-pe \
--private-connection-resource-id "$STORAGE_ID" \
--group-id blob \
--connection-name stpedemo-blob-connection
Output
{
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-pe-demo/providers/Microsoft.Network/privateEndpoints/pe-storage-blob",
"location": "westeurope",
"name": "pe-storage-blob",
"networkInterfaces": [
{
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-pe-demo/providers/Microsoft.Network/networkInterfaces/pe-storage-blob.nic.8388c53a-14fc-4a02-a517-5e462aab03be",
"resourceGroup": "rg-pe-demo"
}
],
"privateLinkServiceConnections": [
{
"groupIds": [ "blob" ],
"name": "stpedemo-blob-connection",
"privateLinkServiceConnectionState": {
"actionsRequired": "None",
"description": "Auto-Approved",
"status": "Approved"
},
"privateLinkServiceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-pe-demo/providers/Microsoft.Storage/storageAccounts/stpedemo",
"provisioningState": "Succeeded"
}
],
"provisioningState": "Succeeded",
"resourceGroup": "rg-pe-demo",
"subnet": {
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-pe-demo/providers/Microsoft.Network/virtualNetworks/vnet-pe-demo/subnets/subnet-pe"
},
"type": "Microsoft.Network/privateEndpoints"
...
}

Link the private endpoint to a private DNS zone for name resolution:

Terminal window
az network private-dns zone create \
--name privatelink.blob.core.windows.net \
--resource-group rg-pe-demo
Output
{
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-pe-demo/providers/Microsoft.Network/privateDnsZones/privatelink.blob.core.windows.net",
"location": "global",
"name": "privatelink.blob.core.windows.net",
"provisioningState": "Succeeded",
"resourceGroup": "rg-pe-demo",
"type": "Microsoft.Network/privateDnsZones"
...
}

Create a DNS zone group to associate the private DNS zone with the private endpoint:

Terminal window
az network private-endpoint dns-zone-group create \
--name dns-zone-group-blob \
--resource-group rg-pe-demo \
--endpoint-name pe-storage-blob \
--private-dns-zone privatelink.blob.core.windows.net \
--zone-name blob-zone
Output
{
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-pe-demo/providers/Microsoft.Network/privateEndpoints/pe-storage-blob/privateDnsZoneGroups/dns-zone-group-blob",
"name": "dns-zone-group-blob",
"privateDnsZoneConfigs": [
{
"name": "blob-zone",
"privateDnsZoneId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-pe-demo/providers/Microsoft.Network/privateDnsZones/privatelink.blob.core.windows.net",
"recordSets": [
{
"fqdn": "stpedemo.privatelink.blob.core.windows.net",
"ipAddresses": [ "10.0.1.4" ],
"provisioningState": "Succeeded",
"recordSetName": "stpedemo",
"recordType": "A",
"ttl": 10
}
]
}
],
"provisioningState": "Succeeded",
"resourceGroup": "rg-pe-demo"
}

Retrieve the details of the private endpoint and list all endpoints in the resource group:

Terminal window
az network private-endpoint show \
--name pe-storage-blob \
--resource-group rg-pe-demo
Output
{
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-pe-demo/providers/Microsoft.Network/privateEndpoints/pe-storage-blob",
"location": "westeurope",
"name": "pe-storage-blob",
"privateLinkServiceConnections": [
{
"groupIds": [ "blob" ],
"name": "stpedemo-blob-connection",
"privateLinkServiceConnectionState": { "status": "Approved", ... },
"privateLinkServiceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-pe-demo/providers/Microsoft.Storage/storageAccounts/stpedemo",
"provisioningState": "Succeeded"
}
],
"provisioningState": "Succeeded",
"resourceGroup": "rg-pe-demo",
"type": "Microsoft.Network/privateEndpoints"
...
}

Then list all private endpoints in the resource group:

Terminal window
az network private-endpoint list \
--resource-group rg-pe-demo
Output
[
{
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-pe-demo/providers/Microsoft.Network/privateEndpoints/pe-storage-blob",
"location": "westeurope",
"name": "pe-storage-blob",
"privateLinkServiceConnections": [ { "groupIds": [ "blob" ], "name": "stpedemo-blob-connection", ... } ],
"provisioningState": "Succeeded",
"resourceGroup": "rg-pe-demo",
"type": "Microsoft.Network/privateEndpoints",
...
}
]

List the DNS zone groups associated with the private endpoint:

Terminal window
az network private-endpoint dns-zone-group list \
--resource-group rg-pe-demo \
--endpoint-name pe-storage-blob
Output
[
{
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-pe-demo/providers/Microsoft.Network/privateEndpoints/pe-storage-blob/privateDnsZoneGroups/dns-zone-group-blob",
"name": "dns-zone-group-blob",
"privateDnsZoneConfigs": [
{
"name": "blob-zone",
"privateDnsZoneId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-pe-demo/providers/Microsoft.Network/privateDnsZones/privatelink.blob.core.windows.net",
"recordSets": [
{ "fqdn": "stpedemo.privatelink.blob.core.windows.net", "ipAddresses": [ "10.0.1.4" ], "recordType": "A", ... }
]
}
],
"provisioningState": "Succeeded"
}
]

When a DNS zone group is created, the emulator automatically registers an A record in the linked private DNS zone using the private IP address assigned to the private endpoint’s network interface. The same address appears in the NIC’s IP configuration, the DNS zone group’s embedded record set (shown in the output above), and the A record in the private DNS zone.

Retrieve the IP address from the private endpoint’s network interface:

Terminal window
NIC_ID=$(az network private-endpoint show \
--name pe-storage-blob \
--resource-group rg-pe-demo \
--query "networkInterfaces[0].id" \
--output tsv)
az network nic show \
--ids "$NIC_ID" \
--query "ipConfigurations[0].privateIPAddress" \
--output tsv
Output
10.0.1.4

List the A records in the private DNS zone:

Terminal window
az network private-dns record-set a list \
--resource-group rg-pe-demo \
--zone-name privatelink.blob.core.windows.net
Output
[
{
"aRecords": [
{ "ipv4Address": "10.0.1.4" }
],
"fqdn": "stpedemo.privatelink.blob.core.windows.net",
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-pe-demo/providers/Microsoft.Network/privateDnsZones/privatelink.blob.core.windows.net/A/stpedemo",
"name": "stpedemo",
"ttl": 10,
"type": "Microsoft.Network/privateDnsZones/A"
}
]

The IP address 10.0.1.4 — the first usable address in the 10.0.1.0/24 subnet — is consistent across all three: the network interface IP configuration, the DNS zone group record set, and the A record in the private DNS zone.

Delete the private endpoint and verify it no longer appears in the list:

Terminal window
az network private-endpoint delete \
--name pe-storage-blob \
--resource-group rg-pe-demo

Then list all private endpoints to confirm the resource group is now empty:

Terminal window
az network private-endpoint list --resource-group rg-pe-demo
Output
[]

The Private Endpoint emulator supports the following features:

  • Create and manage private endpoints: Full lifecycle management including create, get, update, list, and delete.
  • Private Link service connections: Store and return privateLinkServiceConnections with group IDs and connection names.
  • DNS zone group management: Create, get, list, and delete private DNS zone groups for a private endpoint.
  • Group IDs: Support for any service group ID (e.g., blob, file, queue, table, sqlServer).
  • Resource group-scoped listing: List all private endpoints in a resource group.
  • Tags: Apply and update resource tags on private endpoint resources.
  • DNS resolution not performed: A records are automatically registered in private DNS zones when a DNS zone group is created. However, no actual DNS resolution is performed; the emulator does not respond to DNS queries.
  • No private IP assignment enforcement: A private IP is stored but no actual address is reserved from the subnet range.
  • No target service connectivity: The emulator does not verify that the target resource or connection is valid.
  • No data persistence: Private endpoint resources are not persisted and are lost when the emulator is stopped or restarted.

The following samples demonstrate how to use Azure Private Endpoints with LocalStack for Azure:

OperationImplemented
Page 1 of 0
Was this page helpful?