diff --git a/quickstart/101-azfw-with-fwpolicy/main.tf b/quickstart/101-azfw-with-fwpolicy/main.tf new file mode 100644 index 000000000..fb684157b --- /dev/null +++ b/quickstart/101-azfw-with-fwpolicy/main.tf @@ -0,0 +1,120 @@ +resource "random_pet" "rg-name" { + prefix = var.resource_group_name_prefix +} + +resource "azurerm_resource_group" "rg" { + name = random_pet.rg-name.id + location = var.resource_group_location +} + +resource "azurerm_virtual_network" "azfw_vnet" { + name = "azfw-vnet" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + address_space = ["10.10.0.0/24"] +} + +resource "azurerm_ip_group" "workload_ip_group" { + name = "workload-ip-group" + resource_group_name = azurerm_resource_group.rg.name + location = azurerm_resource_group.rg.location + cidrs = ["10.20.0.0/24", "10.30.0.0/24"] +} +resource "azurerm_ip_group" "infra_ip_group" { + name = "infra-ip-group" + resource_group_name = azurerm_resource_group.rg.name + location = azurerm_resource_group.rg.location + cidrs = ["10.40.0.0/24", "10.50.0.0/24"] +} + +resource "azurerm_subnet" "azfw_subnet" { + name = "AzureFirewallSubnet" + resource_group_name = azurerm_resource_group.rg.name + virtual_network_name = azurerm_virtual_network.azfw_vnet.name + address_prefixes = ["10.10.0.0/26"] +} + +resource "azurerm_public_ip" "pip_azfw" { + name = "pip-azfw" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + allocation_method = "Static" + sku = "Standard" +} + +resource "azurerm_firewall_policy" "azfw_policy" { + name = "azfw-policy" + resource_group_name = azurerm_resource_group.rg.name + location = azurerm_resource_group.rg.location + sku = var.firewall_sku_tier + threat_intelligence_mode = "Alert" +} + +resource "azurerm_firewall_policy_rule_collection_group" "net_policy_rule_collection_group" { + name = "DefaultNetworkRuleCollectionGroup" + firewall_policy_id = azurerm_firewall_policy.azfw_policy.id + priority = 200 + network_rule_collection { + name = "DefaultNetworkRuleCollection" + action = "Allow" + priority = 200 + rule { + name = "time-windows" + protocols = ["UDP"] + source_ip_groups = [azurerm_ip_group.workload_ip_group.id, azurerm_ip_group.infra_ip_group.id] + destination_ports = ["123"] + destination_addresses = ["132.86.101.172"] + } + } +} + +resource "azurerm_firewall_policy_rule_collection_group" "app_policy_rule_collection_group" { + name = "DefaulApplicationtRuleCollectionGroup" + firewall_policy_id = azurerm_firewall_policy.azfw_policy.id + priority = 300 + application_rule_collection { + name = "DefaultApplicationRuleCollection" + action = "Allow" + priority = 500 + rule { + name = "AllowWindowsUpdate" + + description = "Allow Windows Update" + protocols { + type = "Http" + port = 80 + } + protocols { + type = "Https" + port = 443 + } + source_ip_groups = [azurerm_ip_group.workload_ip_group.id, azurerm_ip_group.infra_ip_group.id] + destination_fqdn_tags = ["WindowsUpdate"] + } + rule { + name = "Global Rule" + description = "Allow access to Microsoft.com" + protocols { + type = "Https" + port = 443 + } + destination_fqdns = ["*.microsoft.com"] + terminate_tls = false + source_ip_groups = [azurerm_ip_group.workload_ip_group.id, azurerm_ip_group.infra_ip_group.id] + } + } +} + +resource "azurerm_firewall" "fw" { + name = "azfw" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + sku_name = "AZFW_VNet" + sku_tier = var.firewall_sku_tier + ip_configuration { + name = "azfw-ipconfig" + subnet_id = azurerm_subnet.azfw_subnet.id + public_ip_address_id = azurerm_public_ip.pip_azfw.id + } + firewall_policy_id = azurerm_firewall_policy.azfw_policy.id +} \ No newline at end of file diff --git a/quickstart/101-azfw-with-fwpolicy/outputs.tf b/quickstart/101-azfw-with-fwpolicy/outputs.tf new file mode 100644 index 000000000..3d6f89a11 --- /dev/null +++ b/quickstart/101-azfw-with-fwpolicy/outputs.tf @@ -0,0 +1,7 @@ +output "resource_group_name" { + value = azurerm_resource_group.rg.name +} + +output "firewall_name" { + value = azurerm_firewall.fw.name +} \ No newline at end of file diff --git a/quickstart/101-azfw-with-fwpolicy/provider.tf b/quickstart/101-azfw-with-fwpolicy/provider.tf new file mode 100644 index 000000000..18eea7b7d --- /dev/null +++ b/quickstart/101-azfw-with-fwpolicy/provider.tf @@ -0,0 +1,16 @@ +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "~>3.0" + } + random = { + source = "hashicorp/random" + version = "~>3.0" + } + } +} + +provider "azurerm" { + features {} +} diff --git a/quickstart/101-azfw-with-fwpolicy/readme.md b/quickstart/101-azfw-with-fwpolicy/readme.md new file mode 100644 index 000000000..d8e5a8edc --- /dev/null +++ b/quickstart/101-azfw-with-fwpolicy/readme.md @@ -0,0 +1,23 @@ +# Azure Firewall and Azure Firewall Policy + +This template deploys an [Azure Firewall](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/firewall) with an [Azure Firewall Policy](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/firewall_policy) + +## Terraform resource types + +- [azurerm_resource_group](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) +- [azurerm_virtual_network](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network) +- [azurerm_subnet](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/subnet) +- [azurerm_ip_group](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/ip_group) +- [azurerm_public_ip](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/public_ip) +- [azurerm_firewall_policy](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/firewall_policy) +- [azurerm_firewall_policy_rule_collection_group](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/firewall_policy_rule_collection_group) +- [azurerm_firewall](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/firewall) + +## Variables + +| Name | Description | Default value | +|-|-|-| +| `resource_group_location` | location for your resources | eastus | +| `firewall_sku_tier` | Sku size for your Firewall and Firewall Policy | Premium | + +## Example \ No newline at end of file diff --git a/quickstart/101-azfw-with-fwpolicy/variables.tf b/quickstart/101-azfw-with-fwpolicy/variables.tf new file mode 100644 index 000000000..eb12bf647 --- /dev/null +++ b/quickstart/101-azfw-with-fwpolicy/variables.tf @@ -0,0 +1,22 @@ +variable "resource_group_location" { + type = string + description = "Location for all resources." + default = "eastus" +} + +variable "resource_group_name_prefix" { + type = string + description = "Prefix for the Resource Group Name that's combined with a random id so name is unique in your Azure subcription." + default = "rg" +} + +variable "firewall_sku_tier" { + type = string + description = "Firewall SKU." + default = "Premium" # Valid values are Standard and Premium + validation { + condition = contains(["Standard", "Premium"], var.firewall_sku_tier) + error_message = "The sku must be one of the following: Standard, Premium" + } +} + diff --git a/quickstart/201-azfw-with-secure-hub/main.tf b/quickstart/201-azfw-with-secure-hub/main.tf new file mode 100644 index 000000000..d1dc7abf1 --- /dev/null +++ b/quickstart/201-azfw-with-secure-hub/main.tf @@ -0,0 +1,266 @@ +resource "random_pet" "rg-name" { + prefix = var.resource_group_name_prefix +} + +resource "azurerm_resource_group" "rg" { + name = random_pet.rg-name.id + location = var.resource_group_location +} + +resource "azurerm_virtual_wan" "azfw_vwan" { + name = "vwan-azfw-securehub-eus" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + allow_branch_to_branch_traffic = true + disable_vpn_encryption = false +} + +resource "azurerm_virtual_hub" "azfw_vwan_hub" { + name = "hub-azfw-securehub-eus" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + virtual_wan_id = azurerm_virtual_wan.azfw_vwan.id + address_prefix = "10.20.0.0/23" +} + +resource "azurerm_virtual_hub_connection" "azfw_vwan_hub_connection" { + name = "hub-to-spoke" + virtual_hub_id = azurerm_virtual_hub.azfw_vwan_hub.id + remote_virtual_network_id = azurerm_virtual_network.azfw_vnet.id + internet_security_enabled = true + routing { + associated_route_table_id = azurerm_virtual_hub_route_table.vhub_rt.id + propagated_route_table { + route_table_ids = [azurerm_virtual_hub_route_table.vhub_rt.id] + labels = ["VNet"] + } + } +} + +resource "azurerm_public_ip" "pip_azfw" { + name = "pip-azfw-securehub-eus" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + allocation_method = "Static" + sku = "Standard" +} + +resource "azurerm_firewall_policy" "azfw_policy" { + name = "policy-azfw-securehub-eus" + resource_group_name = azurerm_resource_group.rg.name + location = azurerm_resource_group.rg.location + sku = var.firewall_sku_name + threat_intelligence_mode = "Alert" +} + +resource "azurerm_firewall_policy_rule_collection_group" "app_policy_rule_collection_group" { + name = "DefaulApplicationtRuleCollectionGroup" + firewall_policy_id = azurerm_firewall_policy.azfw_policy.id + priority = 300 + application_rule_collection { + name = "DefaultApplicationRuleCollection" + action = "Allow" + priority = 100 + rule { + name = "Allow-MSFT" + description = "Allow access to Microsoft.com" + protocols { + type = "Https" + port = 443 + } + protocols { + type = "Http" + port = 80 + } + destination_fqdns = ["*.microsoft.com"] + terminate_tls = false + source_addresses = ["*"] + } + } +} + +resource "azurerm_firewall" "fw" { + name = "fw-azfw-securehub-eus" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + sku_name = "AZFW_Hub" + sku_tier = var.firewall_sku_name + virtual_hub { + virtual_hub_id = azurerm_virtual_hub.azfw_vwan_hub.id + public_ip_count = 1 + } + firewall_policy_id = azurerm_firewall_policy.azfw_policy.id +} + +resource "azurerm_virtual_network" "azfw_vnet" { + name = "vnet-azfw-securehub-eus" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + address_space = ["10.10.0.0/16"] +} + +resource "azurerm_subnet" "workload_subnet" { + name = "subnet-workload" + resource_group_name = azurerm_resource_group.rg.name + virtual_network_name = azurerm_virtual_network.azfw_vnet.name + address_prefixes = ["10.10.1.0/24"] +} + +resource "azurerm_subnet" "jump_subnet" { + name = "subnet-jump" + resource_group_name = azurerm_resource_group.rg.name + virtual_network_name = azurerm_virtual_network.azfw_vnet.name + address_prefixes = ["10.10.2.0/24"] +} + +resource "azurerm_network_interface" "vm_workload_nic" { + name = "nic-workload" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + + ip_configuration { + name = "ipconfig-workload" + subnet_id = azurerm_subnet.workload_subnet.id + private_ip_address_allocation = "Dynamic" + } +} + +resource "azurerm_public_ip" "vm_jump_pip" { + name = "pip-jump" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + allocation_method = "Static" + sku = "Standard" +} + +resource "azurerm_network_interface" "vm_jump_nic" { + name = "nic-jump" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + + ip_configuration { + name = "ipconfig-jump" + subnet_id = azurerm_subnet.jump_subnet.id + private_ip_address_allocation = "Dynamic" + public_ip_address_id = azurerm_public_ip.vm_jump_pip.id + } +} + +resource "azurerm_network_security_group" "vm_workload_nsg" { + name = "nsg-workload" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name +} + +resource "azurerm_network_security_group" "vm_jump_nsg" { + name = "nsg-jump" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + security_rule { + name = "Allow-RDP" + priority = 300 + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "3389" + source_address_prefix = "*" + destination_address_prefix = "*" + } +} + +resource "azurerm_network_interface_security_group_association" "vm_workload_nsg_association" { + network_interface_id = azurerm_network_interface.vm_workload_nic.id + network_security_group_id = azurerm_network_security_group.vm_workload_nsg.id +} + +resource "azurerm_network_interface_security_group_association" "vm_jump_nsg_association" { + network_interface_id = azurerm_network_interface.vm_jump_nic.id + network_security_group_id = azurerm_network_security_group.vm_jump_nsg.id +} + +resource "azurerm_windows_virtual_machine" "vm_workload" { + name = "workload-vm" + resource_group_name = azurerm_resource_group.rg.name + location = azurerm_resource_group.rg.location + size = var.virtual_machine_size + admin_username = var.admin_username + admin_password = random_password.password.result + network_interface_ids = [azurerm_network_interface.vm_workload_nic.id] + os_disk { + caching = "ReadWrite" + storage_account_type = "Standard_LRS" + } + source_image_reference { + publisher = "MicrosoftWindowsServer" + offer = "WindowsServer" + sku = "2019-Datacenter" + version = "latest" + } +} + +resource "azurerm_windows_virtual_machine" "vm_jump" { + name = "jump-vm" + resource_group_name = azurerm_resource_group.rg.name + location = azurerm_resource_group.rg.location + size = var.virtual_machine_size + admin_username = var.admin_username + admin_password = random_password.password.result + network_interface_ids = [azurerm_network_interface.vm_jump_nic.id] + os_disk { + caching = "ReadWrite" + storage_account_type = "Standard_LRS" + } + source_image_reference { + publisher = "MicrosoftWindowsServer" + offer = "WindowsServer" + sku = "2019-Datacenter" + version = "latest" + } +} + +resource "azurerm_route_table" "rt" { + name = "rt-azfw-securehub-eus" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + disable_bgp_route_propagation = false + route { + name = "jump-to-internet" + address_prefix = "0.0.0.0/0" + next_hop_type = "Internet" + } +} + +resource "azurerm_subnet_route_table_association" "jump_subnet_rt_association" { + subnet_id = azurerm_subnet.jump_subnet.id + route_table_id = azurerm_route_table.rt.id +} + +resource "azurerm_virtual_hub_route_table" "vhub_rt" { + name = "vhub-rt-azfw-securehub-eus" + virtual_hub_id = azurerm_virtual_hub.azfw_vwan_hub.id + route { + name = "workload-SNToFirewall" + destinations_type = "CIDR" + destinations = ["10.10.1.0/24"] + next_hop_type = "ResourceId" + next_hop = azurerm_firewall.fw.id + } + route { + name = "InternetToFirewall" + destinations_type = "CIDR" + destinations = ["0.0.0.0/0"] + next_hop_type = "ResourceId" + next_hop = azurerm_firewall.fw.id + } + labels = ["VNet"] +} + +resource "random_password" "password" { + length = 20 + min_lower = 1 + min_upper = 1 + min_numeric = 1 + min_special = 1 + special = true +} diff --git a/quickstart/201-azfw-with-secure-hub/outputs.tf b/quickstart/201-azfw-with-secure-hub/outputs.tf new file mode 100644 index 000000000..3071a100d --- /dev/null +++ b/quickstart/201-azfw-with-secure-hub/outputs.tf @@ -0,0 +1,18 @@ +output "resource_group_name" { + value = azurerm_resource_group.rg.name +} + +output "virtual_hub_name" { + value = azurerm_virtual_hub.azfw_vwan_hub.name +} + +output "jump_admin_password" { + sensitive = true + value = azurerm_windows_virtual_machine.vm_jump.admin_password +} + +output "workload_admin_password" { + sensitive = true + value = azurerm_windows_virtual_machine.vm_workload.admin_password +} + diff --git a/quickstart/201-azfw-with-secure-hub/provider.tf b/quickstart/201-azfw-with-secure-hub/provider.tf new file mode 100644 index 000000000..bf50b67ec --- /dev/null +++ b/quickstart/201-azfw-with-secure-hub/provider.tf @@ -0,0 +1,21 @@ +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "~>3.0" + } + random = { + source = "hashicorp/random" + version = "~>3.0" + } + } +} + +provider "azurerm" { + features { + virtual_machine { + delete_os_disk_on_deletion = true + skip_shutdown_and_force_delete = true + } + } +} diff --git a/quickstart/201-azfw-with-secure-hub/readme.md b/quickstart/201-azfw-with-secure-hub/readme.md new file mode 100644 index 000000000..91bacf36d --- /dev/null +++ b/quickstart/201-azfw-with-secure-hub/readme.md @@ -0,0 +1,33 @@ +# Azure Firewall with Secure Hub + +This template deploys an [Azure Firewall](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/firewall) in a [Virtual Secure Hub](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_hub) + +## Terraform resource types + +- [azurerm_resource_group](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) +- [azurerm_virtual_wan](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_wan) +- [azurerm_virtual_hub](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_hub) +- [azurerm_virtual_hub_connection](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_hub_connection) +- [azurerm_public_ip](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/public_ip) +- [azurerm_firewall_policy](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/firewall_policy) +- [azurerm_firewall_policy_rule_collection_group](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/firewall_policy_rule_collection_group) +- [azurerm_virtual_network](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network) +- [azurerm_subnet](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/subnet) +- [azurerm_network_interface](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_interface) +- [azurerm_network_security_group](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_security_group) +- [azurerm_network_interface_security_group_association](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_interface_security_group_association +- [azurerm_windows_virtual_machine](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/windows_virtual_machine) +- [azurerm_route_table](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/route_table) +- [azurerm_subnet_route_table_association](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/subnet_route_table_association) +- [azurerm_virtual_hub_route_table](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_hub_route_table) + +## Variables + +| Name | Description | Default value | +|-|-|-| +| `location` | location for your resources | eastus | +| `firewall_sku` | Sku size for your Firewall and Firewall Policy | Premium | +| `virtual_machine_size` | Sku size for your jump and workload vms | Standard_D2_v3 | +| `admin_username` | admin username for the jump and workload vms | azureuser | + +## Example \ No newline at end of file diff --git a/quickstart/201-azfw-with-secure-hub/variables.tf b/quickstart/201-azfw-with-secure-hub/variables.tf new file mode 100644 index 000000000..e76f46d92 --- /dev/null +++ b/quickstart/201-azfw-with-secure-hub/variables.tf @@ -0,0 +1,27 @@ +variable "resource_group_location" { + type = string + description = "Location for all resources." + default = "eastus" +} + +variable "resource_group_name_prefix" { + type = string + description = "Prefix for the Resource Group Name that's combined with a random id so name is unique in your Azure subcription." + default = "rg" +} + +variable "firewall_sku_name" { + type = string + description = "SKU name for the firewall." + default = "Premium" # Valid values are Standard and Premium +} + +variable "virtual_machine_size" { + type = string + description = "Size of the virtual machine." + default = "Standard_D2_v3" +} + +variable "admin_username" { + default = "azureuser" +}