Scenario
Your organisation recently migrated several internal applications into Azure. To simplify deployment, all workloads were placed inside a single virtual network with multiple subnets. During a routine security review, the security team discovered that every VM inside the VNET could freely communicate with every other VM, regardless of workload sensitivity.
This raised a major concern: if one VM were ever compromised, an attacker could move laterally across the network without resistance.
You’ve been asked to implement a solution that:
- Prevents unrestricted communication between subnets
- Allows only the traffic required for each workload
- Enforces least‑privilege access
- Uses Azure‑native controls that scale easily
- Avoids exposing any VM to the public internet
Lab Objectives
- Create a virtual network with multiple subnets
- Deploy Windows and Linux virtual machines
- Configure Azure Bastion for secure RDP/SSH access
- Apply NSGs at the subnet level
- Create custom rules to control traffic between subnets
- Validate that only approved traffic is allowed
Prerequisites
- An active Azure subscription
- Permissions to create networking and compute resources
- Basic understanding of Azure VNETs and NSGs
Create the Virtual Network and Subnets
Create a virtual network with the following subnets:
AzureBastionSubnet
- Required for Azure Bastion
- Must be named exactly:
AzureBastionSubnet
PC Subnet
- Hosts the Windows 11 client VM
Web Server Subnet
- Hosts the Linux web server VM
After creation, verify that all three subnets appear under the VNET.
Deploy the Virtual Machines
Windows 11 VM
- Deploy into the PC Subnet
- No public IP address
- Will be accessed via Azure Bastion (RDP)
Linux Web Server
- Deploy into the Web Server Subnet
- No public IP address
- Will be accessed via Azure Bastion (SSH)
- Install a simple web server such as Apache or Nginx
Once deployed, confirm both VMs are reachable through Bastion.
Configure Azure Bastion
- Create Azure Bastion in the AzureBastionSubnet
- Open each VM and select Connect → Bastion
- Use RDP (Windows) or SSH (Linux) to verify access
- Confirm that neither VM has a public IP assigned
This ensures secure access without exposing the VMs to the internet.
Create and Apply Subnet-Level NSGs
You will create two NSGs and associate them with the PC Subnet and Web Server Subnet.
NSG for PC Subnet
| Rule Name | Source | Destination | Port | Action | Purpose |
|---|---|---|---|---|---|
| Allow‑RDP‑From‑Bastion | Bastion Subnet | PC Subnet | 3389 | Allow | Enable RDP via Bastion |
| Allow‑AzureLB | Azure Load Balancer | PC Subnet | Any | Allow | Required by Azure services |
| Deny‑All | Any | Any | Any | Deny | Block all other traffic |
Associate this NSG with the PC Subnet.
NSG for Web Server Subnet
| Rule Name | Source | Destination | Port | Action | Purpose |
|---|---|---|---|---|---|
| Allow‑SSH‑From‑Bastion | Bastion Subnet | Web Server Subnet | 22 | Allow | Enable SSH via Bastion |
| Allow‑HTTP‑From‑PC | PC Subnet | Web Server Subnet | 80 | Allow | Allow PC to access the web server |
| Allow‑AzureLB | Azure Load Balancer | Web Server Subnet | Any | Allow | Required by Azure services |
| Deny‑All | Any | Any | Any | Deny | Block all other traffic |
Associate this NSG with the Web Server Subnet.
Validate Traffic Flow
Before applying NSGs, all VMs could communicate freely inside the VNET.
After applying NSGs:
- Bastion → PC (RDP): Allowed
- Bastion → Web Server (SSH): Allowed
- PC → Web Server (HTTP): Allowed
- Any other traffic: Denied
This enforces least‑privilege access and prevents lateral movement between workloads.
Conclusion
By applying NSGs at the subnet level, you’ve implemented a scalable and secure method for controlling traffic inside an Azure virtual network. This approach aligns with zero‑trust principles and ensures that only required communication paths remain open while all other traffic is blocked.