CAMPUX Cloud Bootcamp Phase Two · Class Fourteen
Phase Two — Core Infrastructure
Reading 55 min · Drills 6 · 3 Labs
Aligned to AZ-104
Class Fourteen

Private Connectivity

Your PaaS services are born with a public street address, and locking the door is not the same as removing it — this class is about building the private corridor and, harder, making the directory point at it.

§1

The public door you never asked for

The storage account you built in Class Twelve has a public address. So does an Azure SQL database, a Key Vault, a Cosmos DB — nearly every platform service is reachable, by default, at a name that resolves on the open internet. Access is gated by keys and identity, so the door is locked; but the door exists, it is on a public street, and every scanner on the internet can see it and rattle the handle. For a shop with a genuinely public storefront that is fine. For the parts that should only ever be spoken to from inside your own network, a locked public door is a weaker promise than no door at all.

Public endpoint
The default way to reach a PaaS service: a fully-qualified name — campuxstore.blob.core.windows.net — that resolves to a public IP, reachable from anywhere, protected only by authentication and whatever firewall rules you add.

This class is about closing that door properly, and it has two moves that people conflate at their peril. The first is a networking move: give the service a presence inside your own virtual network so traffic never touches the public internet. The second — the one that quietly defeats the first when forgotten — is a naming move: make the service's name resolve to that private presence rather than the public address. Get the corridor right but the directory wrong, and your traffic walks confidently back out to the public door you thought you had closed. Azure offers two networking answers of different strength, and then demands you get the DNS right regardless.

§2

Service endpoints: the half-measure, fairly

The lighter answer is the virtual network service endpoint. You enable it on a subnet, for a particular service type, and it does one useful thing: it tells the PaaS service to trust traffic arriving from that subnet, over the Azure backbone, and lets you deny everything else at the service's firewall.

Service endpoint
A subnet-level setting that extends the subnet's identity to a PaaS service over Azure's backbone, so the service can allow that subnet and refuse the public internet. The service keeps its public IP; you have restricted who may use it, not where it lives.

Read that last sentence twice, because it is the whole limitation. A service endpoint does not give the service a private address. The storage account still answers on its public IP and public name; you have merely configured its firewall to accept only your subnet and reject the rest. Traffic takes an optimised path over Microsoft's backbone rather than the open internet, which is a real improvement — but the endpoint is still, architecturally, a public one with a tighter guest list.

That distinction decides when service endpoints are enough and when they are not. They are free, quick, and fine when your only requirement is "lock this service to my subnets." They fall short the moment the requirement becomes "this service must have no public endpoint at all," or "reach it privately from on-premises or a peered network," or "satisfy an auditor who wants a private IP on a diagram." Service endpoints also bind to the subnet, so they do not extend to traffic originating outside Azure. For anything approaching a serious data-isolation mandate, you want the heavier tool.

§3

Private endpoints: a NIC of your own

The strong answer is the private endpoint, built on Azure Private Link. Instead of restricting who may reach the public address, it gives the service a genuine presence inside your network: a network interface, holding a private IP from one of your subnets, that maps privately to the specific resource.

Private endpoint
A read-only network interface, placed in your subnet with a private IP from its range, that connects privately to one PaaS resource over Azure Private Link. The resource can then refuse all public access; you reach it at an address inside your own network.

The mechanics are worth holding precisely, because they are exam material and real-world fluency at once. Creating a private endpoint provisions a read-only NIC in your chosen subnet — say 10.20.2.10 in Campux's data subnet — bound to the resource for its lifetime. That NIC is the private door. You then set the storage account's public-network-access to Disabled, and the public door is genuinely bricked up: the resource now answers only through the private endpoint, only to networks that can route to that private IP. Unlike a service endpoint, this reaches across peered virtual networks and, with the DNS work of Class Fifteen, from on-premises too — because a private IP is just an address on your network, and your network already knows how to route to it.

