Secure an App Service with Private Endpoints

Lock down an Azure App Service so it's only reachable via a private VNet IP.

Introduction

30 Second Summary

When a company deploys a web application, leaving it open to the entire internet is a security risk. Enterprise teams solve this by placing apps inside private networks, making them invisible to the outside world.

In this project, you will lock down an Azure App Service using a Private Endpoint, making it completely unreachable from the public internet and only accessible through a Virtual Network.

What You'll Build

A network-secured Azure App Service that resolves to a private IP address inside a Virtual Network, with a Private DNS Zone handling hostname resolution.

By the end of this project, you'll have:

  • A Virtual Network with dedicated subnets for integration and private endpoints.
  • A Private Endpoint that assigns a private IP to your App Service and blocks all public access.
  • A Private DNS Zone with auto-registered DNS records so resources inside the VNet can resolve your app's hostname.
  • Secret Mission: Add VNet integration for outbound traffic, achieving full bidirectional network isolation.

Are there any prerequisites?

You need an Azure subscription with billing enabled and the Azure CLI installed on your machine. If you already have both from a previous project, you're good to go.

Set Up the Resource Group and App Service

Before you can secure an app behind a private endpoint, you need an app to secure. In this step, you will create the Azure infrastructure that hosts your web application.

You will provision a resource group to organize everything, an App Service plan to define the compute resources, and a web app running a sample Node.js runtime. Once the app is live and publicly accessible, you will have a clear "before" snapshot to compare against after you lock it down with a private endpoint.

In this step, get ready to:
  • Create a resource group and App Service plan.
  • Deploy a web app with a sample runtime.
  • Verify the app is publicly accessible before locking it down.
Create the resource group and App Service plan

A resource group is a logical container that holds all the Azure resources for a project. Creating one first makes cleanup simple at the end.

  • In your terminal (where you are already logged in via az login), create the resource group by running this command:
az group create --name nextwork-rg --location eastus

What does this command do?

  • --name nextwork-rg sets the name of the resource group that will hold all your project resources.
  • --location eastus places the resource group in the East US region. All resources you create inside it will default to this region.
  • You should see a JSON response with "provisioningState": "Succeeded" in the output.
  • Create the App Service plan by running this command:
az appservice plan create --name nextwork-plan --resource-group nextwork-rg --is-linux --location eastus --sku B1

What does this command do?

  • --name nextwork-plan names your App Service plan.
  • --is-linux specifies a Linux-based plan, which is more cost-effective than Windows for this project.
  • --sku B1 selects the Basic tier. This is the minimum tier that supports Private Endpoints.

💡 Why Linux B1 instead of Windows?

Linux B1 costs $13.14/month compared to $54.75/month for Windows B1. Since the goal of this project is to demonstrate private endpoints (not host a production workload), Linux is the cost-effective choice with identical networking capabilities.

  • Confirm the plan was created successfully by checking the output. You should see a JSON response with "status": "Ready" and "sku" showing B1.

Seeing a permissions error?

Make sure your Azure subscription has billing enabled and that your account has Contributor access. If you see a message about the subscription not being registered for Microsoft.Web, run the following command and try again:

az provider register --namespace Microsoft.Web

Ask for help: Why am I getting a permissions error when creating an App Service plan?

Create the web app and confirm it is publicly accessible

The web app is the actual application that will eventually sit behind the private endpoint. Its name must be globally unique across all of Azure because it becomes part of the public URL.

  • Create the web app by running this command:
az webapp create --name [[APPNAME="nextwork-app-yourname"]] --resource-group nextwork-rg --plan nextwork-plan --runtime "NODE:24-lts"

What does this command do?

  • --name sets the globally unique name for your web app. Replace the placeholder with something unique like nextwork-app- followed by your initials and a number.
  • --runtime "NODE:24-lts" tells Azure to run a Node.js 24 LTS environment. This gives the app a default landing page you can test against.
  • --plan nextwork-plan attaches the app to the B1 plan you just created.

💡 Valid characters for the app name

The name can only contain lowercase letters (a-z), numbers (0-9), and hyphens (-). It must be unique across all of Azure.

  • Once the command completes, look for the "defaultHostName" field in the JSON output. It will look like your-app-name.azurewebsites.net.
  • Open a new browser tab and navigate to your app's URL: https://your-app-name.azurewebsites.net (replacing your-app-name with the name you chose).
  • You should see a default Azure App Service landing page. This confirms the app is live and publicly accessible.

Seeing a 404 or the page won't load?

