├── .gitignore ├── README.md ├── add-udrs-scenario5.sh ├── bastions.tf ├── branch-routes.sh ├── clean-up-after-scenario-4.sh ├── connect-branch-custom-rt.sh ├── connect-branch.sh ├── connect-branch2.sh ├── connect-services-spoke.sh ├── connect-us-east-spokes.sh ├── connect-west-europe-spokes.sh ├── emptyrtbody.json ├── emptyspokeconnection.json ├── enable-routing-nva.sh ├── images ├── microhack-vwan-security.png ├── microhack-vwan.png ├── microhack-vwan.vsdx ├── scenario-4-edit-branch.png ├── scenario-4-edit-shared.png ├── scenario-4-useast-routetables.png ├── scenario-4-we-routetables.png ├── scenario1-ass-prop.png ├── scenario1.png ├── scenario2.png ├── scenario3-ass-prop.png ├── scenario3-hubs.png ├── scenario3.png ├── scenario4-allowedflows.png ├── scenario4-blockedflows.png ├── scenario4.png ├── scenario5-add-custom-routes.png ├── scenario5-add-default-route.png ├── scenario5-disable-prop-def-rt.png ├── scenario5-enable-prop-def-rt.png ├── scenario5-single-default-route.png ├── scenario5.png └── vwan-with-connections.png ├── main.tf ├── onpremconnection.json ├── prep-for-scenario-5.sh ├── prep-for-scenario-6-from-4.sh ├── prep-for-scenario-6.sh ├── spoke.tf ├── variables.tf ├── vm-extensions.tf ├── vnet-gw.tf ├── vnet-gw2.tf └── vwan.tf /.gitignore: -------------------------------------------------------------------------------- 1 | # Local .terraform directories 2 | **/.terraform/* 3 | 4 | # Local lock 5 | .terraform.lock.hcl 6 | 7 | # .tfstate files 8 | *.tfstate 9 | *.tfstate.* 10 | 11 | # tfvars 12 | *.auto.tfvars 13 | 14 | # Crash log files 15 | crash.log 16 | 17 | # Ignore any .tfvars files that are generated automatically for each Terraform run. Most 18 | # .tfvars files are managed as part of configuration and so should be included in 19 | # version control. 20 | # 21 | # example.tfvars 22 | 23 | # Ignore override files as they are usually used to override resources locally and so 24 | # are not checked in 25 | override.tf 26 | override.tf.json 27 | *_override.tf 28 | *_override.tf.json 29 | 30 | # Include override files you do wish to add to version control using negated pattern 31 | # 32 | # !example_override.tf 33 | 34 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan 35 | # example: *tfplan* -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # **Routing in Azure Virtual WAN MicroHack** 2 | 3 | # Contents 4 | [Introduction](#introduction) 5 | 6 | [Objectives](#objectives) 7 | 8 | [Scenario](#scenario) 9 | 10 | [Lab](#lab) 11 | 12 | [Prerequisites](#prerequisites) 13 | 14 | [Scenario 1: Single region Virtual WAN with Default Routing](#scenario-1-single-region-virtual-wan-with-default-routing) 15 | 16 | [Scenario 2: Add a branch connection](#scenario-2-add-a-branch-connection) 17 | 18 | [Scenario 3: Multi-regional Virtual WAN](#scenario-3-multi-regional-virtual-wan) 19 | 20 | [Scenario 4: Isolated Spokes and Shared Services Spoke](#scenario-4-isolated-spokes-and-shared-services-spoke) 21 | 22 | [Scenario 5 (Optional): Filter traffic through a Network Virtual Appliance](#scenario-5-optional-filter-traffic-through-a-network-virtual-appliance) 23 | 24 | [Scenario 6 (Optional): Secured Hubs](#scenario-6-optional-secured-hubs) 25 | 26 | [Close out](#close-out) 27 | 28 | # Introduction 29 | 30 | Azure Virtual WAN can be a core component in a customer's Azure foundation. In [this article](https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/ready/enterprise-scale/network-topology-and-connectivity), the Enterprise Scale Framework explains how Virtual WAN may be used to create a network topology underpinning customer's foundation. 31 | 32 | It is therefore important to understand how Virtual WAN enables connectivity within Azure. The purpose of this MicroHack is to build that understanding by exploring some of the routing capabilities recently introduced. 33 | 34 | The lab starts with a single Hub with Spoke VNETs and default routing. We then connect a simulated on-premise location via S2S VPN. Then we add another regional Hub with Spokes and observe how routing extends across multiple Hubs. Next we implement custom routing patterns for Shared Services- and Isolated Spokes. 35 | 36 | At the end of the MicroHack there is optional content on network security with NVAs and Azure Firewall. Although this is insightful already, it is not yet possible to build a scenario in which 37 | VNET-to-VNET traffic across multiple hubs is [secured through Azure Firewall](https://docs.microsoft.com/en-us/azure/virtual-wan/scenario-route-between-vnets-firewall). 38 | 39 | Prior to starting this MicroHack, please familiarize yourself with routing in Virtual WAN by reviewing the [documentation](https://docs.microsoft.com/en-us/azure/virtual-wan/about-virtual-hub-routing). 40 | 41 | # Objectives 42 | After completing this MicroHack you will: 43 | - Know how to build a hub-and-spoke topology with Virtual WAN 44 | - Understand default routing in Virtual WAN and how this differs from the classic virtual data center hub-and-spoke spoke architecture 45 | - Understand how custom routing works and know how to build some custom routing scenarios 46 | 47 | # Lab 48 | 49 | The lab consists of a Virtual WAN with Hubs in West Europe and US East, 4 Spoke VNETs (2 in West Europe, 1 in US East and 1 US West), a Shared Services VNET in West-Europe and a simulated On-premise location in North Europe. 50 | 51 | Each of the Spoke and On-prem VNETs contains a Virtual Machine running a basic web site. The Shared Services VNET contains an Active Directory Domain Controller. the NVA VNET contains a Linux VM with Iptables. 52 | 53 | An additional VNET containing a Network Virtual Appliance Linux-based firewall is also deployed. This NVA VNET is used in the optional advanced scenario's on network security. 54 | 55 | During the course of the MicroHack you will connect the Spoke and Shared Services VNETs and the On-premise site to Virtual WAN, deploy an additional Virtual WAN Hub, and manipulate and observe routing. 56 | 57 | At the end of the lab your deployment looks like this: 58 | 59 | ![image](images/microhack-vwan.png) 60 | 61 | 62 | Although a Branch (site-to-site VPN) connection is part of this MicroHack, it does not cover the integration with products from SDWAN partners. 63 | 64 | :exclamation: The resources deployed in this lab incur a combined charge of around $40 per day, so do remember to delete the environment when done! 65 | 66 | # Prerequisites 67 | To make the most of your time on this MircoHack, the green elements in the diagram above are deployed and configured for you through Terraform. You will focus on deploying and configuring the blue items using the Azure portal and Cloud Shell. 68 | ## Task 1: Deploy 69 | Steps: 70 | - Log in to Azure Cloud Shell at https://shell.azure.com/ and select Bash 71 | - Set environment variables required by Terraform. These should already be present, but may have been removed after an upgrade to Cloud Shell; Terraform will fail if they are not present: 72 | 73 | `export ARM_USE_MSI=true` 74 | 75 | `export ARM_SUBSCRIPTION_ID=` 76 | 77 | `export ARM_TENANT_ID=` 78 | 79 | - Ensure Azure CLI and extensions are up to date: 80 | 81 | `az upgrade --yes` 82 | 83 | - If necessary select your target subscription: 84 | 85 | `az account set --subscription ` 86 | 87 | - Clone the GitHub repository: 88 | 89 | `git clone https://github.com/mddazure/azure-vwan-microhack` 90 | 91 | - Change directory: 92 | 93 | `cd ./azure-vwan-microhack` 94 | - Initialize terraform and download the azurerm resource provider: 95 | 96 | `terraform init` 97 | 98 | - Now start the deployment (when prompted, confirm with **yes** to start the deployment): 99 | 100 | `terraform apply` 101 | 102 | Deployment takes approximately 30 minutes. 103 | ## Task 2: Explore and verify 104 | 105 | After the Terraform deployment concludes successfully, the following has been deployed into your subscription: 106 | - A resource group named **vwan-microhack-spoke-rg** containing 107 | - Four Spoke VNETs, each containing a Virtual Machine running a simple web site, and a Bastion Host. 108 | - An Onprem VNET containing a Virtual Machine running a simple web site, a VNET Gateway and a Bastion Host. 109 | - A Services VNET containing and a Virtual Machine configured as an Active Directory Domain Controller, and a Bastion Host. 110 | - An NVA VNET containing a Virtual Machine with Linux (Ubuntu 18.4) and Iptables installed, and a Bastion Host. 111 | - A resource group named **vwan-microhack-hub-rg** containing a Virtual WAN resource with one Hub and one VPN Gateway. You will deploy another Hub into this resource group manually later on. 112 | 113 | Verify these resources are present in the portal. 114 | 115 | Credentials are identical for all VMs, as follows: 116 | - User name: AzureAdmin 117 | - Password: Microhack2020 118 | - Domain: micro-hack.local (this is on the ADDC VM only, the other VMs are not joined to this domain yet) 119 | 120 | You may log on to each VM through Bastion. Open a command prompt and type `curl localhost`. The response will be the VM name. When logging on to the ADDC VM before it is ready, you will see "Waiting for the Group Policy Client". That is OK, just let it run while you proceed with the lab. 121 | # Scenario 1: Single Region Virtual WAN with Default Routing 122 | 123 | In this scenario you connect in-region VNETs to the pre-deployed Hub, and establish VNET-to-VNET communication. You will then inspect effective routes on the spoke VMs and take a look at the VWAN Default routing table. 124 | ## Task 1: Baseline 125 | Connect to spoke-1-vm via Bastion, turn off IE Enhanced Security Configuration in Server Manager, open Internet Explorer and attempt to connect to spoke-2-vm at 172.16.2.4. 126 | 127 | :question: Does it connect? 128 | 129 | Check the routing on spoke-1-vm, as follows: 130 | 131 | In the portal, in the Properties view of the VM Overview blade, click on Networking. Then click on the name of the Network Interface. The NIC overview shows, under Support + troubleshooting click Effective routes. 132 | 133 | Alternatively, in Cloud Shell, issue this command: 134 | 135 | `az network nic show-effective-route-table -g vwan-microhack-spoke-rg -n spoke-1-nic --output table` 136 | 137 | :question: Is there a specific route for spoke-2-vnet (172.16.2.0/24)? 138 | 139 | ## Task 2: Connect VNETs 140 | In the portal, navigate to the Virtual WAN named **microhack-vwan** in resource group **vwan-microhack-hub-rg**. 141 | 142 | Click "Virtual network connections" under "Connectivity" and click "+ Add connection" at the top of the page. 143 | 144 | Name your connection **spoke-1-we**, select the hub (microhack-we-hub) and in the Resource group drop down select **vwan-microhack-spoke-rg**. In the Virtual network drop down, select **spoke-1-vnet**. 145 | 146 | Under Routing configuration, select: 147 | - Associate Route Table: Default 148 | - Propagate to Route Tables: Default 149 | - Propgate to labels: default 150 | 151 | Wait for the connection to reach status Succeeded, and do the same for **spoke-2-vnet**. 152 | ![image](images/vwan-with-connections.png) 153 | 154 | Your Virtual WAN now looks like this: 155 | 156 | 157 | ![image](images/scenario1.png) 158 | 159 | :question: Can you now curl from spoke-1-vm to spoke-2-vm and vice versa? 160 | 161 | ### :point_right: Spoke routes 162 | Again observe Effective routes for spoke-1-vm. 163 | 164 | :exclamation: Notice it now has a route for spoke-2-vnet (172.16.2.0/24), pointing to a public address. This is the address of the Route Service, deployed into the Hub to enable routing between peered VNETs, branch connections and other Hubs. The fact that this is a public IP address does not present a security risk, it is not reachable from the internet. 165 | 166 | :exclamation: Notice that the routes that enable spoke-to-spoke communication were **plumbed into the spoke VNETs automatically.** Contrast this with a "classic" hub-and-spoke architecture, where you would need to set up a routing device in the hub VNET and then put UDRs in each of the spokes manually. 167 | 168 | ### :point_right: Hub routes 169 | Navigate to the blade for the microhack-we-hub in your Virtual WAN and select Routing under Connectivity. Notice there are two Route tables present now: Default and None. 170 | 171 | Click on Effective Routes. In the drop downs on the next page, select Route Table and Default respectively. This brings up the Default route table. 172 | 173 | :exclamation: Note that routes for the prefixes of both connected VNETs are present, pointing to the respective VNET connections. 174 | 175 | Go back up to the microhack-vwan overview page, and click Virtual network connections under Connectivity. In the table, under Virtual network, click ">" to view the individual VNET connections. 176 | 177 | A Virtual WAN can contain multiple Route tables, and we'll add some in the course of this MicroHack. Each Connection (Hub-to-Spoke VNET, ExpressRoute, S2S (Branch) VPN or P2S (User) VPN) can be *Associated* with a single table and be *Propagating* to multiple tables. 178 | 179 | :exclamation: The Default table has Associated Connections and Propagating Connections. Both Spoke VNETs are Associated with and Propagating to the Default table. 180 | 181 | *Propagating* means that the Connection's destinations are entered into this Routing table: the table learns the Connection's routes. 182 | 183 | *Associated* means that traffic from the Connections listed is governed by this table, in this case the Default route table. This table decides where traffic sent from the connection to the VWAN Route Service (remember the route entry pointing to the public IP address in the Spoke VM's Effective Routes) goes. 184 | 185 | ![image](images/scenario1-ass-prop.png) 186 | 187 | The None Route table is also present for each Hub; traffic from Connections Associated with this Route table is dropped. 188 | 189 | # Scenario 2: Add a branch connection 190 | 191 | Now connect a branch site via a BGP-enabled VPN connection and explore the routing between spokes and the branch. The branch site is simulated through a VNET with a VNET Gateway which was deployed through Terraform as part of the Prerequisites. 192 | 193 | ## Task 1: Connect a simulated branch site 194 | We are simulating a Branch site by means of a VNET with a VNET Gateway. In reality this would be a VPN device manufactured by one of the [Virtual WAN Partners](https://docs.microsoft.com/en-us/azure/virtual-wan/virtual-wan-locations-partners), and you would use the automation provided by Virtual WAN to configure the device. 195 | 196 | In Cloud Shell, in the azure-vwan-microhack directory 197 | - Run the connect-branch shell script: 198 | 199 | `./connect-branch.sh` 200 | 201 | The script contains Azure CLI commands that create following resources: 202 | - A VPN Site named "onprem" in the Virtual WAN 203 | - A BGP-enabled VPN connection from the "onprem" site to the West Europe Hub 204 | - A Local Network Gateway named "lng" to represent the West Europe Hub 205 | - A BGP-enabled VPN connection from the Gateway in "onprem-vnet" to the Local Network Gateway 206 | 207 | After the script completes, it may take a few minutes for the connection to show "Connected" in the portal. 208 | 209 | Your Virtual WAN now looks like this: 210 | 211 | ![image](images/scenario2.png) 212 | 213 | ## Task 2: Verify connectivity 214 | Connect to onprem-vm via Bastion and turn off IE Enhanced Security Configuration in Server Manager. 215 | 216 | Open a command prompt and type `curl 172.16.1.4` to access spoke-1-vm and `curl 172.16.2.4` to access spoke-2-vm. 217 | 218 | :question: Does it connect? 219 | ## Task 3: Inspect routing 220 | ### :point_right: BGP routing exchange over VPN 221 | In Cloud Shell, in the azure-vwan-microhack directory, run the branch-routes script: 222 | 223 | `./branch-routes.sh` 224 | 225 | This scripts pulls information on the BGP session from the VNET Gateway vnet-onprem-gw. 226 | 227 | :exclamation: Note that the "routes learned" output contains all routes the Gateway knows: those that are in the same VNET, with "origin" indicating "Network", as well as routes learned from the Virtual WAN Hub via BGP with "origin" indicating "EBgp". 228 | 229 | ### :point_right: Branch routes 230 | Now observe Effective Routes for onprem-vm. 231 | 232 | In the portal, in the Properties view of the VM Overview blade, click on Networking. Then click on the name of the Network Interface. The NIC overview shows, under Support + troubleshooting click Effective routes. 233 | 234 | Alternatively, in Cloud Shell, issue this command: 235 | 236 | `az network nic show-effective-route-table -g vwan-microhack-spoke-rg -n onprem-nic --output table` 237 | 238 | :exclamation: Note that routes are present for the Spoke VNETs, pointing to the local VNET VPN Gateway. 239 | 240 | The VNET Gateway learned the routes for the Spoke VNETs via BGP and programmed them into the vm route table automatically, without the need to install UDRs. 241 | 242 | ### :point_right: Spoke routes 243 | Observe Effective Routes for spoke-1-vm: 244 | 245 | `az network nic show-effective-route-table -g vwan-microhack-spoke-rg -n spoke-1-nic --output table` 246 | 247 | :exclamation: Notice that spoke-vm-1 now has routes for the IP ranges of the onprem site, 10.0.1.0/24 and 10.0.2.0/24. This site is connected via VPN, and although "Source" and "Next Hop Type" are the same as for peered VNET spoke-2-vnet, the next hop address is different. 248 | 249 | Whereas the next hop for spoke-vnet-2 is the Hub routing engine, the next hop for VPN connection is the VPN Gateway, which has a private IP address from the range assigned to Hub. 250 | 251 | The routes for the VPN connection where plumbed into the spoke automatically and there is no need to place User Defined Routes in the spoke VNETs. 252 | 253 | ### :point_right: Hub routes 254 | Observe the Effective routes of the Default route table. 255 | 256 | :exclamation: Note that routes for the on-prem site's prefixes are now present, pointing to S2S VPN Gateway. 257 | 258 | Realize that the Route Service itself is not in the data path for branch traffic. The Route Service acts as a route reflector, traffic flows directly between the VM in the spoke and VPN Gateway. 259 | 260 | # Scenario 3: Multi-regional Virtual WAN 261 | We will now expand the Virtual WAN across regions by adding a Hub with Spokes in the US East region. 262 | 263 | A key take away from this scenario is that each hub runs its own routing instance and contains its own routing tables. 264 | 265 | Although routing tables may be called the same across Hubs, Default for example, it is important to realize that these are independent and there is no "global" routing table spanning the entire VWAN. Labels are used to group routing tables, serving as Propagation targets across hubs. 266 | 267 | At the end of this scenario, your lab looks like this: 268 | 269 | ![image](images/scenario3.png) 270 | 271 | ## Task 1: Add a Hub 272 | 273 | In the portal, Select your **microhack-vwan**. Under Connectivity, select Hubs, then +New Hub at the top of the page and complete the Basics dialog as follows: 274 | - Region: East US 275 | - Name: microhack-useast-hub 276 | - Hub private address space: 192.168.1.0/24 277 | 278 | As this Hub will not contain any gateways, skip the other tabs, click Review + create and then Create. 279 | 280 | Alternatively, in Cloud Shell, issue this command: 281 | 282 | `az network vhub create --address-prefix 192.168.1.0/24 --name microhack-useast-hub --vwan microhack-vwan --resource-group vwan-microhack-hub-rg --location eastus --sku Standard` 283 | 284 | This will take a few minutes to complete. 285 | 286 | ## Task 2: Connect VNETs 287 | Connect spoke-3-vnet and spoke-4-vnet to the new Hub. We connected VNETs through the portal in Scenario 1, so to save time we'll do this through a prepared shell script. 288 | 289 | In Cloud Shell, enter 290 | 291 | `./connect-us-east-spokes.sh` 292 | 293 | This will take a few minutes to complete. While the script runs, you can see the connections being added in the portal, in your microhack-vwan under Connectivity, Virtual network connections. Wait for both Connections to show status Succeeded, and for the Hub's Routing status to change from Provisioning to Succeeded. 294 | 295 | ![image](images/scenario3-hubs.png) 296 | 297 | ## Task 3: Verifiy connectivity and inspect routing 298 | Connect to spoke-1-vm via Bastion. Open a command prompt and type `curl 172.16.3.4` to access spoke-3-vm and `curl 172.16.4.4` to access spoke-4-vm. 299 | 300 | Do the same from on-prem-vm. 301 | 302 | :question: Do you see the web pages from spoke-3-vm and spoke--4vm? 303 | 304 | :point_right: Spoke routes 305 | 306 | Observe Effective Routes for spoke-1-vm, either in the portal or in Cloud Shell through 307 | 308 | `az network nic show-effective-route-table -g vwan-microhack-spoke-rg -n spoke-1-nic --output table` 309 | 310 | :question: Which routes have been added to spoke-1-vm's route table? 311 | 312 | :question: What is the next hop for the new routes? 313 | 314 | :exclamation: Realize that Virtual WAN installed these routes into the Spoke 1 VNET automatically! 315 | 316 | Now observe Effective Routes for spoke-3-vm, which is in Spoke 3 connected to the US East Hub: 317 | 318 | `az network nic show-effective-route-table -g vwan-microhack-spoke-rg -n spoke-3-nic --output table` 319 | 320 | :exclamation: Note all routes, both for the US East "local" Spoke 4 and "remote" West Europe destinations, have the address of the Route Service in the US East Hub as their next hop. 321 | 322 | Again, realize that Virtual WAN installed these routes in the Spoke VNETs automatically! 323 | 324 | ### :point_right: BGP routing exchange over VPN 325 | In Cloud Shell, run the branch-routes script: 326 | 327 | `./branch-routes.sh` 328 | 329 | :question: Compare the AS path of the new routes for Spokes 3 and 4, to the AS path of the routes for Spokes 1 and 2. Why are they different? 330 | 331 | :point_right: Hub routes 332 | 333 | Observe Effective Routes of the Default route table on the microhack-we-hub, as you did in Scenario 1. 334 | 335 | :question: Which routes have been added and where do they point? 336 | 337 | :question: What is the meaning of the AS path? 338 | 339 | Then go to Effective Routes of the Default route table on the newly added microhack-eastus-hub. 340 | 341 | :question: Where do the routes for Spoke 1 and Spoke 2 (172.16.(1)(2).0/24) and the Branch (10.0.(1)(2).0/24) point? 342 | 343 | :question: What is their AS path and how does this compare to what you saw on the West Europe hub? 344 | 345 | :point_right: Association and Propagation 346 | 347 | In the portal, in the microhack-vwan blade under Connectivity click Virtual network connections and expand Virtual networks for both Hubs. 348 | 349 | :exclamation: Note that for all 4 connections across both Hubs, under Associated to Route Table it says "defaultRouteTable". 350 | 351 | This means that each connection takes its routing information from the default route table of its *local* hub. This is always the case: the route service in a Hub only programs routing information to its directly connected Spokes. 352 | 353 | :exclamation: Under Propagation to Route Tables, it also says "defaultRouteTable". This means that this connection sends its reachability information (i.e. the prefixes behind it) to its *local* default route table only, but *not* to the other Hub. 354 | 355 | However, we observed that the defaultRouteTable of the West Europe Hub does have routes for the Spokes in US East and vice versa. 356 | 357 | This happens because under Propagating to labels, there is the entry "default". 358 | 359 | ![image](images/scenario3-ass-prop.png) 360 | 361 | Labels are a method of grouping Route Tables across Hubs, so that they do not have to be specified individually. The defaultRouteTables in all Hubs in a VWAN are automatically included in the "default" label, and Propagation to this label is automatically enabled. 362 | 363 | In the next scenario we will explore custom routing patterns enabled by deploying additional routing tables to our hubs. 364 | 365 | # Scenario 4: Isolated Spokes and Shared Services Spoke 366 | :exclamation: The following is scenario is quite advanced and will take some time and effort. 367 | 368 | Imagine an IT department that must facilitate DevOps teams. IT operates a number of central services, such as the networks in and between Azure and on-premise, and the Active Directory domain. 369 | 370 | DevOps teams are given their own VNETs in Azure, connected to a central hub that provides connectivity and the domain. The DevOps teams operate independently and their environments must remain isolated from each other. 371 | 372 | This scenario adds a Shared Services Spoke with a Domain Controller, and changes the routing so that the Spokes can only reach the Branch and the Shared Services Spoke, but remain isolated from each other. 373 | 374 | Please read [this documentation](https://docs.microsoft.com/en-us/azure/virtual-wan/scenario-shared-services-vnet) for background. 375 | 376 | At the end of this Scenario your lab looks like this: 377 | 378 | ![image](images/scenario4.png) 379 | 380 | The Spokes can now no longer talk between themselves: 381 | 382 | ![image](images/scenario4-blockedflows.png) 383 | 384 | ... but communication from the Spokes to the Services VNET and the Branch location is still possible: 385 | 386 | ![image](images/scenario4-allowedflows.png) 387 | 388 | 389 | 390 | ## Task 1: Connect Services Spoke 391 | 392 | Run the following in Cloud Shell to connect services-vnet to microhack-we-hub: 393 | 394 | `./connect-services-spoke.sh` 395 | 396 | Wait for the connection to complete and show status Succeeded in the portal. 397 | 398 | ## Task 2: Create custom Route Tables 399 | 400 | ## :hand: West Europe Hub 401 | 402 | In the microhack-we-hub, under Connectivity select Routing and then +Create route table. Complete the configuration as follows: 403 | - Tab Basics 404 | - Name: RT-Shared-we 405 | - Tab Labels 406 | - Label Name: Shared 407 | - Tab Associations 408 | - In the drop down under Virtual Networks, select both Spokes but do *not* select services-vnet 409 | - Tab Propagations 410 | - Under Branches, at Propagate routes from connections to this route table?, select Yes 411 | - Under Virtual Networks, select services-vnet but do *not* select the Spokes 412 | - Click Create 413 | 414 | The Routing view of the West Europe Hub hub now shows 2 connections associated to the Default table (Shared Service Spoke and Branch), and 4 connections propagating to the Default table (both Spokes, Shared Services and Branch). 415 | 416 | The RT-Shared-we table has 2 connections associated (both Spokes), and 2 connections propagating (Shared Services and Branch). 417 | 418 | ![image](images/scenario-4-we-routetables.png) 419 | 420 | :exclamation: It may take a few minutes for the changes to complete. If RT-Shared-does not look as expected, edit the table and correct the Associations and Propagations settings per the instructions above. 421 | 422 | Before proceeding, ensure that the routing view of microhack-we-hub look as above, and that microhack-we-hub shows Succeeded for Hub status and Routing status. 423 | 424 | ## :hand: US East Hub 425 | 426 | For microhack-useast-hub, under Connectivity select Routing and then +Create route table and complete as follows: 427 | Tab Basics 428 | - Name: RT-Shared-useast 429 | - Tab Labels 430 | - Label Name: Shared 431 | - Tab Associations 432 | - In the drop down under Virtual Networks, select both Spokes. 433 | - Tab Propagations 434 | - Enter *nothing* because: 435 | - We do not want the local Spokes to propagate to this table, as they should not learn each other's routes 436 | - The RT-Shared-useast table must only contain routes to the Shared Services Spoke- and the Branch connections, and it will learn these from the West Europe hub via the inter-hub link 437 | - Click Create 438 | 439 | Routing for the US East Hub shows both Spoke VNET connections propagating to the Default route table, and both are associated with the RT-Shared-useast table. 440 | 441 | ![image](images/scenario-4-useast-routetables.png) 442 | 443 | ## :handshake: Cross-region 444 | 445 | :exclamation: We must also ensure that the Shared Services VNET connection and the Branch connection, which are connected to the West Europe Hub, *also* propagate to the RT-Shared-useast table. 446 | 447 | For the **Shared Services VNET**, this is configured on the connection, and we will use the Shared label which groups the RT-Shared tables in both hubs. 448 | 449 | In the microhack-vwan view, select Virtual network connections. Expand the connections on microhack-we-hub, click the elipsis at the end of the services-vnet row and select Edit. In the Propagate to labels drop-down, select both default and Shared labels, and click Confirm. 450 | 451 | ![image](images/scenario-4-edit-shared.png) 452 | 453 | To let the **Branch** route propagate accross to the East US Hub, the Branches setting in the Propagations tab of RT-Shared-we, the Shared table in the **West Europe** hub, must be updated. Edit RT-Shared-we, click the Propgations tab. Under Branches (Site VPN/ExpressRoute/User VPN) ensure both default and Shared are selected. Click Create. 454 | 455 | ![image](images/scenario-4-edit-branch.png) 456 | 457 | :beetle: **Bug alert** You may see an error message similar to this: 458 | 459 | "Deployment template validation failed: 'The resource 'Microsoft.Network/vpnGateways/microhack-we-hub-vng/vpnConnections/onprem' at line '183' and column '9' is defined multiple times in a template." 460 | 461 | This is caused by a bug. The work around is to close the portal browser tab, log in to the portal from a fresh tab and redo the operation. 462 | 463 | ## Task 3: Verify connectivity 464 | Open a command prompt and type `curl 172.16.2/3/4` to access spoke-2/3/4-vm and `curl 10.0.1.4` to access onprem-vm. 465 | 466 | :question: Do the VMs respond? 467 | 468 | Try to ping spoke-addc-vm (172.16.10.4). 469 | 470 | :question: Does ping succeed? 471 | 472 | ## Task 4 (Optional): Join Spoke vm to Domain 473 | The Shared Service VNET contains an AD domain controller. 474 | 475 | To demonstrate connectivity from the Spokes to the Shared Services VNET, you can optionally join one or more spoke vm's to the domain. 476 | - Point the DNS in spoke-vnet-1 to spoke-addc-vm, in Cloud Shell: 477 | 478 | `az network vnet update --name spoke-1-vnet --resource-group vwan-microhack-spoke-rg --dns-servers 172.16.10.4` 479 | 480 | - On spoke-1-vm, open a command prompt and enter: 481 | 482 | `ipconfig /renew` 483 | 484 | - On spoke-1-vm, open Server Manager and click Local Server. 485 | - Then click WORKGROUP, click the Change ... button, select the Domain radio button under Member of and enter micro-hack.local, click OK. 486 | - Enter credentials 487 | - User name: AzureAdmin 488 | - Password: Microhack2020 489 | 490 | The machine will now join the domain and will need to be restarted for this change to take effect. 491 | 492 | ## Task 5: Inspect routing 493 | 494 | :point_right: Spoke routes 495 | 496 | View Effective Routes for spoke-1-vm, in the portal or in Cloud Shell: 497 | 498 | `az network nic show-effective-route-table -g vwan-microhack-spoke-rg -n spoke-1-nic --output table` 499 | 500 | :question: Identify the routes that you see. Which routes are not there and is that as expected? 501 | 502 | View Effective Routes for spoke-addc-vm: 503 | 504 | `az network nic show-effective-route-table -g vwan-microhack-spoke-rg -n spoke-addc-1-nic --output table` 505 | 506 | :question: Again identify the routes that you see. What is different here from the routes at spoke-vm-1? 507 | 508 | :point_right: Hub routes 509 | 510 | View Effective Routes for the Default table of the West Europe hub: in the portal from microhack-vwan select Hubs, microhack-we-hub, Routing, click Default and View effective routes for this table. 511 | 512 | :question: Are routes for the Spokes (172.16.(1)(2)(3)(4).0/24) present? What does that mean for connections Associated with this table? 513 | 514 | :exclamation: Click Associations and under Current settings (Routing Configuration), note that spoke-1-vnet and spoke-2-vnet are *not* associated with the defaultRouteTable table, but they *are* propagating to defaultRouteTable. 515 | 516 | Go back to the Route Tables view of microhack-we-hub, click RT-Shared-we and then View effective routes for this table. 517 | 518 | :question: Are routes for the Spokes (172.16.(1)(2)(3)(4).0/24) present? 519 | 520 | :question: Are routes for the Shared Services VNET (172.16.10.0/24) and the Branch (10.0.(1)(2).0/24) present? 521 | 522 | :question: As the Spokes are associated with RT-Shared-we, what does this mean for destinations that the Spokes can reach? 523 | 524 | Now view RT-Shared-useast and Default tables for the US East Hub. 525 | 526 | :question: what does RT-Shared-useast contain? Why and what does this mean for the Spokes connected to the US East Hub? 527 | 528 | :exclamation: Note that the Default table does not contain routes. The Default route table of the US East Hub does not have any connections Associated with it. It does have connections Propagating into it, so should contain routing information. *Apparently* a route table shows empty when it has no connections Associated, i.e. nothing to consume its routing information. 529 | 530 | # Close out 531 | You have explored VWAN routing to a good level of detail. As Virtual WAN grows and matures, it is important you have a good understanding of this topic to guide and help customers in a variety of use cases. This MicroHack is available for you to use with your teams, your customers and partners to reinforce their understanding. 532 | 533 | Below are optional challenges on network security in Virtual WAN with Network Virtual Appliances and Secured Hubs. Use this content at your own pace to expand your knowledge and skills. 534 | 535 | **If you decide to continue now, skip the clean-up task below and start on Scenario 5.** 536 | 537 | ## Final Task: Delete all resources 538 | 539 | Run this script to delete all resources: 540 | 541 | `./clean-up-after-scenario-4.sh` 542 | 543 | This may take up to 30 minutes to compete. Remember to verify that all resources have indeed been deleted. 544 | 545 | In Cloud Shell, delete the azure-vwan-microhack directory: 546 | 547 | `rm -rf azure-vwan-microhack` 548 | 549 | 550 | # Scenario 5 (Optional): Filter traffic through a Network Virtual Appliance 551 | Virtual WAN today does not support third party NVA firewalls in the Hub. Third party SD-WAN concentrators from Barracuda and Cisco Viptella are now supported, but that capability does not yet exist for firewall products. 552 | 553 | Third party NVA firewalls must therefore be placed in a Spoke, with protected VNETs peered behind. 554 | See https://docs.microsoft.com/en-us/azure/virtual-wan/scenario-route-through-nva for background on this pattern. 555 | 556 | This scenario demonstrates how to route traffic through a third party Network Virtual Appliance. We use a single Linux VM with IPTables, with a rule set allowing all traffic. 557 | 558 | At the end of this Scenario your VWAN looks like this: 559 | 560 | ![image](images/scenario5.png) 561 | 562 | :exclamation: Note that spoke-1-vnet and spoke-2-vnet are now disconnected from the West Europe Hub, and are peered behind a new Spoke containing the NVA. This nva-vnet is connected to Hub. 563 | 564 | In this scenario we will manipulate routing to direct traffic to and from spoke-1-vnet and spoke-2-vnet through the NVA. Outbound internet traffic from spoke-1-vnet and spoke-2-vnet will also be directed through the NVA, but we will discover that it is not possible to do so for spoke-3-vnet and spoke-4-vnet. 565 | 566 | ## Task 1: Prepare the environment 567 | A number of changes must be made to prepare the Virtual WAN for this scenario: 568 | - Reconfigure for Default routing 569 | - Disconnect Spoke 1 and Spoke 2 from the Hub 570 | - Connect the NVA Spoke to the Hub 571 | - Peer Spoke 1 and Spoke 2 with the NVA Spoke 572 | 573 | To implement these changes, run this script in Cloud Shell: 574 | 575 | `./prep-for-scenario-5.sh` 576 | 577 | This will take a few minutes to complete. 578 | 579 | ## Task 2: Add User Defined Routes 580 | We must now add UDRs to the subnet vmSubnet in both Spoke 1 and Spoke 2 VNETs, to direct all traffic to the NVA in nva-vnet. 581 | 582 | Run this script in Cloud Shell: 583 | 584 | `./add-udrs-scenario5.sh` 585 | 586 | In the portal, verify that a Route table (UDR) named "default-to-nva" has been created, and is associated subnet vmSubnet in both spoke-1-vnet and spoke-2-vnet. 587 | 588 | All traffic outbound from spoke-1-vm and spoke-2-vm is now directed to the NVA in nva-vnet. 589 | 590 | :exclamation: nva-vnet is already connected to West Europe Hub and has routes programmed by the Route Service, so we do not need to add a UDR manually. 591 | 592 | ## Task 3: Modify VWAN routing 593 | The Virtual WAN is not aware that Spoke 1 and Spoke 2 are now behind the NVA, so we must update the routing by adding static custom routes for Spoke 1 and Spoke 2 pointing to the NVA. 594 | 595 | :exclamation: Note that a static custom route must be added to the Default route table of *both* the West Europe *and* the US East Hubs. It is not sufficient to only a static route to the West Europe Hub, as this route will not propagate to remote hubs. 596 | 597 | In the portal, go to the Routing blade of microhack-we-hub. Click the Default route table, and in Basics at the bottom, create a custom route: 598 | - Route name: spoke1-via-nva 599 | - Destination type: leave at CIDR 600 | - Destination prefix: 172.16.1.0/24 601 | - Next hop: select nva-we 602 | - Next Hop IP: now Configure appears, click this and enter 172.16.20.4 under Next Hop IP (this is the IP address of the NVA) 603 | 604 | Create a similar entry for Spoke 2 (172.16.2.0/24). 605 | 606 | ![image](images/scenario5-add-custom-routes.png) 607 | 608 | Click Review+create and then Create. 609 | 610 | Then go the Routing blade of microhack-useast-hub and do the same. You can skip adding the Next Hop IP as the connection to nva-vnet already has this configuration applied. 611 | 612 | ## Task 4: Verify connectivity 613 | :point_right: From "protected" VNETs Spoke 1 and Spoke 2 614 | 615 | On spoke-1-vm, traceroute and curl to each of the Spokes (172.16.(2)(3)(4).4) and to the Branch (10.0.1.4). 616 | 617 | :question: Do all curl connections succeed, what are the first hop addresses? 618 | 619 | On spoke-1-vm, traceroute and browse to www.bing.com. 620 | 621 | :question: Does the browser connection succeed, what is the first hop address? 622 | 623 | :point_right: From "unprotected" VNETs Spoke 3 and Spoke 4 624 | 625 | On spoke-3-vm, traceroute and curl to each of the Spokes (172.16.(1)(2)(4).4) and to the Branch (10.0.1.4). 626 | 627 | :question: Do all curl connections succeed, what are the first hop addresses? 628 | 629 | On spoke-3-vm, traceroute and browse to www.bing.com. 630 | 631 | :question: Does the browser connection succeed, what is the first hop address? 632 | 633 | ## Task 5: Inspect routing 634 | 635 | :point_right: Spoke routes 636 | 637 | We will first look at the routes of one of the tiered Spokes. This is one of the Spokes connected behind the NVA VNET, no longer connected directlty to the Hub. 638 | 639 | View Effective Routes for spoke-1-vm, in the portal or in Cloud Shell: 640 | 641 | `az network nic show-effective-route-table -g vwan-microhack-spoke-rg -n spoke-1-nic --output table` 642 | 643 | :question: Identify the routes that you see. Comparing to Spoke routes we saw in previous scenario's, which routes are not there and is that as expected? Which route is now present and why? 644 | 645 | :exclamation: Realize that VWAN does not have visibility of tiered Spokes and cannot program the routing in the VNET. That is why we had to place UDRs in the tiered Spokes. 646 | 647 | View Effective Routes for spoke-3-vm, in the portal or in Cloud Shell: 648 | 649 | `az network nic show-effective-route-table -g vwan-microhack-spoke-rg -n spoke-3-nic --output table` 650 | 651 | :question: Identify the routes that you see. Comparing to Spoke routes we saw in previous scenario's, is this now different and why (not)?. From the perspective of Spoke 3, has placing Spokes 1 and 2 behind an NVA VNET on the *remote* hub changed its view of the network? 652 | 653 | :point_right: Hub routes 654 | 655 | View Effective Routes for the Default table of the West Europe hub: in the portal from microhack-vwan select Hubs, microhack-we-hub, Routing, click Default and View effective routes for this table. 656 | 657 | :question: Identify the routes for Spokes 1 and 2 (172.16.(1)(2).0/24). Where do they point and how did they get into the table? 658 | 659 | Now view Effective Routes for the Default table of the US East hub. 660 | 661 | :question: Again identify the routes for Spokes 1 and 2 (172.16.(1)(2).0/24). Where do they point and how did they get into the table? 662 | 663 | :exclamation: Note that the routes for the tiered Spokes 1 and 2 in US East Hub's Default table do not have microhack-we-hub (Remote Hub) as destination, but point directly to the nva-we Virtual Network Connection. 664 | 665 | :point_right: Outbound internet access 666 | 667 | Traffic outbound to the internet from Spokes 1 and 2 is directed to the NVA, and it goes out via the NVA's public IP address. Verify this by browsing to www.whatismyipaddress.com from spoke-1-vm, check that the ip address reported is the public ip of the NVA shown in the portal. 668 | ## Task 6: Outbound internet access from the VWAN via NVA in Spoke 669 | Outbound internet from spoke vnets directly connected to the VWAN, such as Spokes 3 and 4, can be forced through the NVA in the Spoke as well. This requires a custom route in the Hub default route tables, for destination prefix 0.0.0.0/0 pointing to the nva-vnet connection. 670 | 671 | :thumbsup: VWAN now supports the default route 0.0.0.0/0 as a custom route entry. 672 | 673 | To make this work, add a custom route in the Default route tables of both the West Europe and US East hubs, for 0.0.0.0/0 pointing to the NVA spoke connection. 674 | 675 | ![image](images/scenario5-add-default-route.png) 676 | 677 | When adding the "default-via-nva" route to each hub, you only need to have the default set **once** when you configure the next hop ip otherwise you would get an error saying "Duplicate destination 0.0.0.0/0 found in[...]": 678 | 679 | ![image](images/scenario5-single-default-route.png) 680 | 681 | In the Spokes directly connected to one of the Hubs, the 0.0.0.0/0 route no longer points directly to the internet but to the Route Service. 682 | 683 | View Effective Routes for spoke-3-vm in Cloud Shell: 684 | 685 | `az network nic show-effective-route-table -g vwan-microhack-spoke-rg -n spoke-3-nic --output table` 686 | 687 | :exclamation: Note that 0.0.0.0/0 now points to the public IP address of the Route Service in the East US Hub. 688 | 689 | If this is not the case, you should check that the "Propagate Default Route" is enabled on the Spoke 3 and Spoke 4 connection to benefit from the internet breakout via West Europe hub. 690 | 691 | ![image](images/scenario5-enable-prop-def-rt.png) 692 | 693 | On the East US Hub, view Effective Routes for the Default Route Table in the portal. 694 | 695 | :exclamation: Note 0.0.0.0/0 pointing to the nva-we connection, and the route for 172.16.20.0/24 (the nva Spoke) pointing to the West Europe Hub. 696 | 697 | Now view Effective Routes for nva-iptables-vm in Cloud Shell: 698 | 699 | `az network nic show-effective-route-table -g vwan-microhack-spoke-rg -n nva-iptables-vm-nic-1 --output table` 700 | 701 | :exclamation: Note that 0.0.0.0/0 points to the public IP address of the Route Service in the West Europe Hub. 702 | 703 | This will direct any internet-bound traffic leaving the NVA ***back*** to the Route Service: a routing loop. Where we want all other Spokes to have their default route pointing the Route Service so that it can forward traffic to the NVA, on the NVA we want the default route to be left pointing to Internet. 704 | 705 | This is achieved by ***disabling*** propagation of the default on the nva-we connection. 706 | 707 | ![image](images/scenario5-disable-prop-def-rt.png) 708 | 709 | You are now ready to access the internet from Spoke 3 and Spoke 4 via the NVA. 710 | 711 | Test by tracerouting from spoke-3-vm to any internet destination. Also verify that connectivity to the cascaded Spoek 1 and Spoke 2 via the NVA is maintained. 712 | 713 | :exclamation: Iptables on the NVA is configured to Source NAT traffic destined for the internet, but not to private destinations in the VWAN. The configuration will be lost when the NVA is restarted. If this happens, recover the rules using the iptables configuration in the file enable-routing-nva.sh. 714 | 715 | # Scenario 6 (Optional): Secured Hubs 716 | 717 | This final and optional scenario converts the Hubs into Secured Hubs through Azure Firewall Manager. This operation deploys Azure Firewall into the Hubs. 718 | 719 | ## Task #1: Restore the Virtual WAN 720 | 721 | To put the VWAN back into "default" state, a number of changes must be made: 722 | 723 | - Disconnect Spoke 1 and Spoke 2 from the the NVA Spoke 724 | - Remove UDRs from Spoke 1 and Spoke 2 725 | - Remove custom routes 726 | - Disconnect the NVA Spoke to the Hub 727 | - Connect Spoke 1 and Spoke 2 to the West Europe Hub 728 | 729 | To implement these changes, run this script in Cloud Shell: 730 | 731 | `./prep-for-scenario-6.sh` 732 | 733 | If you arrive here from Scenario 4, skipping Scenario 5, run this script in Cloud Shell: 734 | 735 | `./prep-for-scenario-6-from-4.sh` 736 | 737 | This will take a few minutes to complete. 738 | 739 | ## Task #2: Convert to Secure Hubs 740 | 741 | We are now ready to convert our Virtual Hubs into Secured Hubs through Azure Firewall Manager. We will create a Firewall Policy in the same flow. 742 | 743 | :exclamation: Note that Firewall Manager is a separate top-level Azure service; it is not part of Virtual WAN. If you don't have it bookmarked already, find Firewall Manager using the search bar at the top of the portal. 744 | 745 | In the Firewall Mananger blade, click Azure Firewall Policies and + Create Azure Firewall Policy. 746 | 747 | **Basics** 748 | - Resource group: select vwan-microhack-hub-rg 749 | - Name: microhack-fw-policy 750 | - Region: West Europe 751 | 752 | **Rules** 753 | - Click + Add a rule collection 754 | - Name: default-policy 755 | - Rule collection type: Network 756 | - Priority: 100 757 | - Action: Allow 758 | - Rules: 759 | - Name: Allow-all 760 | - Source type: IP Address 761 | - Source: * 762 | - Protocol: Any 763 | - Destination Ports: * 764 | - Destination Type: IP Address 765 | - Destination: * 766 | - Click Add 767 | 768 | **Review+create** 769 | 770 | **Create** 771 | 772 | Go back to the Firewall Mananger blade 773 | - Click Virtual Hubs. 774 | - Select `microhack-we-hub`, then click Security providers. 775 | - Under Azure Firewall, click the Add policy button. 776 | - Select `microhack-fw-policy` and click Save. 777 | 778 | This starts deployment of Azure Firewall into microhack-we-hub, converting it to Secured Hub. 779 | 780 | Repeat these steps for microhack-useast-hub. 781 | 782 | This deploys Azure Firewall into your Hubs and applies the Allow-all policy to both. This operation will take a few minutes to complete. 783 | 784 | ## Task 3: Secure Internet traffic 785 | 786 | Route settings for your Secured Hubs are managed in Firewall Manager. 787 | 788 | In the Firewall Manager blade, click Virtual hubs, select microhack-we-hub and then Security configuration. 789 | 790 | In the drop downs under Internet traffic and Private traffic, select Azure Firewall and Send via Azure Firewall and click Save. This sets up Azure Firewall as the security provider, and inserts routes pointing to the Azure Firewall for the prefixes listed as Private traffic prefixes (link next to the drop down. Default this is set to the RFC1918 ranges of 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/24. 791 | 792 | Tick the box next to Connections and click Save. 793 | 794 | :point_right: Spoke routes 795 | 796 | In Cloud Shell, pull up Effective routes of spoke-1-vm: 797 | 798 | `az network nic show-effective-route-table -g vwan-microhack-spoke-rg -n spoke-1-nic --output table` 799 | 800 | :question: where does the default route (0.0.0.0/0) point? 801 | 802 | Display the ip addresses of the he Azure Firewall in the secured hub: 803 | 804 | `az network firewall show -g vwan-microhack-hub-rg -n AzureFirewall_microhack-we-hub --query hubIpAddresses` 805 | 806 | :exclamation: Note that the default route now points to the private (inside) address of the Azure Firewall instance in the secured hub. 807 | 808 | On spoke-1-vm, browse to www.whatismyipaddress.com. 809 | 810 | :exclamation: Note that the outbound ip address is now the public ip address of the Azure Firewall instance. 811 | 812 | ## Task 4: Secure Private traffic 813 | 814 | To be added, this is pending service update enabling V-SH-SH-V pattern. 815 | 816 | # Close out 817 | You have explored VWAN routing to a good level of detail. As Virtual WAN grows and matures, it is important you have a good understanding of the subject, to guide and help customers in a variety of use cases. 818 | 819 | This MicroHack is available for you to use with your teams, your customers and partners to reinforce their understanding. 820 | 821 | ## Final Task: Delete all resources 822 | 823 | Delete the vwan-microhack-hub-rg and vwan-microhack-spoke-rg resource groups. This may take up to 30 minutes to compete. Check back to verify that all resources have indeed been deleted. 824 | 825 | In Cloud Shell, delete the azure-vwan-microhack directory: 826 | 827 | `rm -rf azure-vwan-microhack` 828 | -------------------------------------------------------------------------------- /add-udrs-scenario5.sh: -------------------------------------------------------------------------------- 1 | echo "# creating UDR" 2 | az network route-table create --name default-to-nva --resource-group vwan-microhack-spoke-rg --location westeurope 3 | echo "# creating default route" 4 | az network route-table route create --address-prefix 0.0.0.0/0 --name default-route --next-hop-type VirtualAppliance --next-hop-ip-address 172.16.20.4 --resource-group vwan-microhack-spoke-rg --route-table-name default-to-nva 5 | echo "# associating with vmSubnet in spoke-1-vnet" 6 | az network vnet subnet update --resource-group vwan-microhack-spoke-rg --name vmSubnet --vnet-name spoke-1-vnet --route-table default-to-nva 7 | echo "# associating with vmSubnet in spoke-2-vnet" 8 | az network vnet subnet update --resource-group vwan-microhack-spoke-rg --name vmSubnet --vnet-name spoke-2-vnet --route-table default-to-nva -------------------------------------------------------------------------------- /bastions.tf: -------------------------------------------------------------------------------- 1 | ####################################################################### 2 | ## Create Bastion spoke-1 3 | ####################################################################### 4 | resource "azurerm_public_ip" "bastion-spoke-1-pubip" { 5 | name = "bastion-spoke-1-pubip" 6 | location = var.location-spoke-1 7 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 8 | allocation_method = "Static" 9 | sku = "Standard" 10 | } 11 | 12 | resource "azurerm_bastion_host" "bastion-spoke-1" { 13 | name = "bastion-spoke-1" 14 | location = var.location-spoke-1 15 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 16 | sku = "Standard" 17 | ip_connect_enabled = true 18 | 19 | ip_configuration { 20 | name = "bastion-spoke-1-configuration" 21 | subnet_id = azurerm_subnet.bastion-spoke-1-subnet.id 22 | public_ip_address_id = azurerm_public_ip.bastion-spoke-1-pubip.id 23 | } 24 | } 25 | ####################################################################### 26 | ## Create Bastion spoke-2 27 | ####################################################################### 28 | resource "azurerm_public_ip" "bastion-spoke-2-pubip" { 29 | name = "bastion-spoke-2-pubip" 30 | location = var.location-spoke-2 31 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 32 | allocation_method = "Static" 33 | sku = "Standard" 34 | } 35 | 36 | resource "azurerm_bastion_host" "bastion-spoke-2" { 37 | name = "bastion-spoke-2" 38 | location = var.location-spoke-2 39 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 40 | sku = "Standard" 41 | ip_connect_enabled = true 42 | 43 | ip_configuration { 44 | name = "bastion-spoke-2-configuration" 45 | subnet_id = azurerm_subnet.bastion-spoke-2-subnet.id 46 | public_ip_address_id = azurerm_public_ip.bastion-spoke-2-pubip.id 47 | } 48 | } 49 | ####################################################################### 50 | ## Create Bastion spoke-3 51 | ####################################################################### 52 | resource "azurerm_public_ip" "bastion-spoke-3-pubip" { 53 | name = "bastion-spoke-3-pubip" 54 | location = var.location-spoke-3 55 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 56 | allocation_method = "Static" 57 | sku = "Standard" 58 | } 59 | 60 | resource "azurerm_bastion_host" "bastion-spoke-3" { 61 | name = "bastion-spoke-3" 62 | location = var.location-spoke-3 63 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 64 | sku = "Standard" 65 | ip_connect_enabled = true 66 | 67 | ip_configuration { 68 | name = "bastion-spoke-3-configuration" 69 | subnet_id = azurerm_subnet.bastion-spoke-3-subnet.id 70 | public_ip_address_id = azurerm_public_ip.bastion-spoke-3-pubip.id 71 | } 72 | } 73 | ####################################################################### 74 | ## Create Bastion spoke-4 75 | ####################################################################### 76 | resource "azurerm_public_ip" "bastion-spoke-4-pubip" { 77 | name = "bastion-spoke-4-pubip" 78 | location = var.location-spoke-4 79 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 80 | allocation_method = "Static" 81 | sku = "Standard" 82 | } 83 | 84 | resource "azurerm_bastion_host" "bastion-spoke-4" { 85 | name = "bastion-spoke-4" 86 | location = var.location-spoke-4 87 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 88 | sku = "Standard" 89 | ip_connect_enabled = true 90 | 91 | ip_configuration { 92 | name = "bastion-spoke-4-configuration" 93 | subnet_id = azurerm_subnet.bastion-spoke-4-subnet.id 94 | public_ip_address_id = azurerm_public_ip.bastion-spoke-4-pubip.id 95 | } 96 | } 97 | ####################################################################### 98 | ## Create Bastion onprem 99 | ####################################################################### 100 | resource "azurerm_public_ip" "bastion-onprem-pubip" { 101 | name = "bastion-onprem-pubip" 102 | location = var.location-onprem 103 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 104 | allocation_method = "Static" 105 | sku = "Standard" 106 | } 107 | 108 | resource "azurerm_bastion_host" "bastion-onprem" { 109 | name = "bastion-onprem" 110 | location = var.location-onprem 111 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 112 | sku = "Standard" 113 | ip_connect_enabled = true 114 | 115 | ip_configuration { 116 | name = "bastion-onprem-configuration" 117 | subnet_id = azurerm_subnet.bastion-onprem-subnet.id 118 | public_ip_address_id = azurerm_public_ip.bastion-onprem-pubip.id 119 | } 120 | } 121 | ####################################################################### 122 | ## Create Bastion onprem2 123 | ####################################################################### 124 | resource "azurerm_public_ip" "bastion-onprem2-pubip" { 125 | name = "bastion-onprem2-pubip" 126 | location = var.location-onprem2 127 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 128 | allocation_method = "Static" 129 | sku = "Standard" 130 | } 131 | 132 | resource "azurerm_bastion_host" "bastion-onprem2" { 133 | name = "bastion-onprem2" 134 | location = var.location-onprem2 135 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 136 | sku = "Standard" 137 | ip_connect_enabled = true 138 | 139 | ip_configuration { 140 | name = "bastion-onprem2-configuration" 141 | subnet_id = azurerm_subnet.bastion-onprem2-subnet.id 142 | public_ip_address_id = azurerm_public_ip.bastion-onprem2-pubip.id 143 | } 144 | } 145 | ####################################################################### 146 | ## Create Bastion Services 147 | ####################################################################### 148 | resource "azurerm_public_ip" "bastion-services-pubip" { 149 | name = "bastion-services-pubip" 150 | location = var.location-spoke-services 151 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 152 | allocation_method = "Static" 153 | sku = "Standard" 154 | } 155 | 156 | resource "azurerm_bastion_host" "bastion-services" { 157 | name = "bastion-services" 158 | location = var.location-spoke-services 159 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 160 | sku = "Standard" 161 | ip_connect_enabled = true 162 | 163 | ip_configuration { 164 | name = "bastion-services-configuration" 165 | subnet_id = azurerm_subnet.bastion-services-subnet.id 166 | public_ip_address_id = azurerm_public_ip.bastion-services-pubip.id 167 | } 168 | } 169 | ####################################################################### 170 | ## Create Bastion NVA 171 | ####################################################################### 172 | resource "azurerm_public_ip" "bastion-nva-pubip" { 173 | name = "bastion-services-nva" 174 | location = var.location-spoke-services 175 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 176 | allocation_method = "Static" 177 | sku = "Standard" 178 | } 179 | 180 | resource "azurerm_bastion_host" "bastion-nva" { 181 | name = "bastion-nva" 182 | location = var.location-spoke-services 183 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 184 | sku = "Standard" 185 | ip_connect_enabled = true 186 | 187 | ip_configuration { 188 | name = "bastion-nva-configuration" 189 | subnet_id = azurerm_subnet.bastion-nva-subnet.id 190 | public_ip_address_id = azurerm_public_ip.bastion-nva-pubip.id 191 | } 192 | } -------------------------------------------------------------------------------- /branch-routes.sh: -------------------------------------------------------------------------------- 1 | hubgwbgpaddress=$(az network vpn-gateway show --name microhack-we-hub-vng -g vwan-microhack-hub-rg --query "bgpSettings.bgpPeeringAddresses[?ipconfigurationId == 'Instance0'].defaultBgpIpAddresses" --output tsv) 2 | echo "Hub GW BGP address:" $hubgwbgpaddress 3 | 4 | echo "# VNETGW: Verify BGP peer status" 5 | az network vnet-gateway list-bgp-peer-status -n vnet-gw-onprem -g vwan-microhack-spoke-rg --output table 6 | 7 | echo "# VNETGW: Display routes advertised from onprem gw to hub" 8 | az network vnet-gateway list-advertised-routes -n vnet-gw-onprem -g vwan-microhack-spoke-rg --peer $hubgwbgpaddress --output table 9 | 10 | echo "# VNETGW: Display routes learned by onprem gw from hub" 11 | az network vnet-gateway list-learned-routes -n vnet-gw-onprem -g vwan-microhack-spoke-rg --output table 12 | -------------------------------------------------------------------------------- /clean-up-after-scenario-4.sh: -------------------------------------------------------------------------------- 1 | spoke1vnetid=$(az network vnet show -g vwan-microhack-spoke-rg -n spoke-1-vnet --query "id" --output tsv) 2 | spoke2vnetid=$(az network vnet show -g vwan-microhack-spoke-rg -n spoke-2-vnet --query "id" --output tsv) 3 | spoke3vnetid=$(az network vnet show -g vwan-microhack-spoke-rg -n spoke-3-vnet --query "id" --output tsv) 4 | spoke4vnetid=$(az network vnet show -g vwan-microhack-spoke-rg -n spoke-4-vnet --query "id" --output tsv) 5 | servicesvnetid=$(az network vnet show -g vwan-microhack-spoke-rg -n services-vnet --query "id" --output tsv) 6 | nvavnetid=$(az network vnet show -g vwan-microhack-spoke-rg -n nva-vnet --query "id" --output tsv) 7 | wedefaultrtid=$(az network vhub route-table show --name defaultRouteTable --resource-group vwan-microhack-hub-rg --vhub-name microhack-we-hub --query id --output tsv) 8 | 9 | echo "Removing associations and propagations from rt-shared-we" 10 | 11 | wesharedrtid=$(az network vhub route-table show --name "RT-Shared-we" --resource-group "vwan-microhack-hub-rg" --vhub-name microhack-we-hub --query id --output tsv) 12 | WERESTEP="https://management.azure.com${wesharedrtid}?api-version=2020-05-01" 13 | az rest --method put --uri "$WERESTEP" --body @emptyrtbody.json 14 | while [[ $(az rest --uri $WERESTEP | jq .properties.provisioningState) != "\"Succeeded\"" ]]; do sleep 15; done 15 | spoke1connection=$(az network vhub connection show -n spoke-1-we -g vwan-microhack-hub-rg --vhub-name microhack-we-hub --query "id" -o tsv) 16 | spoke2connection=$(az network vhub connection show -n spoke-2-we -g vwan-microhack-hub-rg --vhub-name microhack-we-hub --query "id" -o tsv) 17 | servicesvnetconnection=$(az network vhub connection show -n services-we -g vwan-microhack-hub-rg --vhub-name microhack-we-hub --query "id" -o tsv) 18 | WEVNETCONNECTIONSPOKE1="https://management.azure.com${spoke1connection}?api-version=2020-05-01" 19 | WEVNETCONNECTIONSPOKE2="https://management.azure.com${spoke2connection}?api-version=2020-05-01" 20 | WEVNETCONNECTIONSERVICES="https://management.azure.com${servicesvnetconnection}?api-version=2020-05-01" 21 | sed "s#spokevnetid#$spoke1vnetid#g" emptyspokeconnection.json | tee emptyspokeconnection-spoke1.json 22 | sed -i "s#wedefaultrtid#$wedefaultrtid#g" emptyspokeconnection-spoke1.json 23 | sed "s#spokevnetid#$spoke2vnetid#g" emptyspokeconnection.json | tee emptyspokeconnection-spoke2.json 24 | sed -i "s#wedefaultrtid#$wedefaultrtid#g" emptyspokeconnection-spoke2.json 25 | sed "s#spokevnetid#$servicesvnetid#g" emptyspokeconnection.json | tee emptyspokeconnection-services.json 26 | sed -i "s#wedefaultrtid#$wedefaultrtid#g" emptyspokeconnection-services.json 27 | az rest --method put --uri $WEVNETCONNECTIONSPOKE1 --body @emptyspokeconnection-spoke1.json 28 | while [[ $(az rest --uri $WEVNETCONNECTIONSPOKE1 | jq .properties.provisioningState) != "\"Succeeded\"" ]]; do sleep 15; done 29 | az rest --method put --uri $WEVNETCONNECTIONSPOKE2 --body @emptyspokeconnection-spoke2.json 30 | while [[ $(az rest --uri $WEVNETCONNECTIONSPOKE2 | jq .properties.provisioningState) != "\"Succeeded\"" ]]; do sleep 15; done 31 | az rest --method put --uri $WEVNETCONNECTIONSERVICES --body @emptyspokeconnection-services.json 32 | while [[ $(az rest --uri $WEVNETCONNECTIONSERVICES | jq .properties.provisioningState) != "\"Succeeded\"" ]]; do sleep 15; done 33 | 34 | echo "Removing associations and propagations from rt-shared-useast" 35 | useastdefaultrtid=$(az network vhub route-table show --name defaultRouteTable --resource-group vwan-microhack-hub-rg --vhub-name microhack-useast-hub --query id --output tsv) 36 | useastsharedrtid=$(az network vhub route-table show --name "rt-shared-useast" --resource-group "vwan-microhack-hub-rg" --vhub-name microhack-useast-hub --query id --output tsv) 37 | USEASTRESTEP="https://management.azure.com${useastsharedrtid}?api-version=2020-05-01" 38 | az rest --method put --uri "$USEASTRESTEP" --body @emptyrtbody.json 39 | while [[ $(az rest --uri $USEASTRESTEP | jq .properties.provisioningState) != "\"Succeeded\"" ]]; do sleep 15; done 40 | spoke3connection=$(az network vhub connection show -n spoke-3-useast -g vwan-microhack-hub-rg --vhub-name microhack-useast-hub --query "id" -o tsv) 41 | spoke4connection=$(az network vhub connection show -n spoke-4-useast -g vwan-microhack-hub-rg --vhub-name microhack-useast-hub --query "id" -o tsv) 42 | USEASTVNETCONNECTIONSPOKE3="https://management.azure.com${spoke3connection}?api-version=2020-05-01" 43 | USEASTVNETCONNECTIONSPOKE4="https://management.azure.com${spoke4connection}?api-version=2020-05-01" 44 | sed "s#spokevnetid#$spoke3vnetid#g" emptyspokeconnection.json | tee emptyspokeconnection-spoke3.json 45 | sed -i "s#wedefaultrtid#$useastdefaultrtid#g" emptyspokeconnection-spoke3.json 46 | sed "s#spokevnetid#$spoke4vnetid#g" emptyspokeconnection.json | tee emptyspokeconnection-spoke4.json 47 | sed -i "s#wedefaultrtid#$useastdefaultrtid#g" emptyspokeconnection-spoke4.json 48 | az rest --method put --uri $USEASTVNETCONNECTIONSPOKE3 --body @emptyspokeconnection-spoke3.json 49 | while [[ $(az rest --uri $USEASTVNETCONNECTIONSPOKE3 | jq .properties.provisioningState) != "\"Succeeded\"" ]]; do sleep 15; done 50 | az rest --method put --uri $USEASTVNETCONNECTIONSPOKE4 --body @emptyspokeconnection-spoke4.json 51 | while [[ $(az rest --uri $USEASTVNETCONNECTIONSPOKE4 | jq .properties.provisioningState) != "\"Succeeded\"" ]]; do sleep 15; done 52 | 53 | 54 | ONPREMCONNECTIONID=$(az network vpn-gateway list -g vwan-microhack-hub-rg --query [].connections[].id -o tsv) 55 | ONPREMCONNECTIONRESTEP="https://management.azure.com${ONPREMCONNECTIONID}?api-version=2020-05-01" 56 | ONPREMCONNECTIONVPNSITE=$(az network vpn-gateway list -g vwan-microhack-hub-rg --query [].connections[].remoteVpnSite.id -o tsv) 57 | sed "s#wedefaultrtid#$wedefaultrtid#g" onpremconnection.json | tee onpremconnection-values.json 58 | sed -i "s#ONPREMCONNECTIONVPNSITE#$ONPREMCONNECTIONVPNSITE#g" onpremconnection-values.json 59 | az rest --method put --uri $ONPREMCONNECTIONRESTEP --body @onpremconnection-values.json 60 | while [[ $(az rest --uri $ONPREMCONNECTIONRESTEP | jq .properties.provisioningState) != "\"Succeeded\"" ]]; do sleep 15; done 61 | 62 | echo "Deleting rt-shared-useast" 63 | az network vhub route-table delete --name rt-shared-useast -g vwan-microhack-hub-rg --vhub-name microhack-useast-hub 64 | echo "Deleting rt-shared-we" 65 | az network vhub route-table delete --name rt-shared-we -g vwan-microhack-hub-rg --vhub-name microhack-we-hub 66 | 67 | echo "Disconnecting Branch" 68 | az network vpn-gateway connection delete --gateway-name microhack-we-hub-vng --name onprem -g vwan-microhack-hub-rg 69 | az network vpn-site delete --name onprem -g vwan-microhack-hub-rg 70 | 71 | echo "Deleting VPN Gateway" 72 | az network vpn-gateway delete --name microhack-we-hub-vng -g vwan-microhack-hub-rg 73 | 74 | echo "Deleting resource groups" 75 | az group delete --resource-group vwan-microhack-hub-rg --no-wait --yes 76 | az group delete --resource-group vwan-microhack-spoke-rg --no-wait --yes -------------------------------------------------------------------------------- /connect-branch-custom-rt.sh: -------------------------------------------------------------------------------- 1 | az extension add --name virtual-wan 2 | 3 | echo "# VNETGW: Get parameters from onprem vnet gateway" 4 | vnetgwtunnelip1=$(az network vnet-gateway show -n vnet-gw-onprem -g vwan-microhack-spoke-rg --query "bgpSettings.bgpPeeringAddresses[0].tunnelIpAddresses[0]" --output tsv) 5 | echo "VNET GW Tunnel address #1:" $vnetgwtunnelip1 6 | vnetgwtunnelip2=$(az network vnet-gateway show -n vnet-gw-onprem -g vwan-microhack-spoke-rg --query "bgpSettings.bgpPeeringAddresses[1].tunnelIpAddresses[0]" --output tsv) 7 | echo "VNET GW Tunnel address #2:" $vnetgwtunnelip2 8 | vnetgwbgpip1=$(az network vnet-gateway show -n vnet-gw-onprem -g vwan-microhack-spoke-rg --query "bgpSettings.bgpPeeringAddresses[0].defaultBgpIpAddresses" --output tsv) 9 | echo "VNET GW BGP address:" $vnetgwbgpip1 10 | vnetgwbgpip2=$(az network vnet-gateway show -n vnet-gw-onprem -g vwan-microhack-spoke-rg --query "bgpSettings.bgpPeeringAddresses[1].defaultBgpIpAddresses" --output tsv) 11 | echo "VNET GW BGP address:" $vnetgwbgpip2 12 | vnetgwasn=$(az network vnet-gateway show -n vnet-gw-onprem -g vwan-microhack-spoke-rg --query "bgpSettings.asn" --output tsv) 13 | echo "VNET GW BGP ASN:" $vnetgwasn 14 | sharedkey="m1cr0hack" 15 | customrt=$(az network vhub route-table show --name custom-rt --resource-group vwan-microhack-hub-rg --vhub-name microhack-we-hub --query "id" --output tsv) 16 | echo "Custom Routetable" 17 | 18 | 19 | 20 | echo "# VWAN: Create remote site" 21 | az network vpn-site create --name onprem -g vwan-microhack-hub-rg --ip-address $vnetgwtunnelip1 --virtual-wan microhack-vwan --location uksouth --device-model VNETGW --device-vendor Azure --asn $vnetgwasn --bgp-peering-address $vnetgwbgpip1 --link-speed 100 --with-link true 22 | 23 | echo "# VWAN: Create connection - remote site link to hub gw" 24 | az network vpn-gateway connection create --gateway-name microhack-we-hub-vng --name onprem-connection -g vwan-microhack-hub-rg --remote-vpn-site onprem --shared-key $sharedkey --enable-bgp true --no-wait 25 | 26 | echo "# VWAN: Get parameters from VWAN Hub GW" 27 | hubgwtunneladdress=$(az network vpn-gateway show --name microhack-we-hub-vng -g vwan-microhack-hub-rg --query "bgpSettings.bgpPeeringAddresses[?ipconfigurationId == 'Instance0'].tunnelIpAddresses[0]" --output tsv) 28 | echo "Hub GW Tunnel address:" $hubgwtunneladdress 29 | hubgwbgpaddress=$(az network vpn-gateway show --name microhack-we-hub-vng -g vwan-microhack-hub-rg --query "bgpSettings.bgpPeeringAddresses[?ipconfigurationId == 'Instance0'].defaultBgpIpAddresses" --output tsv) 30 | echo "Hub GW BGP address:" $hubgwbgpaddress 31 | hubgwasn=$(az network vpn-gateway show --name microhack-we-hub-vng -g vwan-microhack-hub-rg --query "bgpSettings.asn" --output tsv) 32 | echo "Hub GW BGP ASN:" $hubgwasn 33 | 34 | echo "# create local network gateway" 35 | az network local-gateway create -g vwan-microhack-spoke-rg -n lng --gateway-ip-address $hubgwtunneladdress --location westeurope --asn $hubgwasn --bgp-peering-address $hubgwbgpaddress 36 | 37 | echo "# VNET GW: connect from vnet gw to local network gateway" 38 | az network vpn-connection create -n to-we-hub --vnet-gateway1 vnet-gw-onprem -g vwan-microhack-spoke-rg --local-gateway2 lng -l uksouth --shared-key $sharedkey --enable-bgp 39 | 40 | -------------------------------------------------------------------------------- /connect-branch.sh: -------------------------------------------------------------------------------- 1 | az extension add --name virtual-wan 2 | 3 | echo "# VNETGW: Get parameters from onprem vnet gateway" 4 | vnetgwtunnelip1=$(az network vnet-gateway show -n vnet-gw-onprem -g vwan-microhack-spoke-rg --query "bgpSettings.bgpPeeringAddresses[0].tunnelIpAddresses[0]" --output tsv) 5 | echo "VNET GW Tunnel address #1:" $vnetgwtunnelip1 6 | vnetgwtunnelip2=$(az network vnet-gateway show -n vnet-gw-onprem -g vwan-microhack-spoke-rg --query "bgpSettings.bgpPeeringAddresses[1].tunnelIpAddresses[0]" --output tsv) 7 | echo "VNET GW Tunnel address #2:" $vnetgwtunnelip2 8 | vnetgwbgpip1=$(az network vnet-gateway show -n vnet-gw-onprem -g vwan-microhack-spoke-rg --query "bgpSettings.bgpPeeringAddresses[0].defaultBgpIpAddresses" --output tsv) 9 | echo "VNET GW BGP address:" $vnetgwbgpip1 10 | vnetgwbgpip2=$(az network vnet-gateway show -n vnet-gw-onprem -g vwan-microhack-spoke-rg --query "bgpSettings.bgpPeeringAddresses[1].defaultBgpIpAddresses" --output tsv) 11 | echo "VNET GW BGP address:" $vnetgwbgpip2 12 | vnetgwasn=$(az network vnet-gateway show -n vnet-gw-onprem -g vwan-microhack-spoke-rg --query "bgpSettings.asn" --output tsv) 13 | echo "VNET GW BGP ASN:" $vnetgwasn 14 | sharedkey="m1cr0hack" 15 | 16 | echo "# VWAN: Create remote site" 17 | az network vpn-site create --name onprem -g vwan-microhack-hub-rg --ip-address $vnetgwtunnelip1 --virtual-wan microhack-vwan --location uksouth --device-model VNETGW --device-vendor Azure --asn $vnetgwasn --bgp-peering-address $vnetgwbgpip1 --link-speed 100 --with-link true 18 | 19 | echo "# VWAN: Create connection - remote site link to hub gw" 20 | az network vpn-gateway connection create --gateway-name microhack-we-hub-vng --name onprem-connection -g vwan-microhack-hub-rg --remote-vpn-site onprem --shared-key $sharedkey --enable-bgp true --no-wait 21 | 22 | echo "# VWAN: Get parameters from VWAN Hub GW" 23 | hubgwtunneladdress=$(az network vpn-gateway show --name microhack-we-hub-vng -g vwan-microhack-hub-rg --query "bgpSettings.bgpPeeringAddresses[?ipconfigurationId == 'Instance0'].tunnelIpAddresses[0]" --output tsv) 24 | echo "Hub GW Tunnel address:" $hubgwtunneladdress 25 | hubgwbgpaddress=$(az network vpn-gateway show --name microhack-we-hub-vng -g vwan-microhack-hub-rg --query "bgpSettings.bgpPeeringAddresses[?ipconfigurationId == 'Instance0'].defaultBgpIpAddresses" --output tsv) 26 | echo "Hub GW BGP address:" $hubgwbgpaddress 27 | hubgwasn=$(az network vpn-gateway show --name microhack-we-hub-vng -g vwan-microhack-hub-rg --query "bgpSettings.asn" --output tsv) 28 | echo "Hub GW BGP ASN:" $hubgwasn 29 | 30 | echo "# create local network gateway" 31 | az network local-gateway create -g vwan-microhack-spoke-rg -n lng --gateway-ip-address $hubgwtunneladdress --location westeurope --asn $hubgwasn --bgp-peering-address $hubgwbgpaddress 32 | 33 | echo "# VNET GW: connect from vnet gw to local network gateway" 34 | az network vpn-connection create -n to-we-hub --vnet-gateway1 vnet-gw-onprem -g vwan-microhack-spoke-rg --local-gateway2 lng -l uksouth --shared-key $sharedkey --enable-bgp 35 | 36 | -------------------------------------------------------------------------------- /connect-branch2.sh: -------------------------------------------------------------------------------- 1 | az extension add --name virtual-wan 2 | 3 | echo "# VNETGW: Get parameters from onprem2 vnet gateway" 4 | vnetgwtunnelip1=$(az network vnet-gateway show -n vnet-gw-onprem2 -g vwan-microhack-spoke-rg --query "bgpSettings.bgpPeeringAddresses[0].tunnelIpAddresses[0]" --output tsv) 5 | echo "VNET GW Tunnel address #1:" $vnetgwtunnelip1 6 | vnetgwtunnelip2=$(az network vnet-gateway show -n vnet-gw-onprem2 -g vwan-microhack-spoke-rg --query "bgpSettings.bgpPeeringAddresses[1].tunnelIpAddresses[0]" --output tsv) 7 | echo "VNET GW Tunnel address #2:" $vnetgwtunnelip2 8 | vnetgwbgpip1=$(az network vnet-gateway show -n vnet-gw-onprem2 -g vwan-microhack-spoke-rg --query "bgpSettings.bgpPeeringAddresses[0].defaultBgpIpAddresses" --output tsv) 9 | echo "VNET GW BGP address:" $vnetgwbgpip1 10 | vnetgwbgpip2=$(az network vnet-gateway show -n vnet-gw-onprem2 -g vwan-microhack-spoke-rg --query "bgpSettings.bgpPeeringAddresses[1].defaultBgpIpAddresses" --output tsv) 11 | echo "VNET GW BGP address:" $vnetgwbgpip2 12 | vnetgwasn=$(az network vnet-gateway show -n vnet-gw-onprem2 -g vwan-microhack-spoke-rg --query "bgpSettings.asn" --output tsv) 13 | echo "VNET GW BGP ASN:" $vnetgwasn 14 | sharedkey="m1cr0hack" 15 | 16 | echo "# VWAN: Create remote site" 17 | az network vpn-site create --name onprem2 -g vwan-microhack-hub-rg --ip-address $vnetgwtunnelip1 --virtual-wan microhack-vwan --location northeurope --device-model VNETGW --device-vendor Azure --asn $vnetgwasn --bgp-peering-address $vnetgwbgpip1 --link-speed 100 --with-link true 18 | az network vpn-site link add --name onprem2-link2 -g vwan-microhack-hub-rg --ip-address $vnetgwtunnelip2 --site-name onprem2 --asn $vnetgwasn --bgp-peering-address $vnetgwbgpip2 --link-speed 100 19 | 20 | echo "# VWAN: Create connection - remote site link to hub gw" 21 | az network vpn-gateway connection create --gateway-name microhack-we-hub-vng --name onprem2-connection -g vwan-microhack-hub-rg --remote-vpn-site onprem2 --shared-key $sharedkey --enable-bgp true --no-wait 22 | 23 | echo "# VWAN: Get parameters from VWAN Hub GW" 24 | hubgwtunneladdress0=$(az network vpn-gateway show --name microhack-we-hub-vng -g vwan-microhack-hub-rg --query "bgpSettings.bgpPeeringAddresses[?ipconfigurationId == 'Instance0'].tunnelIpAddresses[0]" --output tsv) 25 | hubgwtunneladdress1=$(az network vpn-gateway show --name microhack-we-hub-vng -g vwan-microhack-hub-rg --query "bgpSettings.bgpPeeringAddresses[?ipconfigurationId == 'Instance1'].tunnelIpAddresses[0]" --output tsv) 26 | echo "Hub GW Tunnel address0:" $hubgwtunneladdress0 27 | echo "Hub GW Tunnel address1:" $hubgwtunneladdress1 28 | hubgwbgpaddress0=$(az network vpn-gateway show --name microhack-we-hub-vng -g vwan-microhack-hub-rg --query "bgpSettings.bgpPeeringAddresses[?ipconfigurationId == 'Instance0'].defaultBgpIpAddresses" --output tsv) 29 | hubgwbgpaddress1=$(az network vpn-gateway show --name microhack-we-hub-vng -g vwan-microhack-hub-rg --query "bgpSettings.bgpPeeringAddresses[?ipconfigurationId == 'Instance1'].defaultBgpIpAddresses" --output tsv) 30 | echo "Hub GW BGP address0:" $hubgwbgpaddress0 31 | echo "Hub GW BGP address1:" $hubgwbgpaddress1 32 | hubgwasn=$(az network vpn-gateway show --name microhack-we-hub-vng -g vwan-microhack-hub-rg --query "bgpSettings.asn" --output tsv) 33 | echo "Hub GW BGP ASN:" $hubgwasn 34 | 35 | echo "# create local network gateways" 36 | az network local-gateway create -g vwan-microhack-spoke-rg -n lng2-0 --gateway-ip-address $hubgwtunneladdress0 --location westeurope --asn $hubgwasn --bgp-peering-address $hubgwbgpaddress0 37 | az network local-gateway create -g vwan-microhack-spoke-rg -n lng2-1 --gateway-ip-address $hubgwtunneladdress1 --location westeurope --asn $hubgwasn --bgp-peering-address $hubgwbgpaddress1 38 | 39 | echo "# VNET GW: connect from vnet gw to local network gateways" 40 | az network vpn-connection create -n to-we-hub2-0 --vnet-gateway1 vnet-gw-onprem2 -g vwan-microhack-spoke-rg --local-gateway2 lng2-0 -l westeurope --shared-key $sharedkey --enable-bgp 41 | az network vpn-connection create -n to-we-hub2-1 --vnet-gateway1 vnet-gw-onprem2 -g vwan-microhack-spoke-rg --local-gateway2 lng2-1 -l westeurope --shared-key $sharedkey --enable-bgp 42 | -------------------------------------------------------------------------------- /connect-services-spoke.sh: -------------------------------------------------------------------------------- 1 | servicesid=$(az network vnet show -g vwan-microhack-spoke-rg --name services-vnet --query "id" --output tsv) 2 | az network vhub connection create --name services-we --resource-group vwan-microhack-hub-rg --vhub-name microhack-we-hub --remote-vnet $servicesid --labels default -------------------------------------------------------------------------------- /connect-us-east-spokes.sh: -------------------------------------------------------------------------------- 1 | spoke3id=$(az network vnet show -g vwan-microhack-spoke-rg --name spoke-3-vnet --query "id" --output tsv) 2 | spoke4id=$(az network vnet show -g vwan-microhack-spoke-rg --name spoke-4-vnet --query "id" --output tsv) 3 | az network vhub connection create --name spoke-3-useast --resource-group vwan-microhack-hub-rg --vhub-name microhack-useast-hub --remote-vnet $spoke3id --labels default 4 | az network vhub connection create --name spoke-4-useast --resource-group vwan-microhack-hub-rg --vhub-name microhack-useast-hub --remote-vnet $spoke4id --labels default 5 | -------------------------------------------------------------------------------- /connect-west-europe-spokes.sh: -------------------------------------------------------------------------------- 1 | spoke1id=$(az network vnet show -g vwan-microhack-spoke-rg --name spoke-1-vnet --query "id" --output tsv) 2 | spoke2id=$(az network vnet show -g vwan-microhack-spoke-rg --name spoke-2-vnet --query "id" --output tsv) 3 | az network vhub connection create --name spoke-1-we --resource-group vwan-microhack-hub-rg --vhub-name microhack-we-hub --remote-vnet $spoke1id --labels default 4 | az network vhub connection create --name spoke-2-we --resource-group vwan-microhack-hub-rg --vhub-name microhack-we-hub --remote-vnet $spoke2id --labels default 5 | -------------------------------------------------------------------------------- /emptyrtbody.json: -------------------------------------------------------------------------------- 1 | { 2 | "properties": { 3 | "labels": [], 4 | "routes": [] 5 | } 6 | } -------------------------------------------------------------------------------- /emptyspokeconnection.json: -------------------------------------------------------------------------------- 1 | { 2 | "properties": { 3 | "allowHubToRemoteVnetTransit": true, 4 | "allowRemoteVnetToUseHubVnetGateways": true, 5 | "enableInternetSecurity": false, 6 | "remoteVirtualNetwork": { 7 | "id": "spokevnetid", 8 | "resourceGroup": "vwan-microhack-spoke-rg" 9 | }, 10 | "routingConfiguration": { 11 | "associatedRouteTable": { 12 | "id": "wedefaultrtid" 13 | }, 14 | "propagatedRouteTables": {}, 15 | "vnetRoutes": { 16 | "staticRoutes": [] 17 | } 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /enable-routing-nva.sh: -------------------------------------------------------------------------------- 1 | sudo chmod 777 /etc/sysctl.conf 2 | echo "net.ipv4.ip_forward = 1" > /etc/sysctl.conf 3 | sudo sysctl -p /etc/sysctl.conf 4 | sudo iptables -t nat -A POSTROUTING -d 10.0.0.0/8 -j ACCEPT 5 | sudo iptables -t nat -A POSTROUTING -d 172.16.0.0/12 -j ACCEPT 6 | sudo iptables -t nat -A POSTROUTING -d 192.168.0.0/16 -j ACCEPT 7 | sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE -------------------------------------------------------------------------------- /images/microhack-vwan-security.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mddazure/azure-vwan-microhack/a81da80dd2efc5ece9f778bddca25b9f0813fb2e/images/microhack-vwan-security.png -------------------------------------------------------------------------------- /images/microhack-vwan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mddazure/azure-vwan-microhack/a81da80dd2efc5ece9f778bddca25b9f0813fb2e/images/microhack-vwan.png -------------------------------------------------------------------------------- /images/microhack-vwan.vsdx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mddazure/azure-vwan-microhack/a81da80dd2efc5ece9f778bddca25b9f0813fb2e/images/microhack-vwan.vsdx -------------------------------------------------------------------------------- /images/scenario-4-edit-branch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mddazure/azure-vwan-microhack/a81da80dd2efc5ece9f778bddca25b9f0813fb2e/images/scenario-4-edit-branch.png -------------------------------------------------------------------------------- /images/scenario-4-edit-shared.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mddazure/azure-vwan-microhack/a81da80dd2efc5ece9f778bddca25b9f0813fb2e/images/scenario-4-edit-shared.png -------------------------------------------------------------------------------- /images/scenario-4-useast-routetables.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mddazure/azure-vwan-microhack/a81da80dd2efc5ece9f778bddca25b9f0813fb2e/images/scenario-4-useast-routetables.png -------------------------------------------------------------------------------- /images/scenario-4-we-routetables.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mddazure/azure-vwan-microhack/a81da80dd2efc5ece9f778bddca25b9f0813fb2e/images/scenario-4-we-routetables.png -------------------------------------------------------------------------------- /images/scenario1-ass-prop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mddazure/azure-vwan-microhack/a81da80dd2efc5ece9f778bddca25b9f0813fb2e/images/scenario1-ass-prop.png -------------------------------------------------------------------------------- /images/scenario1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mddazure/azure-vwan-microhack/a81da80dd2efc5ece9f778bddca25b9f0813fb2e/images/scenario1.png -------------------------------------------------------------------------------- /images/scenario2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mddazure/azure-vwan-microhack/a81da80dd2efc5ece9f778bddca25b9f0813fb2e/images/scenario2.png -------------------------------------------------------------------------------- /images/scenario3-ass-prop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mddazure/azure-vwan-microhack/a81da80dd2efc5ece9f778bddca25b9f0813fb2e/images/scenario3-ass-prop.png -------------------------------------------------------------------------------- /images/scenario3-hubs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mddazure/azure-vwan-microhack/a81da80dd2efc5ece9f778bddca25b9f0813fb2e/images/scenario3-hubs.png -------------------------------------------------------------------------------- /images/scenario3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mddazure/azure-vwan-microhack/a81da80dd2efc5ece9f778bddca25b9f0813fb2e/images/scenario3.png -------------------------------------------------------------------------------- /images/scenario4-allowedflows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mddazure/azure-vwan-microhack/a81da80dd2efc5ece9f778bddca25b9f0813fb2e/images/scenario4-allowedflows.png -------------------------------------------------------------------------------- /images/scenario4-blockedflows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mddazure/azure-vwan-microhack/a81da80dd2efc5ece9f778bddca25b9f0813fb2e/images/scenario4-blockedflows.png -------------------------------------------------------------------------------- /images/scenario4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mddazure/azure-vwan-microhack/a81da80dd2efc5ece9f778bddca25b9f0813fb2e/images/scenario4.png -------------------------------------------------------------------------------- /images/scenario5-add-custom-routes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mddazure/azure-vwan-microhack/a81da80dd2efc5ece9f778bddca25b9f0813fb2e/images/scenario5-add-custom-routes.png -------------------------------------------------------------------------------- /images/scenario5-add-default-route.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mddazure/azure-vwan-microhack/a81da80dd2efc5ece9f778bddca25b9f0813fb2e/images/scenario5-add-default-route.png -------------------------------------------------------------------------------- /images/scenario5-disable-prop-def-rt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mddazure/azure-vwan-microhack/a81da80dd2efc5ece9f778bddca25b9f0813fb2e/images/scenario5-disable-prop-def-rt.png -------------------------------------------------------------------------------- /images/scenario5-enable-prop-def-rt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mddazure/azure-vwan-microhack/a81da80dd2efc5ece9f778bddca25b9f0813fb2e/images/scenario5-enable-prop-def-rt.png -------------------------------------------------------------------------------- /images/scenario5-single-default-route.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mddazure/azure-vwan-microhack/a81da80dd2efc5ece9f778bddca25b9f0813fb2e/images/scenario5-single-default-route.png -------------------------------------------------------------------------------- /images/scenario5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mddazure/azure-vwan-microhack/a81da80dd2efc5ece9f778bddca25b9f0813fb2e/images/scenario5.png -------------------------------------------------------------------------------- /images/vwan-with-connections.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mddazure/azure-vwan-microhack/a81da80dd2efc5ece9f778bddca25b9f0813fb2e/images/vwan-with-connections.png -------------------------------------------------------------------------------- /main.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | azurerm = { 4 | source = "hashicorp/azurerm" 5 | version = "3.116.0" 6 | } 7 | } 8 | } 9 | 10 | provider "azurerm" { 11 | features {} 12 | } 13 | 14 | 15 | ####################################################################### 16 | ## Create Resource Group 17 | ####################################################################### 18 | 19 | resource "azurerm_resource_group" "vwan-microhack-spoke-rg" { 20 | name = "vwan-microhack-spoke-rg" 21 | location = var.location-spoke-1 22 | tags = { 23 | environment = "spoke" 24 | deployment = "terraform" 25 | microhack = "vwan" 26 | } 27 | } 28 | 29 | resource "azurerm_resource_group" "vwan-microhack-hub-rg" { 30 | name = "vwan-microhack-hub-rg" 31 | location = var.location-vwan 32 | tags = { 33 | environment = "hub" 34 | deployment = "terraform" 35 | microhack = "vwan" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /onpremconnection.json: -------------------------------------------------------------------------------- 1 | { 2 | "properties": { 3 | "remoteVpnSite": { 4 | "id": "ONPREMCONNECTIONVPNSITE" 5 | }, 6 | "routingConfiguration": { 7 | "associatedRouteTable": { 8 | "id": "wedefaultrtid" 9 | }, 10 | "propagatedRouteTables": { 11 | "ids": [ 12 | { 13 | "id": "wedefaultrtid" 14 | } 15 | ], 16 | "labels": [ 17 | "default" 18 | ] 19 | }, 20 | "vnetRoutes": { 21 | "staticRoutes": [] 22 | } 23 | }, 24 | "connectionBandwidth": 10, 25 | "enableBgp": true, 26 | "enableInternetSecurity": false, 27 | "enableRateLimiting": false, 28 | "ipsecPolicies": [], 29 | "routingWeight": 0, 30 | "sharedKey": "m1cr0hack", 31 | "useLocalAzureIpAddress": false, 32 | "usePolicyBasedTrafficSelectors": false, 33 | "vpnConnectionProtocolType": "IKEv2" 34 | } 35 | } -------------------------------------------------------------------------------- /prep-for-scenario-5.sh: -------------------------------------------------------------------------------- 1 | spoke1vnetid=$(az network vnet show -g vwan-microhack-spoke-rg -n spoke-1-vnet --query "id" --output tsv) 2 | spoke2vnetid=$(az network vnet show -g vwan-microhack-spoke-rg -n spoke-2-vnet --query "id" --output tsv) 3 | spoke3vnetid=$(az network vnet show -g vwan-microhack-spoke-rg -n spoke-3-vnet --query "id" --output tsv) 4 | spoke4vnetid=$(az network vnet show -g vwan-microhack-spoke-rg -n spoke-4-vnet --query "id" --output tsv) 5 | servicesvnetid=$(az network vnet show -g vwan-microhack-spoke-rg -n services-vnet --query "id" --output tsv) 6 | nvavnetid=$(az network vnet show -g vwan-microhack-spoke-rg -n nva-vnet --query "id" --output tsv) 7 | wedefaultrtid=$(az network vhub route-table show --name defaultRouteTable --resource-group vwan-microhack-hub-rg --vhub-name microhack-we-hub --query id --output tsv) 8 | 9 | echo "Removing associations and propagations from rt-shared-we" 10 | 11 | wesharedrtid=$(az network vhub route-table show --name "RT-Shared-we" --resource-group "vwan-microhack-hub-rg" --vhub-name microhack-we-hub --query id --output tsv) 12 | WERESTEP="https://management.azure.com${wesharedrtid}?api-version=2020-05-01" 13 | az rest --method put --uri "$WERESTEP" --body @emptyrtbody.json 14 | while [[ $(az rest --uri $WERESTEP | jq .properties.provisioningState) != "\"Succeeded\"" ]]; do sleep 30; done 15 | spoke1connection=$(az network vhub connection show -n spoke-1-we -g vwan-microhack-hub-rg --vhub-name microhack-we-hub --query "id" -o tsv) 16 | spoke2connection=$(az network vhub connection show -n spoke-2-we -g vwan-microhack-hub-rg --vhub-name microhack-we-hub --query "id" -o tsv) 17 | servicesvnetconnection=$(az network vhub connection show -n services-we -g vwan-microhack-hub-rg --vhub-name microhack-we-hub --query "id" -o tsv) 18 | WEVNETCONNECTIONSPOKE1="https://management.azure.com${spoke1connection}?api-version=2020-05-01" 19 | WEVNETCONNECTIONSPOKE2="https://management.azure.com${spoke2connection}?api-version=2020-05-01" 20 | WEVNETCONNECTIONSERVICES="https://management.azure.com${servicesvnetconnection}?api-version=2020-05-01" 21 | sed "s#spokevnetid#$spoke1vnetid#g" emptyspokeconnection.json | tee emptyspokeconnection-spoke1.json 22 | sed -i "s#wedefaultrtid#$wedefaultrtid#g" emptyspokeconnection-spoke1.json 23 | sed "s#spokevnetid#$spoke2vnetid#g" emptyspokeconnection.json | tee emptyspokeconnection-spoke2.json 24 | sed -i "s#wedefaultrtid#$wedefaultrtid#g" emptyspokeconnection-spoke2.json 25 | sed "s#spokevnetid#$servicesvnetid#g" emptyspokeconnection.json | tee emptyspokeconnection-services.json 26 | sed -i "s#wedefaultrtid#$wedefaultrtid#g" emptyspokeconnection-services.json 27 | az rest --method put --uri $WEVNETCONNECTIONSPOKE1 --body @emptyspokeconnection-spoke1.json 28 | while [[ $(az rest --uri $WEVNETCONNECTIONSPOKE1 | jq .properties.provisioningState) != "\"Succeeded\"" ]]; do sleep 30; done 29 | az rest --method put --uri $WEVNETCONNECTIONSPOKE2 --body @emptyspokeconnection-spoke2.json 30 | while [[ $(az rest --uri $WEVNETCONNECTIONSPOKE2 | jq .properties.provisioningState) != "\"Succeeded\"" ]]; do sleep 30; done 31 | az rest --method put --uri $WEVNETCONNECTIONSERVICES --body @emptyspokeconnection-services.json 32 | while [[ $(az rest --uri $WEVNETCONNECTIONSERVICES | jq .properties.provisioningState) != "\"Succeeded\"" ]]; do sleep 30; done 33 | 34 | 35 | 36 | echo "# removing connection spoke-1-we" 37 | az network vhub connection delete -n spoke-1-we -g vwan-microhack-hub-rg --vhub-name microhack-we-hub --yes 38 | echo "# removing connection spoke-2-we" 39 | az network vhub connection delete -n spoke-2-we -g vwan-microhack-hub-rg --vhub-name microhack-we-hub --yes 40 | 41 | 42 | 43 | echo "Removing associations and propagations from rt-shared-useast" 44 | useastdefaultrtid=$(az network vhub route-table show --name defaultRouteTable --resource-group vwan-microhack-hub-rg --vhub-name microhack-useast-hub --query id --output tsv) 45 | useastsharedrtid=$(az network vhub route-table show --name "rt-shared-useast" --resource-group "vwan-microhack-hub-rg" --vhub-name microhack-useast-hub --query id --output tsv) 46 | USEASTRESTEP="https://management.azure.com${useastsharedrtid}?api-version=2020-05-01" 47 | az rest --method put --uri "$USEASTRESTEP" --body @emptyrtbody.json 48 | while [[ $(az rest --uri $USEASTRESTEP | jq .properties.provisioningState) != "\"Succeeded\"" ]]; do sleep 30; done 49 | spoke3connection=$(az network vhub connection show -n spoke-3-useast -g vwan-microhack-hub-rg --vhub-name microhack-useast-hub --query "id" -o tsv) 50 | spoke4connection=$(az network vhub connection show -n spoke-4-useast -g vwan-microhack-hub-rg --vhub-name microhack-useast-hub --query "id" -o tsv) 51 | USEASTVNETCONNECTIONSPOKE3="https://management.azure.com${spoke3connection}?api-version=2020-05-01" 52 | USEASTVNETCONNECTIONSPOKE4="https://management.azure.com${spoke4connection}?api-version=2020-05-01" 53 | sed "s#spokevnetid#$spoke3vnetid#g" emptyspokeconnection.json | tee emptyspokeconnection-spoke3.json 54 | sed -i "s#wedefaultrtid#$useastdefaultrtid#g" emptyspokeconnection-spoke3.json 55 | sed "s#spokevnetid#$spoke4vnetid#g" emptyspokeconnection.json | tee emptyspokeconnection-spoke4.json 56 | sed -i "s#wedefaultrtid#$useastdefaultrtid#g" emptyspokeconnection-spoke4.json 57 | az rest --method put --uri $USEASTVNETCONNECTIONSPOKE3 --body @emptyspokeconnection-spoke3.json 58 | while [[ $(az rest --uri $USEASTVNETCONNECTIONSPOKE3 | jq .properties.provisioningState) != "\"Succeeded\"" ]]; do sleep 30; done 59 | az rest --method put --uri $USEASTVNETCONNECTIONSPOKE4 --body @emptyspokeconnection-spoke4.json 60 | while [[ $(az rest --uri $USEASTVNETCONNECTIONSPOKE4 | jq .properties.provisioningState) != "\"Succeeded\"" ]]; do sleep 30; done 61 | 62 | 63 | ONPREMCONNECTIONID=$(az network vpn-gateway list -g vwan-microhack-hub-rg --query [].connections[].id -o tsv) 64 | ONPREMCONNECTIONRESTEP="https://management.azure.com${ONPREMCONNECTIONID}?api-version=2020-05-01" 65 | ONPREMCONNECTIONVPNSITE=$(az network vpn-gateway list -g vwan-microhack-hub-rg --query [].connections[].remoteVpnSite.id -o tsv) 66 | sed "s#wedefaultrtid#$wedefaultrtid#g" onpremconnection.json | tee onpremconnection-values.json 67 | sed -i "s#ONPREMCONNECTIONVPNSITE#$ONPREMCONNECTIONVPNSITE#g" onpremconnection-values.json 68 | az rest --method put --uri $ONPREMCONNECTIONRESTEP --body @onpremconnection-values.json 69 | while [[ $(az rest --uri $ONPREMCONNECTIONRESTEP | jq .properties.provisioningState) != "\"Succeeded\"" ]]; do sleep 30; done 70 | 71 | 72 | echo "Deleting rt-shared-useast" 73 | az network vhub route-table delete --name rt-shared-useast -g vwan-microhack-hub-rg --vhub-name microhack-useast-hub 74 | echo "Deleting rt-shared-we" 75 | az network vhub route-table delete --name rt-shared-we -g vwan-microhack-hub-rg --vhub-name microhack-we-hub 76 | 77 | echo "# connecting nva-vnet" 78 | az network vhub connection create -n nva-we -g vwan-microhack-hub-rg --vhub-name microhack-we-hub --remote-vnet $nvavnetid --no-wait 79 | 80 | echo "# peering spoke-1-vnet to nva-vnet" 81 | az network vnet peering create --name spoke1-to-nva --resource-group vwan-microhack-spoke-rg --vnet-name spoke-1-vnet --remote-vnet nva-vnet --allow-vnet-access --allow-forwarded-traffic 82 | az network vnet peering create --name nva-to-spoke1 --resource-group vwan-microhack-spoke-rg --vnet-name nva-vnet --remote-vnet spoke-1-vnet --allow-vnet-access --allow-forwarded-traffic 83 | echo "# peering spoke-2-vnet to nva-vnet" 84 | az network vnet peering create --name spoke2-to-nva --resource-group vwan-microhack-spoke-rg --vnet-name spoke-2-vnet --remote-vnet nva-vnet --allow-vnet-access --allow-forwarded-traffic 85 | az network vnet peering create --name nva-to-spoke2 --resource-group vwan-microhack-spoke-rg --vnet-name nva-vnet --remote-vnet spoke-2-vnet --allow-vnet-access --allow-forwarded-traffic 86 | -------------------------------------------------------------------------------- /prep-for-scenario-6-from-4.sh: -------------------------------------------------------------------------------- 1 | #use when skipping scenario 5 2 | spoke1vnetid=$(az network vnet show -g vwan-microhack-spoke-rg -n spoke-1-vnet --query "id" --output tsv) 3 | spoke2vnetid=$(az network vnet show -g vwan-microhack-spoke-rg -n spoke-2-vnet --query "id" --output tsv) 4 | spoke3vnetid=$(az network vnet show -g vwan-microhack-spoke-rg -n spoke-3-vnet --query "id" --output tsv) 5 | spoke4vnetid=$(az network vnet show -g vwan-microhack-spoke-rg -n spoke-4-vnet --query "id" --output tsv) 6 | servicesvnetid=$(az network vnet show -g vwan-microhack-spoke-rg -n services-vnet --query "id" --output tsv) 7 | nvavnetid=$(az network vnet show -g vwan-microhack-spoke-rg -n nva-vnet --query "id" --output tsv) 8 | wedefaultrtid=$(az network vhub route-table show --name defaultRouteTable --resource-group vwan-microhack-hub-rg --vhub-name microhack-we-hub --query id --output tsv) 9 | 10 | echo "Removing associations and propagations from rt-shared-we" 11 | 12 | wesharedrtid=$(az network vhub route-table show --name "RT-Shared-we" --resource-group "vwan-microhack-hub-rg" --vhub-name microhack-we-hub --query id --output tsv) 13 | WERESTEP="https://management.azure.com${wesharedrtid}?api-version=2020-05-01" 14 | az rest --method put --uri "$WERESTEP" --body @emptyrtbody.json 15 | while [[ $(az rest --uri $WERESTEP | jq .properties.provisioningState) != "\"Succeeded\"" ]]; do sleep 30; done 16 | spoke1connection=$(az network vhub connection show -n spoke-1-we -g vwan-microhack-hub-rg --vhub-name microhack-we-hub --query "id" -o tsv) 17 | spoke2connection=$(az network vhub connection show -n spoke-2-we -g vwan-microhack-hub-rg --vhub-name microhack-we-hub --query "id" -o tsv) 18 | servicesvnetconnection=$(az network vhub connection show -n services-we -g vwan-microhack-hub-rg --vhub-name microhack-we-hub --query "id" -o tsv) 19 | WEVNETCONNECTIONSPOKE1="https://management.azure.com${spoke1connection}?api-version=2020-05-01" 20 | WEVNETCONNECTIONSPOKE2="https://management.azure.com${spoke2connection}?api-version=2020-05-01" 21 | WEVNETCONNECTIONSERVICES="https://management.azure.com${servicesvnetconnection}?api-version=2020-05-01" 22 | sed "s#spokevnetid#$spoke1vnetid#g" emptyspokeconnection.json | tee emptyspokeconnection-spoke1.json 23 | sed -i "s#wedefaultrtid#$wedefaultrtid#g" emptyspokeconnection-spoke1.json 24 | sed "s#spokevnetid#$spoke2vnetid#g" emptyspokeconnection.json | tee emptyspokeconnection-spoke2.json 25 | sed -i "s#wedefaultrtid#$wedefaultrtid#g" emptyspokeconnection-spoke2.json 26 | sed "s#spokevnetid#$servicesvnetid#g" emptyspokeconnection.json | tee emptyspokeconnection-services.json 27 | sed -i "s#wedefaultrtid#$wedefaultrtid#g" emptyspokeconnection-services.json 28 | az rest --method put --uri $WEVNETCONNECTIONSPOKE1 --body @emptyspokeconnection-spoke1.json 29 | while [[ $(az rest --uri $WEVNETCONNECTIONSPOKE1 | jq .properties.provisioningState) != "\"Succeeded\"" ]]; do sleep 30; done 30 | az rest --method put --uri $WEVNETCONNECTIONSPOKE2 --body @emptyspokeconnection-spoke2.json 31 | while [[ $(az rest --uri $WEVNETCONNECTIONSPOKE2 | jq .properties.provisioningState) != "\"Succeeded\"" ]]; do sleep 30; done 32 | az rest --method put --uri $WEVNETCONNECTIONSERVICES --body @emptyspokeconnection-services.json 33 | while [[ $(az rest --uri $WEVNETCONNECTIONSERVICES | jq .properties.provisioningState) != "\"Succeeded\"" ]]; do sleep 30; done 34 | 35 | 36 | 37 | #echo "# removing connection spoke-1-we" 38 | #az network vhub connection delete -n spoke-1-we -g vwan-microhack-hub-rg --vhub-name microhack-we-hub --yes 39 | #echo "# removing connection spoke-2-we" 40 | #az network vhub connection delete -n spoke-2-we -g vwan-microhack-hub-rg --vhub-name microhack-we-hub --yes 41 | 42 | 43 | 44 | echo "Removing associations and propagations from rt-shared-useast" 45 | useastdefaultrtid=$(az network vhub route-table show --name defaultRouteTable --resource-group vwan-microhack-hub-rg --vhub-name microhack-useast-hub --query id --output tsv) 46 | useastsharedrtid=$(az network vhub route-table show --name "rt-shared-useast" --resource-group "vwan-microhack-hub-rg" --vhub-name microhack-useast-hub --query id --output tsv) 47 | USEASTRESTEP="https://management.azure.com${useastsharedrtid}?api-version=2020-05-01" 48 | az rest --method put --uri "$USEASTRESTEP" --body @emptyrtbody.json 49 | while [[ $(az rest --uri $USEASTRESTEP | jq .properties.provisioningState) != "\"Succeeded\"" ]]; do sleep 30; done 50 | spoke3connection=$(az network vhub connection show -n spoke-3-useast -g vwan-microhack-hub-rg --vhub-name microhack-useast-hub --query "id" -o tsv) 51 | spoke4connection=$(az network vhub connection show -n spoke-4-useast -g vwan-microhack-hub-rg --vhub-name microhack-useast-hub --query "id" -o tsv) 52 | USEASTVNETCONNECTIONSPOKE3="https://management.azure.com${spoke3connection}?api-version=2020-05-01" 53 | USEASTVNETCONNECTIONSPOKE4="https://management.azure.com${spoke4connection}?api-version=2020-05-01" 54 | sed "s#spokevnetid#$spoke3vnetid#g" emptyspokeconnection.json | tee emptyspokeconnection-spoke3.json 55 | sed -i "s#wedefaultrtid#$useastdefaultrtid#g" emptyspokeconnection-spoke3.json 56 | sed "s#spokevnetid#$spoke4vnetid#g" emptyspokeconnection.json | tee emptyspokeconnection-spoke4.json 57 | sed -i "s#wedefaultrtid#$useastdefaultrtid#g" emptyspokeconnection-spoke4.json 58 | az rest --method put --uri $USEASTVNETCONNECTIONSPOKE3 --body @emptyspokeconnection-spoke3.json 59 | while [[ $(az rest --uri $USEASTVNETCONNECTIONSPOKE3 | jq .properties.provisioningState) != "\"Succeeded\"" ]]; do sleep 30; done 60 | az rest --method put --uri $USEASTVNETCONNECTIONSPOKE4 --body @emptyspokeconnection-spoke4.json 61 | while [[ $(az rest --uri $USEASTVNETCONNECTIONSPOKE4 | jq .properties.provisioningState) != "\"Succeeded\"" ]]; do sleep 30; done 62 | 63 | 64 | ONPREMCONNECTIONID=$(az network vpn-gateway list -g vwan-microhack-hub-rg --query [].connections[].id -o tsv) 65 | ONPREMCONNECTIONRESTEP="https://management.azure.com${ONPREMCONNECTIONID}?api-version=2020-05-01" 66 | ONPREMCONNECTIONVPNSITE=$(az network vpn-gateway list -g vwan-microhack-hub-rg --query [].connections[].remoteVpnSite.id -o tsv) 67 | sed "s#wedefaultrtid#$wedefaultrtid#g" onpremconnection.json | tee onpremconnection-values.json 68 | sed -i "s#ONPREMCONNECTIONVPNSITE#$ONPREMCONNECTIONVPNSITE#g" onpremconnection-values.json 69 | az rest --method put --uri $ONPREMCONNECTIONRESTEP --body @onpremconnection-values.json 70 | while [[ $(az rest --uri $ONPREMCONNECTIONRESTEP | jq .properties.provisioningState) != "\"Succeeded\"" ]]; do sleep 30; done 71 | 72 | 73 | echo "Deleting rt-shared-useast" 74 | az network vhub route-table delete --name rt-shared-useast -g vwan-microhack-hub-rg --vhub-name microhack-useast-hub 75 | echo "Deleting rt-shared-we" 76 | az network vhub route-table delete --name rt-shared-we -g vwan-microhack-hub-rg --vhub-name microhack-we-hub 77 | 78 | #echo "# connecting nva-vnet" 79 | #az network vhub connection create -n nva-we -g vwan-microhack-hub-rg --vhub-name microhack-we-hub --remote-vnet $nvavnetid --no-wait 80 | 81 | #echo "# peering spoke-1-vnet to nva-vnet" 82 | #az network vnet peering create --name spoke1-to-nva --resource-group vwan-microhack-spoke-rg --vnet-name spoke-1-vnet --remote-vnet nva-vnet --allow-vnet-access --allow-forwarded-traffic 83 | #az network vnet peering create --name nva-to-spoke1 --resource-group vwan-microhack-spoke-rg --vnet-name nva-vnet --remote-vnet spoke-1-vnet --allow-vnet-access --allow-forwarded-traffic 84 | #echo "# peering spoke-2-vnet to nva-vnet" 85 | #az network vnet peering create --name spoke2-to-nva --resource-group vwan-microhack-spoke-rg --vnet-name spoke-2-vnet --remote-vnet nva-vnet --allow-vnet-access --allow-forwarded-traffic 86 | #az network vnet peering create --name nva-to-spoke2 --resource-group vwan-microhack-spoke-rg --vnet-name nva-vnet --remote-vnet spoke-2-vnet --allow-vnet-access --allow-forwarded-traffic 87 | -------------------------------------------------------------------------------- /prep-for-scenario-6.sh: -------------------------------------------------------------------------------- 1 | spoke1vnetid=$(az network vnet show -g vwan-microhack-spoke-rg -n spoke-1-vnet --query "id" --output tsv) 2 | spoke2vnetid=$(az network vnet show -g vwan-microhack-spoke-rg -n spoke-2-vnet --query "id" --output tsv) 3 | spoke3vnetid=$(az network vnet show -g vwan-microhack-spoke-rg -n spoke-3-vnet --query "id" --output tsv) 4 | spoke4vnetid=$(az network vnet show -g vwan-microhack-spoke-rg -n spoke-4-vnet --query "id" --output tsv) 5 | servicesvnetid=$(az network vnet show -g vwan-microhack-spoke-rg -n services-vnet --query "id" --output tsv) 6 | nvavnetid=$(az network vnet show -g vwan-microhack-spoke-rg -n nva-vnet --query "id" --output tsv) 7 | 8 | echo "# removing peerings to from spoke-vnet-1 to nva-vnet" 9 | az network vnet peering delete --name spoke1-to-nva --resource-group vwan-microhack-spoke-rg --vnet-name spoke-1-vnet 10 | az network vnet peering delete --name nva-to-spoke1 --resource-group vwan-microhack-spoke-rg --vnet-name nva-vnet 11 | echo "# removing peerings to from spoke-vnet-2 to nva-vnet" 12 | az network vnet peering delete --name spoke2-to-nva --resource-group vwan-microhack-spoke-rg --vnet-name spoke-2-vnet 13 | az network vnet peering delete --name nva-to-spoke2 --resource-group vwan-microhack-spoke-rg --vnet-name nva-vnet 14 | 15 | echo "# disconnecting nva-vnet" 16 | az network vhub connection delete -n nva-we -g vwan-microhack-hub-rg --vhub-name microhack-we-hub --yes 17 | 18 | echo "# connecting spoke-1-vnet" 19 | az network vhub connection create --name spoke-1-we --resource-group vwan-microhack-hub-rg --vhub-name microhack-we-hub --remote-vnet $spoke1vnetid --labels default 20 | echo "# connecting spoke-2-vnet" 21 | az network vhub connection create --name spoke-2-we --resource-group vwan-microhack-hub-rg --vhub-name microhack-we-hub --remote-vnet $spoke2vnetid --labels default --no-wait 22 | 23 | echo "#removing custom routes from microhack-we-hub" 24 | az network vhub route-table route remove --index 1 -n defaultRouteTable -g vwan-microhack-hub-rg --vhub-name microhack-we-hub 25 | az network vhub route-table route remove --index 1 -n defaultRouteTable -g vwan-microhack-hub-rg --vhub-name microhack-we-hub 26 | az network vhub route-table route remove --index 1 -n defaultRouteTable -g vwan-microhack-hub-rg --vhub-name microhack-we-hub --no-wait 27 | echo "#removing custom routes from microhack-useast-hub" 28 | az network vhub route-table route remove --index 1 -n defaultRouteTable -g vwan-microhack-hub-rg --vhub-name microhack-useast-hub 29 | az network vhub route-table route remove --index 1 -n defaultRouteTable -g vwan-microhack-hub-rg --vhub-name microhack-useast-hub 30 | az network vhub route-table route remove --index 1 -n defaultRouteTable -g vwan-microhack-hub-rg --vhub-name microhack-useast-hub --no-wait 31 | 32 | echo "# detach UDR from vmSubnet in spoke-1-vnet" 33 | az network vnet subnet update --resource-group vwan-microhack-spoke-rg --name vmSubnet --vnet-name spoke-1-vnet --route-table "" 34 | echo "# detach UDR from vmSubnet in spoke-2-vnet" 35 | az network vnet subnet update --resource-group vwan-microhack-spoke-rg --name vmSubnet --vnet-name spoke-2-vnet --route-table "" 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /spoke.tf: -------------------------------------------------------------------------------- 1 | ####################################################################### 2 | ## Create Virtual Network - Spoke 1 3 | ####################################################################### 4 | 5 | resource "azurerm_virtual_network" "spoke-1-vnet" { 6 | name = "spoke-1-vnet" 7 | location = var.location-spoke-1 8 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 9 | address_space = ["172.16.1.0/24"] 10 | 11 | tags = { 12 | environment = "spoke-1" 13 | deployment = "terraform" 14 | microhack = "vwan" 15 | } 16 | } 17 | 18 | ####################################################################### 19 | ## Create Subnets - Spoke 1 20 | ####################################################################### 21 | 22 | resource "azurerm_subnet" "spoke-1-vm-subnet" { 23 | name = "vmSubnet" 24 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 25 | virtual_network_name = azurerm_virtual_network.spoke-1-vnet.name 26 | address_prefixes = ["172.16.1.0/25"] 27 | } 28 | resource "azurerm_subnet" "bastion-spoke-1-subnet" { 29 | name = "AzureBastionSubnet" 30 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 31 | virtual_network_name = azurerm_virtual_network.spoke-1-vnet.name 32 | address_prefixes = ["172.16.1.128/27"] 33 | } 34 | ####################################################################### 35 | ## Create Virtual Network - Spoke 2 36 | ####################################################################### 37 | 38 | resource "azurerm_virtual_network" "spoke-2-vnet" { 39 | name = "spoke-2-vnet" 40 | location = var.location-spoke-2 41 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 42 | address_space = ["172.16.2.0/24"] 43 | 44 | tags = { 45 | environment = "spoke-2" 46 | deployment = "terraform" 47 | microhack = "vwan" 48 | } 49 | } 50 | ####################################################################### 51 | ## Create Subnets - Spoke 2 52 | ####################################################################### 53 | resource "azurerm_subnet" "spoke-2-vm-subnet" { 54 | name = "vmSubnet" 55 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 56 | virtual_network_name = azurerm_virtual_network.spoke-2-vnet.name 57 | address_prefixes = ["172.16.2.0/25"] 58 | } 59 | resource "azurerm_subnet" "bastion-spoke-2-subnet" { 60 | name = "AzureBastionSubnet" 61 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 62 | virtual_network_name = azurerm_virtual_network.spoke-2-vnet.name 63 | address_prefixes = ["172.16.2.128/27"] 64 | } 65 | ####################################################################### 66 | ## Create Virtual Network - Spoke 3 67 | ####################################################################### 68 | resource "azurerm_virtual_network" "spoke-3-vnet" { 69 | name = "spoke-3-vnet" 70 | location = var.location-spoke-3 71 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 72 | address_space = ["172.16.3.0/24"] 73 | 74 | tags = { 75 | environment = "spoke-3" 76 | deployment = "terraform" 77 | microhack = "vwan" 78 | } 79 | } 80 | ####################################################################### 81 | ## Create Subnets - Spoke 3 82 | ####################################################################### 83 | resource "azurerm_subnet" "spoke-3-vm-subnet" { 84 | name = "vmSubnet" 85 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 86 | virtual_network_name = azurerm_virtual_network.spoke-3-vnet.name 87 | address_prefixes = ["172.16.3.0/25"] 88 | } 89 | resource "azurerm_subnet" "bastion-spoke-3-subnet" { 90 | name = "AzureBastionSubnet" 91 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 92 | virtual_network_name = azurerm_virtual_network.spoke-3-vnet.name 93 | address_prefixes = ["172.16.3.128/27"] 94 | } 95 | ####################################################################### 96 | ## Create Virtual Network - Spoke 4 97 | ####################################################################### 98 | 99 | resource "azurerm_virtual_network" "spoke-4-vnet" { 100 | name = "spoke-4-vnet" 101 | location = var.location-spoke-4 102 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 103 | address_space = ["172.16.4.0/24"] 104 | 105 | tags = { 106 | environment = "spoke-4" 107 | deployment = "terraform" 108 | microhack = "vwan" 109 | } 110 | } 111 | ####################################################################### 112 | ## Create Subnets - Spoke 4 113 | ####################################################################### 114 | 115 | resource "azurerm_subnet" "spoke-4-vm-subnet" { 116 | name = "vmSubnet" 117 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 118 | virtual_network_name = azurerm_virtual_network.spoke-4-vnet.name 119 | address_prefixes = ["172.16.4.0/25"] 120 | } 121 | resource "azurerm_subnet" "bastion-spoke-4-subnet" { 122 | name = "AzureBastionSubnet" 123 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 124 | virtual_network_name = azurerm_virtual_network.spoke-4-vnet.name 125 | address_prefixes = ["172.16.4.128/27"] 126 | } 127 | ####################################################################### 128 | ## Create Virtual Network - Onprem 129 | ####################################################################### 130 | 131 | resource "azurerm_virtual_network" "onprem-vnet" { 132 | name = "onprem-vnet" 133 | location = var.location-onprem 134 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 135 | address_space = ["10.0.1.0/24","10.0.2.0/24"] 136 | 137 | tags = { 138 | environment = "onprem" 139 | deployment = "terraform" 140 | microhack = "vwan" 141 | } 142 | } 143 | ####################################################################### 144 | ## Create Subnets - onprem 145 | ####################################################################### 146 | resource "azurerm_subnet" "onprem-vm-subnet" { 147 | name = "vmSubnet" 148 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 149 | virtual_network_name = azurerm_virtual_network.onprem-vnet.name 150 | address_prefixes = ["10.0.1.0/25"] 151 | } 152 | resource "azurerm_subnet" "bastion-onprem-subnet" { 153 | name = "AzureBastionSubnet" 154 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 155 | virtual_network_name = azurerm_virtual_network.onprem-vnet.name 156 | address_prefixes = ["10.0.1.128/27"] 157 | } 158 | resource "azurerm_subnet" "onprem-gateway-subnet" { 159 | name = "GatewaySubnet" 160 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 161 | virtual_network_name = azurerm_virtual_network.onprem-vnet.name 162 | address_prefixes = ["10.0.1.160/27"] 163 | } 164 | ####################################################################### 165 | ## Create Virtual Network - Onprem2 166 | ####################################################################### 167 | 168 | resource "azurerm_virtual_network" "onprem2-vnet" { 169 | name = "onprem2-vnet" 170 | location = var.location-onprem2 171 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 172 | address_space = ["10.0.3.0/24","10.0.4.0/24"] 173 | 174 | tags = { 175 | environment = "onprem" 176 | deployment = "terraform" 177 | microhack = "vwan" 178 | } 179 | } 180 | ####################################################################### 181 | ## Create Subnets - onprem2 182 | ####################################################################### 183 | resource "azurerm_subnet" "onprem2-vm-subnet" { 184 | name = "vmSubnet" 185 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 186 | virtual_network_name = azurerm_virtual_network.onprem2-vnet.name 187 | address_prefixes = ["10.0.3.0/25"] 188 | } 189 | resource "azurerm_subnet" "bastion-onprem2-subnet" { 190 | name = "AzureBastionSubnet" 191 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 192 | virtual_network_name = azurerm_virtual_network.onprem2-vnet.name 193 | address_prefixes = ["10.0.3.128/27"] 194 | } 195 | resource "azurerm_subnet" "onprem2-gateway-subnet" { 196 | name = "GatewaySubnet" 197 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 198 | virtual_network_name = azurerm_virtual_network.onprem2-vnet.name 199 | address_prefixes = ["10.0.3.160/27"] 200 | } 201 | ####################################################################### 202 | ## Create Virtual Network - Services 203 | ####################################################################### 204 | resource "azurerm_virtual_network" "services-vnet" { 205 | name = "services-vnet" 206 | location = var.location-spoke-services 207 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 208 | address_space = ["172.16.10.0/24"] 209 | 210 | tags = { 211 | environment = "services" 212 | deployment = "terraform" 213 | microhack = "vwan" 214 | } 215 | } 216 | ####################################################################### 217 | ## Create Subnets - Services 218 | ####################################################################### 219 | 220 | resource "azurerm_subnet" "services-vm-1-subnet" { 221 | name = "servicesSubnet-1" 222 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 223 | virtual_network_name = azurerm_virtual_network.services-vnet.name 224 | address_prefixes = ["172.16.10.0/25"] 225 | } 226 | resource "azurerm_subnet" "services-vm-2-subnet" { 227 | name = "servicesSubnet-2" 228 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 229 | virtual_network_name = azurerm_virtual_network.services-vnet.name 230 | address_prefixes = ["172.16.10.128/27"] 231 | } 232 | resource "azurerm_subnet" "bastion-services-subnet" { 233 | name = "AzureBastionSubnet" 234 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 235 | virtual_network_name = azurerm_virtual_network.services-vnet.name 236 | address_prefixes = ["172.16.10.160/27"] 237 | } 238 | ####################################################################### 239 | ## Create Virtual Network - NVA 240 | ####################################################################### 241 | resource "azurerm_virtual_network" "nva-vnet" { 242 | name = "nva-vnet" 243 | location = var.location-spoke-services 244 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 245 | address_space = ["172.16.20.0/24"] 246 | 247 | tags = { 248 | environment = "nva" 249 | deployment = "terraform" 250 | microhack = "vwan" 251 | } 252 | } 253 | ####################################################################### 254 | ## Create Subnets - NVA 255 | ####################################################################### 256 | 257 | resource "azurerm_subnet" "nva-subnet-1" { 258 | name = "nva-subnet-1" 259 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 260 | virtual_network_name = azurerm_virtual_network.nva-vnet.name 261 | address_prefixes = ["172.16.20.0/26"] 262 | } 263 | resource "azurerm_subnet" "nva-subnet-2" { 264 | name = "nva-subnet-2" 265 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 266 | virtual_network_name = azurerm_virtual_network.nva-vnet.name 267 | address_prefixes = ["172.16.20.64/26"] 268 | } 269 | resource "azurerm_subnet" "bastion-nva-subnet" { 270 | name = "AzureBastionSubnet" 271 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 272 | virtual_network_name = azurerm_virtual_network.nva-vnet.name 273 | address_prefixes = ["172.16.20.160/27"] 274 | } 275 | ####################################################################### 276 | ## Create Network Interface - Spoke 1 277 | ####################################################################### 278 | 279 | resource "azurerm_network_interface" "spoke-1-nic" { 280 | name = "spoke-1-nic" 281 | location = var.location-spoke-1 282 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 283 | 284 | ip_configuration { 285 | name = "spoke-1-ipconfig" 286 | subnet_id = azurerm_subnet.spoke-1-vm-subnet.id 287 | private_ip_address_allocation = "Dynamic" 288 | } 289 | 290 | tags = { 291 | environment = "spoke-1" 292 | deployment = "terraform" 293 | microhack = "vwan" 294 | } 295 | } 296 | ####################################################################### 297 | ## Create Network Interface - Spoke 2 298 | ####################################################################### 299 | 300 | resource "azurerm_network_interface" "spoke-2-nic" { 301 | name = "spoke-2-nic" 302 | location = var.location-spoke-2 303 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 304 | 305 | 306 | ip_configuration { 307 | name = "spoke-2-ipconfig" 308 | subnet_id = azurerm_subnet.spoke-2-vm-subnet.id 309 | private_ip_address_allocation = "Dynamic" 310 | } 311 | 312 | tags = { 313 | environment = "spoke-1" 314 | deployment = "terraform" 315 | microhack = "vwan" 316 | } 317 | } 318 | ####################################################################### 319 | ## Create Network Interface - Spoke 3 320 | ####################################################################### 321 | 322 | resource "azurerm_network_interface" "spoke-3-nic" { 323 | name = "spoke-3-nic" 324 | location = var.location-spoke-3 325 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 326 | 327 | ip_configuration { 328 | name = "spoke-3-ipconfig" 329 | subnet_id = azurerm_subnet.spoke-3-vm-subnet.id 330 | private_ip_address_allocation = "Dynamic" 331 | } 332 | 333 | tags = { 334 | environment = "spoke-3" 335 | deployment = "terraform" 336 | microhack = "vwan" 337 | } 338 | } 339 | ####################################################################### 340 | ## Create Network Interface - Spoke 4 341 | ####################################################################### 342 | 343 | resource "azurerm_network_interface" "spoke-4-nic" { 344 | name = "spoke-4-nic" 345 | location = var.location-spoke-4 346 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 347 | 348 | ip_configuration { 349 | name = "spoke-4" 350 | subnet_id = azurerm_subnet.spoke-4-vm-subnet.id 351 | private_ip_address_allocation = "Dynamic" 352 | } 353 | 354 | tags = { 355 | environment = "spoke-4" 356 | deployment = "terraform" 357 | microhack = "vwan" 358 | } 359 | } 360 | ####################################################################### 361 | ## Create Network Interface - Spoke onprem 362 | ####################################################################### 363 | 364 | resource "azurerm_network_interface" "onprem-nic" { 365 | name = "onprem-nic" 366 | location = var.location-onprem 367 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 368 | 369 | ip_configuration { 370 | name = "onprem-ipconfig" 371 | subnet_id = azurerm_subnet.onprem-vm-subnet.id 372 | private_ip_address_allocation = "Dynamic" 373 | } 374 | 375 | tags = { 376 | environment = "onprem" 377 | deployment = "terraform" 378 | microhack = "vwan" 379 | } 380 | } 381 | ####################################################################### 382 | ## Create Network Interface - Spoke onprem2 383 | ####################################################################### 384 | 385 | resource "azurerm_network_interface" "onprem2-nic" { 386 | name = "onprem2-nic" 387 | location = var.location-onprem2 388 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 389 | 390 | ip_configuration { 391 | name = "onprem2-ipconfig" 392 | subnet_id = azurerm_subnet.onprem2-vm-subnet.id 393 | private_ip_address_allocation = "Dynamic" 394 | } 395 | 396 | tags = { 397 | environment = "onprem" 398 | deployment = "terraform" 399 | microhack = "vwan" 400 | } 401 | } 402 | ####################################################################### 403 | ## Create Network Interface - ADDC 404 | ####################################################################### 405 | 406 | resource "azurerm_network_interface" "spoke-addc-1-nic" { 407 | name = "spoke-addc-1-nic" 408 | location = var.location-spoke-services 409 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 410 | 411 | ip_configuration { 412 | name = "addc-1-ipconfig" 413 | subnet_id = azurerm_subnet.services-vm-1-subnet.id 414 | private_ip_address_allocation = "Dynamic" 415 | } 416 | 417 | tags = { 418 | environment = "services" 419 | deployment = "terraform" 420 | microhack = "vwan" 421 | } 422 | } 423 | ####################################################################### 424 | ## Create Virtual Machine spoke-1 425 | ####################################################################### 426 | 427 | resource "azurerm_windows_virtual_machine" "spoke-1-vm" { 428 | name = "spoke-1-vm" 429 | location = var.location-spoke-1 430 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 431 | network_interface_ids = [azurerm_network_interface.spoke-1-nic.id] 432 | size = var.vmsize 433 | computer_name = "spoke-1-vm" 434 | admin_username = var.username 435 | admin_password = var.password 436 | provision_vm_agent = true 437 | 438 | source_image_reference { 439 | offer = "WindowsServer" 440 | publisher = "MicrosoftWindowsServer" 441 | sku = "2022-datacenter-azure-edition" 442 | version = "latest" 443 | } 444 | 445 | os_disk { 446 | name = "spoke-1-osdisk" 447 | caching = "ReadWrite" 448 | storage_account_type = "StandardSSD_LRS" 449 | } 450 | 451 | tags = { 452 | environment = "spoke-1" 453 | deployment = "terraform" 454 | microhack = "vwan" 455 | } 456 | } 457 | ####################################################################### 458 | ## Create Virtual Machine spoke-2 459 | ####################################################################### 460 | resource "azurerm_windows_virtual_machine" "spoke-2-vm" { 461 | name = "spoke-2-vm" 462 | location = var.location-spoke-2 463 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 464 | network_interface_ids = [azurerm_network_interface.spoke-2-nic.id] 465 | size = var.vmsize 466 | computer_name = "spoke-2-vm" 467 | admin_username = var.username 468 | admin_password = var.password 469 | provision_vm_agent = true 470 | 471 | 472 | source_image_reference { 473 | offer = "WindowsServer" 474 | publisher = "MicrosoftWindowsServer" 475 | sku = "2022-datacenter-azure-edition" 476 | version = "latest" 477 | } 478 | 479 | os_disk { 480 | name = "spoke-2-osdisk" 481 | caching = "ReadWrite" 482 | storage_account_type = "StandardSSD_LRS" 483 | } 484 | 485 | tags = { 486 | environment = "spoke-2" 487 | deployment = "terraform" 488 | microhack = "vwan" 489 | } 490 | } 491 | ####################################################################### 492 | ## Create Virtual Machine spoke-3 493 | ####################################################################### 494 | resource "azurerm_windows_virtual_machine" "spoke-3-vm" { 495 | name = "spoke-3-vm" 496 | location = var.location-spoke-3 497 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 498 | network_interface_ids = [azurerm_network_interface.spoke-3-nic.id] 499 | size = var.vmsize 500 | computer_name = "spoke-3-vm" 501 | admin_username = var.username 502 | admin_password = var.password 503 | provision_vm_agent = true 504 | 505 | source_image_reference { 506 | offer = "WindowsServer" 507 | publisher = "MicrosoftWindowsServer" 508 | sku = "2022-datacenter-azure-edition" 509 | version = "latest" 510 | } 511 | 512 | os_disk { 513 | name = "spoke-3-osdisk" 514 | caching = "ReadWrite" 515 | storage_account_type = "StandardSSD_LRS" 516 | } 517 | 518 | tags = { 519 | environment = "spoke-3" 520 | deployment = "terraform" 521 | microhack = "vwan" 522 | } 523 | } 524 | ####################################################################### 525 | ## Create Virtual Machine spoke-4 526 | ####################################################################### 527 | resource "azurerm_windows_virtual_machine" "spoke-4-vm" { 528 | name = "spoke-4-vm" 529 | location = var.location-spoke-4 530 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 531 | network_interface_ids = [azurerm_network_interface.spoke-4-nic.id] 532 | size = var.vmsize 533 | computer_name = "spoke-4-vm" 534 | admin_username = var.username 535 | admin_password = var.password 536 | provision_vm_agent = true 537 | 538 | source_image_reference { 539 | offer = "WindowsServer" 540 | publisher = "MicrosoftWindowsServer" 541 | sku = "2022-datacenter-azure-edition" 542 | version = "latest" 543 | } 544 | 545 | os_disk { 546 | name = "spoke-4-osdisk" 547 | caching = "ReadWrite" 548 | storage_account_type = "StandardSSD_LRS" 549 | } 550 | 551 | tags = { 552 | environment = "spoke-4" 553 | deployment = "terraform" 554 | microhack = "vwan" 555 | } 556 | } 557 | ####################################################################### 558 | ## Create Virtual Machine onprem 559 | ####################################################################### 560 | resource "azurerm_windows_virtual_machine" "onprem-vm" { 561 | name = "onprem-vm" 562 | location = var.location-onprem 563 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 564 | network_interface_ids = [azurerm_network_interface.onprem-nic.id] 565 | size = var.vmsize 566 | computer_name = "onprem-vm" 567 | admin_username = var.username 568 | admin_password = var.password 569 | provision_vm_agent = true 570 | 571 | source_image_reference { 572 | offer = "WindowsServer" 573 | publisher = "MicrosoftWindowsServer" 574 | sku = "2022-datacenter-azure-edition" 575 | version = "latest" 576 | } 577 | 578 | os_disk { 579 | name = "onprem-osdisk" 580 | caching = "ReadWrite" 581 | storage_account_type = "StandardSSD_LRS" 582 | } 583 | 584 | tags = { 585 | environment = "onprem" 586 | deployment = "terraform" 587 | microhack = "vwan" 588 | } 589 | } 590 | ####################################################################### 591 | ## Create Virtual Machine onprem2 592 | ####################################################################### 593 | resource "azurerm_windows_virtual_machine" "onprem2-vm" { 594 | name = "onprem2-vm" 595 | location = var.location-onprem2 596 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 597 | network_interface_ids = [azurerm_network_interface.onprem2-nic.id] 598 | size = var.vmsize 599 | computer_name = "onprem2-vm" 600 | admin_username = var.username 601 | admin_password = var.password 602 | provision_vm_agent = true 603 | 604 | source_image_reference { 605 | offer = "WindowsServer" 606 | publisher = "MicrosoftWindowsServer" 607 | sku = "2022-datacenter-azure-edition" 608 | version = "latest" 609 | } 610 | 611 | os_disk { 612 | name = "onprem2-osdisk" 613 | caching = "ReadWrite" 614 | storage_account_type = "StandardSSD_LRS" 615 | } 616 | 617 | tags = { 618 | environment = "onprem" 619 | deployment = "terraform" 620 | microhack = "vwan" 621 | } 622 | } 623 | ####################################################################### 624 | ## Create Virtual Machine spoke-addc 625 | ####################################################################### 626 | resource "azurerm_windows_virtual_machine" "spoke-addc-vm" { 627 | name = "spoke-addc-vm" 628 | location = var.location-spoke-services 629 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 630 | network_interface_ids = [azurerm_network_interface.spoke-addc-1-nic.id] 631 | size = var.vmsize 632 | computer_name = "spoke-addc-vm" 633 | admin_username = var.username 634 | admin_password = var.password 635 | provision_vm_agent = true 636 | 637 | source_image_reference { 638 | offer = "WindowsServer" 639 | publisher = "MicrosoftWindowsServer" 640 | sku = "2022-datacenter-azure-edition" 641 | version = "latest" 642 | } 643 | 644 | os_disk { 645 | name = "spoke-addc-osdisk" 646 | caching = "ReadWrite" 647 | storage_account_type = "StandardSSD_LRS" 648 | } 649 | 650 | tags = { 651 | environment = "addc" 652 | deployment = "terraform" 653 | microhack = "vwan" 654 | } 655 | } 656 | ####################################################################### 657 | ## Create Network Interface - nva-iptables-vm 658 | ####################################################################### 659 | resource "azurerm_public_ip" "nva-iptables-vm-pub-ip"{ 660 | name = "nva-iptables-vm-pub-ip" 661 | location = var.location-spoke-services 662 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 663 | allocation_method = "Static" 664 | tags = { 665 | environment = "nva" 666 | deployment = "terraform" 667 | microhack = "vwan" 668 | } 669 | } 670 | resource "azurerm_network_security_group" "nva-iptables-vm-nsg"{ 671 | name = "nva-iptables-vm-nsg" 672 | location = var.location-spoke-services 673 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 674 | 675 | 676 | security_rule { 677 | name = "http" 678 | priority = 200 679 | direction = "Inbound" 680 | access = "Allow" 681 | protocol = "Tcp" 682 | source_port_range = "*" 683 | destination_port_range = "80" 684 | source_address_prefix = "*" 685 | destination_address_prefix = "*" 686 | } 687 | security_rule { 688 | name = "https" 689 | priority = 210 690 | direction = "Inbound" 691 | access = "Allow" 692 | protocol = "Tcp" 693 | source_port_range = "*" 694 | destination_port_range = "443" 695 | source_address_prefix = "*" 696 | destination_address_prefix = "*" 697 | } 698 | security_rule { 699 | name = "icmp" 700 | priority = 220 701 | direction = "Inbound" 702 | access = "Allow" 703 | protocol = "Tcp" 704 | source_port_range = "*" 705 | destination_port_range = "*" 706 | source_address_prefix = "*" 707 | destination_address_prefix = "*" 708 | } 709 | 710 | tags = { 711 | environment = "nva" 712 | deployment = "terraform" 713 | microhack = "vwan" 714 | } 715 | } 716 | resource "azurerm_network_interface" "nva-iptables-vm-nic-1" { 717 | name = "nva-iptables-vm-nic-1" 718 | location = var.location-spoke-services 719 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 720 | ip_configuration { 721 | name = "nva-1-ipconfig" 722 | subnet_id = azurerm_subnet.nva-subnet-1.id 723 | private_ip_address_allocation = "Static" 724 | private_ip_address = "172.16.20.4" 725 | public_ip_address_id = azurerm_public_ip.nva-iptables-vm-pub-ip.id 726 | } 727 | tags = { 728 | environment = "nva" 729 | deployment = "terraform" 730 | microhack = "vwan" 731 | } 732 | } 733 | resource "azurerm_subnet_network_security_group_association" "nva-iptables-vm-nsg-ass" { 734 | subnet_id = azurerm_subnet.nva-subnet-1.id 735 | network_security_group_id = azurerm_network_security_group.nva-iptables-vm-nsg.id 736 | } 737 | 738 | ####################################################################### 739 | ## Create Virtual Machine - NVA 740 | ####################################################################### 741 | resource "azurerm_linux_virtual_machine" "nva-iptables-vm" { 742 | name = "nva-iptables-vm" 743 | location = var.location-spoke-services 744 | resource_group_name = azurerm_resource_group.vwan-microhack-spoke-rg.name 745 | network_interface_ids = [azurerm_network_interface.nva-iptables-vm-nic-1.id] 746 | size = var.vmsize 747 | admin_username = var.username 748 | admin_password = var.password 749 | disable_password_authentication = false 750 | 751 | source_image_reference { 752 | publisher = "Canonical" 753 | offer = "UbuntuServer" 754 | sku = "18.04-LTS" 755 | version = "latest" 756 | } 757 | 758 | os_disk { 759 | name = "nva-iptables-vm-osdisk" 760 | caching = "ReadWrite" 761 | storage_account_type = "StandardSSD_LRS" 762 | } 763 | 764 | tags = { 765 | environment = "nva" 766 | deployment = "terraform" 767 | microhack = "vwan" 768 | } 769 | } 770 | 771 | 772 | -------------------------------------------------------------------------------- /variables.tf: -------------------------------------------------------------------------------- 1 | variable "location-vwan" { 2 | description = "Location to deploy vwan" 3 | type = string 4 | default = "swedencentral" 5 | //default = "westeurope" 6 | } 7 | variable "location-vwan-we-hub" { 8 | description = "Location to deploy we hub" 9 | type = string 10 | default = "swedencentral" 11 | //default = "westeurope" 12 | } 13 | 14 | variable "location-spoke-1" { 15 | description = "Location to deploy spoke-1" 16 | type = string 17 | default = "swedencentral" 18 | //default = "westeurope" 19 | } 20 | variable "location-spoke-2" { 21 | description = "Location to deploy spoke-2" 22 | type = string 23 | default = "swedencentral" 24 | //default = "westeurope" 25 | } 26 | variable "location-spoke-3" { 27 | description = "Location to deploy spoke-3" 28 | type = string 29 | default = "EastUS" 30 | } 31 | variable "location-spoke-4" { 32 | description = "Location to deploy spoke-4" 33 | type = string 34 | //default = "WestUS2" 35 | default = "EastUS" 36 | } 37 | variable "location-hub-1" { 38 | description = "Location to deploy hub-1" 39 | type = string 40 | default = "swedencentral" 41 | //default = "westeurope" 42 | } 43 | variable "location-hub-2" { 44 | description = "Location to deploy hub-2" 45 | type = string 46 | default = "EastUS" 47 | } 48 | variable "location-onprem" { 49 | description = "Location to deploy onprem" 50 | type = string 51 | default = "uksouth" 52 | } 53 | variable "location-onprem2" { 54 | description = "Location to deploy onprem2" 55 | type = string 56 | default = "swedencentral" 57 | //default = "westeurope" 58 | } 59 | variable "location-spoke-services" { 60 | description = "Location to deploy spoke-services" 61 | type = string 62 | default = "swedencentral" 63 | //default = "westeurope" 64 | } 65 | variable "username" { 66 | description = "Username for Virtual Machines" 67 | type = string 68 | default = "AzureAdmin" 69 | } 70 | 71 | variable "password" { 72 | description = "Virtual Machine password, must meet Azure complexity requirements" 73 | type = string 74 | default = "Microhack2020" 75 | } 76 | variable "vmsize" { 77 | description = "Size of the VMs" 78 | default = "Standard_D2s_v3" 79 | } 80 | -------------------------------------------------------------------------------- /vm-extensions.tf: -------------------------------------------------------------------------------- 1 | 2 | ########################################################## 3 | ## Install IIS role on spoke-1 4 | ########################################################## 5 | resource "azurerm_virtual_machine_extension" "install-iis-spoke-1-vm" { 6 | 7 | name = "install-iis-spoke-1-vm" 8 | virtual_machine_id = azurerm_windows_virtual_machine.spoke-1-vm.id 9 | publisher = "Microsoft.Compute" 10 | type = "CustomScriptExtension" 11 | type_handler_version = "1.9" 12 | 13 | settings = <