The cost is real but modest: a private endpoint bills per hour plus a small charge for data through it, where a service endpoint is free. You are paying for genuine network isolation, and for most regulated or sensitive data that is a bargain. But a private endpoint you create and then misconfigure is worse than none, because it lulls you — and the specific way it goes wrong is always the same, and it is next.

Table 1 — Service endpoint vs private endpoint, decided on five questions
QuestionService endpointPrivate endpoint
Does the resource get a private IP?No — keeps its public IPYes — a NIC in your subnet
Can the public endpoint be removed?No — only firewalled to subnetsYes — public access can be Disabled
Reachable from on-prem / peered VNets?No — bound to the subnetYes — it is just a private IP to route to
Needs Private DNS work?NoYes — or it silently fails (§4)
CostFreePer hour + data

Read the second row twice: it is the one that decides most real mandates. "Lock this service to my subnets" is a service endpoint's job; "this service must have no public endpoint at all" can only be a private endpoint. Reach for the lighter tool when the requirement is genuinely the lighter one, and do not pay for a private endpoint's isolation you were not asked for — but never answer a no-public-endpoint mandate with a service endpoint, because it cannot remove the door it was never designed to remove.

§4

The DNS trap that catches everyone

Here is the mistake that has cost more engineers an afternoon than any other in this topic. You create the private endpoint. The NIC exists, the private IP is assigned, public access is disabled. And your application still cannot reach the storage account — or worse, in a subtler setup, it silently keeps using the public path. The endpoint is perfect. The name is the problem.

Private endpoint, public DNS: no privacy at all.

When you create a private endpoint, Azure quietly changes public DNS so the resource's name becomes a CNAME into a special namespace: campuxstore.blob.core.windows.net now points to campuxstore.privatelink.blob.core.windows.net. But that privatelink name only resolves to your private IP if you have created a Private DNS zone for it and linked it to your virtual network. Without that zone, the privatelink name resolves to the public IP — because the chain is deliberately built to fall back to public, so that clients mid-migration do not break.1

Private DNS zone
An Azure-managed DNS zone — for storage blobs, privatelink.blob.core.windows.net — holding the record that maps the resource's name to its private-endpoint IP. Linked to a VNet, it makes every resource in that network resolve the name privately.

So the rule is absolute: a private endpoint without its Private DNS zone, linked to the network doing the resolving, is not actually private. Either your traffic quietly leaks back to the public endpoint, or — once you disable public access — it fails outright, because the name it looked up points at a door that is now bricked shut. The endpoint being green in the portal tells you the corridor was built; only a DNS lookup returning the private IP tells you the directory points down it. Always verify resolution, from inside the network, before you trust the isolation.2

§5

The pattern interviews ask for: web app to private storage

Assemble the pieces and you get the single most-asked private-networking design: a web application that reaches its storage account entirely privately. Four parts, and every one is load-bearing.

VNet integration
The web app is joined to the VNet for outbound traffic, so its requests originate inside the network — a PaaS app is not in a subnet by default, and without this its traffic never reaches a private IP.
Private endpoint
A NIC with a private IP for the storage account, placed in the data subnet — the private door into the resource.
Private DNS zone
privatelink.blob.core.windows.net, linked to the VNet, mapping the storage name to that private IP so the app resolves it correctly.
Public access disabled
On the storage account, so the only way in is the private endpoint — the step that turns "also reachable privately" into "reachable only privately."
Figure 8: a packet's-eye view of the web-app-to-private-storage pattern. The web app in the app subnet reaches the storage account through a private endpoint — a NIC with a private IP in the data subnet — over the virtual network, while the public internet path from the app to the storage account's public address is struck through in red. app subnet Web app VNet-integrated data subnet Private endpoint NIC · 10.20.2.10 Storage account (blob) private over the VNet public internet path public access disabled DNS: campuxstore.blob.core.windows.net → privatelink zone → 10.20.2.10 (private) Miss the zone and the name points back at the public door.
Figure 8 The pattern, from a packet's point of view. The app, integrated into the VNet, resolves the storage name to 10.20.2.10 — the private endpoint's NIC — and reaches storage entirely over the virtual network. The public path is struck through because public access is disabled. The two lines at the bottom are the load-bearing DNS: without the private zone linked to the VNet, the name resolves to the public IP and the whole private path is quietly bypassed.