Give it 30 seconds and try again. New web apps sometimes take a moment to spin up. If it still fails, double-check that the name you chose was accepted by reviewing the JSON output for errors.

Ask for help: My Azure web app URL is not loading. How do I troubleshoot?

Note the default public URL for later comparison

This public URL is the "before" state of your app. After you create the private endpoint in a later step, this same URL will return a 403 Forbidden error instead of the landing page.

  • Copy your app's full URL (https://your-app-name.azurewebsites.net) and save it somewhere accessible. You will need it again in Step 3 and Step 5.

Why save the URL now?

After the private endpoint is in place, this URL becomes unreachable from the public internet. Having it saved lets you quickly verify the security posture by testing it again later.

Your App Service is live and accessible from anywhere on the internet. Next up, you will create the Virtual Network and subnets that will form the private network boundary around your app.

Create the Virtual Network and Subnets

In Step 1, you deployed an App Service that's publicly accessible to anyone on the internet. Now you'll build the private network that will eventually replace that public access.

A Virtual Network is your own isolated network inside Azure. You'll divide it into two subnets with different jobs: one for VNet integration (outbound traffic) and one for the private endpoint (inbound traffic).

In this step, get ready to:
  • Create a Virtual Network with address space 10.0.0.0/16.
  • Create two subnets: one for VNet integration and one for the private endpoint.
  • Disable private endpoint network policies on the endpoint subnet.
Create the Virtual Network

The Virtual Network defines the overall private address space your resources will communicate within. You'll use a /16 address block, which gives you over 65,000 IP addresses to work with.

  • Create the Virtual Network by running this command:
az network vnet create --resource-group nextwork-rg --location eastus --name nextwork-vnet --address-prefixes 10.0.0.0/16

What does this command do?

  • --resource-group nextwork-rg places the VNet in your existing resource group.
  • --location eastus creates the VNet in the same region as your App Service.
  • --name nextwork-vnet gives the Virtual Network a recognizable name.
  • --address-prefixes 10.0.0.0/16 defines the overall private IP range available inside this network.

You should see a JSON response containing "provisioningState": "Succeeded" confirming the VNet was created.

Seeing a location error?

Make sure the --location value matches the region where you created your resource group in Step 1. If you used a different region, substitute it here.

help me fix a location mismatch error when creating a Virtual Network in Azure CLI

Create the integration subnet

This subnet is reserved for VNet integration, which handles outbound traffic from your App Service. It must be delegated to Microsoft.Web/serverFarms so Azure knows only App Service plans can use it.

  • Create the integration subnet by running this command:
az network vnet subnet create --resource-group nextwork-rg --vnet-name nextwork-vnet --name integration-subnet --address-prefixes 10.0.0.0/24 --delegations Microsoft.Web/serverfarms --disable-private-endpoint-network-policies false

What does this command do?

  • --name integration-subnet creates a subnet named integration-subnet inside your VNet.
  • --address-prefixes 10.0.0.0/24 carves out 256 IP addresses from the VNet's overall /16 range.
  • --delegations Microsoft.Web/serverfarms reserves this subnet exclusively for App Service VNet integration.
  • --disable-private-endpoint-network-policies false keeps the default network policies active on this subnet, since it is not used for private endpoints.

You should see JSON output with "provisioningState": "Succeeded" and the delegation listed under "delegations".

Seeing a delegation error?

Double check the spelling of Microsoft.Web/serverfarms. The s at the end of serverfarms is required. Also confirm the VNet name matches nextwork-vnet exactly.

help me troubleshoot a subnet delegation error in Azure CLI

Create the private endpoint subnet

The second subnet holds the Private Endpoint itself. Private endpoint network policies must be disabled on this subnet so Azure can assign a private IP to your App Service without interference from network security group rules.

  • Create the private endpoint subnet by running this command:
az network vnet subnet create --resource-group nextwork-rg --vnet-name nextwork-vnet --name pe-subnet --address-prefixes 10.0.1.0/24 --disable-private-endpoint-network-policies true

What does this command do?

  • --name pe-subnet creates a subnet named pe-subnet for hosting private endpoints.
  • --address-prefixes 10.0.1.0/24 allocates a separate block of 256 IP addresses that does not overlap with the integration subnet.
  • --disable-private-endpoint-network-policies true turns off network policies so the private endpoint can receive its private IP assignment without being blocked.

The integration subnet and private endpoint subnet cannot be the same subnet. That is why you created two separate subnets with different address ranges.

