diff --git a/.infracost/pricing.gob b/.infracost/pricing.gob
index 8f21c92..3bde55f 100644
Binary files a/.infracost/pricing.gob and b/.infracost/pricing.gob differ
diff --git a/76_migrate_lb_to_natgateway/README.md b/76_migrate_lb_to_natgateway/README.md
index fcf580e..4cb4edb 100644
--- a/76_migrate_lb_to_natgateway/README.md
+++ b/76_migrate_lb_to_natgateway/README.md
@@ -67,7 +67,7 @@ Check outbound egress traffic uses Load Balancer public IP
```bash
kubectl run nginx --image=nginx
sleep 10
-kubectl exec nginx -it -- curl http://ifconfig.me
+kubectl exec nginx -it -- curl http://ifconf.me
```
Note that is the public IP of the Load Balancer. This is the default behavior of AKS clusters.
@@ -89,7 +89,7 @@ Run this command in new powershell session for watch for the downtime of egress
```bash
for ($i = 0; $i -lt 30; $i++) {
date
- kubectl exec nginx -it -- curl http://ifconfig.me
+ kubectl exec nginx -it -- curl http://ifconf.me
sleep 10 # 10 seconds
}
# Wednesday, October 18, 2023 6:07:33 PM
diff --git a/76_migrate_lb_to_natgateway/commands.ps1 b/76_migrate_lb_to_natgateway/commands.ps1
index 7f26d12..1010c0c 100644
--- a/76_migrate_lb_to_natgateway/commands.ps1
+++ b/76_migrate_lb_to_natgateway/commands.ps1
@@ -31,7 +31,7 @@ az aks get-credentials -g $RG -n aks-cluster --overwrite-existing
kubectl run nginx --image=nginx
sleep 10
-kubectl exec nginx -it -- curl http://ifconfig.me
+kubectl exec nginx -it -- curl http://ifconf.me
# Note that is the public IP of the Load Balancer. This is the default behavior of AKS clusters.
@@ -43,7 +43,7 @@ az network nat gateway create -g $RG -n nat-gateway --public-ip-addresses pip-na
az network vnet subnet update -g $RG --vnet-name vnet-aks --name subnet-aks --nat-gateway nat-gateway
-kubectl exec nginx -it -- curl http://ifconfig.me
+kubectl exec nginx -it -- curl http://ifconf.me
# timeout
# Update cluster from loadbalancer to userAssignedNATGateway in BYO vnet scenario
@@ -53,7 +53,7 @@ az aks update -g $RG -n aks-cluster --outbound-type userAssignedNATGateway
for ($i = 0; $i -lt 30; $i++) {
date
- kubectl exec nginx -it -- curl http://ifconfig.me
+ kubectl exec nginx -it -- curl http://ifconf.me
sleep 10
}
diff --git a/77_migrate_lb_to_natgateway_tf/README.md b/77_migrate_lb_to_natgateway_tf/README.md
new file mode 100644
index 0000000..4cb4edb
--- /dev/null
+++ b/77_migrate_lb_to_natgateway_tf/README.md
@@ -0,0 +1,135 @@
+# Migrating OutboundType from Load Balancer to user NAT Gateway
+
+## Introduction
+
+You will learn in this lab how to migrate `outboundType` of an AKS cluster from `LoadBalancer` to `user NAT Gateway`.
+
+Why you might do that ?
+
+Mainly in case your apps are consuming multiple SNAT ports.
+The NAT Gateway manages more efficiently SNAT ports than Load Balancer.
+More details on the lab `65_aks_egress_lb_natgw_udr`.
+
+There are four options for configuring outbound type in AKS:
+1. Load Balancer (default mode)
+2. Managed NAT Gateway
+3. User NAT Gateway
+4. UserDefinedRouting (UDR)
+
+AKS supports migrating from one mode to another.
+
+| BYO VNet | loadBalancer | managedNATGateway | userAssignedNATGateway | userDefinedRouting |
+| ------------ | ------------ | ----------------- | ---------------------- | ------------------ |
+| loadBalancer | N/A | Not Supported | Supported | Supported |
+| managedNATGateway | Not Supported | N/A | Not Supported | Not Supported |
+| userAssignedNATGateway | Supported | Not Supported | N/A | Supported |
+| userDefinedRouting | Supported | Not Supported | Supported | N/A |
+
+Check the following link for an updated information: https://learn.microsoft.com/en-us/azure/aks/egress-outboundtype#update-cluster-from-managednatgateway-to-userdefinedrouting
+
+## Prerequisites
+
+You need first to enable the migration feature.
+
+```bash
+az feature register --namespace "Microsoft.ContainerService" --name "AKS-OutBoundTypeMigrationPreview"
+az feature show --namespace "Microsoft.ContainerService" --name "AKS-OutBoundTypeMigrationPreview"
+az provider register --namespace Microsoft.ContainerService
+```
+
+## 1. Creating an AKS cluster with outbound type load balancer
+
+```bash
+$RG = "rg-aks-cluster-dev"
+
+az group create -n $RG -l westeurope
+
+az network vnet create -g $RG -n vnet-aks --address-prefixes 172.16.0.0/20
+
+$SUBNET_ID = $(az network vnet subnet create -g $RG --vnet-name vnet-aks -n subnet-aks `
+ --address-prefixes 172.16.0.0/22 `
+ --query id --output tsv)
+
+$IDENTITY_ID = $(az identity create -g $RG -n identity-aks --query id --output tsv)
+
+az aks create -g $RG -n aks-cluster `
+ --network-plugin azure `
+ --vnet-subnet-id $SUBNET_ID `
+ --outbound-type loadBalancer `
+ --enable-managed-identity `
+ --assign-identity $IDENTITY_ID
+
+az aks get-credentials -g $RG -n aks-cluster --overwrite-existing
+```
+
+Check outbound egress traffic uses Load Balancer public IP
+
+```bash
+kubectl run nginx --image=nginx
+sleep 10
+kubectl exec nginx -it -- curl http://ifconf.me
+```
+
+Note that is the public IP of the Load Balancer. This is the default behavior of AKS clusters.
+
+## 2. Migrate outbound type from load balancer to user NAT Gateway
+
+### 2.1. Create the user NAT GAteway with its IP address
+
+```bash
+az network public-ip create -g $RG -n pip-natgateway --sku standard
+
+az network nat gateway create -g $RG -n nat-gateway --public-ip-addresses pip-natgateway
+```
+
+### 2.2. Watch for downtime for egress traffic
+
+Run this command in new powershell session for watch for the downtime of egress traffic.
+
+```bash
+for ($i = 0; $i -lt 30; $i++) {
+ date
+ kubectl exec nginx -it -- curl http://ifconf.me
+ sleep 10 # 10 seconds
+}
+# Wednesday, October 18, 2023 6:07:33 PM
+# 20.31.59.30
+# Wednesday, October 18, 2023 6:07:34 PM
+# error: Timeout occurred
+# Wednesday, October 18, 2023 6:08:06 PM
+# Error from server: error dialing backend: EOF
+# Wednesday, October 18, 2023 6:13:09 PM
+# 13.93.68.197
+```
+
+### 2.3. Associate nat gateway with subnet where the workload is associated with.
+
+```bash
+az network vnet subnet update -g $RG --vnet-name vnet-aks --name subnet-aks --nat-gateway nat-gateway
+```
+
+### 2.4. Update cluster from loadBalancer to userAssignedNATGateway in BYO vnet scenario
+
+```bash
+az aks update -g $RG -n aks-cluster --outbound-type userAssignedNATGateway
+```
+
+Now the NAT Gateway is configured for your AKS cluster.
+
+![](images/resources.png)
+
+>It takes about 6 minutes to update the KAS outboundType from Load Balancer to user NAT Gateway. The pods are able to egress traffic during this time.
+
+> It takes few seconds to update the Subnet. During this time, pods are not able to egress traffic.
+
+Note the new IP address of the NAT Gateway used for egress/outbound traffic.
+
+Note that the Load Balancer and its public IP was deleted.
+
+![](images/deleted-lb.png)
+
+## Cleanup resources
+
+```bash
+az group delete -n $RG --yes --no-wait
+```
\ No newline at end of file
diff --git a/77_migrate_lb_to_natgateway_tf/aks.tf b/77_migrate_lb_to_natgateway_tf/aks.tf
new file mode 100644
index 0000000..05c57e7
--- /dev/null
+++ b/77_migrate_lb_to_natgateway_tf/aks.tf
@@ -0,0 +1,32 @@
+resource "azurerm_user_assigned_identity" "identity" {
+ name = "identity-aks"
+ location = azurerm_resource_group.rg.location
+ resource_group_name = azurerm_resource_group.rg.name
+}
+
+resource "azurerm_kubernetes_cluster" "aks" {
+ name = "aks-cluster"
+ location = azurerm_resource_group.rg.location
+ resource_group_name = azurerm_resource_group.rg.name
+ dns_prefix = "aks"
+
+ default_node_pool {
+ name = "default"
+ node_count = 3
+ vm_size = "Standard_B2s_v2"
+ vnet_subnet_id = azurerm_subnet.subnet.id
+ # pod_subnet_id = azurerm_subnet.subnet.id
+ zones = [1, 2, 3]
+ }
+
+ network_profile {
+ network_plugin = "azure"
+ load_balancer_sku = "standard"
+ outbound_type = "userAssignedNATGateway" # "loadBalancer"
+ }
+
+ identity {
+ type = "UserAssigned"
+ identity_ids = [azurerm_user_assigned_identity.identity.id]
+ }
+}
\ No newline at end of file
diff --git a/77_migrate_lb_to_natgateway_tf/commands.ps1 b/77_migrate_lb_to_natgateway_tf/commands.ps1
new file mode 100644
index 0000000..02cf382
--- /dev/null
+++ b/77_migrate_lb_to_natgateway_tf/commands.ps1
@@ -0,0 +1,36 @@
+# prerequisites
+
+az feature register --namespace "Microsoft.ContainerService" --name "AKS-OutBoundTypeMigrationPreview"
+az feature show --namespace "Microsoft.ContainerService" --name "AKS-OutBoundTypeMigrationPreview"
+az provider register --namespace Microsoft.ContainerService
+
+# 1. AKS cluster with outbound type load balancer
+
+terraform init
+
+terraform apply -auto-approve
+
+$RG = "rg-aks-cluster-dev"
+
+az aks get-credentials -g $RG -n aks-cluster --overwrite-existing
+
+# check outbound egress traffic uses Load Balancer public IP
+
+kubectl run nginx --image=nginx
+sleep 10
+kubectl exec nginx -it -- curl http://ifconf.me
+
+# Note that is the public IP of the Load Balancer. This is the default behavior of AKS clusters.
+
+# Associate nat gateway with subnet where the workload is associated with.
+
+az network vnet subnet update -g $RG --vnet-name vnet-aks --name subnet-aks --nat-gateway nat-gateway
+
+# Update cluster from loadbalancer to userAssignedNATGateway in BYO vnet scenario
+az aks update -g $RG -n aks-cluster --outbound-type userAssignedNATGateway
+
+kubectl exec nginx -it -- curl 10.0.1.4
+# Hello from virtual machine: vm-linux, with IP address: 10.0.1.4
+
+# cleanup resources
+az group delete -n $RG --yes --no-wait
\ No newline at end of file
diff --git a/77_migrate_lb_to_natgateway_tf/images/deleted-lb.png b/77_migrate_lb_to_natgateway_tf/images/deleted-lb.png
new file mode 100644
index 0000000..109036a
Binary files /dev/null and b/77_migrate_lb_to_natgateway_tf/images/deleted-lb.png differ
diff --git a/77_migrate_lb_to_natgateway_tf/images/resources.png b/77_migrate_lb_to_natgateway_tf/images/resources.png
new file mode 100644
index 0000000..6257dcb
Binary files /dev/null and b/77_migrate_lb_to_natgateway_tf/images/resources.png differ
diff --git a/77_migrate_lb_to_natgateway_tf/install-webapp.sh b/77_migrate_lb_to_natgateway_tf/install-webapp.sh
new file mode 100644
index 0000000..6e3a244
--- /dev/null
+++ b/77_migrate_lb_to_natgateway_tf/install-webapp.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+sudo apt -qq update
+
+# Install curl and traceroute and jq
+sudo apt -qq install curl traceroute inetutils-traceroute jq -y
+
+# Install NGINX web server
+sudo apt -qq install nginx -y
+
+IP=$(hostname -i)
+
+echo "Hello from virtual machine: $HOSTNAME, with IP address: $IP" > /var/www/html/index.html
+
+# Script to force enable color prompt on Ubuntu and other Linux distros.
+sed -i 's/#force_color_prompt=yes/force_color_prompt=yes/g' ~/.bashrc
+
+# Reload the .bashrc file
+source ~/.bashrc
\ No newline at end of file
diff --git a/77_migrate_lb_to_natgateway_tf/modules/bastion/main.tf b/77_migrate_lb_to_natgateway_tf/modules/bastion/main.tf
new file mode 100644
index 0000000..57c74ae
--- /dev/null
+++ b/77_migrate_lb_to_natgateway_tf/modules/bastion/main.tf
@@ -0,0 +1,25 @@
+resource "azurerm_public_ip" "pip" {
+ name = "pip-bastion"
+ location = var.location
+ resource_group_name = var.resource_group_name
+ allocation_method = "Static"
+ sku = "Standard"
+}
+
+resource "azurerm_bastion_host" "bastion" {
+ name = "bastion-host"
+ location = var.location
+ resource_group_name = var.resource_group_name
+ sku = "Standard" # "Basic", Developer
+ copy_paste_enabled = true
+ file_copy_enabled = true
+ shareable_link_enabled = true
+ tunneling_enabled = true
+ ip_connect_enabled = false
+
+ ip_configuration {
+ name = "configuration"
+ subnet_id = var.subnet_id
+ public_ip_address_id = azurerm_public_ip.pip.id
+ }
+}
diff --git a/77_migrate_lb_to_natgateway_tf/modules/bastion/output.tf b/77_migrate_lb_to_natgateway_tf/modules/bastion/output.tf
new file mode 100644
index 0000000..ef7ee86
--- /dev/null
+++ b/77_migrate_lb_to_natgateway_tf/modules/bastion/output.tf
@@ -0,0 +1,3 @@
+output "bastion_id" {
+ value = azurerm_bastion_host.bastion.id
+}
diff --git a/77_migrate_lb_to_natgateway_tf/modules/bastion/variables.tf b/77_migrate_lb_to_natgateway_tf/modules/bastion/variables.tf
new file mode 100644
index 0000000..f625492
--- /dev/null
+++ b/77_migrate_lb_to_natgateway_tf/modules/bastion/variables.tf
@@ -0,0 +1,11 @@
+variable "resource_group_name" {
+ type = string
+}
+
+variable "subnet_id" {
+ type = string
+}
+
+variable "location" {
+ type = string
+}
diff --git a/77_migrate_lb_to_natgateway_tf/modules/vm_linux/doc.md b/77_migrate_lb_to_natgateway_tf/modules/vm_linux/doc.md
new file mode 100644
index 0000000..91e0b52
--- /dev/null
+++ b/77_migrate_lb_to_natgateway_tf/modules/vm_linux/doc.md
@@ -0,0 +1,49 @@
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 1.2.8 |
+| [azurerm](#requirement\_azurerm) | >= 3.69.0 |
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| [azurerm](#provider\_azurerm) | >= 3.69.0 |
+
+## Modules
+
+No modules.
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [azurerm_linux_virtual_machine.vm](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/linux_virtual_machine) | resource |
+| [azurerm_network_interface.nic_vm](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_interface) | resource |
+| [azurerm_public_ip.pip_vm](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/public_ip) | resource |
+| [azurerm_resource_group.rg](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) | resource |
+| [azurerm_role_assignment.role_contributor](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
+| [azurerm_user_assigned_identity.identity_vm](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) | resource |
+| [azurerm_virtual_machine_extension.vm_extension_linux](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine_extension) | resource |
+
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [admin\_password](#input\_admin\_password) | n/a | `any` | n/a | yes |
+| [admin\_username](#input\_admin\_username) | n/a | `any` | n/a | yes |
+| [enable\_public\_ip](#input\_enable\_public\_ip) | n/a | `any` | n/a | yes |
+| [location](#input\_location) | n/a | `any` | n/a | yes |
+| [resource\_group\_name](#input\_resource\_group\_name) | n/a | `any` | n/a | yes |
+| [subnet\_id](#input\_subnet\_id) | n/a | `any` | n/a | yes |
+| [subscription\_id](#input\_subscription\_id) | n/a | `any` | n/a | yes |
+| [tags](#input\_tags) | n/a | `any` | n/a | yes |
+| [vm\_name](#input\_vm\_name) | n/a | `any` | n/a | yes |
+| [vm\_size](#input\_vm\_size) | n/a | `any` | n/a | yes |
+
+## Outputs
+
+No outputs.
+
\ No newline at end of file
diff --git a/77_migrate_lb_to_natgateway_tf/modules/vm_linux/main.tf b/77_migrate_lb_to_natgateway_tf/modules/vm_linux/main.tf
new file mode 100644
index 0000000..f289ee6
--- /dev/null
+++ b/77_migrate_lb_to_natgateway_tf/modules/vm_linux/main.tf
@@ -0,0 +1,53 @@
+resource "azurerm_public_ip" "pip_vm" {
+ count = var.enable_public_ip ? 1 : 0
+ name = "pip-vm"
+ location = var.location
+ resource_group_name = var.resource_group_name
+ allocation_method = "Dynamic"
+ tags = var.tags
+}
+
+resource "azurerm_network_interface" "nic_vm" {
+ name = "nic-vm"
+ location = var.location
+ resource_group_name = var.resource_group_name
+ enable_ip_forwarding = var.enable_ip_forwarding
+ tags = var.tags
+
+ ip_configuration {
+ name = "internal"
+ subnet_id = var.subnet_id
+ private_ip_address_allocation = "Dynamic"
+ public_ip_address_id = var.enable_public_ip ? azurerm_public_ip.pip_vm.0.id : null
+ }
+}
+
+resource "azurerm_linux_virtual_machine" "vm" {
+ name = var.vm_name
+ resource_group_name = var.resource_group_name
+ location = var.location
+ size = var.vm_size
+ disable_password_authentication = false
+ admin_username = var.admin_username
+ admin_password = var.admin_password
+ network_interface_ids = [azurerm_network_interface.nic_vm.id]
+ tags = var.tags
+
+ custom_data = var.install_webapp ? filebase64("install-webapp.sh") : null
+
+ os_disk {
+ caching = "ReadWrite"
+ storage_account_type = "Standard_LRS"
+ }
+
+ source_image_reference {
+ publisher = "canonical"
+ offer = "0001-com-ubuntu-server-jammy"
+ sku = "22_04-lts-gen2"
+ version = "latest"
+ }
+
+ boot_diagnostics {
+ storage_account_uri = null
+ }
+}
\ No newline at end of file
diff --git a/77_migrate_lb_to_natgateway_tf/modules/vm_linux/output.tf b/77_migrate_lb_to_natgateway_tf/modules/vm_linux/output.tf
new file mode 100644
index 0000000..9d666e4
--- /dev/null
+++ b/77_migrate_lb_to_natgateway_tf/modules/vm_linux/output.tf
@@ -0,0 +1,7 @@
+output "vm_id" {
+ value = azurerm_linux_virtual_machine.vm.id
+}
+
+output "vm_private_ip" {
+ value = azurerm_linux_virtual_machine.vm.private_ip_address
+}
\ No newline at end of file
diff --git a/77_migrate_lb_to_natgateway_tf/modules/vm_linux/variables.tf b/77_migrate_lb_to_natgateway_tf/modules/vm_linux/variables.tf
new file mode 100644
index 0000000..8245460
--- /dev/null
+++ b/77_migrate_lb_to_natgateway_tf/modules/vm_linux/variables.tf
@@ -0,0 +1,32 @@
+variable "resource_group_name" {}
+variable "location" {}
+variable "tags" {
+ type = map
+ default = {}
+}
+variable "subnet_id" {}
+variable "vm_name" {}
+variable "vm_size" {
+ type = string
+ default = "Standard_B2als_v2" # "Standard_B1ms" # Standard_B2ls_v2 # Standard_B2s_v2
+}
+variable "admin_username" {
+ type = string
+ default = "azureuser"
+}
+variable "admin_password" {
+ type = string
+ default = "@Aa123456789" # don't do this
+}
+variable "enable_public_ip" {
+ type = bool
+ default = false
+}
+variable "enable_ip_forwarding" {
+ type = bool
+ default = false
+}
+variable "install_webapp" {
+ type = bool
+ default = false
+}
diff --git a/77_migrate_lb_to_natgateway_tf/natgateway.tf b/77_migrate_lb_to_natgateway_tf/natgateway.tf
new file mode 100644
index 0000000..c6a51fb
--- /dev/null
+++ b/77_migrate_lb_to_natgateway_tf/natgateway.tf
@@ -0,0 +1,22 @@
+resource "azurerm_public_ip" "pip" {
+ name = "pip-natgateway"
+ location = azurerm_resource_group.rg.location
+ resource_group_name = azurerm_resource_group.rg.name
+ allocation_method = "Static"
+ sku = "Standard"
+ zones = ["1"]
+}
+
+resource "azurerm_nat_gateway" "nat-gateway" {
+ name = "nat-gateway"
+ location = azurerm_resource_group.rg.location
+ resource_group_name = azurerm_resource_group.rg.name
+ sku_name = "Standard"
+ idle_timeout_in_minutes = 10
+ zones = ["1"] # Only one Availability Zone can be defined.
+}
+
+resource "azurerm_nat_gateway_public_ip_association" "association" {
+ nat_gateway_id = azurerm_nat_gateway.nat-gateway.id
+ public_ip_address_id = azurerm_public_ip.pip.id
+}
diff --git a/77_migrate_lb_to_natgateway_tf/provider.tf b/77_migrate_lb_to_natgateway_tf/provider.tf
new file mode 100644
index 0000000..104bf9d
--- /dev/null
+++ b/77_migrate_lb_to_natgateway_tf/provider.tf
@@ -0,0 +1,12 @@
+terraform {
+ required_providers {
+ azurerm = {
+ source = "hashicorp/azurerm"
+ version = "3.79.0"
+ }
+ }
+}
+
+provider "azurerm" {
+ features {}
+}
\ No newline at end of file
diff --git a/77_migrate_lb_to_natgateway_tf/rg.tf b/77_migrate_lb_to_natgateway_tf/rg.tf
new file mode 100644
index 0000000..881b30e
--- /dev/null
+++ b/77_migrate_lb_to_natgateway_tf/rg.tf
@@ -0,0 +1,4 @@
+resource "azurerm_resource_group" "rg" {
+ name = "rg-aks-cluster-dev"
+ location = "westeurope"
+}
\ No newline at end of file
diff --git a/77_migrate_lb_to_natgateway_tf/vm.tf b/77_migrate_lb_to_natgateway_tf/vm.tf
new file mode 100644
index 0000000..6f1594c
--- /dev/null
+++ b/77_migrate_lb_to_natgateway_tf/vm.tf
@@ -0,0 +1,61 @@
+resource "azurerm_resource_group" "rg-vm" {
+ name = "rg-vm"
+ location = "westeurope"
+}
+
+resource "azurerm_virtual_network" "vnet-vm" {
+ name = "vnet-vm"
+ location = azurerm_resource_group.rg-vm.location
+ resource_group_name = azurerm_resource_group.rg-vm.name
+ address_space = ["10.0.0.0/16"]
+}
+
+resource "azurerm_subnet" "subnet-bastion" {
+ name = "AzureBastionSubnet"
+ resource_group_name = azurerm_resource_group.rg-vm.name
+ virtual_network_name = azurerm_virtual_network.vnet-vm.name
+ address_prefixes = ["10.0.0.0/24"]
+}
+
+resource "azurerm_subnet" "subnet-vm" {
+ name = "subnet-vm"
+ resource_group_name = azurerm_resource_group.rg-vm.name
+ virtual_network_name = azurerm_virtual_network.vnet-vm.name
+ address_prefixes = ["10.0.1.0/24"]
+}
+
+module "vm-linux" {
+ source = "./modules/vm_linux"
+ vm_name = "vm-linux"
+ resource_group_name = azurerm_resource_group.rg-vm.name
+ location = azurerm_resource_group.rg-vm.location
+ subnet_id = azurerm_subnet.subnet-vm.id
+ install_webapp = true
+}
+
+module "bastion" {
+ source = "./modules/bastion"
+ resource_group_name = azurerm_resource_group.rg-vm.name
+ location = azurerm_resource_group.rg-vm.location
+ subnet_id = azurerm_subnet.subnet-bastion.id
+}
+
+resource "azurerm_virtual_network_peering" "direction1" {
+ name = "direction1"
+ virtual_network_name = azurerm_virtual_network.vnet-vm.name
+ resource_group_name = azurerm_resource_group.rg-vm.name
+ remote_virtual_network_id = azurerm_virtual_network.vnet.id
+ allow_virtual_network_access = true
+ allow_forwarded_traffic = true
+ allow_gateway_transit = false
+}
+
+resource "azurerm_virtual_network_peering" "vnet_peering_spoke_to_hub" {
+ name = "direction2"
+ virtual_network_name = azurerm_virtual_network.vnet.name
+ resource_group_name = azurerm_resource_group.rg.name
+ remote_virtual_network_id = azurerm_virtual_network.vnet-vm.id
+ allow_virtual_network_access = true
+ allow_forwarded_traffic = true
+ allow_gateway_transit = false
+}
\ No newline at end of file
diff --git a/77_migrate_lb_to_natgateway_tf/vnet.tf b/77_migrate_lb_to_natgateway_tf/vnet.tf
new file mode 100644
index 0000000..69e5d6f
--- /dev/null
+++ b/77_migrate_lb_to_natgateway_tf/vnet.tf
@@ -0,0 +1,13 @@
+resource "azurerm_virtual_network" "vnet" {
+ name = "vnet-aks"
+ location = azurerm_resource_group.rg.location
+ resource_group_name = azurerm_resource_group.rg.name
+ address_space = ["172.16.0.0/20"]
+}
+
+resource "azurerm_subnet" "subnet" {
+ name = "subnet-aks"
+ resource_group_name = azurerm_resource_group.rg.name
+ virtual_network_name = azurerm_virtual_network.vnet.name
+ address_prefixes = ["172.16.0.0/22"]
+}
\ No newline at end of file