Every part is boring alone and load-bearing together. The two labs at the end of this class build exactly this pattern — once with the CLI, once by hand in the portal — so you meet each piece twice, from both directions.

Case File · Campux Retail

Campux takes storage private — and trips on DNS first

Private endpoint · the zone forgotten · the fix

Campux's storage account holds order exports and product images that have no business being reachable from the public internet. You create a private endpoint in the data subnet, disable public access, and — moving a touch too fast — skip linking the Private DNS zone to the VNet. Within minutes the storefront's image loads start failing: the app resolves campuxstore.blob.core.windows.net to the old public IP, which now refuses it, because public access is off. The portal cheerfully shows the private endpoint "approved" and green. Everything looks built; nothing works.

The fix is exactly the missing move: create the privatelink.blob.core.windows.net zone, link it to the VNet, and wire it to the endpoint's DNS zone group.3 Seconds later the name resolves to 10.20.2.10, the app reaches storage over the private path, and the images return. The lesson lands harder for having stung: the endpoint was never the hard part — the directory was. Campux now standardises the four-part pattern, and a policy will later require private endpoints on storage across the estate, so the corridor and its directory are built together, by rule, every time.

Watch · Microsoft Learn

The official module, and a CAMPUX overview

Read or work the module first; watch the overview to see it move
Microsoft Learn · Modules

What is Azure Private Link? (docs)
learn.microsoft.com/azure/private-link/private-link-overview

Deeper (AZ-104 / AZ-700): Design and implement private access to Azure services
learn.microsoft.com/training/modules/design-implement-private-access-to-azure-services/

CAMPUX overview video

A short walkthrough of private endpoints and the DNS trap will live here. Video to be added.

Lab 1 · Azure CLI

Create it the CLI way

~10 minutes · Azure Cloud Shell · a throwaway resource group

The first way to build anything on Azure is by describing it in commands you can save, review, and run again. This is the shippable path — the same steps a pipeline will run later. The order is the lesson: build and verify the private path before you close the public one.

  1. Open Cloud Shell — the >_ icon in the top bar of the portal — and choose Bash. (Locally instead: install the Azure CLI and run az login.)On screen: Cloud Shell already knows who you are, so there is no login step and the az command is ready. It is the fastest way to run these without installing anything.

  2. Set names once, so the rest reads cleanly:

    RG=campux-lab; LOC=westeurope; SA=campuxlab$RANDOM
    az group create -n $RG -l $LOC
    az storage account create -n $SA -g $RG -l $LOC --sku Standard_LRS
    az network vnet create -g $RG -n vnet-lab \
      --address-prefixes 10.30.0.0/16 --subnet-name data --subnet-prefixes 10.30.2.0/24
  3. Create the private endpoint for the account's blob service, in the data subnet:

    SA_ID=$(az storage account show -n $SA -g $RG --query id -o tsv)
    az network private-endpoint create -g $RG --name pe-$SA-blob \
      --vnet-name vnet-lab --subnet data \
      --private-connection-resource-id $SA_ID \
      --group-id blob --connection-name $SA-blob
    What just happened: a read-only NIC now sits in the data subnet with a private IP bound to that storage account. The corridor exists — but nothing resolves to it yet.
  4. Create the Private DNS zone, link it to the VNet, and wire it to the endpoint — the step that avoids the §4 trap:

    az network private-dns zone create -g $RG -n privatelink.blob.core.windows.net
    az network private-dns link vnet create -g $RG \
      --zone-name privatelink.blob.core.windows.net \
      --name link-lab --virtual-network vnet-lab --registration-enabled false
    az network private-endpoint dns-zone-group create -g $RG \
      --endpoint-name pe-$SA-blob --name default \
      --zone-name blob --private-dns-zone privatelink.blob.core.windows.net
  5. Verify resolution from inside the VNet, then — only then — close the public door:

    nslookup $SA.blob.core.windows.net   # expect a 10.30.2.x private address
    az storage account update -n $SA -g $RG \
      --public-network-access Disabled --default-action Deny
    The gate: if the lookup still shows a public IP, stop — the DNS zone is not doing its job, and disabling public access now would cause an outage. Fix DNS first.
  6. Tear it all down in one line, so nothing bills overnight:

    az group delete -n $RG --yes --no-wait