You should see JSON output with "provisioningState": "Succeeded" confirming the subnet was created.

  • Verify both subnets exist by running this command:
az network vnet subnet list --resource-group nextwork-rg --vnet-name nextwork-vnet --output table

You should see a table listing both integration-subnet and pe-subnet with their respective address prefixes 10.0.0.0/24 and 10.0.1.0/24.

Only seeing one subnet?

Make sure both subnet create commands completed successfully before running the list command. Scroll up in your terminal to check for any error messages from the earlier commands.

help me figure out why one of my subnets is missing from the list

💡 Why two separate subnets?

Azure requires the VNet integration subnet and the private endpoint subnet to be different subnets. The integration subnet handles outbound traffic from your app, while the private endpoint subnet handles inbound traffic to your app.

Keeping them separate also lets you apply different network policies to each one. The private endpoint subnet has network policies disabled, while the integration subnet keeps them active.

Your Virtual Network is ready with both subnets in place. Next up, you'll create the private endpoint that locks your App Service away from public access.

Create the Private Endpoint

Your Virtual Network and subnets are in place. Now it is time to create the component that actually locks down your App Service.

A Private Endpoint assigns a private IP address from your VNet to the App Service. Once it is created, your app stops accepting traffic from the public internet and only responds to requests arriving through that private IP.

In this step, get ready to:
  • Retrieve the resource ID of your web app.
  • Create a private endpoint in the private endpoint subnet.
  • Verify that public access now returns 403 Forbidden.
Get the resource ID of your web app

The private endpoint creation command needs the full Azure resource ID of the web app it will connect to. You will store this ID in a shell variable for use in the next command.

  • Store your web app's resource ID in a variable by running this command:
RESOURCE_ID=$(az webapp show --name [[WEBAPP_NAME="your unique web app name"]] --resource-group nextwork-rg --query id --output tsv)

What does this command do?

The az webapp show command retrieves your web app's details. The --query id flag extracts only the resource ID field from the JSON output.

The --output tsv flag strips quotation marks so the value can be stored cleanly in the RESOURCE_ID shell variable.

  • Confirm the variable is set by running:
echo $RESOURCE_ID
  • You should see a long string starting with /subscriptions/ and ending with your web app name.

Seeing an empty output?

Make sure the web app name you entered matches the name you chose in Step 1 exactly, including any unique suffix. The resource group must also be nextwork-rg.

help me figure out why my az webapp show command is returning empty output

Create the private endpoint

With the resource ID captured, you can now create the private endpoint. This places a network interface in your pe-subnet and connects it to your web app using the sites group ID that Azure uses for App Service private link connections.

  • Create the private endpoint by running this command:
az network private-endpoint create \
  --resource-group nextwork-rg \
  --name nextwork-pe \
  --location eastus \
  --connection-name nextwork-pe-connection \
  --private-connection-resource-id $RESOURCE_ID \
  --group-id sites \
  --vnet-name nextwork-vnet \
  --subnet pe-subnet

What does this command do?

This creates a private endpoint named nextwork-pe inside the pe-subnet of your VNet. Azure assigns a private IP from the 10.0.1.0/24 range to this endpoint.

The --group-id sites tells Azure this is a private link connection for an App Service web app. The --connection-name is a friendly label for the service connection.

  • Wait for the command to complete. It may take 30-60 seconds. You should see a JSON response in your terminal confirming the endpoint was created.

What happens to public access?

When you create a private endpoint for an App Service app, public access is implicitly disabled. Your app's public URL will now return a 403 Forbidden response to anyone trying to access it from outside the VNet.

🙋‍♀️ Getting an error about network policies?

If you see an error related to private endpoint network policies, confirm that pe-subnet was created with --disable-private-endpoint-network-policies true in Step 2. You can verify this by running az network vnet subnet show --resource-group nextwork-rg --vnet-name nextwork-vnet --name pe-subnet.

help me fix a private endpoint network policies error when creating a private endpoint in Azure

Verify the private endpoint and confirm the 403 response

Now you will confirm the private endpoint exists, check the private IP it received, and verify that public access to your app is blocked.

  • View the private endpoint details by running this command:
az network private-endpoint show \
  --name nextwork-pe \
  --resource-group nextwork-rg \
  --query "{name:name, provisioningState:provisioningState, connectionState:privateLinkServiceConnections[0].privateLinkServiceConnectionState.status}" \
  --output table

What should I see?

