01 / Problem
Separate workloads without implying transit.
The lab explores a common Azure foundation problem: keep application and data networks distinct, give an application a private path to Blob Storage, and make the routing and DNS implications reviewable before deploying anything.
The design had to stay small enough for a personal lab, avoid always-on premium network appliances and include safe deployment, validation and cleanup paths.
02 / Architecture
Three networks. One private service path.
10.0.0.0/16
Management and shared-services subnets, with bidirectional peering to each spoke.
10.10.0.0/16
Workload and private-endpoint subnets. Hosts the Blob private endpoint and receives the private DNS link.
10.20.0.0/16
Separate workload boundary with no app peering or private DNS link to the Blob endpoint.
03 / Implementation
Modules align with operational boundaries.
Subscription-scope orchestration creates project resource groups, then modules define hub networking, spokes, peerings, storage, private DNS, monitoring and cost controls. NSGs and application security groups describe workload intent; user-defined routes blackhole the opposite spoke prefix.
Bash and PowerShell lifecycle scripts verify the active subscription, compile parameters, perform ARM validation and what-if, then require an exact confirmation. Cleanup derives exact names and checks canonical tags and inventories before deletion.
offline checks
→ Bicep + parameter compilation
→ shell / PowerShell guard tests
authorized lifecycle (pending)
→ subscription check → validate → what-if
→ exact confirmation → deploy → connectivity tests
→ ownership checks → teardown04 / Decisions & trade-offs
Private access depends on routing and DNS together.
- No transit appliance: hub peering does not create transitive spoke routing. Omitting Firewall, an NVA and gateways limits cost and scope but also excludes centralized inspected transit.
- Private by default: Blob public networking and shared-key authentication are disabled. The endpoint and private DNS links are authored as one access path.
- Optional compute: the private test VM defaults off. When enabled, it uses VM Run Command without a public IP or inbound SSH rule.
- Optional flow logs: VNet flow logs default off and require an existing regional Network Watcher; Traffic Analytics stays disabled.
- Guarded teardown: cleanup refuses unexpected ownership or inventory instead of broadly deleting subscription resources.
05 / Validation
Offline confidence, live evidence pending.
- Public CI succeededThe linked main-branch run on 4 August 2026 compiled Bicep and parameters, checked scripts and documentation, and scanned for secrets.Run 30944553717 ↗
- Cleanup failure paths are exercised offlineA mock Azure CLI verifies that authentication, ownership and inventory failures stop destructive operations.Repository tests · offline only
- Authenticated Azure validation is pendingNo source evidence yet proves ARM validation,
what-if, resource creation, private DNS/HTTPS behavior, isolation, teardown or cost.No live deployment claim
06 / Current status
Lab: CI validated; Azure deployment pending.
The architecture, Bicep, lifecycle scripts and offline checks are authored. The next evidence milestone requires an authorized personal Azure subscription, cost review, authenticated validation, reviewed what-if, bounded deployment, runtime connectivity tests and ownership-checked teardown.
07 / What I learned
Segmentation is a behavior, not a diagram shape.
Peering, routing and DNS each need distinct tests. Private Link only becomes a usable private path when name resolution and network policy agree. Designing cleanup at the same time as deployment made resource ownership and failure handling much clearer.