Lab 2 · Azure Portal

Create it the portal way

~15 minutes · the same result, built by hand so the wizard teaches you

Now build the identical thing by clicking, because the Create wizard's own tabs name the pieces better than any diagram. Do this with a throwaway storage account you can delete afterwards.

  1. Go to portal.azure.com and sign in.On screen: the home page with a search bar running across the very top. Almost everything in Azure starts from that bar.

  2. In the search bar at the top, type Private endpoints and select it from the results, then click + Create.On screen: the "Private endpoints" service page lists any that exist and offers Create. This launches the "Create a private endpoint" wizard, a row of tabs you move through left to right.

  3. Basics tab: choose your subscription and a resource group (make a throwaway one), name the endpoint pe-campuxlab-blob, and set the region.On screen: the region field matters — it must match the virtual network you attach two tabs along, or that network will not appear in the list. The wizard is quietly enforcing that a private endpoint and its VNet share a region.

  4. Resource tab: pick "Connect to an Azure resource in my directory", choose your storage account, and set Target sub-resource to blob.On screen: that sub-resource dropdown is the same "group id" you passed on the CLI. One storage account exposes blob, file, queue, table — each needs its own endpoint. You are making the blob service private here.

  5. Virtual Network tab: select your VNet and the data subnet.On screen: this is where the endpoint's network interface is placed and given a private IP from the subnet — the abstract "private endpoint" becoming a concrete address like 10.30.2.4 on your own network.

  6. DNS tab: set Integrate with private DNS zone to Yes. This one toggle is the whole of §4.On screen: "Yes" makes the portal create and link privatelink.blob.core.windows.net to your VNet automatically. Choose "No" and you have hand-built the silent failure — the endpoint works, the name still points public. This is the tab to slow down on.

  7. Review + create, then Create. Wait for deployment, then open the endpoint and confirm it shows Approved.

  8. Verify, then lock: from a VM or the app's console inside the VNet, run nslookup on the storage name and confirm a private IP; then open the storage account's Networking blade and set Public network access to Disabled.On screen: the storage Networking blade now lists your private endpoint under "Private endpoint connections", and public access reads Disabled — the picture from Figure 8, made real.

  9. Delete the resource group when finished so the endpoint, storage account and DNS zone all disappear together.

Portal wording and tab order drift over time; if a label here does not match your screen, the concept is the anchor — resource, sub-resource, subnet, and the DNS-integration toggle.

Lab 3 · Explore the service

Read what the blades are telling you

~5 minutes · look, do not change — learn the service by its own screens

