This deployment uses private endpoints for all services, which means they have no public network access. This is the recommended security posture for production workloads.
To access these private resources, the deployment includes:
- ✅ Azure Bastion - Secure browser-based access to VMs
- ✅ Jump VM (Windows) - Management VM inside the virtual network
# Get the Jump VM name from deployment outputs
azd env get-values | grep jumpVm
# Or in Azure Portal:
# 1. Navigate to your resource group
# 2. Find the VM (usually named like "vm-jump-<env>")
# 3. Click "Connect" → "Bastion"
# 4. Enter the username and password (auto-generated during deployment)
Once connected to the Jump VM, you can:
- Key Vault: Access via Azure Portal or Azure CLI
- Cosmos DB: Connect using Data Explorer in Azure Portal
- Azure AI Search: Manage indexes via Azure Portal
- Storage Account: Browse blobs via Azure Portal or Storage Explorer
- Container Registry: Push/pull images using Docker CLI
- AI Foundry: Manage projects and deployments
For enhanced productivity, install these tools on the Jump VM:
# Install Azure CLI
Invoke-WebRequest -Uri https://aka.ms/installazurecliwindows -OutFile .\AzureCLI.msi
Start-Process msiexec.exe -Wait -ArgumentList '/I AzureCLI.msi /quiet'
# Install Azure Storage Explorer
# Download from: https://azure.microsoft.com/features/storage-explorer/
# Install VS Code
# Download from: https://code.visualstudio.com/For production environments, consider:
- Azure VPN Gateway for site-to-site connectivity
- Point-to-Site VPN for individual users
- ExpressRoute for dedicated private connection
To enable VPN, you would need to:
- Deploy VPN Gateway in your VNet
- Configure client certificates or AAD authentication
- Connect from your local machine
If you need CI/CD access to private resources:
-
Enable Build VM in
infra/main.bicepparam:buildVm: true // Linux Build VM (for CI/CD) devopsBuildAgentsNsg: true // Required NSG
-
Add subnet to
vNetDefinition:{ name: 'snet-build-agents' addressPrefix: '10.0.7.0/28' } -
Self-hosted agents can then access private resources directly
You can configure services without private endpoints by modifying individual service definitions. However, this significantly reduces security posture.
| Resource | Monthly Cost (Estimate) | Why Needed |
|---|---|---|
| Azure Bastion Basic | ~$140 | Secure access to Jump VM |
| Jump VM (Standard B2s) | ~$35 | Management access to private resources |
| Total | ~$175/month | Required for private network access |
-
Bastion Basic vs Standard:
- Basic: $140/month, up to 25 concurrent sessions
- Standard: $310/month, unlimited sessions + more features
-
Jump VM Size:
- B2s (2 vCPUs, 4GB): ~$35/month (current default)
- B1s (1 vCPU, 1GB): ~$10/month (minimal usage)
- B4ms (4 vCPUs, 16GB): ~$140/month (heavy usage)
-
Stop Jump VM When Not in Use:
# Stop VM to save compute costs (you only pay for storage) az vm deallocate --resource-group <rg> --name <vm-name> # Start when needed az vm start --resource-group <rg> --name <vm-name>
Savings: ~$35/month when stopped (you still pay for Bastion + disk)
-
Remove Bastion + Jump VM for Development:
⚠️ Only for non-production environments where security is not criticalSet in
infra/main.bicepparam:bastionHost: false jumpVm: false bastionNsg: false jumpboxNsg: false
Remove subnets from
vNetDefinition:// Remove: AzureBastionSubnet // Remove: snet-jumpbox
Savings: ~$175/month
Trade-off: Cannot access private resources; must configure public access
- Use Bastion for Jump VM access - Never expose RDP/SSH ports publicly
- Enable Just-In-Time (JIT) access - Limit when the Jump VM can be accessed
- Use managed identities - Avoid storing credentials on the Jump VM
- Enable MFA - Require multi-factor authentication for Bastion access
- Monitor access - Review Bastion connection logs in Log Analytics
- Principle of least privilege - Grant minimal RBAC permissions needed
- Check Bastion subnet name is exactly
AzureBastionSubnet - Verify NSG allows Bastion traffic (bastionNsg should be enabled)
- Ensure Bastion subnet is at least /26 (64 addresses)
- Check Bastion deployment succeeded in Azure Portal
- Verify private endpoints were created for each service
- Check private DNS zones are linked to the VNet
- Ensure NSGs allow traffic from Jump VM subnet to private endpoints subnet
- Test DNS resolution:
nslookup <service-name>.vault.azure.net
Credentials are auto-generated during deployment. To reset:
az vm user update \
--resource-group <rg> \
--name <vm-name> \
--username azureuser \
--password <new-password>