You should see a table showing the name nextwork-pe, provisioning state Succeeded, and connection state Approved. The Approved status means the App Service accepted the private link connection automatically.

  • Now confirm that public access is blocked. Open your browser and navigate to your app's public URL:
curl -s -o /dev/null -w "%{http_code}" https://[[WEBAPP_NAME="your unique web app name"]].azurewebsites.net
  • You should see 403 as the output. This confirms your app is no longer accessible from the public internet.
  • You can also paste https://your unique web app name.azurewebsites.net into your browser. You should see a 403 Forbidden error page.

Still seeing your app load publicly?

The private endpoint takes a moment to propagate. Wait 1-2 minutes and try again. If the app still loads, confirm the private endpoint was created successfully using the az network private-endpoint show command above.

help me understand why my App Service is still publicly accessible after creating a private endpoint

Your App Service is now hidden from the public internet. Next up, you will configure a Private DNS zone so that resources inside the VNet can resolve your app's hostname to its new private IP address.

Configure the Private DNS Zone

Your private endpoint is live and public access is blocked. But there's a problem: how do resources inside your Virtual Network actually find your app?

They need DNS. Without a Private DNS zone, a VM or service inside your VNet would try to resolve your app's hostname through public DNS and get blocked. In this step, you'll create a Private DNS zone that maps your app's hostname to its private IP address inside the VNet.

In this step, get ready to:
  • Create a Private DNS zone for App Service private endpoints.
  • Link the DNS zone to your Virtual Network.
  • Create a DNS Zone Group that auto-registers DNS records for your private endpoint.
Create the Private DNS zone

A Private DNS zone is a DNS namespace that only resources inside linked Virtual Networks can query. Azure uses a specific zone name for App Service private endpoints: privatelink.azurewebsites.net.

  • Create the Private DNS zone by running this command:
az network private-dns zone create --resource-group nextwork-rg --name privatelink.azurewebsites.net

What does this command do?

This creates a private DNS namespace called privatelink.azurewebsites.net inside your resource group. Any A records added to this zone will only be visible to Virtual Networks that you explicitly link to it.

  • You should see JSON output confirming the zone was created, with provisioningState showing Succeeded.

Zone creation failed?

Make sure you spelled the zone name exactly as privatelink.azurewebsites.net. A typo here means DNS records won't resolve correctly for your App Service.

Also confirm you're still logged in to Azure CLI by running az account show.

help me troubleshoot why my Private DNS zone failed to create

Link the DNS zone to your Virtual Network

The zone exists, but no Virtual Network can see it yet. You need to create a VNet link so that resources inside nextwork-vnet can resolve records in this zone.

  • Link the DNS zone to your VNet by running this command:
az network private-dns link vnet create --resource-group nextwork-rg --name nextwork-vnet-link --zone-name privatelink.azurewebsites.net --virtual-network nextwork-vnet --registration-enabled False

What does this command do?

  • --name nextwork-vnet-link gives the link a descriptive name so you can identify which VNet is connected to this zone.
  • --virtual-network nextwork-vnet tells Azure which VNet should be able to resolve records in this zone.
  • --registration-enabled False disables auto-registration of VM hostnames. You only want the private endpoint records here, not every VM hostname in the VNet.
  • You should see JSON output with provisioningState showing Succeeded and virtualNetworkLinkState showing Completed.

Link creation failed?

Check that --zone-name matches the exact zone you just created (privatelink.azurewebsites.net) and that --virtual-network uses your VNet name nextwork-vnet.

help me fix my Private DNS VNet link creation error

💡 Why is registration disabled?

VNet links support auto-registration, where every VM created in the linked VNet gets a DNS record in the zone automatically. You don't want that here. Your zone is specifically for the private endpoint's A record, which the DNS Zone Group handles in the next substep.

Create a DNS Zone Group for automatic record registration

The final piece is a DNS Zone Group. This connects your private endpoint to the DNS zone and automatically creates A records so your app's hostname resolves to its private IP.

  • Create the DNS Zone Group by running this command:
az network private-endpoint dns-zone-group create --resource-group nextwork-rg --endpoint-name nextwork-pe --name nextwork-dns-zone-group --private-dns-zone privatelink.azurewebsites.net --zone-name privatelink.azurewebsites.net

What does this command do?

  • --endpoint-name nextwork-pe targets the private endpoint you created earlier.
  • --private-dns-zone privatelink.azurewebsites.net tells Azure which DNS zone to register records in.
  • Azure automatically creates A records in the zone for your app's hostname and its SCM (deployment) endpoint, both pointing to the private endpoint's IP address.
  • You should see JSON output confirming the zone group was created with provisioningState showing Succeeded.