Creating a thing and reading a thing are different skills, and interviews and incidents both test the second. Open what you built and let each blade explain a concept you just met.

  1. Open the private endpoint resource and read its overview: the private IP, the VNet and subnet it lives in, and the resource it fronts.On screen: the "Network interface" link proves the point of the whole class — a private endpoint is a NIC. Follow it and you see an ordinary network card with a private IP, no different from a VM's.

  2. Open the Private DNS zone privatelink.blob.core.windows.net and look at its records and its "Virtual network links".On screen: an A record maps your account name to the private IP, and the VNet link shows which networks resolve it. This is, concretely, the thing whose absence causes the §4 trap — you are looking at the fix.

  3. Open the storage account → Networking blade and read the top of the page.On screen: "Public network access: Disabled" and a "Private endpoint connections" list with yours "Approved". Three settings tell the entire security story of this account at a glance.

  4. From inside the VNet, run nslookup on the storage name once more and read the answer as a sentence: name → privatelink CNAME → private IP.On screen: the resolution chain from §4, printed in your own terminal. If you can narrate those three hops out loud, you understand private connectivity better than most people who have configured it.

On the job

Closing the finding with a refused connection

You · Cloud Engineer · security wants the database off the internet

"Why is our database reachable from the public internet at all?" You agree, and fix it properly: a private endpoint gives the database a private IP in the subnet, a private DNS zone points the name at it, and public access is switched off. The app never notices — same connection string — and the auditor's finding closes with a screenshot of a refused public connection.

Class Fourteen

Examination

Four drills, then two situations. The situations have no marking scheme — write your answer before you reveal the reasoning, or the exercise is worthless. Nothing is stored; this is between you and the page.

Drill 01Recall · endpoint type
What does creating a private endpoint for a storage account actually provision?
Marked

B. A private endpoint is a NIC with a private IP in your subnet, connected to the one resource over Private Link — a genuine private presence inside your network. A describes a service endpoint, which only restricts access to the still-public address; that is the distinction the whole class turns on. C and D are inventions — no new public IP, no tunnel. If you can say "a NIC with a private IP," you can tell a private endpoint from everything that merely guards the public one.

Drill 02Recall · endpoint type
A team needs a storage account to have no public endpoint at all, reachable only from their network and a peered one. Service endpoint, or private endpoint?
Marked

B. Only a private endpoint provides a private IP and lets you set public network access to disabled, satisfying "no public endpoint." A is the trap: a service endpoint leaves the public IP in place and merely restricts who may use it — it can never satisfy a no-public-endpoint mandate. C ignores that the two differ precisely on this point, and D is false — public access can be disabled once a private endpoint exists. "Restrict the public door" and "remove the public door" are different requirements needing different tools.

Drill 03Select three
Which three statements are true?
Marked

The NIC with a private IP, the need for a linked Private DNS zone, and the cost difference. The two false statements are the load-bearing misconceptions: a service endpoint never grants a private IP — it restricts access to the public one — and DNS emphatically does not take care of itself. Azure inserts the CNAME to the privatelink name, but you must create and link the zone, or resolution falls back to the public IP. Believing DNS is automatic is precisely how the case file broke.

Drill 04Spot the error
This plan to make a storage account private will cause an outage. Which step is the flaw?
PLAN — take campuxstore private

1.  Create a private endpoint for the blob service in the data subnet.
2.  Disable public network access on the storage account.
3.  App keeps using campuxstore.blob.core.windows.net, unchanged.
4.  (No Private DNS zone is created or linked to the VNet.)
Marked

Line four. Without a Private DNS zone linked to the VNet, the storage name still resolves to the public IP. With public access then disabled at step 2, the app looks up the name, gets the public address, and is refused — a self-inflicted outage. Line three is fine if DNS is fixed; the name should not change, that is the point of the private zone. The missing zone is the whole failure.

Consider the ordering, too: even with the zone added, disabling public access (step 2) before verifying private resolution is reckless. The correct sequence is endpoint, zone, verify the lookup returns the private IP, then disable public access. This plan gets both the missing zone and the order wrong — and either alone would take the storefront down.

Situation 01Write before you reveal
Security issues a mandate: no Campux storage account may have a public endpoint, effective this quarter. Several are live and serving the storefront right now. Sequence the change so nothing goes down.
The dangerous version of this change is one step in the wrong order. Which step must come last?
Reasoning

