diff --git a/.gitignore b/.gitignore
index 8ce960d..d491460 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,352 +1,352 @@
-## Ignore Visual Studio temporary files, build results, and
-## files generated by popular Visual Studio add-ons.
-##
-## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
-
-main.json
-
-# User-specific files
-*.rsuser
-*.suo
-*.user
-*.userosscache
-*.sln.docstates
-
-# User-specific files (MonoDevelop/Xamarin Studio)
-*.userprefs
-
-# Mono auto generated files
-mono_crash.*
-
-# Build results
-[Dd]ebug/
-[Dd]ebugPublic/
-[Rr]elease/
-[Rr]eleases/
-x64/
-x86/
-[Aa][Rr][Mm]/
-[Aa][Rr][Mm]64/
-bld/
-[Bb]in/
-[Oo]bj/
-[Ll]og/
-[Ll]ogs/
-
-# Visual Studio 2015/2017 cache/options directory
-.vs/
-# Uncomment if you have tasks that create the project's static files in wwwroot
-#wwwroot/
-
-# Visual Studio 2017 auto generated files
-Generated\ Files/
-
-# MSTest test Results
-[Tt]est[Rr]esult*/
-[Bb]uild[Ll]og.*
-
-# NUnit
-*.VisualState.xml
-TestResult.xml
-nunit-*.xml
-
-# Build Results of an ATL Project
-[Dd]ebugPS/
-[Rr]eleasePS/
-dlldata.c
-
-# Benchmark Results
-BenchmarkDotNet.Artifacts/
-
-# .NET Core
-project.lock.json
-project.fragment.lock.json
-artifacts/
-
-# StyleCop
-StyleCopReport.xml
-
-# Files built by Visual Studio
-*_i.c
-*_p.c
-*_h.h
-*.ilk
-*.meta
-*.obj
-*.iobj
-*.pch
-*.pdb
-*.ipdb
-*.pgc
-*.pgd
-*.rsp
-*.sbr
-*.tlb
-*.tli
-*.tlh
-*.tmp
-*.tmp_proj
-*_wpftmp.csproj
-*.log
-*.vspscc
-*.vssscc
-.builds
-*.pidb
-*.svclog
-*.scc
-
-# Chutzpah Test files
-_Chutzpah*
-
-# Visual C++ cache files
-ipch/
-*.aps
-*.ncb
-*.opendb
-*.opensdf
-*.sdf
-*.cachefile
-*.VC.db
-*.VC.VC.opendb
-
-# Visual Studio profiler
-*.psess
-*.vsp
-*.vspx
-*.sap
-
-# Visual Studio Trace Files
-*.e2e
-
-# TFS 2012 Local Workspace
-$tf/
-
-# Guidance Automation Toolkit
-*.gpState
-
-# ReSharper is a .NET coding add-in
-_ReSharper*/
-*.[Rr]e[Ss]harper
-*.DotSettings.user
-
-# TeamCity is a build add-in
-_TeamCity*
-
-# DotCover is a Code Coverage Tool
-*.dotCover
-
-# AxoCover is a Code Coverage Tool
-.axoCover/*
-!.axoCover/settings.json
-
-# Visual Studio code coverage results
-*.coverage
-*.coveragexml
-
-# NCrunch
-_NCrunch_*
-.*crunch*.local.xml
-nCrunchTemp_*
-
-# MightyMoose
-*.mm.*
-AutoTest.Net/
-
-# Web workbench (sass)
-.sass-cache/
-
-# Installshield output folder
-[Ee]xpress/
-
-# DocProject is a documentation generator add-in
-DocProject/buildhelp/
-DocProject/Help/*.HxT
-DocProject/Help/*.HxC
-DocProject/Help/*.hhc
-DocProject/Help/*.hhk
-DocProject/Help/*.hhp
-DocProject/Help/Html2
-DocProject/Help/html
-
-# Click-Once directory
-publish/
-
-# Publish Web Output
-*.[Pp]ublish.xml
-*.azurePubxml
-# Note: Comment the next line if you want to checkin your web deploy settings,
-# but database connection strings (with potential passwords) will be unencrypted
-*.pubxml
-*.publishproj
-
-# Microsoft Azure Web App publish settings. Comment the next line if you want to
-# checkin your Azure Web App publish settings, but sensitive information contained
-# in these scripts will be unencrypted
-PublishScripts/
-
-# NuGet Packages
-*.nupkg
-# NuGet Symbol Packages
-*.snupkg
-# The packages folder can be ignored because of Package Restore
-**/[Pp]ackages/*
-# except build/, which is used as an MSBuild target.
-!**/[Pp]ackages/build/
-# Uncomment if necessary however generally it will be regenerated when needed
-#!**/[Pp]ackages/repositories.config
-# NuGet v3's project.json files produces more ignorable files
-*.nuget.props
-*.nuget.targets
-
-# Microsoft Azure Build Output
-csx/
-*.build.csdef
-
-# Microsoft Azure Emulator
-ecf/
-rcf/
-
-# Windows Store app package directories and files
-AppPackages/
-BundleArtifacts/
-Package.StoreAssociation.xml
-_pkginfo.txt
-*.appx
-*.appxbundle
-*.appxupload
-
-# Visual Studio cache files
-# files ending in .cache can be ignored
-*.[Cc]ache
-# but keep track of directories ending in .cache
-!?*.[Cc]ache/
-
-# Others
-ClientBin/
-~$*
-*~
-*.dbmdl
-*.dbproj.schemaview
-*.jfm
-*.pfx
-*.publishsettings
-orleans.codegen.cs
-
-# Including strong name files can present a security risk
-# (https://github.com/github/gitignore/pull/2483#issue-259490424)
-#*.snk
-
-# Since there are multiple workflows, uncomment next line to ignore bower_components
-# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
-#bower_components/
-
-# RIA/Silverlight projects
-Generated_Code/
-
-# Backup & report files from converting an old project file
-# to a newer Visual Studio version. Backup files are not needed,
-# because we have git ;-)
-_UpgradeReport_Files/
-Backup*/
-UpgradeLog*.XML
-UpgradeLog*.htm
-ServiceFabricBackup/
-*.rptproj.bak
-
-# SQL Server files
-*.mdf
-*.ldf
-*.ndf
-
-# Business Intelligence projects
-*.rdl.data
-*.bim.layout
-*.bim_*.settings
-*.rptproj.rsuser
-*- [Bb]ackup.rdl
-*- [Bb]ackup ([0-9]).rdl
-*- [Bb]ackup ([0-9][0-9]).rdl
-
-# Microsoft Fakes
-FakesAssemblies/
-
-# GhostDoc plugin setting file
-*.GhostDoc.xml
-
-# Node.js Tools for Visual Studio
-.ntvs_analysis.dat
-node_modules/
-
-# Visual Studio 6 build log
-*.plg
-
-# Visual Studio 6 workspace options file
-*.opt
-
-# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
-*.vbw
-
-# Visual Studio LightSwitch build output
-**/*.HTMLClient/GeneratedArtifacts
-**/*.DesktopClient/GeneratedArtifacts
-**/*.DesktopClient/ModelManifest.xml
-**/*.Server/GeneratedArtifacts
-**/*.Server/ModelManifest.xml
-_Pvt_Extensions
-
-# Paket dependency manager
-.paket/paket.exe
-paket-files/
-
-# FAKE - F# Make
-.fake/
-
-# CodeRush personal settings
-.cr/personal
-
-# Python Tools for Visual Studio (PTVS)
-__pycache__/
-*.pyc
-
-# Cake - Uncomment if you are using it
-# tools/**
-# !tools/packages.config
-
-# Tabs Studio
-*.tss
-
-# Telerik's JustMock configuration file
-*.jmconfig
-
-# BizTalk build output
-*.btp.cs
-*.btm.cs
-*.odx.cs
-*.xsd.cs
-
-# OpenCover UI analysis results
-OpenCover/
-
-# Azure Stream Analytics local run output
-ASALocalRun/
-
-# MSBuild Binary and Structured Log
-*.binlog
-
-# NVidia Nsight GPU debugger configuration file
-*.nvuser
-
-# MFractors (Xamarin productivity tool) working folder
-.mfractor/
-
-# Local History for Visual Studio
-.localhistory/
-
-# BeatPulse healthcheck temp database
-healthchecksdb
-
-# Backup folder for Package Reference Convert tool in Visual Studio 2017
-MigrationBackup/
-
-# Ionide (cross platform F# VS Code tools) working folder
-.ionide/
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
+
+main.json
+
+# User-specific files
+*.rsuser
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Mono auto generated files
+mono_crash.*
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+[Ll]ogs/
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# Visual Studio 2017 auto generated files
+Generated\ Files/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUnit
+*.VisualState.xml
+TestResult.xml
+nunit-*.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET Core
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
+*_i.c
+*_p.c
+*_h.h
+*.ilk
+*.meta
+*.obj
+*.iobj
+*.pch
+*.pdb
+*.ipdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*_wpftmp.csproj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# NuGet Symbol Packages
+*.snupkg
+# The packages folder can be ignored because of Package Restore
+**/[Pp]ackages/*
+# except build/, which is used as an MSBuild target.
+!**/[Pp]ackages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+*.appxbundle
+*.appxupload
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!?*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+*.rptproj.rsuser
+*- [Bb]ackup.rdl
+*- [Bb]ackup ([0-9]).rdl
+*- [Bb]ackup ([0-9][0-9]).rdl
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# CodeRush personal settings
+.cr/personal
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
+
+# Local History for Visual Studio
+.localhistory/
+
+# BeatPulse healthcheck temp database
+healthchecksdb
+
+# Backup folder for Package Reference Convert tool in Visual Studio 2017
+MigrationBackup/
+
+# Ionide (cross platform F# VS Code tools) working folder
+.ionide/
diff --git a/deploy/README.md b/deploy/README.md
index 9a2ce93..3e7efe0 100644
--- a/deploy/README.md
+++ b/deploy/README.md
@@ -1,24 +1,24 @@
-# Sample
-
-## Getting started
-
-This sample uses [Bicep](https://docs.microsoft.com/en-us/azure/azure-resource-manager/bicep/overview) to define a modular deployment presented in [topology](../doc/topology.md).
-
-### Install
-
-1. Install the Azure CLI by following the [docs](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) article.
-
-1. Install Bicep from within the Azure CLI:
-
-```
-$ az bicep install
-```
-
-### Deploy
-
-1. Deploy the `main.bicep` file from the `src` directory of this sample:
-
-```
-$ cd deploy/src/
-$ az deployment sub create --location australiacentral --template-file main.bicep
-```
+# Sample
+
+## Getting started
+
+This sample uses [Bicep](https://docs.microsoft.com/en-us/azure/azure-resource-manager/bicep/overview) to define a modular deployment presented in [topology](../doc/topology.md).
+
+### Install
+
+1. Install the Azure CLI by following the [docs](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) article.
+
+1. Install Bicep from within the Azure CLI:
+
+```
+$ az bicep install
+```
+
+### Deploy
+
+1. Deploy the `main.bicep` file from the `src` directory of this sample:
+
+```
+$ cd deploy/src/
+$ az deployment sub create --location australiacentral --template-file main.bicep
+```
diff --git a/deploy/nva/1-nic+mgmt/cloud-init/20-disable-config-network.cfg b/deploy/nva/1-nic+mgmt/cloud-init/20-disable-config-network.cfg
new file mode 100644
index 0000000..8f6600c
--- /dev/null
+++ b/deploy/nva/1-nic+mgmt/cloud-init/20-disable-config-network.cfg
@@ -0,0 +1,2 @@
+network:
+ config: disabled
\ No newline at end of file
diff --git a/deploy/nva/1-nic+mgmt/cloud-init/README.md b/deploy/nva/1-nic+mgmt/cloud-init/README.md
new file mode 100644
index 0000000..689d4a3
--- /dev/null
+++ b/deploy/nva/1-nic+mgmt/cloud-init/README.md
@@ -0,0 +1 @@
+Place these files in `/etc/cloud/cloud.cfg.d/`.
diff --git a/deploy/nva/1-nic+mgmt/iptables/README.md b/deploy/nva/1-nic+mgmt/iptables/README.md
new file mode 100644
index 0000000..1f1024c
--- /dev/null
+++ b/deploy/nva/1-nic+mgmt/iptables/README.md
@@ -0,0 +1 @@
+Place these files in `/etc/iptables/`.
diff --git a/deploy/nva/1-nic+mgmt/iptables/iptables.rules b/deploy/nva/1-nic+mgmt/iptables/iptables.rules
new file mode 100644
index 0000000..b4a4abc
--- /dev/null
+++ b/deploy/nva/1-nic+mgmt/iptables/iptables.rules
@@ -0,0 +1,51 @@
+# Generated by iptables-save v1.8.7 on Thu Aug 12 00:48:20 2021
+*filter
+:INPUT ACCEPT [26093:11318598]
+:FORWARD ACCEPT [3795:7962603]
+:OUTPUT ACCEPT [28950:9367807]
+COMMIT
+# Completed on Thu Aug 12 00:48:20 2021
+# Generated by iptables-save v1.8.7 on Thu Aug 12 00:48:20 2021
+*mangle
+:PREROUTING ACCEPT [6678:10373822]
+:INPUT ACCEPT [5301:2588033]
+:FORWARD ACCEPT [1377:7785789]
+:OUTPUT ACCEPT [6125:2025111]
+:POSTROUTING ACCEPT [7502:9810900]
+-A PREROUTING ! -s 168.63.129.16/32 -i eth1 -j MARK --set-xmark 0x100/0x300 # in eth1 not AzILB probe use route table 0x100.
+-A PREROUTING -s 168.63.129.16/32 -i eth1 -j MARK --set-xmark 0x1000/0x3000 # in eth1 and AzILB probe use route table 0x1000.
+-A PREROUTING -d 20.36.44.155/32 -i eth1 -j MARK --set-xmark 0x1/0xff # in eth1 and from a LB rule add extra mark for dnat/snat.
+-A PREROUTING -j CONNMARK --save-mark --nfmask 0xffffffff --ctmask 0xffffffff # save all marks.
+-A FORWARD -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff # restore all marks from local.
+-A OUTPUT -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff # restore all marks through local.
+COMMIT
+# Completed on Thu Aug 12 00:48:20 2021
+# Generated by iptables-save v1.8.7 on Thu Aug 12 00:48:20 2021
+*nat
+:PREROUTING ACCEPT [327:17028]
+:INPUT ACCEPT [324:16848]
+:OUTPUT ACCEPT [790:49662]
+:POSTROUTING ACCEPT [0:0]
+-A PREROUTING -i eth1 -p tcp -m mark --mark 0x1/0xff -m tcp --dport 80 -j DNAT --to-destination 10.0.4.12:8080
+-A POSTROUTING -o eth1 -m mark --mark 0x1/0xff -j MASQUERADE
+-A POSTROUTING -o eth1 -s 10.0.0.0/8 -d 10.0.0.0/8 -j ACCEPT
+-A POSTROUTING -o eth1 -s 10.0.0.0/8 -d 172.16.0.0/12 -j ACCEPT
+-A POSTROUTING -o eth1 -s 10.0.0.0/8 -d 192.168.0.0/16 -j ACCEPT
+-A POSTROUTING -o eth1 -s 172.16.0.0/12 -d 10.0.0.0/8 -j ACCEPT
+-A POSTROUTING -o eth1 -s 172.16.0.0/12 -d 172.16.0.0/12 -j ACCEPT
+-A POSTROUTING -o eth1 -s 172.16.0.0/12 -d 192.168.0.0/16 -j ACCEPT
+-A POSTROUTING -o eth1 -s 192.168.0.0/16 -d 10.0.0.0/8 -j ACCEPT
+-A POSTROUTING -o eth1 -s 192.168.0.0/16 -d 172.16.0.0/12 -j ACCEPT
+-A POSTROUTING -o eth1 -s 192.168.0.0/16 -d 192.168.0.0/16 -j ACCEPT
+-A POSTROUTING -o eth1 -j MASQUERADE
+COMMIT
+# Completed on Thu Aug 12 00:48:20 2021
+# Generated by iptables-save v1.8.7 on Thu Aug 12 00:48:20 2021
+*security
+:INPUT ACCEPT [6718:3316200]
+:FORWARD ACCEPT [1999:7837749]
+:OUTPUT ACCEPT [2587:426353]
+-A OUTPUT -d 168.63.129.16/32 -p tcp -m owner --uid-owner 0 -j ACCEPT
+-A OUTPUT -d 168.63.129.16/32 -p tcp -m conntrack --ctstate INVALID,NEW -j DROP
+COMMIT
+# Completed on Thu Aug 12 00:48:20 2021
\ No newline at end of file
diff --git a/deploy/nva/1-nic+mgmt/sysctl/99-enable-ipv4-forwarding.conf b/deploy/nva/1-nic+mgmt/sysctl/99-enable-ipv4-forwarding.conf
new file mode 100644
index 0000000..5aad62d
--- /dev/null
+++ b/deploy/nva/1-nic+mgmt/sysctl/99-enable-ipv4-forwarding.conf
@@ -0,0 +1 @@
+net.ipv4.ip_forward = 1
\ No newline at end of file
diff --git a/deploy/nva/1-nic+mgmt/sysctl/README.md b/deploy/nva/1-nic+mgmt/sysctl/README.md
new file mode 100644
index 0000000..f4dd235
--- /dev/null
+++ b/deploy/nva/1-nic+mgmt/sysctl/README.md
@@ -0,0 +1 @@
+Place these files in `/etc/sysctl.d/`.
diff --git a/deploy/nva/1-nic+mgmt/systemd-networkd/README.md b/deploy/nva/1-nic+mgmt/systemd-networkd/README.md
new file mode 100644
index 0000000..96bc866
--- /dev/null
+++ b/deploy/nva/1-nic+mgmt/systemd-networkd/README.md
@@ -0,0 +1 @@
+Place these files in `/etc/systemd/network`.
diff --git a/deploy/nva/1-nic+mgmt/systemd-networkd/eth0.network b/deploy/nva/1-nic+mgmt/systemd-networkd/eth0.network
new file mode 100644
index 0000000..c31a23c
--- /dev/null
+++ b/deploy/nva/1-nic+mgmt/systemd-networkd/eth0.network
@@ -0,0 +1,9 @@
+[Match]
+Name=eth0
+
+[Network]
+DHCP=ipv4
+LinkLocalAddressing=no
+
+[DHCPv4]
+UseMTU=yes
diff --git a/deploy/nva/1-nic+mgmt/systemd-networkd/eth1.network b/deploy/nva/1-nic+mgmt/systemd-networkd/eth1.network
new file mode 100644
index 0000000..af1c8f3
--- /dev/null
+++ b/deploy/nva/1-nic+mgmt/systemd-networkd/eth1.network
@@ -0,0 +1,39 @@
+[Match]
+Name=eth1
+
+[Network]
+DHCP=ipv4
+LinkLocalAddressing=no
+
+[DHCPv4]
+UseMTU=yes
+UseRoutes=no
+UseDNS=no
+
+# Define local route policy for load balancer probe
+
+[RoutingPolicyRule]
+From=0.0.0.0/0
+FirewallMark=0x1000/0x00003000
+Table=1000
+
+[Route]
+Destination=168.63.129.16/32
+Gateway=10.0.1.177
+GatewayOnLink=yes
+Metric=10
+Table=1000
+
+# Define routes for this interface
+
+[RoutingPolicyRule]
+From=0.0.0.0/0
+FirewallMark=0x100/0x00000300
+Table=100
+
+[Route]
+Destination=0.0.0.0/0
+Gateway=10.0.1.177
+GatewayOnLink=yes
+Metric=10
+Table=100
\ No newline at end of file
diff --git a/deploy/nva/1-nic/cloud-init/20-disable-config-network.cfg b/deploy/nva/1-nic/cloud-init/20-disable-config-network.cfg
new file mode 100644
index 0000000..8f6600c
--- /dev/null
+++ b/deploy/nva/1-nic/cloud-init/20-disable-config-network.cfg
@@ -0,0 +1,2 @@
+network:
+ config: disabled
\ No newline at end of file
diff --git a/deploy/nva/1-nic/cloud-init/README.md b/deploy/nva/1-nic/cloud-init/README.md
new file mode 100644
index 0000000..689d4a3
--- /dev/null
+++ b/deploy/nva/1-nic/cloud-init/README.md
@@ -0,0 +1 @@
+Place these files in `/etc/cloud/cloud.cfg.d/`.
diff --git a/deploy/nva/1-nic/iptables/README.md b/deploy/nva/1-nic/iptables/README.md
new file mode 100644
index 0000000..1f1024c
--- /dev/null
+++ b/deploy/nva/1-nic/iptables/README.md
@@ -0,0 +1 @@
+Place these files in `/etc/iptables/`.
diff --git a/deploy/nva/1-nic/iptables/iptables.rules b/deploy/nva/1-nic/iptables/iptables.rules
new file mode 100644
index 0000000..bcb6b9f
--- /dev/null
+++ b/deploy/nva/1-nic/iptables/iptables.rules
@@ -0,0 +1,49 @@
+# Generated by iptables-save v1.8.7 on Thu Aug 12 00:48:20 2021
+*filter
+:INPUT ACCEPT [26093:11318598]
+:FORWARD ACCEPT [3795:7962603]
+:OUTPUT ACCEPT [28950:9367807]
+COMMIT
+# Completed on Thu Aug 12 00:48:20 2021
+# Generated by iptables-save v1.8.7 on Thu Aug 12 00:48:20 2021
+*mangle
+:PREROUTING ACCEPT [6678:10373822]
+:INPUT ACCEPT [5301:2588033]
+:FORWARD ACCEPT [1377:7785789]
+:OUTPUT ACCEPT [6125:2025111]
+:POSTROUTING ACCEPT [7502:9810900]
+-A PREROUTING -d 20.36.44.155/32 -i eth0 -j MARK --set-xmark 0x1/0xff # in eth0 and from a LB rule add extra mark for dnat/snat.
+-A PREROUTING -j CONNMARK --save-mark --nfmask 0xffffffff --ctmask 0xffffffff # save all marks.
+-A FORWARD -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff # restore all marks from local.
+-A OUTPUT -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff # restore all marks through local.
+COMMIT
+# Completed on Thu Aug 12 00:48:20 2021
+# Generated by iptables-save v1.8.7 on Thu Aug 12 00:48:20 2021
+*nat
+:PREROUTING ACCEPT [327:17028]
+:INPUT ACCEPT [324:16848]
+:OUTPUT ACCEPT [790:49662]
+:POSTROUTING ACCEPT [0:0]
+-A PREROUTING -i eth0 -p tcp -m mark --mark 0x1/0xff -m tcp --dport 80 -j DNAT --to-destination 10.0.4.12:8080
+-A POSTROUTING -o eth0 -m mark --mark 0x1/0xff -j MASQUERADE
+-A POSTROUTING -o eth0 -s 10.0.0.0/8 -d 10.0.0.0/8 -j ACCEPT
+-A POSTROUTING -o eth0 -s 10.0.0.0/8 -d 172.16.0.0/12 -j ACCEPT
+-A POSTROUTING -o eth0 -s 10.0.0.0/8 -d 192.168.0.0/16 -j ACCEPT
+-A POSTROUTING -o eth0 -s 172.16.0.0/12 -d 10.0.0.0/8 -j ACCEPT
+-A POSTROUTING -o eth0 -s 172.16.0.0/12 -d 172.16.0.0/12 -j ACCEPT
+-A POSTROUTING -o eth0 -s 172.16.0.0/12 -d 192.168.0.0/16 -j ACCEPT
+-A POSTROUTING -o eth0 -s 192.168.0.0/16 -d 10.0.0.0/8 -j ACCEPT
+-A POSTROUTING -o eth0 -s 192.168.0.0/16 -d 172.16.0.0/12 -j ACCEPT
+-A POSTROUTING -o eth0 -s 192.168.0.0/16 -d 192.168.0.0/16 -j ACCEPT
+-A POSTROUTING -o eth0 -j MASQUERADE
+COMMIT
+# Completed on Thu Aug 12 00:48:20 2021
+# Generated by iptables-save v1.8.7 on Thu Aug 12 00:48:20 2021
+*security
+:INPUT ACCEPT [6718:3316200]
+:FORWARD ACCEPT [1999:7837749]
+:OUTPUT ACCEPT [2587:426353]
+-A OUTPUT -d 168.63.129.16/32 -p tcp -m owner --uid-owner 0 -j ACCEPT
+-A OUTPUT -d 168.63.129.16/32 -p tcp -m conntrack --ctstate INVALID,NEW -j DROP
+COMMIT
+# Completed on Thu Aug 12 00:48:20 2021
\ No newline at end of file
diff --git a/deploy/nva/1-nic/sysctl/99-enable-ipv4-forwarding.conf b/deploy/nva/1-nic/sysctl/99-enable-ipv4-forwarding.conf
new file mode 100644
index 0000000..5aad62d
--- /dev/null
+++ b/deploy/nva/1-nic/sysctl/99-enable-ipv4-forwarding.conf
@@ -0,0 +1 @@
+net.ipv4.ip_forward = 1
\ No newline at end of file
diff --git a/deploy/nva/1-nic/sysctl/README.md b/deploy/nva/1-nic/sysctl/README.md
new file mode 100644
index 0000000..f4dd235
--- /dev/null
+++ b/deploy/nva/1-nic/sysctl/README.md
@@ -0,0 +1 @@
+Place these files in `/etc/sysctl.d/`.
diff --git a/deploy/nva/1-nic/systemd-networkd/README.md b/deploy/nva/1-nic/systemd-networkd/README.md
new file mode 100644
index 0000000..96bc866
--- /dev/null
+++ b/deploy/nva/1-nic/systemd-networkd/README.md
@@ -0,0 +1 @@
+Place these files in `/etc/systemd/network`.
diff --git a/deploy/nva/1-nic/systemd-networkd/eth0.network b/deploy/nva/1-nic/systemd-networkd/eth0.network
new file mode 100644
index 0000000..c31a23c
--- /dev/null
+++ b/deploy/nva/1-nic/systemd-networkd/eth0.network
@@ -0,0 +1,9 @@
+[Match]
+Name=eth0
+
+[Network]
+DHCP=ipv4
+LinkLocalAddressing=no
+
+[DHCPv4]
+UseMTU=yes
diff --git a/deploy/nva/2-nic+mgmt/cloud-init/20-disable-config-network.cfg b/deploy/nva/2-nic+mgmt/cloud-init/20-disable-config-network.cfg
new file mode 100644
index 0000000..8f6600c
--- /dev/null
+++ b/deploy/nva/2-nic+mgmt/cloud-init/20-disable-config-network.cfg
@@ -0,0 +1,2 @@
+network:
+ config: disabled
\ No newline at end of file
diff --git a/deploy/nva/2-nic+mgmt/cloud-init/README.md b/deploy/nva/2-nic+mgmt/cloud-init/README.md
new file mode 100644
index 0000000..689d4a3
--- /dev/null
+++ b/deploy/nva/2-nic+mgmt/cloud-init/README.md
@@ -0,0 +1 @@
+Place these files in `/etc/cloud/cloud.cfg.d/`.
diff --git a/deploy/nva/2-nic+mgmt/iptables/README.md b/deploy/nva/2-nic+mgmt/iptables/README.md
new file mode 100644
index 0000000..1f1024c
--- /dev/null
+++ b/deploy/nva/2-nic+mgmt/iptables/README.md
@@ -0,0 +1 @@
+Place these files in `/etc/iptables/`.
diff --git a/deploy/nva/2-nic+mgmt/iptables/iptables.rules b/deploy/nva/2-nic+mgmt/iptables/iptables.rules
new file mode 100644
index 0000000..756fb9d
--- /dev/null
+++ b/deploy/nva/2-nic+mgmt/iptables/iptables.rules
@@ -0,0 +1,44 @@
+# Generated by iptables-save v1.8.7 on Wed Aug 11 23:16:43 2021
+*filter
+:INPUT ACCEPT [503846:245889975]
+:FORWARD ACCEPT [11715:572454]
+:OUTPUT ACCEPT [593369:190021026]
+COMMIT
+# Completed on Wed Aug 11 23:16:43 2021
+# Generated by iptables-save v1.8.7 on Wed Aug 11 23:16:43 2021
+*mangle
+:PREROUTING ACCEPT [1579:386844]
+:INPUT ACCEPT [1265:373204]
+:FORWARD ACCEPT [314:13640]
+:OUTPUT ACCEPT [1339:464027]
+:POSTROUTING ACCEPT [1653:477667]
+-A PREROUTING ! -s 168.63.129.16/32 -i eth1 -j MARK --set-xmark 0x100/0x300 # in eth1 not AzILB probe use route table 0x100.
+-A PREROUTING ! -s 168.63.129.16/32 -i eth2 -j MARK --set-xmark 0x100/0x300 # in eth2 not AzPLB probe use route table 0x100.
+-A PREROUTING -s 168.63.129.16/32 -i eth1 -j MARK --set-xmark 0x1000/0x3000 # in eth1 and AzILB probe use route table 0x1000.
+-A PREROUTING -s 168.63.129.16/32 -i eth2 -j MARK --set-xmark 0x2000/0x3000 # in eth2 and AzPLB probe use route table 0x2000.
+-A PREROUTING -d 20.36.44.155/32 -i eth2 -j MARK --set-xmark 0x1/0xff # in eth2 and from a LB rule add extra mark for dnat/snat.
+-A PREROUTING -j CONNMARK --save-mark --nfmask 0xffffffff --ctmask 0xffffffff # save all marks.
+-A FORWARD -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff # restore all marks from local.
+-A OUTPUT -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff # restore all marks through local.
+COMMIT
+# Completed on Wed Aug 11 23:16:43 2021
+# Generated by iptables-save v1.8.7 on Wed Aug 11 23:16:43 2021
+*nat
+:PREROUTING ACCEPT [166:8632]
+:INPUT ACCEPT [166:8632]
+:OUTPUT ACCEPT [384:23040]
+:POSTROUTING ACCEPT [384:23040]
+-A PREROUTING -i eth2 -p tcp -m mark --mark 0x1/0xff -m tcp --dport 80 -j DNAT --to-destination 10.0.4.12:8080
+-A POSTROUTING -o eth1 -m mark --mark 0x1/0xff -j MASQUERADE
+-A POSTROUTING -o eth2 -j MASQUERADE
+COMMIT
+# Completed on Wed Aug 11 23:16:43 2021
+# Generated by iptables-save v1.8.7 on Wed Aug 11 23:16:43 2021
+*security
+:INPUT ACCEPT [8576:9413117]
+:FORWARD ACCEPT [1192:54136]
+:OUTPUT ACCEPT [2206:353552]
+-A OUTPUT -d 168.63.129.16/32 -p tcp -m owner --uid-owner 0 -j ACCEPT
+-A OUTPUT -d 168.63.129.16/32 -p tcp -m conntrack --ctstate INVALID,NEW -j DROP
+COMMIT
+# Completed on Wed Aug 11 23:16:43 2021
\ No newline at end of file
diff --git a/deploy/nva/2-nic+mgmt/sysctl/99-enable-ipv4-forwarding.conf b/deploy/nva/2-nic+mgmt/sysctl/99-enable-ipv4-forwarding.conf
new file mode 100644
index 0000000..5aad62d
--- /dev/null
+++ b/deploy/nva/2-nic+mgmt/sysctl/99-enable-ipv4-forwarding.conf
@@ -0,0 +1 @@
+net.ipv4.ip_forward = 1
\ No newline at end of file
diff --git a/deploy/nva/2-nic+mgmt/sysctl/README.md b/deploy/nva/2-nic+mgmt/sysctl/README.md
new file mode 100644
index 0000000..f4dd235
--- /dev/null
+++ b/deploy/nva/2-nic+mgmt/sysctl/README.md
@@ -0,0 +1 @@
+Place these files in `/etc/sysctl.d/`.
diff --git a/deploy/nva/2-nic+mgmt/systemd-networkd/README.md b/deploy/nva/2-nic+mgmt/systemd-networkd/README.md
new file mode 100644
index 0000000..96bc866
--- /dev/null
+++ b/deploy/nva/2-nic+mgmt/systemd-networkd/README.md
@@ -0,0 +1 @@
+Place these files in `/etc/systemd/network`.
diff --git a/deploy/nva/2-nic+mgmt/systemd-networkd/eth0.network b/deploy/nva/2-nic+mgmt/systemd-networkd/eth0.network
new file mode 100644
index 0000000..c31a23c
--- /dev/null
+++ b/deploy/nva/2-nic+mgmt/systemd-networkd/eth0.network
@@ -0,0 +1,9 @@
+[Match]
+Name=eth0
+
+[Network]
+DHCP=ipv4
+LinkLocalAddressing=no
+
+[DHCPv4]
+UseMTU=yes
diff --git a/deploy/nva/2-nic+mgmt/systemd-networkd/eth1.network b/deploy/nva/2-nic+mgmt/systemd-networkd/eth1.network
new file mode 100644
index 0000000..591646a
--- /dev/null
+++ b/deploy/nva/2-nic+mgmt/systemd-networkd/eth1.network
@@ -0,0 +1,53 @@
+[Match]
+Name=eth1
+
+[Network]
+DHCP=ipv4
+LinkLocalAddressing=no
+
+[DHCPv4]
+UseMTU=yes
+UseRoutes=no
+UseDNS=no
+
+# Define local route policy for load balancer probe
+
+[RoutingPolicyRule]
+From=0.0.0.0/0
+FirewallMark=0x1000/0x00003000
+Table=1000
+
+[Route]
+Destination=168.63.129.16/32
+Gateway=10.0.1.161
+GatewayOnLink=yes
+Metric=10
+Table=1000
+
+# Define routes for this interface
+
+[RoutingPolicyRule]
+From=0.0.0.0/0
+FirewallMark=0x100/0x00000300
+Table=100
+
+[Route]
+Destination=10.0.0.0/8
+Gateway=10.0.1.161
+GatewayOnLink=yes
+Metric=10
+Table=100
+
+[Route]
+Destination=172.16.0.0/12
+Gateway=10.0.1.161
+GatewayOnLink=yes
+Metric=10
+Table=100
+
+[Route]
+Destination=192.168.0.0/16
+Gateway=10.0.1.161
+GatewayOnLink=yes
+Metric=10
+Table=100
\ No newline at end of file
diff --git a/deploy/nva/2-nic+mgmt/systemd-networkd/eth2.network b/deploy/nva/2-nic+mgmt/systemd-networkd/eth2.network
new file mode 100644
index 0000000..7cbdaae
--- /dev/null
+++ b/deploy/nva/2-nic+mgmt/systemd-networkd/eth2.network
@@ -0,0 +1,39 @@
+[Match]
+Name=eth2
+
+[Network]
+DHCP=ipv4
+LinkLocalAddressing=no
+
+[DHCPv4]
+UseMTU=yes
+UseRoutes=no
+UseDNS=no
+
+# Define local route policy for load balancer probe
+
+[RoutingPolicyRule]
+From=0.0.0.0/0
+FirewallMark=0x2000/0x00003000
+Table=2000
+
+[Route]
+Destination=168.63.129.16/32
+Gateway=10.0.1.177
+GatewayOnLink=yes
+Metric=10
+Table=2000
+
+# Define routes for this interface
+
+[RoutingPolicyRule]
+From=0.0.0.0/0
+FirewallMark=0x100/0x00000300
+Table=100
+
+[Route]
+Destination=0.0.0.0/0
+Gateway=10.0.1.177
+GatewayOnLink=yes
+Metric=10
+Table=100
\ No newline at end of file
diff --git a/deploy/nva/2-nic/cloud-init/20-disable-config-network.cfg b/deploy/nva/2-nic/cloud-init/20-disable-config-network.cfg
new file mode 100644
index 0000000..8f6600c
--- /dev/null
+++ b/deploy/nva/2-nic/cloud-init/20-disable-config-network.cfg
@@ -0,0 +1,2 @@
+network:
+ config: disabled
\ No newline at end of file
diff --git a/deploy/nva/2-nic/cloud-init/README.md b/deploy/nva/2-nic/cloud-init/README.md
new file mode 100644
index 0000000..689d4a3
--- /dev/null
+++ b/deploy/nva/2-nic/cloud-init/README.md
@@ -0,0 +1 @@
+Place these files in `/etc/cloud/cloud.cfg.d/`.
diff --git a/deploy/nva/2-nic/iptables/README.md b/deploy/nva/2-nic/iptables/README.md
new file mode 100644
index 0000000..1f1024c
--- /dev/null
+++ b/deploy/nva/2-nic/iptables/README.md
@@ -0,0 +1 @@
+Place these files in `/etc/iptables/`.
diff --git a/deploy/nva/2-nic/iptables/iptables.rules b/deploy/nva/2-nic/iptables/iptables.rules
new file mode 100644
index 0000000..bb621aa
--- /dev/null
+++ b/deploy/nva/2-nic/iptables/iptables.rules
@@ -0,0 +1,43 @@
+# Generated by iptables-save v1.8.7 on Wed Aug 11 23:16:43 2021
+*filter
+:INPUT ACCEPT [503846:245889975]
+:FORWARD ACCEPT [11715:572454]
+:OUTPUT ACCEPT [593369:190021026]
+COMMIT
+# Completed on Wed Aug 11 23:16:43 2021
+# Generated by iptables-save v1.8.7 on Wed Aug 11 23:16:43 2021
+*mangle
+:PREROUTING ACCEPT [1579:386844]
+:INPUT ACCEPT [1265:373204]
+:FORWARD ACCEPT [314:13640]
+:OUTPUT ACCEPT [1339:464027]
+:POSTROUTING ACCEPT [1653:477667]
+-A PREROUTING ! -s 168.63.129.16/32 -i eth0 -j MARK --set-xmark 0x100/0x300 # in eth0 not AzILB probe use route table 0x100.
+-A PREROUTING ! -s 168.63.129.16/32 -i eth1 -j MARK --set-xmark 0x100/0x300 # in eth1 not AzPLB probe use route table 0x100.
+-A PREROUTING -s 168.63.129.16/32 -i eth1 -j MARK --set-xmark 0x1000/0x3000 # in eth1 and AzPLB probe use route table 0x1000.
+-A PREROUTING -d 20.36.44.155/32 -i eth1 -j MARK --set-xmark 0x1/0xff # in eth1 and from a LB rule add extra mark for dnat/snat.
+-A PREROUTING -j CONNMARK --save-mark --nfmask 0xffffffff --ctmask 0xffffffff # save all marks.
+-A FORWARD -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff # restore all marks from local.
+-A OUTPUT -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff # restore all marks through local.
+COMMIT
+# Completed on Wed Aug 11 23:16:43 2021
+# Generated by iptables-save v1.8.7 on Wed Aug 11 23:16:43 2021
+*nat
+:PREROUTING ACCEPT [166:8632]
+:INPUT ACCEPT [166:8632]
+:OUTPUT ACCEPT [384:23040]
+:POSTROUTING ACCEPT [384:23040]
+-A PREROUTING -i eth1 -p tcp -m mark --mark 0x1/0xff -m tcp --dport 80 -j DNAT --to-destination 10.0.4.12:8080
+-A POSTROUTING -o eth0 -m mark --mark 0x1/0xff -j MASQUERADE
+-A POSTROUTING -o eth1 -j MASQUERADE
+COMMIT
+# Completed on Wed Aug 11 23:16:43 2021
+# Generated by iptables-save v1.8.7 on Wed Aug 11 23:16:43 2021
+*security
+:INPUT ACCEPT [8576:9413117]
+:FORWARD ACCEPT [1192:54136]
+:OUTPUT ACCEPT [2206:353552]
+-A OUTPUT -d 168.63.129.16/32 -p tcp -m owner --uid-owner 0 -j ACCEPT
+-A OUTPUT -d 168.63.129.16/32 -p tcp -m conntrack --ctstate INVALID,NEW -j DROP
+COMMIT
+# Completed on Wed Aug 11 23:16:43 2021
\ No newline at end of file
diff --git a/deploy/nva/2-nic/sysctl/99-enable-ipv4-forwarding.conf b/deploy/nva/2-nic/sysctl/99-enable-ipv4-forwarding.conf
new file mode 100644
index 0000000..5aad62d
--- /dev/null
+++ b/deploy/nva/2-nic/sysctl/99-enable-ipv4-forwarding.conf
@@ -0,0 +1 @@
+net.ipv4.ip_forward = 1
\ No newline at end of file
diff --git a/deploy/nva/2-nic/sysctl/README.md b/deploy/nva/2-nic/sysctl/README.md
new file mode 100644
index 0000000..f4dd235
--- /dev/null
+++ b/deploy/nva/2-nic/sysctl/README.md
@@ -0,0 +1 @@
+Place these files in `/etc/sysctl.d/`.
diff --git a/deploy/nva/2-nic/systemd-networkd/README.md b/deploy/nva/2-nic/systemd-networkd/README.md
new file mode 100644
index 0000000..96bc866
--- /dev/null
+++ b/deploy/nva/2-nic/systemd-networkd/README.md
@@ -0,0 +1 @@
+Place these files in `/etc/systemd/network`.
diff --git a/deploy/nva/2-nic/systemd-networkd/eth0.network b/deploy/nva/2-nic/systemd-networkd/eth0.network
new file mode 100644
index 0000000..9436594
--- /dev/null
+++ b/deploy/nva/2-nic/systemd-networkd/eth0.network
@@ -0,0 +1,37 @@
+[Match]
+Name=eth0
+
+[Network]
+DHCP=ipv4
+LinkLocalAddressing=no
+
+[DHCPv4]
+UseMTU=yes
+
+# Define routes for this interface
+
+[RoutingPolicyRule]
+From=0.0.0.0/0
+FirewallMark=0x100/0x00000300
+Table=100
+
+[Route]
+Destination=10.0.0.0/8
+Gateway=10.0.1.161
+GatewayOnLink=yes
+Metric=10
+Table=100
+
+[Route]
+Destination=172.16.0.0/12
+Gateway=10.0.1.161
+GatewayOnLink=yes
+Metric=10
+Table=100
+
+[Route]
+Destination=192.168.0.0/16
+Gateway=10.0.1.161
+GatewayOnLink=yes
+Metric=10
+Table=100
\ No newline at end of file
diff --git a/deploy/nva/2-nic/systemd-networkd/eth1.network b/deploy/nva/2-nic/systemd-networkd/eth1.network
new file mode 100644
index 0000000..af1c8f3
--- /dev/null
+++ b/deploy/nva/2-nic/systemd-networkd/eth1.network
@@ -0,0 +1,39 @@
+[Match]
+Name=eth1
+
+[Network]
+DHCP=ipv4
+LinkLocalAddressing=no
+
+[DHCPv4]
+UseMTU=yes
+UseRoutes=no
+UseDNS=no
+
+# Define local route policy for load balancer probe
+
+[RoutingPolicyRule]
+From=0.0.0.0/0
+FirewallMark=0x1000/0x00003000
+Table=1000
+
+[Route]
+Destination=168.63.129.16/32
+Gateway=10.0.1.177
+GatewayOnLink=yes
+Metric=10
+Table=1000
+
+# Define routes for this interface
+
+[RoutingPolicyRule]
+From=0.0.0.0/0
+FirewallMark=0x100/0x00000300
+Table=100
+
+[Route]
+Destination=0.0.0.0/0
+Gateway=10.0.1.177
+GatewayOnLink=yes
+Metric=10
+Table=100
\ No newline at end of file
diff --git a/deploy/src/core-net-bastion/main.bicep b/deploy/src/core-net-bastion/main.bicep
index f5643ff..a4dcf2b 100644
--- a/deploy/src/core-net-bastion/main.bicep
+++ b/deploy/src/core-net-bastion/main.bicep
@@ -1,45 +1,45 @@
-param shortLocation string
-param vnetId string
-
-// Determine the location based on the resource group
-var location = resourceGroup().location
-
-var name = 'bastion'
-
-resource ipBastion 'Microsoft.Network/publicIPAddresses@2021-02-01' = {
- name: '${shortLocation}-${name}-ip'
- location: location
- sku: {
- name: 'Standard'
- tier: 'Regional'
- }
- properties: {
- publicIPAddressVersion: 'IPv4'
- publicIPAllocationMethod: 'Static'
- idleTimeoutInMinutes: 4
- }
-}
-
-resource bastion 'Microsoft.Network/bastionHosts@2021-02-01' = {
- name: '${shortLocation}-${name}'
- location: location
- properties: {
- ipConfigurations: [
- {
- name: 'ipconfig1'
- properties: {
- privateIPAllocationMethod: 'Dynamic'
- publicIPAddress: {
- id: ipBastion.id
- }
- subnet: {
- id: '${vnetId}/subnets/AzureBastionSubnet'
- }
- }
- }
- ]
- }
- sku: {
- name: 'Basic'
- }
-}
+param shortLocation string
+param vnetId string
+
+// Determine the location based on the resource group
+var location = resourceGroup().location
+
+var name = 'bastion'
+
+resource ipBastion 'Microsoft.Network/publicIPAddresses@2021-02-01' = {
+ name: '${shortLocation}-${name}-ip'
+ location: location
+ sku: {
+ name: 'Standard'
+ tier: 'Regional'
+ }
+ properties: {
+ publicIPAddressVersion: 'IPv4'
+ publicIPAllocationMethod: 'Static'
+ idleTimeoutInMinutes: 4
+ }
+}
+
+resource bastion 'Microsoft.Network/bastionHosts@2021-02-01' = {
+ name: '${shortLocation}-${name}'
+ location: location
+ properties: {
+ ipConfigurations: [
+ {
+ name: 'ipconfig1'
+ properties: {
+ privateIPAllocationMethod: 'Dynamic'
+ publicIPAddress: {
+ id: ipBastion.id
+ }
+ subnet: {
+ id: '${vnetId}/subnets/AzureBastionSubnet'
+ }
+ }
+ }
+ ]
+ }
+ sku: {
+ name: 'Basic'
+ }
+}
diff --git a/deploy/src/core-net/main.bicep b/deploy/src/core-net/main.bicep
index 1dd65aa..f1c5fd2 100644
--- a/deploy/src/core-net/main.bicep
+++ b/deploy/src/core-net/main.bicep
@@ -1,362 +1,362 @@
-// Resource declaration in Bicep
-// https://docs.microsoft.com/en-us/azure/azure-resource-manager/bicep/resource-declaration
-
-param shortLocation string
-param regionAddressPrefix string
-param regionSpokes array
-
-// Determine the location based on the resource group
-var location = resourceGroup().location
-
-// Get the needed octets to handle different address spaces for each region
-var octet1 = int(split(regionAddressPrefix, '.')[0])
-var octet2 = int(split(regionAddressPrefix, '.')[1])
-
-var hubVnet = {
- name: '${shortLocation}-hub'
- prefixes: [
- '${octet1}.${octet2}.0.0/22'
- ]
- gatewaySubnet: {
- prefix: '${octet1}.${octet2}.0.0/24'
- }
- azureFirewallSubnet: {
- prefix: '${octet1}.${octet2}.1.0/26'
- lbIpAddress: '${octet1}.${octet2}.1.4' // the first available ip address in this subnet
- }
- azureFirewallManagementSubnet: {
- prefix: '${octet1}.${octet2}.1.64/26'
- }
- nvaSubnetManagement: {
- name: 'NvaSubnetManagement'
- prefix: '${octet1}.${octet2}.1.128/28'
- }
- nvaSubnetDiagnostic: {
- name: 'NvaSubnetDiagnostic'
- prefix: '${octet1}.${octet2}.1.144/28'
- }
- nvaSubnetInternal: {
- name: 'NvaSubnetInternal'
- prefix: '${octet1}.${octet2}.1.160/28'
- lbIpAddress: '${octet1}.${octet2}.1.174' // the last available ip address in this subnet
- }
- nvaSubnetPublic: {
- name: 'NvaSubnetPublic'
- prefix: '${octet1}.${octet2}.1.176/28'
- }
- azureBastionSubnet: {
- prefix: '${octet1}.${octet2}.1.192/27'
- }
- routeServerSubnet: {
- prefix: '${octet1}.${octet2}.1.224/27'
- }
- applicationGatewaySubnet1: {
- name: 'ApplicationGatewaySubnet1'
- prefix: '${octet1}.${octet2}.2.0/25'
- }
- applicationGatewaySubnet2: {
- name: 'ApplicationGatewaySubnet2'
- prefix: '${octet1}.${octet2}.2.128/25'
- }
- applicationGatewaySubnet3: {
- name: 'ApplicationGatewaySubnet3'
- prefix: '${octet1}.${octet2}.3.0/25'
- }
- vmSubnet1: {
- name: 'VmSubnet1'
- prefix: '${octet1}.${octet2}.3.128/28'
- }
- vmSubnet2: {
- name: 'VmSubnet2'
- prefix: '${octet1}.${octet2}.3.144/28'
- }
-}
-
-/*
- IMPORTANT
- Add any vm subnets from the hub that need to route through the firewall
- to this list.
-*/
-var hubVmSubnets = [
- {
- name: hubVnet.vmSubnet1.name
- prefix: hubVnet.vmSubnet1.prefix
- isStandalone: false
- }
- {
- name: hubVnet.vmSubnet2.name
- prefix: hubVnet.vmSubnet2.prefix
- isStandalone: false
- }
-]
-
-/*
- Choose to use either the Nva or Azure firewall:
- var routeTableNextHopIpAddress = hubVnet.azureFirewallSubnet.lbIpAddress //<-- use Azure Firewall
- var routeTableNextHopIpAddress = hubVnet.nvaSubnetInternal.lbIpAddress //<-- use Nva firewall
-*/
-var routeTableNextHopIpAddress = hubVnet.azureFirewallSubnet.lbIpAddress //<-- use Azure Firewall
-
-// Use the information provided so far to determine route table entries
-var routesDefault = [
- {
- name: 'default'
- properties: {
- addressPrefix: '0.0.0.0/0'
- nextHopType: 'VirtualAppliance'
- nextHopIpAddress: routeTableNextHopIpAddress
- }
- }
-]
-var routesHubVmSubnets = [for destination in hubVmSubnets: {
- name: 'to-${toUpper(hubVnet.name)}-${toUpper(destination.name)}-subnet'
- properties: {
- addressPrefix: destination.prefix
- nextHopType: 'VirtualAppliance'
- nextHopIpAddress: routeTableNextHopIpAddress
- }
-}]
-var routesSpokeVnets = [for destination in regionSpokes: {
- name: 'to-${toUpper(destination.name)}-vnet'
- properties: {
- addressPrefix: destination.prefix
- nextHopType: 'VirtualAppliance'
- nextHopIpAddress: routeTableNextHopIpAddress
- }
-}]
-
-// Create hub network security groups
-resource nsg_hubVnetNvaSubnetManagement 'Microsoft.Network/networkSecurityGroups@2021-02-01' = {
- location: location
- name: '${shortLocation}-hub-${hubVnet.nvaSubnetManagement.name}-nsg'
-}
-resource nsg_hubVnetNvaSubnetDiagnostic 'Microsoft.Network/networkSecurityGroups@2021-02-01' = {
- location: location
- name: '${shortLocation}-hub-${hubVnet.nvaSubnetDiagnostic.name}-nsg'
-}
-resource nsg_hubVnetNvaSubnetInternal 'Microsoft.Network/networkSecurityGroups@2021-02-01' = {
- location: location
- name: '${shortLocation}-hub-${hubVnet.nvaSubnetInternal.name}-nsg'
- properties: {
- securityRules: [
- {
- name: 'Allow-Inbound-RFC1918'
- properties: {
- direction: 'Inbound'
- access: 'Allow'
- priority: 1000
- protocol: '*'
- destinationAddressPrefix: '*'
- destinationPortRange: '*'
- sourceAddressPrefixes: [
- '10.0.0.0/8'
- '172.16.0.0/12'
- '192.168.0.0/16'
- ]
- sourcePortRange: '*'
- }
- }
- ]
- }
-}
-resource nsg_hubVnetNvaSubnetPublic 'Microsoft.Network/networkSecurityGroups@2021-02-01' = {
- location: location
- name: '${shortLocation}-hub-${hubVnet.nvaSubnetPublic.name}-nsg'
- properties: {
- securityRules: [
- {
- name: 'Allow-Inbound-All'
- properties: {
- direction: 'Inbound'
- access: 'Allow'
- priority: 1000
- protocol: '*'
- destinationAddressPrefix: '*'
- destinationPortRange: '*'
- sourceAddressPrefix: '*'
- sourcePortRange: '*'
- }
- }
- ]
- }
-}
-resource nsg_hubVnetVmSubnet1 'Microsoft.Network/networkSecurityGroups@2021-02-01' = {
- location: location
- name: '${shortLocation}-hub-${hubVnet.vmSubnet1.name}-nsg'
-}
-resource nsg_hubVnetVmSubnet2 'Microsoft.Network/networkSecurityGroups@2021-02-01' = {
- location: location
- name: '${shortLocation}-hub-${hubVnet.vmSubnet2.name}-nsg'
-}
-
-// Create a template network security group for spokes
-resource nsg_spokeTemplate 'Microsoft.Network/networkSecurityGroups@2021-02-01' = {
- location: location
- name: '${shortLocation}-spoke-vnet-nsg'
-}
-
-// Create hub route tables
-resource rt_hubVnetGatewaySubnet 'Microsoft.Network/routeTables@2021-02-01' = {
- location: location
- name: '${shortLocation}-hub-GatewaySubnet-rt'
- properties: {
- disableBgpRoutePropagation: false // must be false for the GatewaySubnet
- routes: concat(routesSpokeVnets, routesHubVmSubnets) // define all routes except for 'default'
- }
-}
-
-var filteredRoutes1 = [for route in routesHubVmSubnets: (route.properties.addressPrefix != hubVnet.vmSubnet1.prefix) ? route : routesDefault[0]]
-resource rt_hubVnetVmSubnet1 'Microsoft.Network/routeTables@2021-02-01' = {
- location: location
- name: '${shortLocation}-hub-${hubVnet.vmSubnet1.name}-rt'
- properties: {
- disableBgpRoutePropagation: true // must be true
- routes: union(concat(routesSpokeVnets, filteredRoutes1), routesDefault) // define all routes except for its own subnet
- }
-}
-
-var filteredRoutes2 = [for route in routesHubVmSubnets: (route.properties.addressPrefix != hubVnet.vmSubnet2.prefix) ? route : routesDefault[0]]
-resource rt_hubVnetVmSubnet2 'Microsoft.Network/routeTables@2021-02-01' = {
- location: location
- name: '${shortLocation}-hub-${hubVnet.vmSubnet2.name}-rt'
- properties: {
- disableBgpRoutePropagation: true // must be true
- routes: union(concat(routesSpokeVnets, filteredRoutes2), routesDefault) // define all routes except for its own subnet
- }
-}
-
-// Create a template route table for spokes
-resource rt_spokeTemplate 'Microsoft.Network/routeTables@2021-02-01' = {
- location: location
- name: '${shortLocation}-spoke-vnet-rt'
- properties: {
- disableBgpRoutePropagation: true // must be true
- routes: concat(routesDefault, routesHubVmSubnets) // only need to define 'default' route and any vm subnets in the hub
- }
-}
-
-// Create hub virtual network
-resource vnet_hub 'Microsoft.Network/virtualNetworks@2021-02-01' = {
- location: location
- name: hubVnet.name
- properties: {
- addressSpace: {
- addressPrefixes: hubVnet.prefixes
- }
- subnets: [
- {
- name: 'GatewaySubnet'
- properties: {
- addressPrefix: hubVnet.gatewaySubnet.prefix
- routeTable: {
- id: rt_hubVnetGatewaySubnet.id
- }
- }
- }
- {
- name: 'AzureFirewallSubnet'
- properties: {
- addressPrefix: hubVnet.azureFirewallSubnet.prefix
- }
- }
- {
- name: 'AzureFirewallManagementSubnet'
- properties: {
- addressPrefix: hubVnet.azureFirewallManagementSubnet.prefix
- }
- }
- {
- name: hubVnet.nvaSubnetManagement.name
- properties: {
- addressPrefix: hubVnet.nvaSubnetManagement.prefix
- networkSecurityGroup: {
- id: nsg_hubVnetNvaSubnetManagement.id
- }
- }
- }
- {
- name: hubVnet.nvaSubnetDiagnostic.name
- properties: {
- addressPrefix: hubVnet.nvaSubnetDiagnostic.prefix
- networkSecurityGroup: {
- id: nsg_hubVnetNvaSubnetDiagnostic.id
- }
- }
- }
- {
- name: hubVnet.nvaSubnetInternal.name
- properties: {
- addressPrefix: hubVnet.nvaSubnetInternal.prefix
- networkSecurityGroup: {
- id: nsg_hubVnetNvaSubnetInternal.id
- }
- }
- }
- {
- name: hubVnet.nvaSubnetPublic.name
- properties: {
- addressPrefix: hubVnet.nvaSubnetPublic.prefix
- networkSecurityGroup: {
- id: nsg_hubVnetNvaSubnetPublic.id
- }
- }
- }
- {
- name: 'AzureBastionSubnet'
- properties: {
- addressPrefix: hubVnet.azureBastionSubnet.prefix
- }
- }
- {
- name: 'RouteServerSubnet'
- properties: {
- addressPrefix: hubVnet.routeServerSubnet.prefix
- }
- }
- {
- name: hubVnet.applicationGatewaySubnet1.name
- properties: {
- addressPrefix: hubVnet.applicationGatewaySubnet1.prefix
- }
- }
- {
- name: hubVnet.applicationGatewaySubnet2.name
- properties: {
- addressPrefix: hubVnet.applicationGatewaySubnet2.prefix
- }
- }
- {
- name: hubVnet.applicationGatewaySubnet3.name
- properties: {
- addressPrefix: hubVnet.applicationGatewaySubnet3.prefix
- }
- }
- {
- name: hubVnet.vmSubnet1.name
- properties: {
- addressPrefix: hubVnet.vmSubnet1.prefix
- networkSecurityGroup: {
- id: nsg_hubVnetVmSubnet1.id
- }
- routeTable: {
- id: rt_hubVnetVmSubnet1.id
- }
- }
- }
- {
- name: hubVnet.vmSubnet2.name
- properties: {
- addressPrefix: hubVnet.vmSubnet2.prefix
- networkSecurityGroup: {
- id: nsg_hubVnetVmSubnet2.id
- }
- routeTable: {
- id: rt_hubVnetVmSubnet2.id
- }
- }
- }
- ]
- }
-}
-
-output vnetHubId string = vnet_hub.id
+// Resource declaration in Bicep
+// https://docs.microsoft.com/en-us/azure/azure-resource-manager/bicep/resource-declaration
+
+param shortLocation string
+param regionAddressPrefix string
+param regionSpokes array
+
+// Determine the location based on the resource group
+var location = resourceGroup().location
+
+// Get the needed octets to handle different address spaces for each region
+var octet1 = int(split(regionAddressPrefix, '.')[0])
+var octet2 = int(split(regionAddressPrefix, '.')[1])
+
+var hubVnet = {
+ name: '${shortLocation}-hub'
+ prefixes: [
+ '${octet1}.${octet2}.0.0/22'
+ ]
+ gatewaySubnet: {
+ prefix: '${octet1}.${octet2}.0.0/24'
+ }
+ azureFirewallSubnet: {
+ prefix: '${octet1}.${octet2}.1.0/26'
+ lbIpAddress: '${octet1}.${octet2}.1.4' // the first available ip address in this subnet
+ }
+ azureFirewallManagementSubnet: {
+ prefix: '${octet1}.${octet2}.1.64/26'
+ }
+ nvaSubnetManagement: {
+ name: 'NvaSubnetManagement'
+ prefix: '${octet1}.${octet2}.1.128/28'
+ }
+ nvaSubnetDiagnostic: {
+ name: 'NvaSubnetDiagnostic'
+ prefix: '${octet1}.${octet2}.1.144/28'
+ }
+ nvaSubnetInternal: {
+ name: 'NvaSubnetInternal'
+ prefix: '${octet1}.${octet2}.1.160/28'
+ lbIpAddress: '${octet1}.${octet2}.1.174' // the last available ip address in this subnet
+ }
+ nvaSubnetPublic: {
+ name: 'NvaSubnetPublic'
+ prefix: '${octet1}.${octet2}.1.176/28'
+ }
+ azureBastionSubnet: {
+ prefix: '${octet1}.${octet2}.1.192/27'
+ }
+ routeServerSubnet: {
+ prefix: '${octet1}.${octet2}.1.224/27'
+ }
+ applicationGatewaySubnet1: {
+ name: 'ApplicationGatewaySubnet1'
+ prefix: '${octet1}.${octet2}.2.0/25'
+ }
+ applicationGatewaySubnet2: {
+ name: 'ApplicationGatewaySubnet2'
+ prefix: '${octet1}.${octet2}.2.128/25'
+ }
+ applicationGatewaySubnet3: {
+ name: 'ApplicationGatewaySubnet3'
+ prefix: '${octet1}.${octet2}.3.0/25'
+ }
+ vmSubnet1: {
+ name: 'VmSubnet1'
+ prefix: '${octet1}.${octet2}.3.128/28'
+ }
+ vmSubnet2: {
+ name: 'VmSubnet2'
+ prefix: '${octet1}.${octet2}.3.144/28'
+ }
+}
+
+/*
+ IMPORTANT
+ Add any vm subnets from the hub that need to route through the firewall
+ to this list.
+*/
+var hubVmSubnets = [
+ {
+ name: hubVnet.vmSubnet1.name
+ prefix: hubVnet.vmSubnet1.prefix
+ isStandalone: false
+ }
+ {
+ name: hubVnet.vmSubnet2.name
+ prefix: hubVnet.vmSubnet2.prefix
+ isStandalone: false
+ }
+]
+
+/*
+ Choose to use either the Nva or Azure firewall:
+ var routeTableNextHopIpAddress = hubVnet.azureFirewallSubnet.lbIpAddress //<-- use Azure Firewall
+ var routeTableNextHopIpAddress = hubVnet.nvaSubnetInternal.lbIpAddress //<-- use Nva firewall
+*/
+var routeTableNextHopIpAddress = hubVnet.azureFirewallSubnet.lbIpAddress //<-- use Azure Firewall
+
+// Use the information provided so far to determine route table entries
+var routesDefault = [
+ {
+ name: 'default'
+ properties: {
+ addressPrefix: '0.0.0.0/0'
+ nextHopType: 'VirtualAppliance'
+ nextHopIpAddress: routeTableNextHopIpAddress
+ }
+ }
+]
+var routesHubVmSubnets = [for destination in hubVmSubnets: {
+ name: 'to-${toUpper(hubVnet.name)}-${toUpper(destination.name)}-subnet'
+ properties: {
+ addressPrefix: destination.prefix
+ nextHopType: 'VirtualAppliance'
+ nextHopIpAddress: routeTableNextHopIpAddress
+ }
+}]
+var routesSpokeVnets = [for destination in regionSpokes: {
+ name: 'to-${toUpper(destination.name)}-vnet'
+ properties: {
+ addressPrefix: destination.prefix
+ nextHopType: 'VirtualAppliance'
+ nextHopIpAddress: routeTableNextHopIpAddress
+ }
+}]
+
+// Create hub network security groups
+resource nsg_hubVnetNvaSubnetManagement 'Microsoft.Network/networkSecurityGroups@2021-02-01' = {
+ location: location
+ name: '${shortLocation}-hub-${hubVnet.nvaSubnetManagement.name}-nsg'
+}
+resource nsg_hubVnetNvaSubnetDiagnostic 'Microsoft.Network/networkSecurityGroups@2021-02-01' = {
+ location: location
+ name: '${shortLocation}-hub-${hubVnet.nvaSubnetDiagnostic.name}-nsg'
+}
+resource nsg_hubVnetNvaSubnetInternal 'Microsoft.Network/networkSecurityGroups@2021-02-01' = {
+ location: location
+ name: '${shortLocation}-hub-${hubVnet.nvaSubnetInternal.name}-nsg'
+ properties: {
+ securityRules: [
+ {
+ name: 'Allow-Inbound-RFC1918'
+ properties: {
+ direction: 'Inbound'
+ access: 'Allow'
+ priority: 1000
+ protocol: '*'
+ destinationAddressPrefix: '*'
+ destinationPortRange: '*'
+ sourceAddressPrefixes: [
+ '10.0.0.0/8'
+ '172.16.0.0/12'
+ '192.168.0.0/16'
+ ]
+ sourcePortRange: '*'
+ }
+ }
+ ]
+ }
+}
+resource nsg_hubVnetNvaSubnetPublic 'Microsoft.Network/networkSecurityGroups@2021-02-01' = {
+ location: location
+ name: '${shortLocation}-hub-${hubVnet.nvaSubnetPublic.name}-nsg'
+ properties: {
+ securityRules: [
+ {
+ name: 'Allow-Inbound-All'
+ properties: {
+ direction: 'Inbound'
+ access: 'Allow'
+ priority: 1000
+ protocol: '*'
+ destinationAddressPrefix: '*'
+ destinationPortRange: '*'
+ sourceAddressPrefix: '*'
+ sourcePortRange: '*'
+ }
+ }
+ ]
+ }
+}
+resource nsg_hubVnetVmSubnet1 'Microsoft.Network/networkSecurityGroups@2021-02-01' = {
+ location: location
+ name: '${shortLocation}-hub-${hubVnet.vmSubnet1.name}-nsg'
+}
+resource nsg_hubVnetVmSubnet2 'Microsoft.Network/networkSecurityGroups@2021-02-01' = {
+ location: location
+ name: '${shortLocation}-hub-${hubVnet.vmSubnet2.name}-nsg'
+}
+
+// Create a template network security group for spokes
+resource nsg_spokeTemplate 'Microsoft.Network/networkSecurityGroups@2021-02-01' = {
+ location: location
+ name: '${shortLocation}-spoke-vnet-nsg'
+}
+
+// Create hub route tables
+resource rt_hubVnetGatewaySubnet 'Microsoft.Network/routeTables@2021-02-01' = {
+ location: location
+ name: '${shortLocation}-hub-GatewaySubnet-rt'
+ properties: {
+ disableBgpRoutePropagation: false // must be false for the GatewaySubnet
+ routes: concat(routesSpokeVnets, routesHubVmSubnets) // define all routes except for 'default'
+ }
+}
+
+var filteredRoutes1 = [for route in routesHubVmSubnets: (route.properties.addressPrefix != hubVnet.vmSubnet1.prefix) ? route : routesDefault[0]]
+resource rt_hubVnetVmSubnet1 'Microsoft.Network/routeTables@2021-02-01' = {
+ location: location
+ name: '${shortLocation}-hub-${hubVnet.vmSubnet1.name}-rt'
+ properties: {
+ disableBgpRoutePropagation: true // must be true
+ routes: union(concat(routesSpokeVnets, filteredRoutes1), routesDefault) // define all routes except for its own subnet
+ }
+}
+
+var filteredRoutes2 = [for route in routesHubVmSubnets: (route.properties.addressPrefix != hubVnet.vmSubnet2.prefix) ? route : routesDefault[0]]
+resource rt_hubVnetVmSubnet2 'Microsoft.Network/routeTables@2021-02-01' = {
+ location: location
+ name: '${shortLocation}-hub-${hubVnet.vmSubnet2.name}-rt'
+ properties: {
+ disableBgpRoutePropagation: true // must be true
+ routes: union(concat(routesSpokeVnets, filteredRoutes2), routesDefault) // define all routes except for its own subnet
+ }
+}
+
+// Create a template route table for spokes
+resource rt_spokeTemplate 'Microsoft.Network/routeTables@2021-02-01' = {
+ location: location
+ name: '${shortLocation}-spoke-vnet-rt'
+ properties: {
+ disableBgpRoutePropagation: true // must be true
+ routes: concat(routesDefault, routesHubVmSubnets) // only need to define 'default' route and any vm subnets in the hub
+ }
+}
+
+// Create hub virtual network
+resource vnet_hub 'Microsoft.Network/virtualNetworks@2021-02-01' = {
+ location: location
+ name: hubVnet.name
+ properties: {
+ addressSpace: {
+ addressPrefixes: hubVnet.prefixes
+ }
+ subnets: [
+ {
+ name: 'GatewaySubnet'
+ properties: {
+ addressPrefix: hubVnet.gatewaySubnet.prefix
+ routeTable: {
+ id: rt_hubVnetGatewaySubnet.id
+ }
+ }
+ }
+ {
+ name: 'AzureFirewallSubnet'
+ properties: {
+ addressPrefix: hubVnet.azureFirewallSubnet.prefix
+ }
+ }
+ {
+ name: 'AzureFirewallManagementSubnet'
+ properties: {
+ addressPrefix: hubVnet.azureFirewallManagementSubnet.prefix
+ }
+ }
+ {
+ name: hubVnet.nvaSubnetManagement.name
+ properties: {
+ addressPrefix: hubVnet.nvaSubnetManagement.prefix
+ networkSecurityGroup: {
+ id: nsg_hubVnetNvaSubnetManagement.id
+ }
+ }
+ }
+ {
+ name: hubVnet.nvaSubnetDiagnostic.name
+ properties: {
+ addressPrefix: hubVnet.nvaSubnetDiagnostic.prefix
+ networkSecurityGroup: {
+ id: nsg_hubVnetNvaSubnetDiagnostic.id
+ }
+ }
+ }
+ {
+ name: hubVnet.nvaSubnetInternal.name
+ properties: {
+ addressPrefix: hubVnet.nvaSubnetInternal.prefix
+ networkSecurityGroup: {
+ id: nsg_hubVnetNvaSubnetInternal.id
+ }
+ }
+ }
+ {
+ name: hubVnet.nvaSubnetPublic.name
+ properties: {
+ addressPrefix: hubVnet.nvaSubnetPublic.prefix
+ networkSecurityGroup: {
+ id: nsg_hubVnetNvaSubnetPublic.id
+ }
+ }
+ }
+ {
+ name: 'AzureBastionSubnet'
+ properties: {
+ addressPrefix: hubVnet.azureBastionSubnet.prefix
+ }
+ }
+ {
+ name: 'RouteServerSubnet'
+ properties: {
+ addressPrefix: hubVnet.routeServerSubnet.prefix
+ }
+ }
+ {
+ name: hubVnet.applicationGatewaySubnet1.name
+ properties: {
+ addressPrefix: hubVnet.applicationGatewaySubnet1.prefix
+ }
+ }
+ {
+ name: hubVnet.applicationGatewaySubnet2.name
+ properties: {
+ addressPrefix: hubVnet.applicationGatewaySubnet2.prefix
+ }
+ }
+ {
+ name: hubVnet.applicationGatewaySubnet3.name
+ properties: {
+ addressPrefix: hubVnet.applicationGatewaySubnet3.prefix
+ }
+ }
+ {
+ name: hubVnet.vmSubnet1.name
+ properties: {
+ addressPrefix: hubVnet.vmSubnet1.prefix
+ networkSecurityGroup: {
+ id: nsg_hubVnetVmSubnet1.id
+ }
+ routeTable: {
+ id: rt_hubVnetVmSubnet1.id
+ }
+ }
+ }
+ {
+ name: hubVnet.vmSubnet2.name
+ properties: {
+ addressPrefix: hubVnet.vmSubnet2.prefix
+ networkSecurityGroup: {
+ id: nsg_hubVnetVmSubnet2.id
+ }
+ routeTable: {
+ id: rt_hubVnetVmSubnet2.id
+ }
+ }
+ }
+ ]
+ }
+}
+
+output vnetHubId string = vnet_hub.id
diff --git a/deploy/src/main.bicep b/deploy/src/main.bicep
index 5421778..482c321 100644
--- a/deploy/src/main.bicep
+++ b/deploy/src/main.bicep
@@ -1,83 +1,83 @@
-targetScope = 'subscription'
-
-param location string = 'australiacentral'
-
-// Lookup region code based on location parameter
-var regionCodeLookup = {
- australiacentral: 'auc'
- australiaeast: 'aue'
- australiasoutheast: 'ase'
-}
-var shortLocation = regionCodeLookup[location]
-
-// Lookup region prefix based on location parameter
-var regionPrefixLookup = {
- australiacentral: '10.0.0.0/16'
- australiaeast: '10.1.0.0/16'
- australiasoutheast: '10.2.0.0/16'
-}
-var regionAddressPrefix = regionPrefixLookup[location]
-
-// Get the needed octets to handle different address spaces for each region
-var octet1 = int(split(regionAddressPrefix, '.')[0])
-var octet2 = int(split(regionAddressPrefix, '.')[1])
-
-/*
- IMPORTANT
- Update this list each time a new spoke is created
-*/
-var regionSpokes = [
- {
- name: '${shortLocation}-spoke1'
- prefix: '${octet1}.${octet2}.4.0/24'
- isStandalone: false
- }
- {
- name: '${shortLocation}-spoke2'
- prefix: '${octet1}.${octet2}.5.0/25'
- isStandalone: false
- }
- {
- name: '${shortLocation}-spoke3'
- prefix: '${octet1}.${octet2}.5.128/26'
- isStandalone: false
- }
- {
- name: '${shortLocation}-spokeN'
- prefix: '${octet1}.${octet2}.255.0/24'
- isStandalone: false
- }
-]
-
-// Create core resource groups and update their deployment
-resource rgCoreNet 'Microsoft.Resources/resourceGroups@2021-04-01' = {
- name: '${shortLocation}-core-net'
- location: location
-}
-
-module depCoreNet 'core-net/main.bicep' = {
- name: '${rgCoreNet.name}'
- scope: rgCoreNet
- params: {
- shortLocation: shortLocation
- regionAddressPrefix: regionAddressPrefix
- regionSpokes: regionSpokes
- }
-}
-
-resource rgCoreNetBastion 'Microsoft.Resources/resourceGroups@2021-04-01' = {
- name: '${shortLocation}-core-net-bastion'
- location: location
- dependsOn: [
- depCoreNet
- ]
-}
-
-module depCoreNetBastion 'core-net-bastion/main.bicep' = {
- name: '${rgCoreNetBastion.name}'
- scope: rgCoreNetBastion
- params: {
- shortLocation: shortLocation
- vnetId: depCoreNet.outputs.vnetHubId
- }
-}
+targetScope = 'subscription'
+
+param location string = 'australiacentral'
+
+// Lookup region code based on location parameter
+var regionCodeLookup = {
+ australiacentral: 'auc'
+ australiaeast: 'aue'
+ australiasoutheast: 'ase'
+}
+var shortLocation = regionCodeLookup[location]
+
+// Lookup region prefix based on location parameter
+var regionPrefixLookup = {
+ australiacentral: '10.0.0.0/16'
+ australiaeast: '10.1.0.0/16'
+ australiasoutheast: '10.2.0.0/16'
+}
+var regionAddressPrefix = regionPrefixLookup[location]
+
+// Get the needed octets to handle different address spaces for each region
+var octet1 = int(split(regionAddressPrefix, '.')[0])
+var octet2 = int(split(regionAddressPrefix, '.')[1])
+
+/*
+ IMPORTANT
+ Update this list each time a new spoke is created
+*/
+var regionSpokes = [
+ {
+ name: '${shortLocation}-spoke1'
+ prefix: '${octet1}.${octet2}.4.0/24'
+ isStandalone: false
+ }
+ {
+ name: '${shortLocation}-spoke2'
+ prefix: '${octet1}.${octet2}.5.0/25'
+ isStandalone: false
+ }
+ {
+ name: '${shortLocation}-spoke3'
+ prefix: '${octet1}.${octet2}.5.128/26'
+ isStandalone: false
+ }
+ {
+ name: '${shortLocation}-spokeN'
+ prefix: '${octet1}.${octet2}.255.0/24'
+ isStandalone: false
+ }
+]
+
+// Create core resource groups and update their deployment
+resource rgCoreNet 'Microsoft.Resources/resourceGroups@2021-04-01' = {
+ name: '${shortLocation}-core-net'
+ location: location
+}
+
+module depCoreNet 'core-net/main.bicep' = {
+ name: '${rgCoreNet.name}'
+ scope: rgCoreNet
+ params: {
+ shortLocation: shortLocation
+ regionAddressPrefix: regionAddressPrefix
+ regionSpokes: regionSpokes
+ }
+}
+
+resource rgCoreNetBastion 'Microsoft.Resources/resourceGroups@2021-04-01' = {
+ name: '${shortLocation}-core-net-bastion'
+ location: location
+ dependsOn: [
+ depCoreNet
+ ]
+}
+
+module depCoreNetBastion 'core-net-bastion/main.bicep' = {
+ name: '${rgCoreNetBastion.name}'
+ scope: rgCoreNetBastion
+ params: {
+ shortLocation: shortLocation
+ vnetId: depCoreNet.outputs.vnetHubId
+ }
+}
diff --git a/doc/basics.md b/doc/basics.md
index ef48161..09b7050 100644
--- a/doc/basics.md
+++ b/doc/basics.md
@@ -1,41 +1,41 @@
-# VNet Basics
-
-#### [prev](./concepts.md) | [home](./welcome.md) | [next](./topology-overview.md)
-
-## How does a virtual machine connect to the network?
-
-> Configure IP address and DNS settings outside of the VMs OS. Leave the VM to use DHCP (yes, even for NVAs).
-
-Subnets and other VNets
-- Connected by default.
-- A basic NSG provides minimum ingress/egress controls.
-
-Internet locations
-- NAT is performed by the networking fabric by-default.
-- A public IP is **NOT** needed for internet access.
-
-On-premises network
-- Via the internet.
-- Via a Gateway.
-
-More information for [Outbound connection (flows)](https://docs.microsoft.com/en-us/azure/load-balancer/load-balancer-outbound-connections)
-
-## How do you connect to a virtual machine?
-
-Azure Bastion (or even via console)
-- RDP and SSH over HTTPS.
-- Secure, simple, effective.
-- [VNet peering and Azure Bastion](https://docs.microsoft.com/en-us/azure/bastion/vnet-peering).
-
-Via an on-premises connection
-- Connecting to the virtual machine's private IP address.
-
-Via the internet
-- Through an Application Gateway or Firewall.
-- Assigning a public IP to the virtual machine directly.
-
-## What are the basics?
-
-![VNet Reference](/png/basics.png)
-[Virtual network basics](https://docs.microsoft.com/en-us/azure/virtual-network/virtual-networks-faq)
-
+# VNet Basics
+
+#### [prev](./concepts.md) | [home](./welcome.md) | [next](./topology-overview.md)
+
+## How does a virtual machine connect to the network?
+
+> Configure IP address and DNS settings outside of the VMs OS. Leave the VM to use DHCP (yes, even for NVAs).
+
+Subnets and other VNets
+- Connected by default.
+- A basic NSG provides minimum ingress/egress controls.
+
+Internet locations
+- NAT is performed by the networking fabric by-default.
+- A public IP is **NOT** needed for internet access.
+
+On-premises network
+- Via the internet.
+- Via a Gateway.
+
+More information for [Outbound connection (flows)](https://docs.microsoft.com/en-us/azure/load-balancer/load-balancer-outbound-connections)
+
+## How do you connect to a virtual machine?
+
+Azure Bastion (or even via console)
+- RDP and SSH over HTTPS.
+- Secure, simple, effective.
+- [VNet peering and Azure Bastion](https://docs.microsoft.com/en-us/azure/bastion/vnet-peering).
+
+Via an on-premises connection
+- Connecting to the virtual machine's private IP address.
+
+Via the internet
+- Through an Application Gateway or Firewall.
+- Assigning a public IP to the virtual machine directly.
+
+## What are the basics?
+
+![VNet Reference](/png/basics.png)
+[Virtual network basics](https://docs.microsoft.com/en-us/azure/virtual-network/virtual-networks-faq)
+
diff --git a/doc/concepts.md b/doc/concepts.md
index d647037..a46031e 100644
--- a/doc/concepts.md
+++ b/doc/concepts.md
@@ -1,84 +1,84 @@
-# Concepts
-
-#### [prev](./why.md) | [home](./welcome.md) | [next](./basics.md)
-
-Icon | Short Name | Full Name
---|--|--
-![vnet icon](/svg/virtualnetworks.svg) | VNet | Virtual Network
-![nsg icon](/svg/networksecuritygroups.svg) | NSG | Network Security Group
-![udr icon](/svg/routetables.svg) | UDR | User Defined Route / Route Table
-![nic icon](/svg/networkinterfaces.svg) | NIC | Network Interface Card
-![ilb icon](/svg/loadbalancers.svg) | ILB | Internal Load Balancer
-![nva icon](/svg/azurefirewalls.svg) | NVA | Network Virtual Appliance
-![gw icon](/svg/virtualnetworkgateways.svg) | GW | Gateway
-![gw icon](/svg/publicipaddresses.svg) | PIP | Public IP Address
-![waf icon](/png/waf-icon.png) | WAF | Web Application Firewall
-
-## VNet
-A logical address space housing virtual subnets.
-- Special subnets exist for interacting with the platform.
-- Special subnets are identified by their name, e.g. `GatewaySubnet`.
-- Can be connected to other VNets using Peering.
-
-## NSG
-A semi-statefull (*read non-statefull) low level (layer 3) packet filter.
-- Rules based on ip address and port.
-- Has constructs to determine Azure services instead of using IP addresses.
-- Associated to subnets, virtual machines or both.
-
-## UDR
-A routing table that allows users to override system routes.
-- Associated to subnets.
-- Inherited by NICs of VM and certain platform services.
-
-## NIC
-A virtual network card to connect virtual machines to a subnet.
-- Assigned to a single virtual machine and associated to a subnet.
-- House 1 or more IP configurations for the VM (including public and private IP address)
-- Virtual machine can have more than one (but this is not a good idea).
-- Make routing decisions and part of the wider routing platform.
-
-## ILB
-A low cost, very fast load balancer capable of maintaining flow symmetry.
-- Not actually a resource;
-- A rule within the underlying virtual network fabric.
-
-## NVA
-An essential part of the Hub and Spoke topology.
-- Azure Firewall is the native NVA option.
-- Non-native options include 3rd party appliances.
-- High level filtering (layer 7) between VNets, subnets, internet and on-premises.
-
-## GW
-Gateways facilitate more comprehensive connectivity options.
-- There are VPN Gateways and ExpressRoute Gateways.
-- Linked to the GatewaySubnet.
-- Make routing decisions.
-
-## Endpoints
-
-Public endpoints
-- Take the form of a public IP address or public DNS Name.
-- Azure services and any resource that can be assigned a public IP resource.
-- Not always static or deterministic.
-
-Private endpoints
-- Take the form of a private IP address.
-- Any resource that can be associated to a subnet.
-- Not always static or deterministic.
-
-Service endpoints
-- Metadata containing routing information and service identifiers.
-- Used to optimise routing between VNets and Azure services (using the network back-plane).
-- Used to identify Azure services in NSG and Azure Firewall rules.
-
-Private Link
-- Takes the form of a private IP address and private DNS Name.
-- Associated to Azure services.
-- You are responsible for the hosting the DNS name and correct name resolution.
-
- ## WAF
- A Web Application Firewall in a PAAS Firewall which inspects requests on their way to an origin web server, and will block requests before they reach the server.
-- Web application firewall is used in context with an Application Gateway, Azure Front Door or Azure CDN (Preview).
-- WAF provides centralized protection of your web applications against a number of layer 7 attack types. These include SQL injection attacks, cross-site scripting attacks, large request bodies, malformed HTTP requests, and many others. They can also enforce IP address restrictions, including blocking requests from IP addresses known to be used by malicious bots.
-- WAFs can be deployed at the edge (using Front Door or CDN), or regionally on an Application Gateway instance.
+# Concepts
+
+#### [prev](./why.md) | [home](./welcome.md) | [next](./basics.md)
+
+Icon | Short Name | Full Name
+--|--|--
+![vnet icon](/svg/virtualnetworks.svg) | VNet | Virtual Network
+![nsg icon](/svg/networksecuritygroups.svg) | NSG | Network Security Group
+![udr icon](/svg/routetables.svg) | UDR | User Defined Route / Route Table
+![nic icon](/svg/networkinterfaces.svg) | NIC | Network Interface Card
+![ilb icon](/svg/loadbalancers.svg) | ILB | Internal Load Balancer
+![nva icon](/svg/azurefirewalls.svg) | NVA | Network Virtual Appliance
+![gw icon](/svg/virtualnetworkgateways.svg) | GW | Gateway
+![gw icon](/svg/publicipaddresses.svg) | PIP | Public IP Address
+![waf icon](/png/waf-icon.png) | WAF | Web Application Firewall
+
+## VNet
+A logical address space housing virtual subnets.
+- Special subnets exist for interacting with the platform.
+- Special subnets are identified by their name, e.g. `GatewaySubnet`.
+- Can be connected to other VNets using Peering.
+
+## NSG
+A semi-statefull (*read non-statefull) low level (layer 3) packet filter.
+- Rules based on ip address and port.
+- Has constructs to determine Azure services instead of using IP addresses.
+- Associated to subnets, virtual machines or both.
+
+## UDR
+A routing table that allows users to override system routes.
+- Associated to subnets.
+- Inherited by NICs of VM and certain platform services.
+
+## NIC
+A virtual network card to connect virtual machines to a subnet.
+- Assigned to a single virtual machine and associated to a subnet.
+- House 1 or more IP configurations for the VM (including public and private IP address)
+- Virtual machine can have more than one (but this is not a good idea).
+- Make routing decisions and part of the wider routing platform.
+
+## ILB
+A low cost, very fast load balancer capable of maintaining flow symmetry.
+- Not actually a resource;
+- A rule within the underlying virtual network fabric.
+
+## NVA
+An essential part of the Hub and Spoke topology.
+- Azure Firewall is the native NVA option.
+- Non-native options include 3rd party appliances.
+- High level filtering (layer 7) between VNets, subnets, internet and on-premises.
+
+## GW
+Gateways facilitate more comprehensive connectivity options.
+- There are VPN Gateways and ExpressRoute Gateways.
+- Linked to the GatewaySubnet.
+- Make routing decisions.
+
+## Endpoints
+
+Public endpoints
+- Take the form of a public IP address or public DNS Name.
+- Azure services and any resource that can be assigned a public IP resource.
+- Not always static or deterministic.
+
+Private endpoints
+- Take the form of a private IP address.
+- Any resource that can be associated to a subnet.
+- Not always static or deterministic.
+
+Service endpoints
+- Metadata containing routing information and service identifiers.
+- Used to optimise routing between VNets and Azure services (using the network back-plane).
+- Used to identify Azure services in NSG and Azure Firewall rules.
+
+Private Link
+- Takes the form of a private IP address and private DNS Name.
+- Associated to Azure services.
+- You are responsible for the hosting the DNS name and correct name resolution.
+
+ ## WAF
+ A Web Application Firewall in a PAAS Firewall which inspects requests on their way to an origin web server, and will block requests before they reach the server.
+- Web application firewall is used in context with an Application Gateway, Azure Front Door or Azure CDN (Preview).
+- WAF provides centralized protection of your web applications against a number of layer 7 attack types. These include SQL injection attacks, cross-site scripting attacks, large request bodies, malformed HTTP requests, and many others. They can also enforce IP address restrictions, including blocking requests from IP addresses known to be used by malicious bots.
+- WAFs can be deployed at the edge (using Front Door or CDN), or regionally on an Application Gateway instance.
diff --git a/doc/connectivity.md b/doc/connectivity.md
index 16f2e82..57395e3 100644
--- a/doc/connectivity.md
+++ b/doc/connectivity.md
@@ -1,67 +1,67 @@
-# Connectivity
-
-#### [prev](./topology-overview.md) | [home](./welcome.md) | [next](./routing.md)
-
-## Connectivity between Azure Virtual Networks
-Use [Virtual network peering](https://docs.microsoft.com/en-us/azure/virtual-network/virtual-network-peering-overview), fundamental in hub and spoke model.
-
-### Peering Key points
-* Cross Subscription, Tenant and Region Connectivty
-* Peering charge per gb
-* Peering is not transative without the use of NVA and UDR
-* Limitations with basic load balancers and some services see [Requirements and constraints](https://docs.microsoft.com/en-us/azure/virtual-network/virtual-network-manage-peering#requirements-and-constraints) for more detail
-
-Alternatives
-* S2S VPN
-* Shared ER Circuit
-
-![VNet Reference](/png/local-or-remote-gateway-in-peered-virtual-network.png)
-
-## Connectivity to another network outside of Azure
-If you need to communicate with services (using a private ip) in another network there are a few options depending on what your requirements are:
-the two main options are
-* [VPN](https://docs.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-about-vpngateways)
-* [Express Route](https://docs.microsoft.com/en-us/azure/expressroute/expressroute-introduction)
-
-The Azure Architecture center has a a great article comparing the two [here](https://docs.microsoft.com/en-us/azure/architecture/reference-architectures/hybrid-networking/) also review the gateway [planning table](https://docs.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-about-vpngateways#planningtable)
-
-### VPN key points
-* [Devices](https://docs.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-about-vpn-devices) - validated devices and supported IPSec/IKE settings
-* [SKU](https://docs.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-about-vpngateways#gwsku) - determines aggregate througput
-* Routing - Can use either [BGP](https://docs.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-bgp-overview) or static routes using [Local Network Gateways](https://docs.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#lng)
-* [Availability Design](https://docs.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-highlyavailable)
-* Expect provisioning to take 40-60 minutes
-
-### Express Route key points
-* [Peering Locations](https://docs.microsoft.com/en-us/azure/expressroute/expressroute-locations-providers) - MSEE is not equal to an Azure Region
-* [Peering Types](https://docs.microsoft.com/en-us/azure/expressroute/expressroute-circuit-peerings) - Microsoft and private, do I need 1 or the other or both?
-* [Routing Requirements](https://docs.microsoft.com/en-us/azure/expressroute/expressroute-routing) - Public IP, ASN, etc
-* [High Availabililty](https://docs.microsoft.com/en-us/azure/expressroute/designing-for-high-availability-with-expressroute) - Path redundancy and first mile considerations
-* [Disaster Recovery](https://docs.microsoft.com/en-us/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering) - Designing for disaster recovery with ExpressRoute
-* [Pricing](https://azure.microsoft.com/en-us/pricing/details/expressroute/) - For private peering dont forget to take into account circuit, gateway, egress and carrier charges.
-
-## For more advanced scenarios make sure you are aware of
-* [Virtual WAN](https://docs.microsoft.com/en-us/azure/virtual-wan/virtual-wan-about)
-* [ExpressRoute Global Reach](https://docs.microsoft.com/en-us/azure/expressroute/expressroute-global-reach)
-* [Coexistance of ER and VPN Gateways](https://docs.microsoft.com/en-us/azure/expressroute/expressroute-howto-coexist-resource-manager)
-
-## Private connectivity to PaaS resources
-We recommend adopting strategies like Zero Trust and moving the focus from network perimeters to Identity. However not everyone or system can make this shift today. We have increasing support for private access to normally public services. There are a few different approaches to this:
-* [Dedicated Service](https://docs.microsoft.com/en-us/azure/virtual-network/virtual-network-for-azure-services) - Deploy dedicated but managed infrastructure inside your VNET e.g SQL Managed Instance or App Service Environment
-* [Service Endpoint](https://docs.microsoft.com/en-us/azure/virtual-network/virtual-network-service-endpoints-overview) - Allow ACLd Access to a public endpoint, firewall other access. Not accessible from remote networks
-* [Private Endpoints](https://docs.microsoft.com/en-us/azure/private-link/private-endpoint-overview) - Provision private ip address in the virtual network that will enable access to public resource. Not supported for all services see [Availbilty](https://docs.microsoft.com/en-us/azure/private-link/private-link-overview#availability)
-
-OPINION:
->Relying heavily on these mechanisms will make integration increasingly difficult, some services will have a loss of features when IP addresses are restricted. Remember many of the services were designed for a public cloud. Examples:
->* [Azure SQL import/export service](https://docs.microsoft.com/en-us/azure/azure-sql/database/network-access-controls-overview#allow-azure-services)
->* Managing some storage account settings from the portal [Storage Recommendations](https://docs.microsoft.com/en-us/azure/storage/blobs/security-recommendations#networking)
->* Using PowerBI to easily integrate with data services
-
-## Alternatives to private connectivity
-You may not need a full hybrid network to support your workloads. Some services offer their own connectivity options which might be worth exploring if you only need connectivity for 1 or two solutions.
-
-Examples:
-* [Azure Relay](https://docs.microsoft.com/en-us/azure/azure-relay/relay-what-is-it)
-* [Data Gateway](https://docs.microsoft.com/en-us/data-integration/gateway/service-gateway-onprem)
-* Exposing services using [Mutual Certificate Authentication](https://docs.microsoft.com/en-us/azure/api-management/api-management-howto-mutual-certificates)
-
+# Connectivity
+
+#### [prev](./topology-overview.md) | [home](./welcome.md) | [next](./routing.md)
+
+## Connectivity between Azure Virtual Networks
+Use [Virtual network peering](https://docs.microsoft.com/en-us/azure/virtual-network/virtual-network-peering-overview), fundamental in hub and spoke model.
+
+### Peering Key points
+* Cross Subscription, Tenant and Region Connectivty
+* Peering charge per gb
+* Peering is not transative without the use of NVA and UDR
+* Limitations with basic load balancers and some services see [Requirements and constraints](https://docs.microsoft.com/en-us/azure/virtual-network/virtual-network-manage-peering#requirements-and-constraints) for more detail
+
+Alternatives
+* S2S VPN
+* Shared ER Circuit
+
+![VNet Reference](/png/local-or-remote-gateway-in-peered-virtual-network.png)
+
+## Connectivity to another network outside of Azure
+If you need to communicate with services (using a private ip) in another network there are a few options depending on what your requirements are:
+the two main options are
+* [VPN](https://docs.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-about-vpngateways)
+* [Express Route](https://docs.microsoft.com/en-us/azure/expressroute/expressroute-introduction)
+
+The Azure Architecture center has a a great article comparing the two [here](https://docs.microsoft.com/en-us/azure/architecture/reference-architectures/hybrid-networking/) also review the gateway [planning table](https://docs.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-about-vpngateways#planningtable)
+
+### VPN key points
+* [Devices](https://docs.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-about-vpn-devices) - validated devices and supported IPSec/IKE settings
+* [SKU](https://docs.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-about-vpngateways#gwsku) - determines aggregate througput
+* Routing - Can use either [BGP](https://docs.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-bgp-overview) or static routes using [Local Network Gateways](https://docs.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#lng)
+* [Availability Design](https://docs.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-highlyavailable)
+* Expect provisioning to take 40-60 minutes
+
+### Express Route key points
+* [Peering Locations](https://docs.microsoft.com/en-us/azure/expressroute/expressroute-locations-providers) - MSEE is not equal to an Azure Region
+* [Peering Types](https://docs.microsoft.com/en-us/azure/expressroute/expressroute-circuit-peerings) - Microsoft and private, do I need 1 or the other or both?
+* [Routing Requirements](https://docs.microsoft.com/en-us/azure/expressroute/expressroute-routing) - Public IP, ASN, etc
+* [High Availabililty](https://docs.microsoft.com/en-us/azure/expressroute/designing-for-high-availability-with-expressroute) - Path redundancy and first mile considerations
+* [Disaster Recovery](https://docs.microsoft.com/en-us/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering) - Designing for disaster recovery with ExpressRoute
+* [Pricing](https://azure.microsoft.com/en-us/pricing/details/expressroute/) - For private peering dont forget to take into account circuit, gateway, egress and carrier charges.
+
+## For more advanced scenarios make sure you are aware of
+* [Virtual WAN](https://docs.microsoft.com/en-us/azure/virtual-wan/virtual-wan-about)
+* [ExpressRoute Global Reach](https://docs.microsoft.com/en-us/azure/expressroute/expressroute-global-reach)
+* [Coexistance of ER and VPN Gateways](https://docs.microsoft.com/en-us/azure/expressroute/expressroute-howto-coexist-resource-manager)
+
+## Private connectivity to PaaS resources
+We recommend adopting strategies like Zero Trust and moving the focus from network perimeters to Identity. However not everyone or system can make this shift today. We have increasing support for private access to normally public services. There are a few different approaches to this:
+* [Dedicated Service](https://docs.microsoft.com/en-us/azure/virtual-network/virtual-network-for-azure-services) - Deploy dedicated but managed infrastructure inside your VNET e.g SQL Managed Instance or App Service Environment
+* [Service Endpoint](https://docs.microsoft.com/en-us/azure/virtual-network/virtual-network-service-endpoints-overview) - Allow ACLd Access to a public endpoint, firewall other access. Not accessible from remote networks
+* [Private Endpoints](https://docs.microsoft.com/en-us/azure/private-link/private-endpoint-overview) - Provision private ip address in the virtual network that will enable access to public resource. Not supported for all services see [Availbilty](https://docs.microsoft.com/en-us/azure/private-link/private-link-overview#availability)
+
+OPINION:
+>Relying heavily on these mechanisms will make integration increasingly difficult, some services will have a loss of features when IP addresses are restricted. Remember many of the services were designed for a public cloud. Examples:
+>* [Azure SQL import/export service](https://docs.microsoft.com/en-us/azure/azure-sql/database/network-access-controls-overview#allow-azure-services)
+>* Managing some storage account settings from the portal [Storage Recommendations](https://docs.microsoft.com/en-us/azure/storage/blobs/security-recommendations#networking)
+>* Using PowerBI to easily integrate with data services
+
+## Alternatives to private connectivity
+You may not need a full hybrid network to support your workloads. Some services offer their own connectivity options which might be worth exploring if you only need connectivity for 1 or two solutions.
+
+Examples:
+* [Azure Relay](https://docs.microsoft.com/en-us/azure/azure-relay/relay-what-is-it)
+* [Data Gateway](https://docs.microsoft.com/en-us/data-integration/gateway/service-gateway-onprem)
+* Exposing services using [Mutual Certificate Authentication](https://docs.microsoft.com/en-us/azure/api-management/api-management-howto-mutual-certificates)
+
diff --git a/doc/faq.md b/doc/faq.md
index 368635f..975f2e3 100644
--- a/doc/faq.md
+++ b/doc/faq.md
@@ -1,12 +1,12 @@
-# Frequently Asked Questions
-
-#### [prev](./mgmt.md) | [home](./welcome.md) | [next](./welcome.md)
-
-- [Azure Virtual Network FAQ](https://docs.microsoft.com/en-us/azure/virtual-network/virtual-networks-faq)
-- [Azure Firewall FAQ](https://docs.microsoft.com/en-us/azure/firewall/firewall-faq)
-- [Application Gateway FAQ](https://docs.microsoft.com/en-us/azure/application-gateway/application-gateway-faq)
-- [VPN Gateway FAQ](https://docs.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-vpn-faq)
-- [ExpressRoute FAQ](https://docs.microsoft.com/en-us/azure/expressroute/expressroute-faqs)
-- [Azure Network Watcher FAQ](https://docs.microsoft.com/en-us/azure/network-watcher/frequently-asked-questions)
-- [Azure Load Balancer FAQ](https://docs.microsoft.com/en-us/azure/load-balancer/load-balancer-faqs)
+# Frequently Asked Questions
+
+#### [prev](./mgmt.md) | [home](./welcome.md) | [next](./welcome.md)
+
+- [Azure Virtual Network FAQ](https://docs.microsoft.com/en-us/azure/virtual-network/virtual-networks-faq)
+- [Azure Firewall FAQ](https://docs.microsoft.com/en-us/azure/firewall/firewall-faq)
+- [Application Gateway FAQ](https://docs.microsoft.com/en-us/azure/application-gateway/application-gateway-faq)
+- [VPN Gateway FAQ](https://docs.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-vpn-faq)
+- [ExpressRoute FAQ](https://docs.microsoft.com/en-us/azure/expressroute/expressroute-faqs)
+- [Azure Network Watcher FAQ](https://docs.microsoft.com/en-us/azure/network-watcher/frequently-asked-questions)
+- [Azure Load Balancer FAQ](https://docs.microsoft.com/en-us/azure/load-balancer/load-balancer-faqs)
- [Traffic Analytics FAQ](https://docs.microsoft.com/en-us/azure/network-watcher/traffic-analytics-faq)
\ No newline at end of file
diff --git a/doc/mgmt.md b/doc/mgmt.md
index 8961493..70c52eb 100644
--- a/doc/mgmt.md
+++ b/doc/mgmt.md
@@ -1,66 +1,66 @@
-# Management
-
-#### [prev](./security.md) | [home](./welcome.md) | [next](./faq.md)
-
-## Azure Network Watcher
-
-Azure Network Watcher provides tools to monitor, diagnose, view metrics, and enable or disable logs for resources in an Azure virtual network. Network Watcher is designed to monitor and repair the network health of IaaS (Infrastructure-as-a-Service) products which includes Virtual Machines, Virtual Networks, Application Gateways, Load balancers, etc. Note: It is not intended for and will not work for PaaS monitoring or Web analytics.
-
-[What is Azure Network Watcher?](https://docs.microsoft.com/en-us/azure/network-watcher/network-watcher-monitoring-overview)
-
-## Flow logs
-
-Network security group (NSG) flow logs is a feature of Azure Network Watcher that allows you to log information about IP traffic flowing through an NSG. Flow data is sent to Azure Storage accounts from where you can access it as well as export it to any visualization tool, SIEM, or IDS of your choice.
-
-[Introduction to flow logging for network security groups](https://docs.microsoft.com/en-us/azure/network-watcher/network-watcher-nsg-flow-logging-overview)
-
-## Traffic analytics
-
-Traffic Analytics is a cloud-based solution that provides visibility into user and application activity in cloud networks. Traffic analytics analyzes Network Watcher network security group (NSG) flow logs to provide insights into traffic flow in your Azure cloud.
-
-[Why traffic analytics?](https://docs.microsoft.com/en-us/azure/network-watcher/traffic-analytics)
-
-![Traffic analytics geo-map](/png/traffic-analytics.png)
-
-## Troubleshooting
-
-1. Do not rely on ICMP it will get dropped at specific points.
-1. Most endpoints are not ping'able, such as your VPN Gateway endpoint.
-
-[Introduction to variable packet capture in Azure Network Watcher](https://docs.microsoft.com/en-us/azure/network-watcher/network-watcher-packet-capture-overview)
-
-### Effective routes
-
-- Diagnostic property located on a Network Interface Card resource.
-- Dynamically updated and requires the NIC to be attached to a running VM.
-
-![Effective routes](/png/effective-routes.png)
-
-[Diagnose a virtual machine routing problem](https://docs.microsoft.com/en-us/azure/virtual-network/diagnose-network-routing-problem)
-
-### Effective network security rules
-
-- Diagnostic property located on a Network Interface Card resource.
-- Dynamically updated and requires the NIC to be attached to a running VM.
-
-![Effective security rules](/png/effective-security-rules.png)
-
-[Diagnose a virtual machine network traffic filter problem](https://docs.microsoft.com/en-us/azure/virtual-network/diagnose-network-traffic-filter-problem)
-
-### Packet capture
-
-Network Watcher variable packet capture allows you to create packet capture sessions to track traffic to and from a virtual machine. Packet capture helps to diagnose network anomalies both reactively and proactively. Other uses include gathering network statistics, gaining information on network intrusions, to debug client-server communications and much more.
-
-Portal link: [Network Watcher | Packet capture](https://ms.portal.azure.com/#blade/Microsoft_Azure_Network/NetworkWatcherMenuBlade/packetCapture)
-
-### Azure Serial Console
-
-The Serial Console in the Azure portal provides access to a text-based console for virtual machines (VMs) and virtual machine scale set instances running either Linux or Windows. This serial connection connects to the ttyS0 or COM1 serial port of the VM or virtual machine scale set instance, providing access independent of the network or operating system state. The serial console can only be accessed by using the Azure portal and is allowed only for those users who have an access role of Contributor or higher to the VM or virtual machine scale set.
-
-[Azure Serial Console for Linux](https://docs.microsoft.com/en-us/azure/virtual-machines/troubleshooting/serial-console-linux)
-
-![Serial console](/png/serial-console-linux.png)
-
-[Azure Serial Console for Windows](https://docs.microsoft.com/en-us/azure/virtual-machines/troubleshooting/serial-console-windows)
-
+# Management
+
+#### [prev](./security.md) | [home](./welcome.md) | [next](./faq.md)
+
+## Azure Network Watcher
+
+Azure Network Watcher provides tools to monitor, diagnose, view metrics, and enable or disable logs for resources in an Azure virtual network. Network Watcher is designed to monitor and repair the network health of IaaS (Infrastructure-as-a-Service) products which includes Virtual Machines, Virtual Networks, Application Gateways, Load balancers, etc. Note: It is not intended for and will not work for PaaS monitoring or Web analytics.
+
+[What is Azure Network Watcher?](https://docs.microsoft.com/en-us/azure/network-watcher/network-watcher-monitoring-overview)
+
+## Flow logs
+
+Network security group (NSG) flow logs is a feature of Azure Network Watcher that allows you to log information about IP traffic flowing through an NSG. Flow data is sent to Azure Storage accounts from where you can access it as well as export it to any visualization tool, SIEM, or IDS of your choice.
+
+[Introduction to flow logging for network security groups](https://docs.microsoft.com/en-us/azure/network-watcher/network-watcher-nsg-flow-logging-overview)
+
+## Traffic analytics
+
+Traffic Analytics is a cloud-based solution that provides visibility into user and application activity in cloud networks. Traffic analytics analyzes Network Watcher network security group (NSG) flow logs to provide insights into traffic flow in your Azure cloud.
+
+[Why traffic analytics?](https://docs.microsoft.com/en-us/azure/network-watcher/traffic-analytics)
+
+![Traffic analytics geo-map](/png/traffic-analytics.png)
+
+## Troubleshooting
+
+1. Do not rely on ICMP it will get dropped at specific points.
+1. Most endpoints are not ping'able, such as your VPN Gateway endpoint.
+
+[Introduction to variable packet capture in Azure Network Watcher](https://docs.microsoft.com/en-us/azure/network-watcher/network-watcher-packet-capture-overview)
+
+### Effective routes
+
+- Diagnostic property located on a Network Interface Card resource.
+- Dynamically updated and requires the NIC to be attached to a running VM.
+
+![Effective routes](/png/effective-routes.png)
+
+[Diagnose a virtual machine routing problem](https://docs.microsoft.com/en-us/azure/virtual-network/diagnose-network-routing-problem)
+
+### Effective network security rules
+
+- Diagnostic property located on a Network Interface Card resource.
+- Dynamically updated and requires the NIC to be attached to a running VM.
+
+![Effective security rules](/png/effective-security-rules.png)
+
+[Diagnose a virtual machine network traffic filter problem](https://docs.microsoft.com/en-us/azure/virtual-network/diagnose-network-traffic-filter-problem)
+
+### Packet capture
+
+Network Watcher variable packet capture allows you to create packet capture sessions to track traffic to and from a virtual machine. Packet capture helps to diagnose network anomalies both reactively and proactively. Other uses include gathering network statistics, gaining information on network intrusions, to debug client-server communications and much more.
+
+Portal link: [Network Watcher | Packet capture](https://ms.portal.azure.com/#blade/Microsoft_Azure_Network/NetworkWatcherMenuBlade/packetCapture)
+
+### Azure Serial Console
+
+The Serial Console in the Azure portal provides access to a text-based console for virtual machines (VMs) and virtual machine scale set instances running either Linux or Windows. This serial connection connects to the ttyS0 or COM1 serial port of the VM or virtual machine scale set instance, providing access independent of the network or operating system state. The serial console can only be accessed by using the Azure portal and is allowed only for those users who have an access role of Contributor or higher to the VM or virtual machine scale set.
+
+[Azure Serial Console for Linux](https://docs.microsoft.com/en-us/azure/virtual-machines/troubleshooting/serial-console-linux)
+
+![Serial console](/png/serial-console-linux.png)
+
+[Azure Serial Console for Windows](https://docs.microsoft.com/en-us/azure/virtual-machines/troubleshooting/serial-console-windows)
+
![Serial console](/png/serial-console-windows.png)
\ No newline at end of file
diff --git a/doc/routing.md b/doc/routing.md
index cc605f0..83c8a98 100644
--- a/doc/routing.md
+++ b/doc/routing.md
@@ -1,35 +1,35 @@
-# Routing
-
-#### [prev](./connectivity.md) | [home](./welcome.md) | [next](./topology.md)
-
-## Route types in Azure
-* [System Routes](https://docs.microsoft.com/en-us/azure/virtual-network/virtual-networks-udr-overview)
-* [Custom Routes](https://docs.microsoft.com/en-us/azure/virtual-network/virtual-networks-udr-overview)
-
-Azure automatically creates system routes and assigns the routes to each subnet in a virtual network.
-Custom routes can be created either manaully i.e. [user-defined](https://docs.microsoft.com/en-us/azure/virtual-network/virtual-networks-udr-overview#user-defined) or by exchanging border gateway protocol (BGP) routes between your on-premises network gateway and an Azure virtual network gateway.
-
-## BGP and Azure networking
-An on-premises network gateway can exchange routes with an Azure virtual network gateway using the border gateway protocol (BGP). Using BGP with an Azure virtual network gateway is dependent on the type you selected when you created the gateway. If the type you selected were:
-
-* ExpressRoute: You must use BGP to advertise on-premises routes to the Microsoft Edge router. You cannot create user-defined routes to force traffic to the ExpressRoute virtual network gateway if you deploy a virtual network gateway deployed as type: ExpressRoute. You can use user-defined routes for forcing traffic from the Express Route to, for example, a Network Virtual Appliance.
-* VPN: You can, optionally use BGP.
-
-## Route Selection in Azure
-
-If multiple routes contain the same address prefix, Azure selects the route type, based on the following priority:
-
-1. User-defined route
-2. BGP route
-3. System route
-
-## User defined routes and next hop types
-You can create custom, or user-defined(static), routes in Azure to override Azure's default system routes, or to add additional routes to a subnet's route table. In Azure, you create a route table, then associate the route table to zero or more virtual network subnets.
-Following next hop types are available when creating user-defined route:
-* Virtual appliance
-* Virtual Network Gateway
-* None
-* Virtual Network
-* Internet
-
-![Routing Reference](/png/routing.png)
+# Routing
+
+#### [prev](./connectivity.md) | [home](./welcome.md) | [next](./topology.md)
+
+## Route types in Azure
+* [System Routes](https://docs.microsoft.com/en-us/azure/virtual-network/virtual-networks-udr-overview)
+* [Custom Routes](https://docs.microsoft.com/en-us/azure/virtual-network/virtual-networks-udr-overview)
+
+Azure automatically creates system routes and assigns the routes to each subnet in a virtual network.
+Custom routes can be created either manaully i.e. [user-defined](https://docs.microsoft.com/en-us/azure/virtual-network/virtual-networks-udr-overview#user-defined) or by exchanging border gateway protocol (BGP) routes between your on-premises network gateway and an Azure virtual network gateway.
+
+## BGP and Azure networking
+An on-premises network gateway can exchange routes with an Azure virtual network gateway using the border gateway protocol (BGP). Using BGP with an Azure virtual network gateway is dependent on the type you selected when you created the gateway. If the type you selected were:
+
+* ExpressRoute: You must use BGP to advertise on-premises routes to the Microsoft Edge router. You cannot create user-defined routes to force traffic to the ExpressRoute virtual network gateway if you deploy a virtual network gateway deployed as type: ExpressRoute. You can use user-defined routes for forcing traffic from the Express Route to, for example, a Network Virtual Appliance.
+* VPN: You can, optionally use BGP.
+
+## Route Selection in Azure
+
+If multiple routes contain the same address prefix, Azure selects the route type, based on the following priority:
+
+1. User-defined route
+2. BGP route
+3. System route
+
+## User defined routes and next hop types
+You can create custom, or user-defined(static), routes in Azure to override Azure's default system routes, or to add additional routes to a subnet's route table. In Azure, you create a route table, then associate the route table to zero or more virtual network subnets.
+Following next hop types are available when creating user-defined route:
+* Virtual appliance
+* Virtual Network Gateway
+* None
+* Virtual Network
+* Internet
+
+![Routing Reference](/png/routing.png)
diff --git a/doc/security.md b/doc/security.md
index 52a1721..06b73e6 100644
--- a/doc/security.md
+++ b/doc/security.md
@@ -1,48 +1,48 @@
-# Security
-
-#### [prev](./topology.md) | [home](./welcome.md) | [next](./mgmt.md)
-
-## Network Security Groups (NSG)
-A network security group contains security rules that allow or deny inbound network traffic to, or outbound network traffic from, several types of Azure resources.
-
-A network security group contains zero, or as many rules as desired, within Azure subscription limits. Each rule specifies the following properties:
-
-* Name
-* Priority
-* Source
-* Source Port ranges
-* Destionation
-* Destionation Port Ranges
-* Protocol
-
-Each Security rule is created as either Inboud or Outbound rule.
-Each NSG also has default security rules which are created automaticly by Azure.
-
-https://docs.microsoft.com/en-us/azure/virtual-network/security-overview
-
-## Application Security Groups
-Application security groups enable you to configure network security as a natural extension of an application's structure, allowing you to group virtual machines and define network security policies based on those groups.
-
-https://docs.microsoft.com/en-us/azure/virtual-network/application-security-groups
-
-## Service Tags
-A service tag represents a group of IP address prefixes from a given Azure service. Microsoft manages the address prefixes encompassed by the service tag and automatically updates the service tag as addresses change, minimizing the complexity of frequent updates to network security rules.
-
-https://docs.microsoft.com/en-us/azure/virtual-network/service-tags-overview
-
-## Endpoint type
-Make sure to understand the endpoint type you are using and threat model controls for that endpoint.
-
-## Azure Bastion
-Use NSGs with Azure Bastion to create a separate administrative channel.
-
-## DDoS Protection
-Distributed denial of service (DDoS) attacks are some of the largest availability and security concerns facing customers that are moving their applications to the cloud. A DDoS attack attempts to exhaust an application's resources, making the application unavailable to legitimate users. DDoS attacks can be targeted at any endpoint that is publicly reachable through the internet.
-https://docs.microsoft.com/en-us/azure/virtual-network/ddos-protection-overview
-
-## Azure Firewall
-Azure Firewall is a managed, cloud-based network security service that protects your Azure Virtual Network resources. It's a fully stateful firewall as a service with built-in high availability and unrestricted cloud scalability.
-https://docs.microsoft.com/en-us/azure/firewall/overview
-
-## WAF
-Azure native web application firewall (WAF) service that provides powerful protection for web apps.
+# Security
+
+#### [prev](./topology.md) | [home](./welcome.md) | [next](./mgmt.md)
+
+## Network Security Groups (NSG)
+A network security group contains security rules that allow or deny inbound network traffic to, or outbound network traffic from, several types of Azure resources.
+
+A network security group contains zero, or as many rules as desired, within Azure subscription limits. Each rule specifies the following properties:
+
+* Name
+* Priority
+* Source
+* Source Port ranges
+* Destionation
+* Destionation Port Ranges
+* Protocol
+
+Each Security rule is created as either Inboud or Outbound rule.
+Each NSG also has default security rules which are created automaticly by Azure.
+
+https://docs.microsoft.com/en-us/azure/virtual-network/security-overview
+
+## Application Security Groups
+Application security groups enable you to configure network security as a natural extension of an application's structure, allowing you to group virtual machines and define network security policies based on those groups.
+
+https://docs.microsoft.com/en-us/azure/virtual-network/application-security-groups
+
+## Service Tags
+A service tag represents a group of IP address prefixes from a given Azure service. Microsoft manages the address prefixes encompassed by the service tag and automatically updates the service tag as addresses change, minimizing the complexity of frequent updates to network security rules.
+
+https://docs.microsoft.com/en-us/azure/virtual-network/service-tags-overview
+
+## Endpoint type
+Make sure to understand the endpoint type you are using and threat model controls for that endpoint.
+
+## Azure Bastion
+Use NSGs with Azure Bastion to create a separate administrative channel.
+
+## DDoS Protection
+Distributed denial of service (DDoS) attacks are some of the largest availability and security concerns facing customers that are moving their applications to the cloud. A DDoS attack attempts to exhaust an application's resources, making the application unavailable to legitimate users. DDoS attacks can be targeted at any endpoint that is publicly reachable through the internet.
+https://docs.microsoft.com/en-us/azure/virtual-network/ddos-protection-overview
+
+## Azure Firewall
+Azure Firewall is a managed, cloud-based network security service that protects your Azure Virtual Network resources. It's a fully stateful firewall as a service with built-in high availability and unrestricted cloud scalability.
+https://docs.microsoft.com/en-us/azure/firewall/overview
+
+## WAF
+Azure native web application firewall (WAF) service that provides powerful protection for web apps.
diff --git a/doc/topology-overview.md b/doc/topology-overview.md
index 7235c74..23aae70 100644
--- a/doc/topology-overview.md
+++ b/doc/topology-overview.md
@@ -1,10 +1,10 @@
-# Topology Overview
-
-#### [prev](./basics.md) | [home](./welcome.md) | [next](./connectivity.md)
-
-## Hub and spoke
-
-![Topology Diagram](/png/topology.png)
-
-A more [detailed](./topology.md) breakdown of the hub and spoke topology is covered after introducing connectivity and routing.
-
+# Topology Overview
+
+#### [prev](./basics.md) | [home](./welcome.md) | [next](./connectivity.md)
+
+## Hub and spoke
+
+![Topology Diagram](/png/topology.png)
+
+A more [detailed](./topology.md) breakdown of the hub and spoke topology is covered after introducing connectivity and routing.
+
diff --git a/doc/topology.md b/doc/topology.md
index fc7ba1d..d8160a9 100644
--- a/doc/topology.md
+++ b/doc/topology.md
@@ -1,72 +1,72 @@
-# Topology
-
-#### [prev](./routing.md) | [home](./welcome.md) | [next](./security.md)
-
-## Hub and spoke
-
-A working example for a hub and spoke topology is available for you to [try out](/deploy/).
-
-![Topology Diagram](/png/topology-210726.png)
-
-## Address scheme
-
-Use a /16 for each region.
-
-Location | Type | Name | Address Space
----|---|---|---
-Primary Region | vnet | hub | 10.1.0.0/22
-Primary Region | vnet | spoke1 | 10.1.4.0/24
-Primary Region | vnet | spoke2 | 10.1.5.0/24
-Primary Region | vnet | ... | ...
-Primary Region | vnet | spokeN | 10.1.254.0/24
-Primary Region | pool | P2S VPN | 10.1.255.0/24
-
-> Primary region supernet 10.1.0.0/16
-
-Location | Type | Name | Address Space
----|---|---|---
-Secondary Region | vnet | hub | 10.2.0.0/22
-Secondary Region | vnet | spoke1 | 10.2.4.0/24
-Secondary Region | vnet | spoke2 | 10.2.5.0/24
-Secondary Region | vnet | ... | ...
-Secondary Region | vnet | spokeN | 10.2.254.0/24
-Secondary Region | pool | P2S VPN | 10.2.255.0/24
-
-> Secondary region supernet 10.2.0.0/16
-
-## Hub subnets
-
-Use a single address space of 10.x.0.0/22 for each hub divided into the following subnets.
-
-Subnet Name | Network | Bits | Size | Usable | Reserved | First | Last | Broadcast
----|---|---|---|---|---|---|---|---
-GatewaySubnet | .0.0 | /24 | 256 | 251 | .1, .2, .3 | .4 | .254 | .255
-AzureFirewallSubnet | .1.0 | /26 | 64 | 59 | .1, .2, .3 | .4 | .62 | .63
-AzureFirewallManagementSubnet | .1.64 | /26 | 64 | 59 | .65, .66, .67 | .68 | .126 | .127
-NvaSubnet1 | .1.128 | /28 | 16 | 11 | .129, .130, .131 | .132 | .142 | .143
-NvaSubnet2 | .1.144 | /28 | 16 | 11 | .145, .146, .147 | .148 | .158 | .159
-NvaSubnet3 | .1.160 | /28 | 16 | 11 | .161, .162, .163 | .164 | .174 | .175
-NvaSubnet4 | .1.176 | /28 | 16 | 11 | .177, .178, .179 | .180 | .190 | .191
-AzureBastionSubnet | .1.192 | /27 | 32 | 27 | .193, .194, .195 | .196 | .222 | .223
-RouteServerSubnet | .1.224 | /27 | 32 | 27 | .225, .226, .227 | .228 | .254 | .255
-ApplicationGatewaySubnet1 | .2.0 | /25 | 128 | 123 | .1, .2, .3 | .4 | .126 | .127
-ApplicationGatewaySubnet2 | .2.128 | /25 | 128 | 123 | .129, .130, .131 | .132 | .254 | .255
-ApplicationGatewaySubnet3 | .3.0 | /25 | 128 | 123 | .1, .2, .3 | .4 | .126 | .127
-VmSubnet1 | .3.128 | /28 | 16 | 11 | .129, .130, .131 | .132 | .142 | .143
-VmSubnet2 | .3.144 | /28 | 16 | 11 | .145, .146, .147 | .148 | .158 | .159
-(spare) | .3.160 | /27 | 32 | 27 | .161, .162, .163 | .164 | .190 | .191
-(spare) | .3.192 | /26 | 64 | 59 | .193, .194, .195 | .196 | .254 | .255
-
-> Reserve .255.0/24 for Point to Site VPN.
-
-## Spoke subnets
-
-Spoke vnets are dynamic and map to an application or group of (heavily) related applications. Spoke vnets vary in size but are usually smaller rather than larger and subnets align to the application's requirements.
-
-## Other topologies
-
-There is no golden topology that will fit every workload scenario.
-- Consider the workload.
-- Consider availability requirements (including global and regional).
-- Consider peering costs.
-- Don't underestimate hidden costs and administrative overheads.
+# Topology
+
+#### [prev](./routing.md) | [home](./welcome.md) | [next](./security.md)
+
+## Hub and spoke
+
+A working example for a hub and spoke topology is available for you to [try out](/deploy/).
+
+![Topology Diagram](/png/topology-210726.png)
+
+## Address scheme
+
+Use a /16 for each region.
+
+Location | Type | Name | Address Space
+---|---|---|---
+Primary Region | vnet | hub | 10.1.0.0/22
+Primary Region | vnet | spoke1 | 10.1.4.0/24
+Primary Region | vnet | spoke2 | 10.1.5.0/24
+Primary Region | vnet | ... | ...
+Primary Region | vnet | spokeN | 10.1.254.0/24
+Primary Region | pool | P2S VPN | 10.1.255.0/24
+
+> Primary region supernet 10.1.0.0/16
+
+Location | Type | Name | Address Space
+---|---|---|---
+Secondary Region | vnet | hub | 10.2.0.0/22
+Secondary Region | vnet | spoke1 | 10.2.4.0/24
+Secondary Region | vnet | spoke2 | 10.2.5.0/24
+Secondary Region | vnet | ... | ...
+Secondary Region | vnet | spokeN | 10.2.254.0/24
+Secondary Region | pool | P2S VPN | 10.2.255.0/24
+
+> Secondary region supernet 10.2.0.0/16
+
+## Hub subnets
+
+Use a single address space of 10.x.0.0/22 for each hub divided into the following subnets.
+
+Subnet Name | Network | Bits | Size | Usable | Reserved | First | Last | Broadcast
+---|---|---|---|---|---|---|---|---
+GatewaySubnet | .0.0 | /24 | 256 | 251 | .1, .2, .3 | .4 | .254 | .255
+AzureFirewallSubnet | .1.0 | /26 | 64 | 59 | .1, .2, .3 | .4 | .62 | .63
+AzureFirewallManagementSubnet | .1.64 | /26 | 64 | 59 | .65, .66, .67 | .68 | .126 | .127
+NvaSubnet1 | .1.128 | /28 | 16 | 11 | .129, .130, .131 | .132 | .142 | .143
+NvaSubnet2 | .1.144 | /28 | 16 | 11 | .145, .146, .147 | .148 | .158 | .159
+NvaSubnet3 | .1.160 | /28 | 16 | 11 | .161, .162, .163 | .164 | .174 | .175
+NvaSubnet4 | .1.176 | /28 | 16 | 11 | .177, .178, .179 | .180 | .190 | .191
+AzureBastionSubnet | .1.192 | /27 | 32 | 27 | .193, .194, .195 | .196 | .222 | .223
+RouteServerSubnet | .1.224 | /27 | 32 | 27 | .225, .226, .227 | .228 | .254 | .255
+ApplicationGatewaySubnet1 | .2.0 | /25 | 128 | 123 | .1, .2, .3 | .4 | .126 | .127
+ApplicationGatewaySubnet2 | .2.128 | /25 | 128 | 123 | .129, .130, .131 | .132 | .254 | .255
+ApplicationGatewaySubnet3 | .3.0 | /25 | 128 | 123 | .1, .2, .3 | .4 | .126 | .127
+VmSubnet1 | .3.128 | /28 | 16 | 11 | .129, .130, .131 | .132 | .142 | .143
+VmSubnet2 | .3.144 | /28 | 16 | 11 | .145, .146, .147 | .148 | .158 | .159
+(spare) | .3.160 | /27 | 32 | 27 | .161, .162, .163 | .164 | .190 | .191
+(spare) | .3.192 | /26 | 64 | 59 | .193, .194, .195 | .196 | .254 | .255
+
+> Reserve .255.0/24 for Point to Site VPN.
+
+## Spoke subnets
+
+Spoke vnets are dynamic and map to an application or group of (heavily) related applications. Spoke vnets vary in size but are usually smaller rather than larger and subnets align to the application's requirements.
+
+## Other topologies
+
+There is no golden topology that will fit every workload scenario.
+- Consider the workload.
+- Consider availability requirements (including global and regional).
+- Consider peering costs.
+- Don't underestimate hidden costs and administrative overheads.
diff --git a/doc/welcome.md b/doc/welcome.md
index 3cc018c..211d26b 100644
--- a/doc/welcome.md
+++ b/doc/welcome.md
@@ -1,23 +1,23 @@
-# Welcome to the FastTrack for Azure Networking Call
-## We will start 3-4 minutes after the scheduled time to accommodate those still connecting
-
-> This call will not be recorded due to the wide audience and to encourage questions.
-
-**Questions?** Feel free to type them in the chat window at any time. Note that questions you post will be public.
-
-**Slideless** No PowerPoint, we promise! As we update this content you will get the changes straight away.
-
-**Feeback** We would love to hear your thoughts, please provide us your feedback and register for other sessions at [//aka.ms/ftalive](https://aka.ms/ftalive).
-
-Agenda
-1. [Why should we talk about networking?](./why.md)
-1. [Concepts](./concepts.md)
-1. [VNet Basics](./basics.md)
-1. [Topology (overview)](./topology-overview.md)
-1. [Connectivity](./connectivity.md)
-1. [Routing](./routing.md)
-1. [Topology (explained)](./topology.md)
-1. [Security](./security.md)
-1. [Management](./mgmt.md)
-1. [QnA](./faq.md)
-
+# Welcome to the FastTrack for Azure Networking Call
+## We will start 3-4 minutes after the scheduled time to accommodate those still connecting
+
+> This call will not be recorded due to the wide audience and to encourage questions.
+
+**Questions?** Feel free to type them in the chat window at any time. Note that questions you post will be public.
+
+**Slideless** No PowerPoint, we promise! As we update this content you will get the changes straight away.
+
+**Feeback** We would love to hear your thoughts, please provide us your feedback and register for other sessions at [//aka.ms/ftalive](https://aka.ms/ftalive).
+
+Agenda
+1. [Why should we talk about networking?](./why.md)
+1. [Concepts](./concepts.md)
+1. [VNet Basics](./basics.md)
+1. [Topology (overview)](./topology-overview.md)
+1. [Connectivity](./connectivity.md)
+1. [Routing](./routing.md)
+1. [Topology (explained)](./topology.md)
+1. [Security](./security.md)
+1. [Management](./mgmt.md)
+1. [QnA](./faq.md)
+
diff --git a/doc/why.md b/doc/why.md
index 8dc3e08..603ef23 100644
--- a/doc/why.md
+++ b/doc/why.md
@@ -1,31 +1,31 @@
-# Why should we talk about networking?
-
-#### [prev](./welcome.md) | [home](./welcome.md) | [next](./concepts.md)
-
-## Networking in Azure is defined virtually (what is this "Fabric" I keep hearing about)
-
-This means networking concepts learnt traditionally don't always apply.
-
-This also means newer techniques are available when designing a network topology.
-
-## Common traps and wrong assumptions
-
-Thinking there is still layer 2
-- Running a DHCP server in Azure.
-- Multiple NICs on NVAs.
-
-Force tunneling and hair-pinning
-- Assuming no public IP equals no internet access.
-- Fear of Public Endpoints.
-
-VNet mistakes
-- Nesting VNets.
-- Forgetting to use NSGs.
-- Asking too much from NSGs.
-- Trying to put PaaS services "into" a VNet.
-
-Troubleshoot difficulties
-- Using ICMP.
-- The platform does routing not the VMs.
-- Misconfigured DNS.
-
+# Why should we talk about networking?
+
+#### [prev](./welcome.md) | [home](./welcome.md) | [next](./concepts.md)
+
+## Networking in Azure is defined virtually (what is this "Fabric" I keep hearing about)
+
+This means networking concepts learnt traditionally don't always apply.
+
+This also means newer techniques are available when designing a network topology.
+
+## Common traps and wrong assumptions
+
+Thinking there is still layer 2
+- Running a DHCP server in Azure.
+- Multiple NICs on NVAs.
+
+Force tunneling and hair-pinning
+- Assuming no public IP equals no internet access.
+- Fear of Public Endpoints.
+
+VNet mistakes
+- Nesting VNets.
+- Forgetting to use NSGs.
+- Asking too much from NSGs.
+- Trying to put PaaS services "into" a VNet.
+
+Troubleshoot difficulties
+- Using ICMP.
+- The platform does routing not the VMs.
+- Misconfigured DNS.
+
diff --git a/svg/loadbalancers.svg b/svg/loadbalancers.svg
index 46762b6..f51d47b 100644
--- a/svg/loadbalancers.svg
+++ b/svg/loadbalancers.svg
@@ -1,16 +1,16 @@
-
+
diff --git a/svg/routetables.svg b/svg/routetables.svg
index 8f6e3cb..f540edf 100644
--- a/svg/routetables.svg
+++ b/svg/routetables.svg
@@ -1,18 +1,18 @@
-