DNS Zone Group creation failed?

Verify that --endpoint-name matches your private endpoint name (nextwork-pe) and that the DNS zone privatelink.azurewebsites.net was successfully created in the previous substep.

help me troubleshoot my DNS Zone Group creation error

Now verify the A records were auto-created in your DNS zone.

  • List the A records in your Private DNS zone by running this command:
az network private-dns record-set a list --resource-group nextwork-rg --zone-name privatelink.azurewebsites.net
  • You should see A record entries in the JSON output. Look for your app's hostname pointing to a private IP address from the 10.0.1.0/24 subnet range.

What should I see?

The output includes A records for two hostnames: your app (e.g. nextwork-app-[unique]) and its SCM endpoint (e.g. nextwork-app-[unique].scm). Both point to the same private IP address assigned from your pe-subnet.

This means any resource inside nextwork-vnet that queries DNS for your app's hostname will receive this private IP instead of a public one.

Your DNS configuration is complete. Any resource inside the linked VNet can now resolve your app's hostname to its private IP. Next up, you'll validate the full network isolation from end to end.

Validate the Network Isolation

You have built every piece of the network isolation puzzle. The private endpoint is in place, the DNS zone is configured, and the zone group has auto-registered your app's hostname.

Now it is time to prove that the setup actually works. In this step, you will confirm that your app is unreachable from the public internet, verify that DNS records point to the private IP, and review the private endpoint's connection status.

In this step, get ready to:
  • Confirm the app's public URL returns 403 Forbidden.
  • Verify DNS A records resolve to the private endpoint IP.
  • Review the private endpoint configuration and connection state.
Confirm public access is blocked

Your App Service was publicly accessible before you created the private endpoint. Now that the private endpoint exists, Azure implicitly blocks all public traffic to the app.

  • Test the public URL from your terminal by running this command:
curl https://[[WEBAPP_URL="your-app-name.azurewebsites.net"]]

What does this command do?

`curl` sends an HTTP request to the URL you provide. Since your app now has a private endpoint, Azure rejects any request that does not originate from inside the Virtual Network.

Your local machine is on the public internet, so the request is denied. You should see a 403 Forbidden response in the output.

  • Look at the response in your terminal. You should see a 403 Forbidden status, confirming that public access is blocked.
  • You can also paste the same URL into your browser. You will see an error page or a 403 message instead of the default App Service landing page.

Still seeing a 200 OK response?

If the app still loads successfully, the private endpoint may not have finished provisioning. Wait 1-2 minutes and try again.

Also confirm that you created the private endpoint with the correct web app resource ID. Run az network private-endpoint show --name nextwork-pe --resource-group nextwork-rg and check that the privateLinkServiceConnections section references your web app.

Help me troubleshoot why my App Service is still publicly accessible after creating a private endpoint.

Verify DNS records point to the private IP

The DNS Zone Group you created in the previous step automatically registered A records in the Private DNS Zone. These records map your app's hostname to the private endpoint's IP address inside the VNet.

  • List the A records in your Private DNS zone by running:
az network private-dns record-set a list --resource-group nextwork-rg --zone-name privatelink.azurewebsites.net --output table

What should I see?

The output displays A records that were auto-created by the DNS Zone Group. You should see at least two records: one for your app's hostname and one for the SCM (deployment) endpoint.

The IP address in each record is the private IP assigned from the 10.0.1.0/24 subnet. This proves that any resource inside the VNet resolving your app's hostname will be directed to the private endpoint, not the public internet.

  • Confirm that the ipv4Address column shows an IP from the 10.0.1.x range.

No A records showing up?

If the list is empty, the DNS Zone Group may not have been created correctly. Run az network private-endpoint dns-zone-group list --endpoint-name nextwork-pe --resource-group nextwork-rg to check that the group exists and is associated with privatelink.azurewebsites.net.

Help me figure out why my Private DNS zone has no A records for my private endpoint.

Review the private endpoint connection status

The final check confirms that your private endpoint's connection to the App Service is fully approved and operational.

  • Display the full private endpoint configuration by running:
az network private-endpoint show --name nextwork-pe --resource-group nextwork-rg --output table

What am I looking for?

The key field to check is the connection status inside privateLinkServiceConnections. It should show Approved. This means the App Service accepted the private endpoint connection.

If you want more detail, you can re-run the command without --output table to see the full JSON output, which includes the subnet, IP configuration, and DNS zone group association.

  • Confirm the PrivateLinkServiceConnectionState shows Approved in the output.