Build the private path completely before removing the public one. For each account: create the private endpoint, create and link the Private DNS zone, wire it to the endpoint, and ensure the consuming apps are VNet-integrated so they can route to the private IP. Nothing customer-facing has changed yet — the public door is still open, so the site keeps working while you assemble the corridor.

Verify resolution from inside the network — this is the gate. From within the VNet, confirm the storage name now resolves to the private-endpoint IP, and that the app genuinely reaches storage over it. Only a passing lookup earns the right to proceed; "the portal shows it approved" is not the same as "the name resolves privately."

Disable public access last, and roll it out one account at a time. With the private path proven, set public network access to disabled — the only step that can break something, now made safe because the corridor is already carrying the traffic. Do it per account, watching each, rather than all at once. Then make it durable with an Azure Policy that denies public access on storage, so new accounts are born compliant and the mandate holds without anyone remembering it. Corridor first, verify, then brick the door — never the reverse.

Situation 02Write before you reveal
A teammate says: "Private endpoints cost money and DNS is fiddly. Let's just turn on a service endpoint for the subnet instead — it's free and it keeps traffic off the internet, so it's basically the same thing." Is it? Respond.
"Basically the same" hides the one difference the mandate is about.
Reasoning

Concede the true part: a service endpoint is free and does keep traffic on Azure's backbone. For a requirement that is only "restrict this service to my subnets," it is a perfectly good, cheaper answer, and reaching for a private endpoint there is over-engineering. So the teammate is not wrong in general — they are wrong for this requirement.

Name the difference that matters here. A service endpoint leaves the resource with a public IP and a public name; it restricts the guest list but never removes the door. The security mandate is "no public endpoint," which a service endpoint can never satisfy — the public endpoint still exists, merely firewalled. Only a private endpoint gives a private IP and lets public access be disabled outright.

Address the objections rather than dismiss them. The cost is modest and is what the mandate is buying; the DNS is fiddly exactly once, then codified into the standard pattern so it is never hand-done again. "Basically the same" collapses a real architectural distinction — restrict versus remove — into a phrase, and the auditor will not accept the phrase. Match the tool to the actual requirement, and here the requirement names private endpoints whether we like the price or not.

Examination record · first attempt
0/4
Class Fourteen · Complete
Retain this much

Five things worth carrying out of this class

  1. PaaS services are public by default. Locking the door with keys and firewalls is weaker than removing the public door entirely.
  2. A service endpoint restricts a still-public resource to your subnets; it is free but never removes the public endpoint.
  3. A private endpoint is a NIC with a private IP in your subnet, and lets you disable public access — genuine isolation, at a modest cost.
  4. A private endpoint without its linked Private DNS zone is not private: the name falls back to the public IP and the corridor is bypassed.
  5. The pattern is four parts — VNet integration, private endpoint, Private DNS zone, public access disabled — and you verify resolution before closing the public door.
Notes
  1. The fallback to public is deliberate, not a bug: the privatelink CNAME is publicly resolvable so that clients partway through a migration — some private, some not — keep working. The consequence for you is that a missing or unlinked Private DNS zone fails silently toward the public IP rather than erroring, which is exactly why it is so easy to miss. Always test the lookup from inside the network; a green portal blade is not proof.
  2. Resolving the private name from on-premises is a further step this class does not fully cover: on-prem resolvers do not see your Azure Private DNS zone, so you point them at a DNS forwarder or the Azure DNS Private Resolver living in the VNet, which then answers from the zone. Class Fifteen picks up that on-prem-to-Azure resolver picture; here, assume resolution happens from inside the VNet.
  3. Not every service exposes exactly the same knobs. The group id (blob, file, sqlServer, and so on) and the matching privatelink zone name differ per service and per sub-resource, and a storage account with several services needs a private endpoint and zone per service you want private. Check the current per-service DNS zone values before you build; the shape is identical, the names are not.