How would a client inside the VNet reach the app?

A virtual machine or container running inside nextwork-vnet would resolve nextwork-app-[unique].azurewebsites.net to the private IP (from the 10.0.1.0/24 subnet) thanks to the Private DNS zone linked to the VNet.

Traffic never leaves the Microsoft backbone network. The client connects directly to the private endpoint's network interface, bypassing the public internet entirely.

🙋‍♀️ Connection state showing Pending?

If the status is Pending instead of Approved, the connection was created with manual approval required. For App Service private endpoints created via CLI with the resource ID, this should auto-approve. Re-check that you used the correct resource ID for your web app.

Help me understand why my private endpoint connection state is Pending instead of Approved.

Secret mission

Add VNet Integration for Outbound Traffic

Your App Service is locked down for inbound traffic. But what about outbound? Right now, any API call or database connection your app makes still goes over the public internet. In this secret mission, you will add VNet integration to route all outbound traffic through your Virtual Network, achieving full bidirectional network isolation.

Clean Up Your Resources

Clean Up Your Resources

Decide whether to keep your resources running, pause them to come back later, or delete them entirely. The B1 App Service plan costs approximately $0.44/day ($13.14/month), so charges accrue as long as the resource group exists.

Cost warning

Your App Service plan (nextwork-plan, Linux B1) charges approximately $13.14/month even with no traffic. Charges continue as long as the plan exists in your subscription.

If you are done with this project, delete the entire resource group to stop all charges immediately.

Resources you used:

  • Resource group nextwork-rg (contains all resources below).
  • App Service plan nextwork-plan (Linux B1, ~$13.14/month).
  • Web App nextwork-app-[unique] with private endpoint and VNet integration.
  • Virtual Network nextwork-vnet with two subnets (integration-subnet and pe-subnet).
  • Private Endpoint nextwork-pe and DNS Zone Group nextwork-dns-zone-group.
  • Private DNS Zone privatelink.azurewebsites.net with VNet link nextwork-vnet-link.

Keep everything running

No action needed. Choose this if you are still actively experimenting with your network-isolated App Service or plan to build on top of it.

  • Monitor your spending in Azure Cost Management to avoid surprises.
  • Remember that the B1 plan charges ~$0.44/day regardless of traffic.

Pause - I'll come back to this later

You cannot fully pause an App Service plan. However, you can scale down to the Free (F1) tier to stop charges. This removes private endpoint support, so your networking configuration will break until you scale back up.

  • Scale the plan down to the Free tier by running:
az appservice plan update --name nextwork-plan --resource-group nextwork-rg --sku F1

What happens when you scale down?

The Free tier does not support private endpoints. Your private endpoint (nextwork-pe) and VNet integration will stop working. When you are ready to resume, scale back up to B1 with --sku B1 and verify your networking configuration.

  • To resume later, scale back up by running:
az appservice plan update --name nextwork-plan --resource-group nextwork-rg --sku B1

Delete - I don't want to use this again

Remove all project resources and stop all charges immediately. Since everything lives in a single resource group, one command deletes it all.

  • Delete the entire resource group by running:
az group delete --name nextwork-rg --yes --no-wait

What does this command do?

This deletes the resource group nextwork-rg and every resource inside it: the App Service plan, web app, VNet, private endpoint, DNS zone, and all associated configurations.

The --yes flag skips the confirmation prompt. The --no-wait flag returns control to your terminal immediately while Azure completes the deletion in the background.

  • Verify the deletion has started by running:
az group list --output table

If nextwork-rg no longer appears in the list, the deletion is complete or in progress. Charges stop as soon as the resources are removed.

Nice Work!

Nice Work!

You just built a production-grade, network-isolated Azure App Service using Private Endpoints and Private DNS. This is the exact security pattern enterprises use to protect sensitive workloads from public exposure.

Here's what you accomplished:

  • Created a Private Endpoint that assigned a private IP to your App Service and blocked all public access with a 403 Forbidden response.
  • Configured a Private DNS zone (privatelink.azurewebsites.net) with automatic DNS record registration via DNS Zone Groups, so resources inside the VNet resolve the app's hostname to its private IP.
  • Validated network isolation end-to-end by confirming the public URL returns 403 and DNS records point to the private endpoint IP with an Approved connection state.
  • Secret Mission: Added VNet integration for outbound traffic, achieving full bidirectional network isolation on the App Service.

Ready to quiz yourself?