From bfc6facfa174fe43e2732fee985badfb03ef60e2 Mon Sep 17 00:00:00 2001 From: Adrian Celebanski Date: Mon, 4 Mar 2024 20:53:19 +0100 Subject: [PATCH 1/5] Fix admonitions --- examples/appgw/README.md | 4 ++-- examples/appgw/variables.tf | 3 ++- modules/loadbalancer/README.md | 9 ++++----- modules/loadbalancer/variables.tf | 9 ++++----- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/examples/appgw/README.md b/examples/appgw/README.md index 992114d3..671ea179 100644 --- a/examples/appgw/README.md +++ b/examples/appgw/README.md @@ -349,7 +349,8 @@ Example: name_prefix = "test-" ``` -NOTICE. This prefix is not applied to existing resources. If you plan to reuse i.e. a VNET please specify it's full name, +**Note!** \ +This prefix is not applied to existing resources. If you plan to reuse i.e. a VNET please specify it's full name, even if it is also prefixed with the same value as the one in this property. @@ -375,5 +376,4 @@ Default value: `true` - \ No newline at end of file diff --git a/examples/appgw/variables.tf b/examples/appgw/variables.tf index 796b38b0..2727f4e3 100644 --- a/examples/appgw/variables.tf +++ b/examples/appgw/variables.tf @@ -21,7 +21,8 @@ variable "name_prefix" { name_prefix = "test-" ``` - NOTICE. This prefix is not applied to existing resources. If you plan to reuse i.e. a VNET please specify it's full name, + **Note!** \ + This prefix is not applied to existing resources. If you plan to reuse i.e. a VNET please specify it's full name, even if it is also prefixed with the same value as the one in this property. EOF default = "" diff --git a/modules/loadbalancer/README.md b/modules/loadbalancer/README.md index 3e53bfb2..2d044303 100644 --- a/modules/loadbalancer/README.md +++ b/modules/loadbalancer/README.md @@ -225,11 +225,10 @@ Below are the properties for the `in_rules` map: Below are the properties for `out_rules` map. -> [!Warning] -> Setting at least one `out_rule` switches the outgoing traffic from SNAT to outbound rules. -> Keep in mind that since we use a single backend, -> and you cannot mix SNAT and outbound rules traffic in rules using the same backend, -> setting one `out_rule` switches the outgoing traffic route for **ALL** `in_rules`. +**Warning!** \ +Setting at least one `out_rule` switches the outgoing traffic from SNAT to outbound rules. Keep in mind that since we use a +single backend, and you cannot mix SNAT and outbound rules traffic in rules using the same backend, setting one `out_rule` +switches the outgoing traffic route for **ALL** `in_rules`. - `name` - (`string`, required) a name of an outbound rule - `protocol` - (`string`, required) protocol used by the rule. One of `All`, `Tcp` or `Udp` is accepted diff --git a/modules/loadbalancer/variables.tf b/modules/loadbalancer/variables.tf index 4f0bde88..e76ba3e1 100644 --- a/modules/loadbalancer/variables.tf +++ b/modules/loadbalancer/variables.tf @@ -106,11 +106,10 @@ variable "frontend_ips" { Below are the properties for `out_rules` map. - > [!Warning] - > Setting at least one `out_rule` switches the outgoing traffic from SNAT to outbound rules. - > Keep in mind that since we use a single backend, - > and you cannot mix SNAT and outbound rules traffic in rules using the same backend, - > setting one `out_rule` switches the outgoing traffic route for **ALL** `in_rules`. + **Warning!** \ + Setting at least one `out_rule` switches the outgoing traffic from SNAT to outbound rules. Keep in mind that since we use a + single backend, and you cannot mix SNAT and outbound rules traffic in rules using the same backend, setting one `out_rule` + switches the outgoing traffic route for **ALL** `in_rules`. - `name` - (`string`, required) a name of an outbound rule - `protocol` - (`string`, required) protocol used by the rule. One of `All`, `Tcp` or `Udp` is accepted From b2ce828c5d1dff499ec9c4b6f12d39aa096be860 Mon Sep 17 00:00:00 2001 From: Adrian Celebanski Date: Tue, 5 Mar 2024 12:51:40 +0100 Subject: [PATCH 2/5] Fix examples code style --- examples/appgw/README.md | 4 +- examples/appgw/example.tfvars | 7 +- examples/appgw/main.tf | 20 +- examples/appgw/variables.tf | 1 - examples/common_vmseries/README.md | 465 +++++------ examples/common_vmseries/example.tfvars | 111 +-- examples/common_vmseries/main.tf | 169 ++-- examples/common_vmseries/variables.tf | 769 +++++++++--------- .../common_vmseries_and_autoscale/README.md | 274 ++++--- .../example.tfvars | 18 +- .../common_vmseries_and_autoscale/main.tf | 83 +- .../variables.tf | 551 +++++++------ examples/dedicated_vmseries/README.md | 464 +++++------ examples/dedicated_vmseries/example.tfvars | 27 +- examples/dedicated_vmseries/main.tf | 169 ++-- examples/dedicated_vmseries/variables.tf | 769 +++++++++--------- .../README.md | 274 ++++--- .../example.tfvars | 20 +- .../dedicated_vmseries_and_autoscale/main.tf | 83 +- .../variables.tf | 549 +++++++------ examples/gwlb_with_vmseries/README.md | 463 ++++++----- examples/gwlb_with_vmseries/example.tfvars | 34 +- examples/gwlb_with_vmseries/main.tf | 56 +- examples/gwlb_with_vmseries/variables.tf | 467 ++++++----- examples/standalone_panorama/README.md | 172 ++-- examples/standalone_panorama/example.tfvars | 12 +- examples/standalone_panorama/main.tf | 27 +- examples/standalone_panorama/outputs.tf | 2 +- examples/standalone_panorama/variables.tf | 159 ++-- examples/standalone_vmseries/README.md | 459 +++++------ examples/standalone_vmseries/example.tfvars | 12 +- examples/standalone_vmseries/main.tf | 172 ++-- examples/standalone_vmseries/variables.tf | 769 +++++++++--------- examples/virtual_network_gateway/README.md | 80 +- .../virtual_network_gateway/example.tfvars | 8 +- examples/virtual_network_gateway/main.tf | 18 +- examples/virtual_network_gateway/outputs.tf | 2 +- examples/virtual_network_gateway/variables.tf | 67 +- 38 files changed, 3985 insertions(+), 3821 deletions(-) diff --git a/examples/appgw/README.md b/examples/appgw/README.md index 671ea179..4eca71de 100644 --- a/examples/appgw/README.md +++ b/examples/appgw/README.md @@ -42,8 +42,8 @@ Providers used in this module: Modules used in this module: Name | Version | Source | Description --- | --- | --- | --- -`vnet` | - | ../../modules/vnet | Manage the network required for the topology. -`appgw` | - | ../../modules/appgw | Create Application Gateway +`vnet` | - | ../../modules/vnet | +`appgw` | - | ../../modules/appgw | Resources used in this module: diff --git a/examples/appgw/example.tfvars b/examples/appgw/example.tfvars index ffd4a7fb..efbe70e7 100644 --- a/examples/appgw/example.tfvars +++ b/examples/appgw/example.tfvars @@ -1,4 +1,5 @@ -# --- GENERAL --- # +### GENERAL ### + location = "North Europe" resource_group_name = "appgw-example" name_prefix = "fosix-" @@ -7,8 +8,8 @@ tags = { "CreatedWith" = "Terraform" } +### NETWORK ### -# --- VNET PART --- # vnets = { transit = { name = "transit" @@ -36,7 +37,7 @@ vnets = { } } -# --- APPGW PART --- # +### LOAD BALANCING ### appgws = { "public-empty" = { diff --git a/examples/appgw/main.tf b/examples/appgw/main.tf index 1bde6a85..52e4fd39 100644 --- a/examples/appgw/main.tf +++ b/examples/appgw/main.tf @@ -1,4 +1,5 @@ -# Create or source the Resource Group. +### Create or source a Resource Group ### + # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group resource "azurerm_resource_group" "this" { count = var.create_resource_group ? 1 : 0 @@ -18,7 +19,8 @@ locals { resource_group = var.create_resource_group ? azurerm_resource_group.this[0] : data.azurerm_resource_group.this[0] } -# Create public IP in order to reuse it in 1 of the application gateways +### Create a public IP in order to reuse it in one of the Application Gateways ### + # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/public_ip resource "azurerm_public_ip" "this" { name = "pip-existing" @@ -31,7 +33,8 @@ resource "azurerm_public_ip" "this" { tags = var.tags } -# Manage the network required for the topology. +### Manage the network required for the topology ### + module "vnet" { source = "../../modules/vnet" @@ -47,15 +50,18 @@ module "vnet" { create_subnets = each.value.create_subnets subnets = each.value.subnets - network_security_groups = { for k, v in each.value.network_security_groups : k => merge(v, { name = "${var.name_prefix}${v.name}" }) + network_security_groups = { + for k, v in each.value.network_security_groups : k => merge(v, { name = "${var.name_prefix}${v.name}" }) } - route_tables = { for k, v in each.value.route_tables : k => merge(v, { name = "${var.name_prefix}${v.name}" }) + route_tables = { + for k, v in each.value.route_tables : k => merge(v, { name = "${var.name_prefix}${v.name}" }) } tags = var.tags } -# Create Application Gateway +### Create Application Gateways ### + module "appgw" { source = "../../modules/appgw" @@ -90,4 +96,4 @@ module "appgw" { tags = var.tags depends_on = [module.vnet, azurerm_public_ip.this] -} \ No newline at end of file +} diff --git a/examples/appgw/variables.tf b/examples/appgw/variables.tf index 2727f4e3..3db178a9 100644 --- a/examples/appgw/variables.tf +++ b/examples/appgw/variables.tf @@ -69,7 +69,6 @@ variable "vnets" { - `route_tables` - (`map`, optional) map of Route Tables to create, for details see [VNET module documentation](../../modules/vnet/README.md#route_tables) EOF - type = map(object({ name = string create_virtual_network = optional(bool, true) diff --git a/examples/common_vmseries/README.md b/examples/common_vmseries/README.md index 1c7115a5..c7128938 100644 --- a/examples/common_vmseries/README.md +++ b/examples/common_vmseries/README.md @@ -17,8 +17,7 @@ common VM-Series for all traffic; for a discussion of other options, please see ## Reference Architecture Design -![simple](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/assets/2110772/aa2ae33a-fb46-4a1c-9811-98ea3b132297) - +![simple](https://github.com/PaloAltoNetworks/terraform-azurerm-vmseries-modules/assets/6574404/a7c2452d-f926-49da-bf21-9d840282a0a2) This code implements: @@ -41,8 +40,7 @@ and may present scale limitations with all traffic flowing through a single set that occurs when traffic crosses virtual routers. This option is suitable for proof-of-concepts and smaller scale deployments because the number of firewalls low. However, the technical integration complexity is high. -![Detailed Topology Diagram](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/assets/2110772/8e8da6e0-afba-4bb5-b2c7-a95c7250dab3) - +![Detailed Topology Diagram](https://user-images.githubusercontent.com/2110772/234920647-c7dc77c1-d86c-42ac-ba5a-59a95439ef23.png) This reference architecture consists of: @@ -173,8 +171,8 @@ terraform destroy Name | Type | Description --- | --- | --- -[`location`](#location) | `string` | The Azure region to use. [`resource_group_name`](#resource_group_name) | `string` | Name of the Resource Group. +[`location`](#location) | `string` | The Azure region to use. [`vnets`](#vnets) | `map` | A map defining VNETs. [`appgws`](#appgws) | `map` | A map defining all Application Gateways in the current deployment. @@ -183,11 +181,11 @@ Name | Type | Description Name | Type | Description --- | --- | --- -[`tags`](#tags) | `map` | Map of tags to assign to the created resources. [`name_prefix`](#name_prefix) | `string` | A prefix that will be added to all created resources. [`create_resource_group`](#create_resource_group) | `bool` | When set to `true` it will cause a Resource Group creation. +[`tags`](#tags) | `map` | Map of tags to assign to the created resources. [`natgws`](#natgws) | `map` | A map defining NAT Gateways. -[`load_balancers`](#load_balancers) | `map` | A map containing configuration for all (private and public) Load Balancers. +[`load_balancers`](#load_balancers) | `map` | A map containing configuration for all (both private and public) Load Balancers. [`availability_sets`](#availability_sets) | `map` | A map defining availability sets. [`ngfw_metrics`](#ngfw_metrics) | `object` | A map controlling metrics-relates resources. [`bootstrap_storages`](#bootstrap_storages) | `map` | A map defining Azure Storage Accounts used to host file shares for bootstrapping NGFWs. @@ -225,13 +223,13 @@ Providers used in this module: Modules used in this module: Name | Version | Source | Description --- | --- | --- | --- -`vnet` | - | ../../modules/vnet | Manage the network required for the topology. +`vnet` | - | ../../modules/vnet | `natgw` | - | ../../modules/natgw | -`load_balancer` | - | ../../modules/loadbalancer | create load balancers, both internal and external -`ngfw_metrics` | - | ../../modules/ngfw_metrics | create the actual VM-Series VMs and resources +`load_balancer` | - | ../../modules/loadbalancer | +`appgw` | - | ../../modules/appgw | +`ngfw_metrics` | - | ../../modules/ngfw_metrics | `bootstrap` | - | ../../modules/bootstrap | `vmseries` | - | ../../modules/vmseries | -`appgw` | - | ../../modules/appgw | Resources used in this module: @@ -248,46 +246,45 @@ Resources used in this module: -#### location -The Azure region to use. +#### resource_group_name + +Name of the Resource Group. Type: string [back to list](#modules-required-inputs) +#### location - -#### resource_group_name - -Name of the Resource Group. +The Azure region to use. Type: string [back to list](#modules-required-inputs) + #### vnets A map defining VNETs. For detailed documentation on each property refer to [module documentation](../../modules/vnet/README.md) -- `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, - `false` will source an existing VNET. -- `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be - a full resource name, including prefixes. -- `address_space` - (`list(string)`, required when `create_virtual_network = false`) a list of CIDRs for a newly - created VNET -- `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which - the VNET will reside or is sourced from +- `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, `false` will source + an existing VNET. +- `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be a + full resource name, including prefixes. +- `address_space` - (`list`, required when `create_virtual_network = false`) a list of CIDRs for a newly created VNET. +- `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which the + VNET will reside or is sourced from. - `create_subnets` - (`bool`, optional, defaults to `true`) if `true`, create Subnets inside the Virtual Network, - otherwise use source existing subnets + otherwise use source existing subnets. - `subnets` - (`map`, optional) map of Subnets to create or source, for details see - [VNET module documentation](../../modules/vnet/README.md#subnets) + [VNET module documentation](../../modules/vnet/README.md#subnets). - `network_security_groups` - (`map`, optional) map of Network Security Groups to create, for details see - [VNET module documentation](../../modules/vnet/README.md#network_security_groups) + [VNET module documentation](../../modules/vnet/README.md#network_security_groups). - `route_tables` - (`map`, optional) map of Route Tables to create, for details see - [VNET module documentation](../../modules/vnet/README.md#route_tables) + [VNET module documentation](../../modules/vnet/README.md#route_tables). Type: @@ -342,10 +339,6 @@ map(object({ - - - - #### appgws A map defining all Application Gateways in the current deployment. @@ -364,25 +357,25 @@ Below you can find a brief list of most important properties: described by `subnet_key`. - `subnet_key` - (`string`, required) a key pointing to a Subnet definition in the `var.vnets` map, this has to be an Application Gateway V2 dedicated subnet. -- `zones` - (`list`, optional, defaults to module defaults) parameter controlling if this is a zonal, or a non-zonal +- `zones` - (`list`, optional, defaults to module default) parameter controlling if this is a zonal, or a non-zonal deployment. - `public_ip` - (`map`, required) defines a Public IP resource used by the Application Gateway instance, a newly created Public IP will have it's name prefixes with `var.name_prefix`. - `listeners` - (`map`, required) defines Application Gateway's Listeners, see [module's documentation](../../modules/appgw/README.md#listeners) for details. -- `backend_pool` - (`map`, optional, defaults to module defaults) backend pool definition, when skipped an empty backend +- `backend_pool` - (`map`, optional, defaults to module default) backend pool definition, when skipped an empty backend will be created. - `backend_settings` - (`map`, optional, mutually exclusive with `redirects` and `url_path_maps`) defines HTTP backend settings, see [module's documentation](../../modules/appgw/README.md#backend_settings) for details. -- `probes` - (`map`, optional, defaults to module defaults) defines backend probes used check health of backends, see +- `probes` - (`map`, optional, defaults to module default) defines backend probes used check health of backends, see [module's documentation](../../modules/appgw/README.md#probes) for details. -- `rewrites` - (`map`, optional, defaults to module defaults) defines rewrite rules, see +- `rewrites` - (`map`, optional, defaults to module default) defines rewrite rules, see [module's documentation](../../modules/appgw/README.md#rewrites) for details. -- `redirects - (`map`, optional, mutually exclusive with `backend_settings` and `url_path_maps`) static redirects +- `redirects` - (`map`, optional, mutually exclusive with `backend_settings` and `url_path_maps`) static redirects definition, see [module's documentation](../../modules/appgw/README.md#redirects) for details. -- `url_path_maps - (`map`, optional, mutually exclusive with `backend_settings` and `redirects`) URL path maps definition, +- `url_path_maps` - (`map`, optional, mutually exclusive with `backend_settings` and `redirects`) URL path maps definition, see [module's documentation](../../modules/appgw/README.md#url_path_maps) for details. -- `rules - (`map`, required) Application Gateway Rules definition, bind together a `listener` with either +- `rules` - (`map`, required) Application Gateway Rules definition, bind together a `listener` with either `backend_setting`, `redirect` or `url_path_map`, see [module's documentation](../../modules/appgw/README.md#rules) for details. @@ -519,18 +512,11 @@ map(object({ -### Optional Inputs - - -#### tags -Map of tags to assign to the created resources. -Type: map(string) -Default value: `map[]` -[back to list](#modules-optional-inputs) +### Optional Inputs #### name_prefix @@ -571,6 +557,17 @@ Default value: `true` +#### tags + +Map of tags to assign to the created resources. + +Type: map(string) + +Default value: `map[]` + +[back to list](#modules-optional-inputs) + + #### natgws A map defining NAT Gateways. @@ -580,21 +577,21 @@ explicitly). Please refer to Microsoft documentation for notes on NAT Gateway's For detailed documentation on each property refer to [module documentation](../../modules/natgw/README.md). Following properties are supported: -- `create_natgw` - (`bool`, optional, defaults to `true`) create (`true`) or source an existing NAT Gateway (`false`), - created or sourced: the NAT Gateway will be assigned to a subnet created by the `vnet` module. -- `name` - (`string`, required) a name of a NAT Gateway. In case `create_natgw = false` this should be a full - resource name, including prefixes. -- `resource_group_name - (`string`, optional) name of a Resource Group hosting the NAT Gateway (newly created or the existing - one). -- `zone` - (`string`, optional) an Availability Zone in which the NAT Gateway will be placed, when skipped - AzureRM will pick a zone. -- `idle_timeout` - (`number`, optional, defults to 4) connection IDLE timeout in minutes, for newly created resources. -- `vnet_key` - (`string`, required) a name (key value) of a VNET defined in `var.vnets` that hosts a subnet this - NAT Gateway will be assigned to. -- `subnet_keys` - (`list(string)`, required) a list of subnets (key values) the NAT Gateway will be assigned to, defined - in `var.vnets` for a VNET described by `vnet_name`. -- `public_ip` - (`object`, optional) an object defining a public IP resource attached to the NAT Gateway. -- `public_ip_prefix` - (`object`, optional) an object defining a public IP prefix resource attached to the NAT Gatway. +- `name` - (`string`, required) a name of a NAT Gateway. In case `create_natgw = false` this should be a full + resource name, including prefixes. +- `vnet_key` - (`string`, required) a name (key value) of a VNET defined in `var.vnets` that hosts a subnet this + NAT Gateway will be assigned to. +- `subnet_keys` - (`list(string)`, required) a list of subnets (key values) the NAT Gateway will be assigned to, + defined in `var.vnets` for a VNET described by `vnet_name`. +- `create_natgw` - (`bool`, optional, defaults to `true`) create (`true`) or source an existing NAT Gateway (`false`), + created or sourced: the NAT Gateway will be assigned to a subnet created by the `vnet` module. +- `resource_group_name` - (`string`, optional) name of a Resource Group hosting the NAT Gateway (newly created or the existing + one). +- `zone` - (`string`, optional) an Availability Zone in which the NAT Gateway will be placed, when skipped + Azure will pick a zone. +- `idle_timeout` - (`number`, optional, defults to 4) connection IDLE timeout in minutes, for newly created resources. +- `public_ip` - (`object`, optional) an object defining a public IP resource attached to the NAT Gateway. +- `public_ip_prefix` - (`object`, optional) an object defining a public IP prefix resource attached to the NAT Gatway. Example: ``` @@ -616,13 +613,13 @@ Type: ```hcl map(object({ - create_natgw = optional(bool, true) name = string + vnet_key = string + subnet_keys = list(string) + create_natgw = optional(bool, true) resource_group_name = optional(string) zone = optional(string) idle_timeout = optional(number, 4) - vnet_key = string - subnet_keys = list(string) public_ip = optional(object({ create = bool name = string @@ -644,7 +641,7 @@ Default value: `map[]` #### load_balancers -A map containing configuration for all (private and public) Load Balancers. +A map containing configuration for all (both private and public) Load Balancers. This is a brief description of available properties. For a detailed one please refer to [module documentation](../../modules/loadbalancer/README.md). @@ -654,26 +651,29 @@ Following properties are available: - `name` - (`string`, required) a name of the Load Balancer. - `vnet_key` - (`string`, optional, defaults to `null`) a key pointing to a VNET definition in the `var.vnets` map that stores the Subnet described by `subnet_key`. -- `zones` - (`list`, optional, defaults to module defaults) a list of zones for Load Balancer's fronted IP +- `zones` - (`list`, optional, defaults to module default) a list of zones for Load Balancer's frontend IP configurations. -- `backend_name` - (`string`, optional, defaults to module defaults) a name of the backend pool to create. -- `health_probes` - (`map`, optional, defaults to `null`) a map defining health probes that will be used by - load balancing rules; please check +- `backend_name` - (`string`, optional, defaults to module default) a name of the backend pool to create. +- `health_probes` - (`map`, optional, defaults to `null`) a map defining health probes that will be used by load + balancing rules, please refer to [module documentation](../../modules/loadbalancer/README.md#health_probes) for more specific use cases and available properties. -- `nsg_auto_rules_settings` - (`map`, optional, defaults to `null`) a map defining a location of an existing NSG rule - that will be populated with `Allow` rules for each load balancing rule (`in_rules`); please check - [module documentation](../../modules/loadbalancer/README.md#nsg_auto_rules_settings) - for available properties; please note that in this example two additional properties are - available: - - `nsg_vnet_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to a VNET definition - in the `var.vnets` map that stores the NSG described by `nsg_key`. - - `nsg_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to an NSG definition - in the `var.vnets` map. -- `frontend_ips` - (`map`, optional, defaults to `{}`) a map containing frontend IP configuration with respective - `in_rules` and `out_rules` +- `nsg_auto_rules_settings` - (`map`, optional, defaults to `null`) a map defining a location of an existing NSG rule that will + be populated with `Allow` rules for each load balancing rule (`in_rules`), please refer to + [module documentation](../../modules/loadbalancer/README.md#nsg_auto_rules_settings) for + available properties. + + Please note that in this example two additional properties are available: + + - `nsg_vnet_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to a VNET definition in the + `var.vnets` map that stores the NSG described by `nsg_key`. + - `nsg_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to an NSG definition in the + `var.vnets` map. - Please refer to [module documentation](../../modules/loadbalancer/README.md#frontend_ips) for available properties. +- `frontend_ips` - (`map`, optional, defaults to `{}`) a map containing frontend IP configuration with respective + `in_rules` and `out_rules`, please refer to + [module documentation](../../modules/loadbalancer/README.md#frontend_ips) for available + properties. **Note!** \ In this example the `subnet_id` is not available directly, another property has been introduced instead: @@ -707,10 +707,10 @@ map(object({ })) frontend_ips = optional(map(object({ name = string + subnet_key = optional(string) public_ip_name = optional(string) create_public_ip = optional(bool, false) public_ip_resource_group_name = optional(string) - subnet_key = optional(string) private_ip_address = optional(string) gwlb_key = optional(string) in_rules = optional(map(object({ @@ -739,17 +739,20 @@ Default value: `map[]` [back to list](#modules-optional-inputs) + #### availability_sets A map defining availability sets. Can be used to provide infrastructure high availability when zones cannot be used. Following properties are supported: -- `name` - name of the Application Insights. -- `update_domain_count` - specifies the number of update domains that are used, defaults to 5 (Azure defaults). -- `fault_domain_count` - specifies the number of fault domains that are used, defaults to 3 (Azure defaults). -Please keep in mind that Azure defaults are not working for each region (especially the small ones, w/o any Availability Zones). -Please verify how many update and fault domain are supported in a region before deploying this resource. +- `name` - (`string`, required) name of the Application Insights. +- `update_domain_count` - (`number`, optional, defaults to Azure default) specifies the number of update domains that are used. +- `fault_domain_count` - (`number`, optional, defaults to Azure default) specifies the number of fault domains that are used. + +**Note!** \ +Please keep in mind that Azure defaults are not working for every region (especially the small ones, without any Availability +Zones). Please verify how many update and fault domain are supported in a region before deploying this resource. Type: @@ -757,8 +760,8 @@ Type: ```hcl map(object({ name = string - update_domain_count = optional(number, 5) - fault_domain_count = optional(number, 3) + update_domain_count = optional(number) + fault_domain_count = optional(number) })) ``` @@ -774,22 +777,22 @@ A map controlling metrics-relates resources. When set to explicit `null` (default) it will disable any metrics resources in this deployment. When defined it will either create or source a Log Analytics Workspace and create Application Insights instances (one per each -Scale Set). All instances will be automatically connected to the workspace. -The name of the Application Insights instance will be derived from the Scale Set name and suffixed with `-ai`. +Scale Set). All instances will be automatically connected to the workspace. The name of the Application Insights instance will +be derived from the Scale Set name and suffixed with `-ai`. All the settings available below are common to the Log Analytics Workspace and Application Insight instances. Following properties are available: -- `name` - (`string`, required) name of the (common) Log Analytics Workspace +- `name` - (`string`, required) name of the (common) Log Analytics Workspace. - `create_workspace` - (`bool`, optional, defaults to `true`) controls whether we create or source an existing Log - Analytics Workspace + Analytics Workspace. - `resource_group_name` - (`string`, optional, defaults to `var.resource_group_name`) name of the Resource Group hosting - the Log Analytics Workspace -- `sku` - (`string`, optional, defaults to module defaults) the SKU of the Log Analytics Workspace. -- `metrics_retention_in_days` - (`number`, optional, defaults to module defaults) workspace and insights data retention in - days, possible values are between 30 and 730. For sourced Workspaces this applies only to - the Application Insights instances. + the Log Analytics Workspace. +- `sku` - (`string`, optional, defaults to module default) the SKU of the Log Analytics Workspace. +- `metrics_retention_in_days` - (`number`, optional, defaults to module default) workspace and insights data retention in days, + possible values are between 30 and 730. For sourced Workspaces this applies only to the + Application Insights instances. Type: @@ -818,43 +821,52 @@ You can create or re-use an existing Storage Account and/or File Share. For deta - `name` - (`string`, required) name of the Storage Account that will be created or sourced. - **Note** \ - For new Storage Accounts this name will not be prefixed with `var.name_prefix`. \ - Please note the limitations on naming. This has to be a globally unique name, between 3 and 63 chars, only lower-case - letters and numbers. + **Note** \ + For new Storage Accounts this name will not be prefixed with `var.name_prefix`. \ + Please note the limitations on naming. This has to be a globally unique name, between 3 and 63 chars, only lower-case letters + and numbers. -- `resource_group_name` - (`string`, optional, defaults to `null`) name of the Resource Group that hosts (sourced) or will - host (created) a Storage Account. When skipped the code will fall back to +- `resource_group_name` - (`string`, optional, defaults to `null`) name of the Resource Group that hosts (sourced) or + will host (created) a Storage Account. When skipped the code will fall back to `var.resource_group_name`. -- `storage_account` - (`map`, optional, defaults to `{}`) a map controlling basic Storage Account configuration, for - detailed documentation see - [module's documentation](../../modules/bootstrap/README.md#storage_account). The property you - should pay attention to is: - - `create` - (`bool`, optional, defaults to module defaults) controls if the Storage Account specified in - the `name` property will be created or sourced. +- `storage_account` - (`map`, optional, defaults to `{}`) a map controlling basic Storage Account configuration. + + The property you should pay attention to is: + + - `create` - (`bool`, optional, defaults to module default) controls if the Storage Account specified in the `name` property + will be created or sourced. + + For detailed documentation see [module's documentation](../../modules/bootstrap/README.md#storage_account). + - `storage_network_security` - (`map`, optional, defaults to `{}`) a map defining network security settings for a **new** - storage account, for details see - [module's documentation](../../modules/bootstrap/README.md#storage_network_security). Properties - worth mentioning are: - - `allowed_subnet_keys` - (`list`, optional, defaults to `[]`) a list of keys pointing to Subnet definitions in the - `var.vnets` map. These Subnets will have dedicated access to the Storage Account. For this to - work they also need to have the Storage Account Service Endpoint enabled. - - `vnet_key` - a key pointing to a VNET definition in the `var.vnets` map that stores the Subnets described - in `allowed_subnet_keys`. -- `file_shares_configuration` - (`map`, optional, defaults to `{}`) a map defining common File Share setting. For detailed - documentation see - [module's documentation](../../modules/bootstrap/README.md#file_shares_configuration). The - properties you should pay your attention to are: - - `create_file_shares` - (`bool`, optional, defaults to module defaults) controls if the File Shares defined in the + storage account. + + The properties you should pay attention to are: + + - `allowed_subnet_keys` - (`list`, optional, defaults to `[]`) a list of keys pointing to Subnet definitions in the + `var.vnets` map. These Subnets will have dedicated access to the Storage Account. For this to work + they also need to have the Storage Account Service Endpoint enabled. + - `vnet_key` - (`string`, optional) a key pointing to a VNET definition in the `var.vnets` map that stores the + Subnets described in `allowed_subnet_keys`. + + For detailed documentation see [module's documentation](../../modules/bootstrap/README.md#storage_network_security). + +- `file_shares_configuration` - (`map`, optional, defaults to `{}`) a map defining common File Share setting. + + The properties you should pay attention to are: + + - `create_file_shares` - (`bool`, optional, defaults to module default) controls if the File Shares defined in the `file_shares` property will be created or sourced. - - `disable_package_dirs_creation` - (`bool`, optional, defaults to module defaults) for sourced File Shares, controls if the + - `disable_package_dirs_creation` - (`bool`, optional, defaults to module default) for sourced File Shares, controls if the bootstrap package folder structure will be created. + + For detailed documentation see [module's documentation](../../modules/bootstrap/README.md#file_shares_configuration). + - `file_shares` - (`map`, optional, defaults to `{}`) a map that holds File Shares and bootstrap package configuration. For detailed description see [module's documentation](../../modules/bootstrap/README.md#file_shares). - Type: ```hcl @@ -897,129 +909,121 @@ Default value: `map[]` #### vmseries -A map defining Azure Virtual Machines based on Palo Alto Networks Next Generation Firewall image.. +A map defining Azure Virtual Machines based on Palo Alto Networks Next Generation Firewall image. For details and defaults for available options please refer to the [`vmseries`](../../modules/vmseries/README.md) module. The most basic properties are as follows: - `name` - (`string`, required) name of the VM, will be prefixed with the value of `var.name_prefix`. +- `vnet_key` - (`string`, required) a key of a VNET defined in `var.vnets`. This is the VNET that hosts subnets used to + deploy network interfaces for deployed VM. - `authentication` - (`map`, optional, defaults to example defaults) authentication settings for the deployed VM. - The `authentication` property is optional and holds the firewall admin access details. By default, standard username - `panadmin` will be set and a random password will be auto-generated for you (available in Terraform outputs). + The `authentication` property is optional and holds the firewall admin access details. By default, standard username + `panadmin` will be set and a random password will be auto-generated for you (available in Terraform outputs). - **Note!** \ - The `disable_password_authentication` property is by default `false` in this example. When using this value, you don't have - to specify anything but you can still additionally pass SSH keys for authentication. You can however set this property to - `true`, then you have to specify `ssh_keys` property. - - For all properties and their default values see [module's documentation](../../modules/vmseries/README.md#authentication). - -- `image` - (`map`, required) properties defining a base image used by the deployed VM. - - The `image` property is required but there are only 2 properties (mutually exclusive) that have to be set, either: - - - `version` - (`string`) describes the PAN-OS image version from Azure Marketplace. - - `custom_id` - (`string`) absolute ID of your own custom PAN-OS image. - - For details on the other properties refer to [module's documentation](../../modules/vmseries/README.md#image). - -- `virtual_machine` - (`map`, optional, defaults to module defaults) a map that groups most common VM configuration options. - - The most often used option are as follows: - - - `size` - (`string`, optional, defaults to module defaults) Azure VM size (type). Consult the *VM-Series Deployment - Guide* as only a few selected sizes are supported. - - `zone` - (`string`, optional, defaults to module defaults) the Availability Zone in which the VM and (if deployed) - public IP addresses will be created. - - `disk_type` - (`string`, optional, defaults to module defaults) type of a Managed Disk which should be created, possible - values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected `size` values). - - `bootstrap_options` - (`string`, optional, mutually exclusive with `bootstrap_package`) bootstrap options passed to PAN-OS - when launched for the 1st time, for details see module documentation. - - `bootstrap_package` - (`map`, optional, mutually exclusive with `bootstrap_options`) a map defining content of the - bootstrap package. - - **Note!** \ - At least one of `static_files`, `bootstrap_xml_template` or `bootstrap_package_path` is required. You can use a - combination of all 3. The `bootstrap_package_path` is the less important. For details on this mechanism and for details - on the other properties see the [`bootstrap` module documentation](../../modules/bootstrap/README.md). - - Following properties are available: - - - `bootstrap_storage_key` - (`string`, required) a key of a bootstrap storage defined in `var.bootstrap_storages` that - will host bootstrap packages. Each package will be hosted on a separate File Share. - The File Shares will be created automatically, one for each firewall. - - `static_files` - (`map`, optional, defaults to `{}`) a map containing files that will be copied to a File - Share, see [`file_shares.bootstrap_files`](../../modules/bootstrap/README.md#file_shares) - property documentation for details. - - `bootstrap_package_path` - (`string`, optional, defaults to `null`) a path to a folder containing a full bootstrap - package. - - `bootstrap_xml_template` - (`string`, optional, defaults to `null`) a path to a `bootstrap.xml` template. If this - example is using full bootstrap method, the sample templates are in - [`templates`](./templates) folder. - - The templates are used to provide `day0` like configuration which consists of: - - - network interfaces configuration. - - one or more (depending on the architecture) Virtual Routers configurations. This config contains static routes - required for the Load Balancer (and Application Gateway, if defined) health checks to work and routes that allow - Inbound and OBEW traffic. - - *any-any* security rule. - - an outbound NAT rule that will allow the Outbound traffic to flow to the internet. - - **Note!** \ - Day0 configuration is **not meant** to be **secure**. It's here marly to help with the basic firewall setup. - - When `bootstrap_xml_template` is set, one of the following properties might be required. - - - `private_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key - pointing to a private Subnet definition in `var.vnets` (the `vnet_key` property is used to - identify a VNET). The Subnet definition is used to calculate static routes for a private - Load Balancer health checks and for Inbound traffic. - - `public_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key - pointing to a public Subnet definition in `var.vnets` (the `vnet_key` property is used to - identify a VNET). The Subnet definition is used to calculate static routes for a public - Load Balancer health checks and for Outbound traffic. - - `ai_update_interval` - (`number`, optional, defaults to `5`) Application Insights update interval, used only when - `ngfw_metrics` module is defined and used in this example. The Application Insights - Instrumentation Key will be populated automatically. - - `intranet_cidr` - (`string`, optional, defaults to `null`) a CIDR of the Intranet - combined CIDR of all - private networks. When set it will override the private Subnet CIDR for inbound traffic - static routes. - - For details on the other properties refer to [module's documentation](../../modules/panorama/README.md#virtual_machine). + **Note!** \ + The `disable_password_authentication` property is by default `false` in this example. When using this value, you don't have + to specify anything but you can still additionally pass SSH keys for authentication. You can however set this property to + `true`, then you have to specify `ssh_keys` property. -- `vnet_key` - (`string`, required) a key of a VNET defined in `var.vnets`. This is the VNET that hosts subnets used to - deploy network interfaces for deployed VM. + For all properties and their default values see [module's documentation](../../modules/vmseries/README.md#authentication). -- `interfaces` - (`list`, required) configuration of all network interfaces - - **Note!** \ - Order of the interfaces does matter - the 1st interface is the management one. +- `image` - (`map`, required) properties defining a base image used by the deployed VM. The `image` property is + required but there are only 2 properties (mutually exclusive) that have to be set, either: - For details on available properties please see [module's documentation](../../modules/panorama/README.md#interfaces). + - `version` - (`string`, optional) describes the PAN-OS image version from Azure Marketplace. + - `custom_id` - (`string`, optional) absolute ID of your own custom PAN-OS image. - The most important ones are listed below: + For details on all properties refer to [module's documentation](../../modules/vmseries/README.md#image). - - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`). - - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in - `var.vnets`. Key identifying the VNET is defined in `virtual_machine.vnet_key` property. - - `create_public_ip` - (`bool`, optional, defaults to `false`) create a Public IP for an interface. - - `load_balancer_key` - (`string`, optional, defaults to `null`) key of a Load Balancer defined in `var.loadbalancers` - variable, network interface that has this property defined will be added to the Load - Balancer's backend pool. - - `application_gateway_key` - (`string`, optional, defaults to `null`) key of an Application Gateway defined in `var.appgws` - variable, network interface that has this property defined will be added to the Application - Gateway's backend pool. +- `virtual_machine` - (`map`, optional, defaults to module default) a map that groups most common VM configuration options. + Most common properties are: + - `size` - (`string`, optional, defaults to module default) Azure VM size (type). Consult the *VM-Series + Deployment Guide* as only a few selected sizes are supported. + - `zone` - (`string`, optional, defaults to module default) the Availability Zone in which the VM and (if + deployed) public IP addresses will be created. + - `disk_type` - (`string`, optional, defaults to module default) type of a Managed Disk which should be created, + possible values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected + `size` values). + - `bootstrap_options` - (`string`, optional, mutually exclusive with `bootstrap_package`) bootstrap options passed to PAN-OS + when launched for the 1st time, for details see module documentation. + - `bootstrap_package` - (`map`, optional, mutually exclusive with `bootstrap_options`) a map defining content of the + bootstrap package. + + **Note!** \ + At least one of `static_files`, `bootstrap_xml_template` or `bootstrap_package_path` is required. You can use a combination + of all 3. The `bootstrap_package_path` is the less important. For details on this mechanism and for details on the other + properties see the [`bootstrap` module documentation](../../modules/bootstrap/README.md). + + Following properties are available: + + - `bootstrap_storage_key` - (`string`, required) a key of a bootstrap storage defined in `var.bootstrap_storages` that + will host bootstrap packages. Each package will be hosted on a separate File Share. The File + Shares will be created automatically, one for each firewall. + - `static_files` - (`map`, optional, defaults to `{}`) a map containing files that will be copied to a File + Share, see [`file_shares.bootstrap_files`](../../modules/bootstrap/README.md#file_shares) + property documentation for details. + - `bootstrap_package_path` - (`string`, optional, defaults to `null`) a path to a folder containing a full bootstrap + package. + - `bootstrap_xml_template` - (`string`, optional, defaults to `null`) a path to a `bootstrap.xml` template. If this example + is using full bootstrap method, the sample templates are in [`templates`](./templates) folder. + + The templates are used to provide `day0` like configuration which consists of: + + - network interfaces configuration. + - one or more (depending on the architecture) Virtual Routers configurations. This config contains static routes + required for the Load Balancer (and Application Gateway, if defined) health checks to work and routes that allow + Inbound and OBEW traffic. + - *any-any* security rule. + - an outbound NAT rule that will allow the Outbound traffic to flow to the Internet. + + **Note!** \ + Day0 configuration is **not meant** to be **secure**. It's here merely to help with the basic firewall setup. When + `bootstrap_xml_template` is set, one of the following properties might be required. + + - `private_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key + pointing to a private Subnet definition in `var.vnets` (the `vnet_key` property is used to + identify a VNET). The Subnet definition is used to calculate static routes for a private + Load Balancer health checks and for Inbound traffic. + - `public_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key + pointing to a public Subnet definition in `var.vnets` (the `vnet_key` property is used to + identify a VNET). The Subnet definition is used to calculate static routes for a public + Load Balancer health checks and for Outbound traffic. + - `ai_update_interval` - (`number`, optional, defaults to `5`) Application Insights update interval, used only when + `ngfw_metrics` module is defined and used in this example. The Application Insights + Instrumentation Key will be populated automatically. + - `intranet_cidr` - (`string`, optional, defaults to `null`) a CIDR of the Intranet - combined CIDR of all + private networks. When set it will override the private Subnet CIDR for inbound traffic + static routes. + + For details on all properties refer to [module's documentation](../../modules/panorama/README.md#virtual_machine). + +- `interfaces` - (`list`, required) configuration of all network interfaces. Order of the interfaces does matter - the + 1st interface is the management one. Most common properties are: + + - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`). + - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in + `var.vnets`. Key identifying the VNET is defined in `virtual_machine.vnet_key` property. + - `create_public_ip` - (`bool`, optional, defaults to `false`) create a Public IP for an interface. + - `load_balancer_key` - (`string`, optional, defaults to `null`) key of a Load Balancer defined in `var.loadbalancers` + variable, network interface that has this property defined will be added to the Load Balancer's + backend pool. + - `application_gateway_key` - (`string`, optional, defaults to `null`) key of an Application Gateway defined in `var.appgws` + variable, network interface that has this property defined will be added to the Application + Gateway's backend pool. + + For details on all properties refer to [module's documentation](../../modules/panorama/README.md#interfaces). Type: ```hcl map(object({ - name = string + name = string + vnet_key = string authentication = optional(object({ username = optional(string, "panadmin") password = optional(string) @@ -1060,7 +1064,6 @@ map(object({ identity_ids = optional(list(string)) allow_extension_operations = optional(bool) }) - vnet_key = string interfaces = list(object({ name = string subnet_key = string @@ -1079,6 +1082,4 @@ Default value: `map[]` [back to list](#modules-optional-inputs) - - \ No newline at end of file diff --git a/examples/common_vmseries/example.tfvars b/examples/common_vmseries/example.tfvars index 3dcf6c81..5bdd7084 100644 --- a/examples/common_vmseries/example.tfvars +++ b/examples/common_vmseries/example.tfvars @@ -1,4 +1,5 @@ -# --- GENERAL --- # +### GENERAL ### + location = "North Europe" resource_group_name = "transit-vnet-common" name_prefix = "example-" @@ -7,7 +8,8 @@ tags = { "CreatedWith" = "Terraform" } -# --- VNET PART --- # +### NETWORK ### + vnets = { "transit" = { name = "transit" @@ -123,8 +125,8 @@ vnets = { } } +### LOAD BALANCING ### -# --- LOAD BALANCING PART --- # load_balancers = { "public" = { name = "public-lb" @@ -168,10 +170,59 @@ load_balancers = { } } -# --- VMSERIES PART --- # +appgws = { + public = { + name = "appgw" + vnet_key = "transit" + subnet_key = "appgw" + public_ip = { + name = "appgw-pip" + } + listeners = { + "http" = { + name = "http" + port = 80 + } + } + backend_settings = { + http = { + name = "http" + port = 80 + protocol = "Http" + } + } + rewrites = { + xff = { + name = "XFF-set" + rules = { + "xff-strip-port" = { + name = "xff-strip-port" + sequence = 100 + request_headers = { + "X-Forwarded-For" = "{var_add_x_forwarded_for_proxy}" + } + } + } + } + } + rules = { + "http" = { + name = "http" + listener_key = "http" + backend_key = "http" + rewrite_key = "xff" + priority = 1 + } + } + } +} + +### VM-SERIES ### + vmseries = { "fw-1" = { - name = "firewall01" + name = "firewall01" + vnet_key = "transit" image = { version = "10.2.3" } @@ -180,7 +231,6 @@ vmseries = { zone = 1 bootstrap_options = "type=dhcp-client" } - vnet_key = "transit" interfaces = [ { name = "vm01-mgmt" @@ -233,52 +283,3 @@ vmseries = { ] } } - - -# --- APPLICATION GATEWAYs --- # -appgws = { - public = { - name = "appgw" - vnet_key = "transit" - subnet_key = "appgw" - public_ip = { - name = "appgw-pip" - } - listeners = { - "http" = { - name = "http" - port = 80 - } - } - backend_settings = { - http = { - name = "http" - port = 80 - protocol = "Http" - } - } - rewrites = { - xff = { - name = "XFF-set" - rules = { - "xff-strip-port" = { - name = "xff-strip-port" - sequence = 100 - request_headers = { - "X-Forwarded-For" = "{var_add_x_forwarded_for_proxy}" - } - } - } - } - } - rules = { - "http" = { - name = "http" - listener_key = "http" - backend_key = "http" - rewrite_key = "xff" - priority = 1 - } - } - } -} diff --git a/examples/common_vmseries/main.tf b/examples/common_vmseries/main.tf index ecee2c8d..29fd01d5 100644 --- a/examples/common_vmseries/main.tf +++ b/examples/common_vmseries/main.tf @@ -1,4 +1,5 @@ -# Generate a random password. +### Generate a random password ### + # https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password resource "random_password" "this" { count = anytrue([ @@ -26,7 +27,8 @@ locals { } } -# Create or source the Resource Group. +### Create or source a Resource Group ### + # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group resource "azurerm_resource_group" "this" { count = var.create_resource_group ? 1 : 0 @@ -46,7 +48,8 @@ locals { resource_group = var.create_resource_group ? azurerm_resource_group.this[0] : data.azurerm_resource_group.this[0] } -# Manage the network required for the topology. +### Manage the network required for the topology ### + module "vnet" { source = "../../modules/vnet" @@ -62,15 +65,16 @@ module "vnet" { create_subnets = each.value.create_subnets subnets = each.value.subnets - network_security_groups = { for k, v in each.value.network_security_groups : k => merge(v, { name = "${var.name_prefix}${v.name}" }) + network_security_groups = { + for k, v in each.value.network_security_groups : k => merge(v, { name = "${var.name_prefix}${v.name}" }) } - route_tables = { for k, v in each.value.route_tables : k => merge(v, { name = "${var.name_prefix}${v.name}" }) + route_tables = { + for k, v in each.value.route_tables : k => merge(v, { name = "${var.name_prefix}${v.name}" }) } tags = var.tags } - module "natgw" { source = "../../modules/natgw" @@ -84,15 +88,19 @@ module "natgw" { idle_timeout = each.value.idle_timeout subnet_ids = { for v in each.value.subnet_keys : v => module.vnet[each.value.vnet_key].subnet_ids[v] } - public_ip = try(merge(each.value.public_ip, { name = "${each.value.public_ip.create ? var.name_prefix : ""}${each.value.public_ip.name}" }), null) - public_ip_prefix = try(merge(each.value.public_ip_prefix, { name = "${each.value.public_ip_prefix.create ? var.name_prefix : ""}${each.value.public_ip_prefix.name}" }), null) + public_ip = try(merge(each.value.public_ip, { + name = "${each.value.public_ip.create ? var.name_prefix : ""}${each.value.public_ip.name}" + }), null) + public_ip_prefix = try(merge(each.value.public_ip_prefix, { + name = "${each.value.public_ip_prefix.create ? var.name_prefix : ""}${each.value.public_ip_prefix.name}" + }), null) tags = var.tags depends_on = [module.vnet] } +### Create Load Balancers, both internal and external ### -# create load balancers, both internal and external module "load_balancer" { source = "../../modules/loadbalancer" @@ -109,7 +117,8 @@ module "load_balancer" { nsg_auto_rules_settings = try( { nsg_name = try( - "${var.name_prefix}${var.vnets[each.value.nsg_auto_rules_settings.nsg_vnet_key].network_security_groups[each.value.nsg_auto_rules_settings.nsg_key].name}", + "${var.name_prefix}${var.vnets[each.value.nsg_auto_rules_settings.nsg_vnet_key].network_security_groups[ + each.value.nsg_auto_rules_settings.nsg_key].name}", each.value.nsg_auto_rules_settings.nsg_name ) nsg_resource_group_name = try( @@ -137,9 +146,65 @@ module "load_balancer" { depends_on = [module.vnet] } +### Create Application Gateways ### + +locals { + nics_with_appgw_key = flatten([ + for k, v in var.vmseries : [ + for nic in v.interfaces : { + vm_key = k + nic_name = nic.name + appgw_key = nic.application_gateway_key + } if nic.application_gateway_key != null + ]]) + + ips_4_nics_with_appgw_key = { + for v in local.nics_with_appgw_key : + v.appgw_key => module.vmseries[v.vm_key].interfaces["${var.name_prefix}${v.nic_name}"].private_ip_address... + } +} + +module "appgw" { + source = "../../modules/appgw" + + for_each = var.appgws + + name = "${var.name_prefix}${each.value.name}" + resource_group_name = local.resource_group.name + location = var.location + subnet_id = module.vnet[each.value.vnet_key].subnet_ids[each.value.subnet_key] + + zones = each.value.zones + public_ip = merge( + each.value.public_ip, + { name = "${each.value.public_ip.create ? var.name_prefix : ""}${each.value.public_ip.name}" } + ) + domain_name_label = each.value.domain_name_label + capacity = each.value.capacity + enable_http2 = each.value.enable_http2 + waf = each.value.waf + managed_identities = each.value.managed_identities + global_ssl_policy = each.value.global_ssl_policy + ssl_profiles = each.value.ssl_profiles + frontend_ip_configuration_name = each.value.frontend_ip_configuration_name + listeners = each.value.listeners + backend_pool = merge( + each.value.backend_pool, + length(local.ips_4_nics_with_appgw_key) == 0 ? {} : { vmseries_ips = local.ips_4_nics_with_appgw_key[each.key] } + ) + backend_settings = each.value.backend_settings + probes = each.value.probes + rewrites = each.value.rewrites + redirects = each.value.redirects + url_path_maps = each.value.url_path_maps + rules = each.value.rules + + tags = var.tags + depends_on = [module.vnet, module.vmseries] +} +### Create VM-Series VMs and closely associated resources ### -# create the actual VM-Series VMs and resources module "ngfw_metrics" { source = "../../modules/ngfw_metrics" @@ -147,9 +212,11 @@ module "ngfw_metrics" { create_workspace = var.ngfw_metrics.create_workspace - name = "${var.ngfw_metrics.create_workspace ? var.name_prefix : ""}${var.ngfw_metrics.name}" - resource_group_name = var.ngfw_metrics.create_workspace ? local.resource_group.name : coalesce(var.ngfw_metrics.resource_group_name, local.resource_group.name) - location = var.location + name = "${var.ngfw_metrics.create_workspace ? var.name_prefix : ""}${var.ngfw_metrics.name}" + resource_group_name = var.ngfw_metrics.create_workspace ? local.resource_group.name : ( + coalesce(var.ngfw_metrics.resource_group_name, local.resource_group.name) + ) + location = var.location log_analytics_workspace = { sku = var.ngfw_metrics.sku @@ -161,6 +228,7 @@ module "ngfw_metrics" { tags = var.tags } +# https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file resource "local_file" "bootstrap_xml" { for_each = { for k, v in var.vmseries : @@ -287,8 +355,10 @@ module "vmseries" { coalesce( each.value.virtual_machine.bootstrap_options, join(",", [ - "storage-account=${module.bootstrap[each.value.virtual_machine.bootstrap_package.bootstrap_storage_key].storage_account_name}", - "access-key=${module.bootstrap[each.value.virtual_machine.bootstrap_package.bootstrap_storage_key].storage_account_primary_access_key}", + "storage-account=${module.bootstrap[ + each.value.virtual_machine.bootstrap_package.bootstrap_storage_key].storage_account_name}", + "access-key=${module.bootstrap[ + each.value.virtual_machine.bootstrap_package.bootstrap_storage_key].storage_account_primary_access_key}", "file-share=${each.key}", "share-directory=None" ]), @@ -299,10 +369,12 @@ module "vmseries" { ) interfaces = [for v in each.value.interfaces : { - name = "${var.name_prefix}${v.name}" - subnet_id = module.vnet[each.value.vnet_key].subnet_ids[v.subnet_key] - create_public_ip = v.create_public_ip - public_ip_name = v.create_public_ip ? "${var.name_prefix}${coalesce(v.public_ip_name, "${v.name}-pip")}" : v.public_ip_name + name = "${var.name_prefix}${v.name}" + subnet_id = module.vnet[each.value.vnet_key].subnet_ids[v.subnet_key] + create_public_ip = v.create_public_ip + public_ip_name = v.create_public_ip ? "${ + var.name_prefix}${coalesce(v.public_ip_name, "${v.name}-pip") + }" : v.public_ip_name public_ip_resource_group_name = v.public_ip_resource_group_name private_ip_address = v.private_ip_address attach_to_lb_backend_pool = v.load_balancer_key != null @@ -318,60 +390,3 @@ module "vmseries" { module.bootstrap, ] } - -# Create Application Gateway - -locals { - nics_with_appgw_key = flatten([ - for k, v in var.vmseries : [ - for nic in v.interfaces : { - vm_key = k - nic_name = nic.name - appgw_key = nic.application_gateway_key - } if nic.application_gateway_key != null - ]]) - - ips_4_nics_with_appgw_key = { - for v in local.nics_with_appgw_key : - v.appgw_key => module.vmseries[v.vm_key].interfaces["${var.name_prefix}${v.nic_name}"].private_ip_address... - } -} - -module "appgw" { - source = "../../modules/appgw" - - for_each = var.appgws - - name = "${var.name_prefix}${each.value.name}" - resource_group_name = local.resource_group.name - location = var.location - subnet_id = module.vnet[each.value.vnet_key].subnet_ids[each.value.subnet_key] - - zones = each.value.zones - public_ip = merge( - each.value.public_ip, - { name = "${each.value.public_ip.create ? var.name_prefix : ""}${each.value.public_ip.name}" } - ) - domain_name_label = each.value.domain_name_label - capacity = each.value.capacity - enable_http2 = each.value.enable_http2 - waf = each.value.waf - managed_identities = each.value.managed_identities - global_ssl_policy = each.value.global_ssl_policy - ssl_profiles = each.value.ssl_profiles - frontend_ip_configuration_name = each.value.frontend_ip_configuration_name - listeners = each.value.listeners - backend_pool = merge( - each.value.backend_pool, - length(local.ips_4_nics_with_appgw_key) == 0 ? {} : { vmseries_ips = local.ips_4_nics_with_appgw_key[each.key] } - ) - backend_settings = each.value.backend_settings - probes = each.value.probes - rewrites = each.value.rewrites - redirects = each.value.redirects - url_path_maps = each.value.url_path_maps - rules = each.value.rules - - tags = var.tags - depends_on = [module.vnet, module.vmseries] -} diff --git a/examples/common_vmseries/variables.tf b/examples/common_vmseries/variables.tf index 9057e006..8a26966e 100644 --- a/examples/common_vmseries/variables.tf +++ b/examples/common_vmseries/variables.tf @@ -1,14 +1,4 @@ -### GENERAL -variable "tags" { - description = "Map of tags to assign to the created resources." - default = {} - type = map(string) -} - -variable "location" { - description = "The Azure region to use." - type = string -} +### GENERAL ### variable "name_prefix" { description = <<-EOF @@ -45,33 +35,41 @@ variable "resource_group_name" { type = string } +variable "location" { + description = "The Azure region to use." + type = string +} + +variable "tags" { + description = "Map of tags to assign to the created resources." + default = {} + type = map(string) +} +### NETWORK ### -### VNET variable "vnets" { description = <<-EOF A map defining VNETs. For detailed documentation on each property refer to [module documentation](../../modules/vnet/README.md) - - `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, - `false` will source an existing VNET. - - `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be - a full resource name, including prefixes. - - `address_space` - (`list(string)`, required when `create_virtual_network = false`) a list of CIDRs for a newly - created VNET - - `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which - the VNET will reside or is sourced from + - `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, `false` will source + an existing VNET. + - `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be a + full resource name, including prefixes. + - `address_space` - (`list`, required when `create_virtual_network = false`) a list of CIDRs for a newly created VNET. + - `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which the + VNET will reside or is sourced from. - `create_subnets` - (`bool`, optional, defaults to `true`) if `true`, create Subnets inside the Virtual Network, - otherwise use source existing subnets + otherwise use source existing subnets. - `subnets` - (`map`, optional) map of Subnets to create or source, for details see - [VNET module documentation](../../modules/vnet/README.md#subnets) + [VNET module documentation](../../modules/vnet/README.md#subnets). - `network_security_groups` - (`map`, optional) map of Network Security Groups to create, for details see - [VNET module documentation](../../modules/vnet/README.md#network_security_groups) + [VNET module documentation](../../modules/vnet/README.md#network_security_groups). - `route_tables` - (`map`, optional) map of Route Tables to create, for details see - [VNET module documentation](../../modules/vnet/README.md#route_tables) + [VNET module documentation](../../modules/vnet/README.md#route_tables). EOF - type = map(object({ name = string resource_group_name = optional(string) @@ -125,21 +123,21 @@ variable "natgws" { For detailed documentation on each property refer to [module documentation](../../modules/natgw/README.md). Following properties are supported: - - `create_natgw` - (`bool`, optional, defaults to `true`) create (`true`) or source an existing NAT Gateway (`false`), - created or sourced: the NAT Gateway will be assigned to a subnet created by the `vnet` module. - - `name` - (`string`, required) a name of a NAT Gateway. In case `create_natgw = false` this should be a full - resource name, including prefixes. - - `resource_group_name - (`string`, optional) name of a Resource Group hosting the NAT Gateway (newly created or the existing - one). - - `zone` - (`string`, optional) an Availability Zone in which the NAT Gateway will be placed, when skipped - AzureRM will pick a zone. - - `idle_timeout` - (`number`, optional, defults to 4) connection IDLE timeout in minutes, for newly created resources. - - `vnet_key` - (`string`, required) a name (key value) of a VNET defined in `var.vnets` that hosts a subnet this - NAT Gateway will be assigned to. - - `subnet_keys` - (`list(string)`, required) a list of subnets (key values) the NAT Gateway will be assigned to, defined - in `var.vnets` for a VNET described by `vnet_name`. - - `public_ip` - (`object`, optional) an object defining a public IP resource attached to the NAT Gateway. - - `public_ip_prefix` - (`object`, optional) an object defining a public IP prefix resource attached to the NAT Gatway. + - `name` - (`string`, required) a name of a NAT Gateway. In case `create_natgw = false` this should be a full + resource name, including prefixes. + - `vnet_key` - (`string`, required) a name (key value) of a VNET defined in `var.vnets` that hosts a subnet this + NAT Gateway will be assigned to. + - `subnet_keys` - (`list(string)`, required) a list of subnets (key values) the NAT Gateway will be assigned to, + defined in `var.vnets` for a VNET described by `vnet_name`. + - `create_natgw` - (`bool`, optional, defaults to `true`) create (`true`) or source an existing NAT Gateway (`false`), + created or sourced: the NAT Gateway will be assigned to a subnet created by the `vnet` module. + - `resource_group_name` - (`string`, optional) name of a Resource Group hosting the NAT Gateway (newly created or the existing + one). + - `zone` - (`string`, optional) an Availability Zone in which the NAT Gateway will be placed, when skipped + Azure will pick a zone. + - `idle_timeout` - (`number`, optional, defults to 4) connection IDLE timeout in minutes, for newly created resources. + - `public_ip` - (`object`, optional) an object defining a public IP resource attached to the NAT Gateway. + - `public_ip_prefix` - (`object`, optional) an object defining a public IP prefix resource attached to the NAT Gatway. Example: ``` @@ -158,13 +156,13 @@ variable "natgws" { EOF default = {} type = map(object({ - create_natgw = optional(bool, true) name = string + vnet_key = string + subnet_keys = list(string) + create_natgw = optional(bool, true) resource_group_name = optional(string) zone = optional(string) idle_timeout = optional(number, 4) - vnet_key = string - subnet_keys = list(string) public_ip = optional(object({ create = bool name = string @@ -179,12 +177,11 @@ variable "natgws" { })) } +### LOAD BALANCING ### - -### Load Balancing variable "load_balancers" { description = <<-EOF - A map containing configuration for all (private and public) Load Balancers. + A map containing configuration for all (both private and public) Load Balancers. This is a brief description of available properties. For a detailed one please refer to [module documentation](../../modules/loadbalancer/README.md). @@ -194,26 +191,29 @@ variable "load_balancers" { - `name` - (`string`, required) a name of the Load Balancer. - `vnet_key` - (`string`, optional, defaults to `null`) a key pointing to a VNET definition in the `var.vnets` map that stores the Subnet described by `subnet_key`. - - `zones` - (`list`, optional, defaults to module defaults) a list of zones for Load Balancer's fronted IP + - `zones` - (`list`, optional, defaults to module default) a list of zones for Load Balancer's frontend IP configurations. - - `backend_name` - (`string`, optional, defaults to module defaults) a name of the backend pool to create. - - `health_probes` - (`map`, optional, defaults to `null`) a map defining health probes that will be used by - load balancing rules; please check + - `backend_name` - (`string`, optional, defaults to module default) a name of the backend pool to create. + - `health_probes` - (`map`, optional, defaults to `null`) a map defining health probes that will be used by load + balancing rules, please refer to [module documentation](../../modules/loadbalancer/README.md#health_probes) for more specific use cases and available properties. - - `nsg_auto_rules_settings` - (`map`, optional, defaults to `null`) a map defining a location of an existing NSG rule - that will be populated with `Allow` rules for each load balancing rule (`in_rules`); please check - [module documentation](../../modules/loadbalancer/README.md#nsg_auto_rules_settings) - for available properties; please note that in this example two additional properties are - available: - - `nsg_vnet_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to a VNET definition - in the `var.vnets` map that stores the NSG described by `nsg_key`. - - `nsg_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to an NSG definition - in the `var.vnets` map. - - `frontend_ips` - (`map`, optional, defaults to `{}`) a map containing frontend IP configuration with respective - `in_rules` and `out_rules` + - `nsg_auto_rules_settings` - (`map`, optional, defaults to `null`) a map defining a location of an existing NSG rule that will + be populated with `Allow` rules for each load balancing rule (`in_rules`), please refer to + [module documentation](../../modules/loadbalancer/README.md#nsg_auto_rules_settings) for + available properties. + + Please note that in this example two additional properties are available: + + - `nsg_vnet_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to a VNET definition in the + `var.vnets` map that stores the NSG described by `nsg_key`. + - `nsg_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to an NSG definition in the + `var.vnets` map. - Please refer to [module documentation](../../modules/loadbalancer/README.md#frontend_ips) for available properties. + - `frontend_ips` - (`map`, optional, defaults to `{}`) a map containing frontend IP configuration with respective + `in_rules` and `out_rules`, please refer to + [module documentation](../../modules/loadbalancer/README.md#frontend_ips) for available + properties. **Note!** \ In this example the `subnet_id` is not available directly, another property has been introduced instead: @@ -245,10 +245,10 @@ variable "load_balancers" { })) frontend_ips = optional(map(object({ name = string + subnet_key = optional(string) public_ip_name = optional(string) create_public_ip = optional(bool, false) public_ip_resource_group_name = optional(string) - subnet_key = optional(string) private_ip_address = optional(string) gwlb_key = optional(string) in_rules = optional(map(object({ @@ -272,29 +272,195 @@ variable "load_balancers" { })) } +variable "appgws" { + description = <<-EOF + A map defining all Application Gateways in the current deployment. + + For detailed documentation on how to configure this resource, for available properties, especially for the defaults, + refer to [module documentation](../../modules/appgw/README.md). + + **Note!** \ + The `rules` property is meant to bind together `backend_setting`, `redirect` or `url_path_map` (all 3 are mutually exclusive). + It represents the Rules section of an Application Gateway in Azure Portal. + + Below you can find a brief list of most important properties: + + - `name` - (`string`, required) the name of the Application Gateway, will be prefixed with `var.name_prefix`. + - `vnet_key` - (`string`, required) a key pointing to a VNET definition in the `var.vnets` map that stores the Subnet + described by `subnet_key`. + - `subnet_key` - (`string`, required) a key pointing to a Subnet definition in the `var.vnets` map, this has to be an + Application Gateway V2 dedicated subnet. + - `zones` - (`list`, optional, defaults to module default) parameter controlling if this is a zonal, or a non-zonal + deployment. + - `public_ip` - (`map`, required) defines a Public IP resource used by the Application Gateway instance, a newly created + Public IP will have it's name prefixes with `var.name_prefix`. + - `listeners` - (`map`, required) defines Application Gateway's Listeners, see + [module's documentation](../../modules/appgw/README.md#listeners) for details. + - `backend_pool` - (`map`, optional, defaults to module default) backend pool definition, when skipped an empty backend + will be created. + - `backend_settings` - (`map`, optional, mutually exclusive with `redirects` and `url_path_maps`) defines HTTP backend + settings, see [module's documentation](../../modules/appgw/README.md#backend_settings) for details. + - `probes` - (`map`, optional, defaults to module default) defines backend probes used check health of backends, see + [module's documentation](../../modules/appgw/README.md#probes) for details. + - `rewrites` - (`map`, optional, defaults to module default) defines rewrite rules, see + [module's documentation](../../modules/appgw/README.md#rewrites) for details. + - `redirects` - (`map`, optional, mutually exclusive with `backend_settings` and `url_path_maps`) static redirects + definition, see [module's documentation](../../modules/appgw/README.md#redirects) for details. + - `url_path_maps` - (`map`, optional, mutually exclusive with `backend_settings` and `redirects`) URL path maps definition, + see [module's documentation](../../modules/appgw/README.md#url_path_maps) for details. + - `rules` - (`map`, required) Application Gateway Rules definition, bind together a `listener` with either + `backend_setting`, `redirect` or `url_path_map`, see + [module's documentation](../../modules/appgw/README.md#rules) for details. + EOF + type = map(object({ + name = string + vnet_key = string + subnet_key = string + zones = optional(list(string)) + public_ip = object({ + name = string + create = optional(bool, true) + resource_group_name = optional(string) + }) + domain_name_label = optional(string) + capacity = optional(object({ + static = optional(number) + autoscale = optional(object({ + min = number + max = number + })) + })) + enable_http2 = optional(bool) + waf = optional(object({ + prevention_mode = bool + rule_set_type = optional(string) + rule_set_version = optional(string) + })) + managed_identities = optional(list(string)) + global_ssl_policy = optional(object({ + type = optional(string) + name = optional(string) + min_protocol_version = optional(string) + cipher_suites = optional(list(string)) + })) + ssl_profiles = optional(map(object({ + name = string + ssl_policy_name = optional(string) + ssl_policy_min_protocol_version = optional(string) + ssl_policy_cipher_suites = optional(list(string)) + }))) + frontend_ip_configuration_name = optional(string) + listeners = map(object({ + name = string + port = number + protocol = optional(string) + host_names = optional(list(string)) + ssl_profile_name = optional(string) + ssl_certificate_path = optional(string) + ssl_certificate_pass = optional(string) + ssl_certificate_vault_id = optional(string) + custom_error_pages = optional(map(string)) + })) + backend_pool = optional(object({ + name = optional(string) + vmseries_ips = optional(list(string)) + })) + backend_settings = optional(map(object({ + name = string + port = number + protocol = string + path = optional(string) + hostname_from_backend = optional(string) + hostname = optional(string) + timeout = optional(number) + use_cookie_based_affinity = optional(bool) + affinity_cookie_name = optional(string) + probe = optional(string) + root_certs = optional(map(object({ + name = string + path = string + }))) + }))) + probes = optional(map(object({ + name = string + path = string + host = optional(string) + port = optional(number) + protocol = optional(string) + interval = optional(number) + timeout = optional(number) + threshold = optional(number) + match_code = optional(list(number)) + match_body = optional(string) + }))) + rewrites = optional(map(object({ + name = optional(string) + rules = optional(map(object({ + name = string + sequence = number + conditions = optional(map(object({ + pattern = string + ignore_case = optional(bool) + negate = optional(bool) + }))) + request_headers = optional(map(string)) + response_headers = optional(map(string)) + }))) + }))) + redirects = optional(map(object({ + name = string + type = string + target_listener_key = optional(string) + target_url = optional(string) + include_path = optional(bool) + include_query_string = optional(bool) + }))) + url_path_maps = optional(map(object({ + name = string + backend_key = string + path_rules = optional(map(object({ + paths = list(string) + backend_key = optional(string) + redirect_key = optional(string) + }))) + }))) + rules = map(object({ + name = string + priority = number + backend_key = optional(string) + listener_key = string + rewrite_key = optional(string) + url_path_map_key = optional(string) + redirect_key = optional(string) + })) + })) +} + +### VM-SERIES ### variable "availability_sets" { description = <<-EOF A map defining availability sets. Can be used to provide infrastructure high availability when zones cannot be used. Following properties are supported: - - `name` - name of the Application Insights. - - `update_domain_count` - specifies the number of update domains that are used, defaults to 5 (Azure defaults). - - `fault_domain_count` - specifies the number of fault domains that are used, defaults to 3 (Azure defaults). - Please keep in mind that Azure defaults are not working for each region (especially the small ones, w/o any Availability Zones). - Please verify how many update and fault domain are supported in a region before deploying this resource. + - `name` - (`string`, required) name of the Application Insights. + - `update_domain_count` - (`number`, optional, defaults to Azure default) specifies the number of update domains that are used. + - `fault_domain_count` - (`number`, optional, defaults to Azure default) specifies the number of fault domains that are used. + + **Note!** \ + Please keep in mind that Azure defaults are not working for every region (especially the small ones, without any Availability + Zones). Please verify how many update and fault domain are supported in a region before deploying this resource. EOF default = {} nullable = false type = map(object({ name = string - update_domain_count = optional(number, 5) - fault_domain_count = optional(number, 3) + update_domain_count = optional(number) + fault_domain_count = optional(number) })) } - variable "ngfw_metrics" { description = <<-EOF A map controlling metrics-relates resources. @@ -302,22 +468,22 @@ variable "ngfw_metrics" { When set to explicit `null` (default) it will disable any metrics resources in this deployment. When defined it will either create or source a Log Analytics Workspace and create Application Insights instances (one per each - Scale Set). All instances will be automatically connected to the workspace. - The name of the Application Insights instance will be derived from the Scale Set name and suffixed with `-ai`. + Scale Set). All instances will be automatically connected to the workspace. The name of the Application Insights instance will + be derived from the Scale Set name and suffixed with `-ai`. All the settings available below are common to the Log Analytics Workspace and Application Insight instances. Following properties are available: - - `name` - (`string`, required) name of the (common) Log Analytics Workspace + - `name` - (`string`, required) name of the (common) Log Analytics Workspace. - `create_workspace` - (`bool`, optional, defaults to `true`) controls whether we create or source an existing Log - Analytics Workspace + Analytics Workspace. - `resource_group_name` - (`string`, optional, defaults to `var.resource_group_name`) name of the Resource Group hosting - the Log Analytics Workspace - - `sku` - (`string`, optional, defaults to module defaults) the SKU of the Log Analytics Workspace. - - `metrics_retention_in_days` - (`number`, optional, defaults to module defaults) workspace and insights data retention in - days, possible values are between 30 and 730. For sourced Workspaces this applies only to - the Application Insights instances. + the Log Analytics Workspace. + - `sku` - (`string`, optional, defaults to module default) the SKU of the Log Analytics Workspace. + - `metrics_retention_in_days` - (`number`, optional, defaults to module default) workspace and insights data retention in days, + possible values are between 30 and 730. For sourced Workspaces this applies only to the + Application Insights instances. EOF default = null type = object({ @@ -338,41 +504,50 @@ variable "bootstrap_storages" { - `name` - (`string`, required) name of the Storage Account that will be created or sourced. - **Note** \ - For new Storage Accounts this name will not be prefixed with `var.name_prefix`. \ - Please note the limitations on naming. This has to be a globally unique name, between 3 and 63 chars, only lower-case - letters and numbers. + **Note** \ + For new Storage Accounts this name will not be prefixed with `var.name_prefix`. \ + Please note the limitations on naming. This has to be a globally unique name, between 3 and 63 chars, only lower-case letters + and numbers. - - `resource_group_name` - (`string`, optional, defaults to `null`) name of the Resource Group that hosts (sourced) or will - host (created) a Storage Account. When skipped the code will fall back to + - `resource_group_name` - (`string`, optional, defaults to `null`) name of the Resource Group that hosts (sourced) or + will host (created) a Storage Account. When skipped the code will fall back to `var.resource_group_name`. - - `storage_account` - (`map`, optional, defaults to `{}`) a map controlling basic Storage Account configuration, for - detailed documentation see - [module's documentation](../../modules/bootstrap/README.md#storage_account). The property you - should pay attention to is: - - `create` - (`bool`, optional, defaults to module defaults) controls if the Storage Account specified in - the `name` property will be created or sourced. + - `storage_account` - (`map`, optional, defaults to `{}`) a map controlling basic Storage Account configuration. + + The property you should pay attention to is: + + - `create` - (`bool`, optional, defaults to module default) controls if the Storage Account specified in the `name` property + will be created or sourced. + + For detailed documentation see [module's documentation](../../modules/bootstrap/README.md#storage_account). + - `storage_network_security` - (`map`, optional, defaults to `{}`) a map defining network security settings for a **new** - storage account, for details see - [module's documentation](../../modules/bootstrap/README.md#storage_network_security). Properties - worth mentioning are: - - `allowed_subnet_keys` - (`list`, optional, defaults to `[]`) a list of keys pointing to Subnet definitions in the - `var.vnets` map. These Subnets will have dedicated access to the Storage Account. For this to - work they also need to have the Storage Account Service Endpoint enabled. - - `vnet_key` - a key pointing to a VNET definition in the `var.vnets` map that stores the Subnets described - in `allowed_subnet_keys`. - - `file_shares_configuration` - (`map`, optional, defaults to `{}`) a map defining common File Share setting. For detailed - documentation see - [module's documentation](../../modules/bootstrap/README.md#file_shares_configuration). The - properties you should pay your attention to are: - - `create_file_shares` - (`bool`, optional, defaults to module defaults) controls if the File Shares defined in the + storage account. + + The properties you should pay attention to are: + + - `allowed_subnet_keys` - (`list`, optional, defaults to `[]`) a list of keys pointing to Subnet definitions in the + `var.vnets` map. These Subnets will have dedicated access to the Storage Account. For this to work + they also need to have the Storage Account Service Endpoint enabled. + - `vnet_key` - (`string`, optional) a key pointing to a VNET definition in the `var.vnets` map that stores the + Subnets described in `allowed_subnet_keys`. + + For detailed documentation see [module's documentation](../../modules/bootstrap/README.md#storage_network_security). + + - `file_shares_configuration` - (`map`, optional, defaults to `{}`) a map defining common File Share setting. + + The properties you should pay attention to are: + + - `create_file_shares` - (`bool`, optional, defaults to module default) controls if the File Shares defined in the `file_shares` property will be created or sourced. - - `disable_package_dirs_creation` - (`bool`, optional, defaults to module defaults) for sourced File Shares, controls if the + - `disable_package_dirs_creation` - (`bool`, optional, defaults to module default) for sourced File Shares, controls if the bootstrap package folder structure will be created. + + For detailed documentation see [module's documentation](../../modules/bootstrap/README.md#file_shares_configuration). + - `file_shares` - (`map`, optional, defaults to `{}`) a map that holds File Shares and bootstrap package configuration. For detailed description see [module's documentation](../../modules/bootstrap/README.md#file_shares). - EOF default = {} nullable = false @@ -410,127 +585,119 @@ variable "bootstrap_storages" { variable "vmseries" { description = <<-EOF - A map defining Azure Virtual Machines based on Palo Alto Networks Next Generation Firewall image.. + A map defining Azure Virtual Machines based on Palo Alto Networks Next Generation Firewall image. For details and defaults for available options please refer to the [`vmseries`](../../modules/vmseries/README.md) module. The most basic properties are as follows: - `name` - (`string`, required) name of the VM, will be prefixed with the value of `var.name_prefix`. + - `vnet_key` - (`string`, required) a key of a VNET defined in `var.vnets`. This is the VNET that hosts subnets used to + deploy network interfaces for deployed VM. - `authentication` - (`map`, optional, defaults to example defaults) authentication settings for the deployed VM. - The `authentication` property is optional and holds the firewall admin access details. By default, standard username - `panadmin` will be set and a random password will be auto-generated for you (available in Terraform outputs). + The `authentication` property is optional and holds the firewall admin access details. By default, standard username + `panadmin` will be set and a random password will be auto-generated for you (available in Terraform outputs). - **Note!** \ - The `disable_password_authentication` property is by default `false` in this example. When using this value, you don't have - to specify anything but you can still additionally pass SSH keys for authentication. You can however set this property to - `true`, then you have to specify `ssh_keys` property. - - For all properties and their default values see [module's documentation](../../modules/vmseries/README.md#authentication). - - - `image` - (`map`, required) properties defining a base image used by the deployed VM. - - The `image` property is required but there are only 2 properties (mutually exclusive) that have to be set, either: - - - `version` - (`string`) describes the PAN-OS image version from Azure Marketplace. - - `custom_id` - (`string`) absolute ID of your own custom PAN-OS image. - - For details on the other properties refer to [module's documentation](../../modules/vmseries/README.md#image). - - - `virtual_machine` - (`map`, optional, defaults to module defaults) a map that groups most common VM configuration options. - - The most often used option are as follows: - - - `size` - (`string`, optional, defaults to module defaults) Azure VM size (type). Consult the *VM-Series Deployment - Guide* as only a few selected sizes are supported. - - `zone` - (`string`, optional, defaults to module defaults) the Availability Zone in which the VM and (if deployed) - public IP addresses will be created. - - `disk_type` - (`string`, optional, defaults to module defaults) type of a Managed Disk which should be created, possible - values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected `size` values). - - `bootstrap_options` - (`string`, optional, mutually exclusive with `bootstrap_package`) bootstrap options passed to PAN-OS - when launched for the 1st time, for details see module documentation. - - `bootstrap_package` - (`map`, optional, mutually exclusive with `bootstrap_options`) a map defining content of the - bootstrap package. - - **Note!** \ - At least one of `static_files`, `bootstrap_xml_template` or `bootstrap_package_path` is required. You can use a - combination of all 3. The `bootstrap_package_path` is the less important. For details on this mechanism and for details - on the other properties see the [`bootstrap` module documentation](../../modules/bootstrap/README.md). - - Following properties are available: - - - `bootstrap_storage_key` - (`string`, required) a key of a bootstrap storage defined in `var.bootstrap_storages` that - will host bootstrap packages. Each package will be hosted on a separate File Share. - The File Shares will be created automatically, one for each firewall. - - `static_files` - (`map`, optional, defaults to `{}`) a map containing files that will be copied to a File - Share, see [`file_shares.bootstrap_files`](../../modules/bootstrap/README.md#file_shares) - property documentation for details. - - `bootstrap_package_path` - (`string`, optional, defaults to `null`) a path to a folder containing a full bootstrap - package. - - `bootstrap_xml_template` - (`string`, optional, defaults to `null`) a path to a `bootstrap.xml` template. If this - example is using full bootstrap method, the sample templates are in - [`templates`](./templates) folder. - - The templates are used to provide `day0` like configuration which consists of: - - - network interfaces configuration. - - one or more (depending on the architecture) Virtual Routers configurations. This config contains static routes - required for the Load Balancer (and Application Gateway, if defined) health checks to work and routes that allow - Inbound and OBEW traffic. - - *any-any* security rule. - - an outbound NAT rule that will allow the Outbound traffic to flow to the internet. - - **Note!** \ - Day0 configuration is **not meant** to be **secure**. It's here marly to help with the basic firewall setup. - - When `bootstrap_xml_template` is set, one of the following properties might be required. - - - `private_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key - pointing to a private Subnet definition in `var.vnets` (the `vnet_key` property is used to - identify a VNET). The Subnet definition is used to calculate static routes for a private - Load Balancer health checks and for Inbound traffic. - - `public_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key - pointing to a public Subnet definition in `var.vnets` (the `vnet_key` property is used to - identify a VNET). The Subnet definition is used to calculate static routes for a public - Load Balancer health checks and for Outbound traffic. - - `ai_update_interval` - (`number`, optional, defaults to `5`) Application Insights update interval, used only when - `ngfw_metrics` module is defined and used in this example. The Application Insights - Instrumentation Key will be populated automatically. - - `intranet_cidr` - (`string`, optional, defaults to `null`) a CIDR of the Intranet - combined CIDR of all - private networks. When set it will override the private Subnet CIDR for inbound traffic - static routes. - - For details on the other properties refer to [module's documentation](../../modules/panorama/README.md#virtual_machine). + **Note!** \ + The `disable_password_authentication` property is by default `false` in this example. When using this value, you don't have + to specify anything but you can still additionally pass SSH keys for authentication. You can however set this property to + `true`, then you have to specify `ssh_keys` property. - - `vnet_key` - (`string`, required) a key of a VNET defined in `var.vnets`. This is the VNET that hosts subnets used to - deploy network interfaces for deployed VM. + For all properties and their default values see [module's documentation](../../modules/vmseries/README.md#authentication). - - `interfaces` - (`list`, required) configuration of all network interfaces - - **Note!** \ - Order of the interfaces does matter - the 1st interface is the management one. + - `image` - (`map`, required) properties defining a base image used by the deployed VM. The `image` property is + required but there are only 2 properties (mutually exclusive) that have to be set, either: + + - `version` - (`string`, optional) describes the PAN-OS image version from Azure Marketplace. + - `custom_id` - (`string`, optional) absolute ID of your own custom PAN-OS image. - For details on available properties please see [module's documentation](../../modules/panorama/README.md#interfaces). + For details on all properties refer to [module's documentation](../../modules/vmseries/README.md#image). - The most important ones are listed below: + - `virtual_machine` - (`map`, optional, defaults to module default) a map that groups most common VM configuration options. + Most common properties are: - - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`). - - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in - `var.vnets`. Key identifying the VNET is defined in `virtual_machine.vnet_key` property. - - `create_public_ip` - (`bool`, optional, defaults to `false`) create a Public IP for an interface. - - `load_balancer_key` - (`string`, optional, defaults to `null`) key of a Load Balancer defined in `var.loadbalancers` - variable, network interface that has this property defined will be added to the Load - Balancer's backend pool. - - `application_gateway_key` - (`string`, optional, defaults to `null`) key of an Application Gateway defined in `var.appgws` - variable, network interface that has this property defined will be added to the Application - Gateway's backend pool. + - `size` - (`string`, optional, defaults to module default) Azure VM size (type). Consult the *VM-Series + Deployment Guide* as only a few selected sizes are supported. + - `zone` - (`string`, optional, defaults to module default) the Availability Zone in which the VM and (if + deployed) public IP addresses will be created. + - `disk_type` - (`string`, optional, defaults to module default) type of a Managed Disk which should be created, + possible values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected + `size` values). + - `bootstrap_options` - (`string`, optional, mutually exclusive with `bootstrap_package`) bootstrap options passed to PAN-OS + when launched for the 1st time, for details see module documentation. + - `bootstrap_package` - (`map`, optional, mutually exclusive with `bootstrap_options`) a map defining content of the + bootstrap package. + **Note!** \ + At least one of `static_files`, `bootstrap_xml_template` or `bootstrap_package_path` is required. You can use a combination + of all 3. The `bootstrap_package_path` is the less important. For details on this mechanism and for details on the other + properties see the [`bootstrap` module documentation](../../modules/bootstrap/README.md). + + Following properties are available: + + - `bootstrap_storage_key` - (`string`, required) a key of a bootstrap storage defined in `var.bootstrap_storages` that + will host bootstrap packages. Each package will be hosted on a separate File Share. The File + Shares will be created automatically, one for each firewall. + - `static_files` - (`map`, optional, defaults to `{}`) a map containing files that will be copied to a File + Share, see [`file_shares.bootstrap_files`](../../modules/bootstrap/README.md#file_shares) + property documentation for details. + - `bootstrap_package_path` - (`string`, optional, defaults to `null`) a path to a folder containing a full bootstrap + package. + - `bootstrap_xml_template` - (`string`, optional, defaults to `null`) a path to a `bootstrap.xml` template. If this example + is using full bootstrap method, the sample templates are in [`templates`](./templates) folder. + + The templates are used to provide `day0` like configuration which consists of: + + - network interfaces configuration. + - one or more (depending on the architecture) Virtual Routers configurations. This config contains static routes + required for the Load Balancer (and Application Gateway, if defined) health checks to work and routes that allow + Inbound and OBEW traffic. + - *any-any* security rule. + - an outbound NAT rule that will allow the Outbound traffic to flow to the Internet. + + **Note!** \ + Day0 configuration is **not meant** to be **secure**. It's here merely to help with the basic firewall setup. When + `bootstrap_xml_template` is set, one of the following properties might be required. + + - `private_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key + pointing to a private Subnet definition in `var.vnets` (the `vnet_key` property is used to + identify a VNET). The Subnet definition is used to calculate static routes for a private + Load Balancer health checks and for Inbound traffic. + - `public_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key + pointing to a public Subnet definition in `var.vnets` (the `vnet_key` property is used to + identify a VNET). The Subnet definition is used to calculate static routes for a public + Load Balancer health checks and for Outbound traffic. + - `ai_update_interval` - (`number`, optional, defaults to `5`) Application Insights update interval, used only when + `ngfw_metrics` module is defined and used in this example. The Application Insights + Instrumentation Key will be populated automatically. + - `intranet_cidr` - (`string`, optional, defaults to `null`) a CIDR of the Intranet - combined CIDR of all + private networks. When set it will override the private Subnet CIDR for inbound traffic + static routes. + + For details on all properties refer to [module's documentation](../../modules/panorama/README.md#virtual_machine). + + - `interfaces` - (`list`, required) configuration of all network interfaces. Order of the interfaces does matter - the + 1st interface is the management one. Most common properties are: + + - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`). + - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in + `var.vnets`. Key identifying the VNET is defined in `virtual_machine.vnet_key` property. + - `create_public_ip` - (`bool`, optional, defaults to `false`) create a Public IP for an interface. + - `load_balancer_key` - (`string`, optional, defaults to `null`) key of a Load Balancer defined in `var.loadbalancers` + variable, network interface that has this property defined will be added to the Load Balancer's + backend pool. + - `application_gateway_key` - (`string`, optional, defaults to `null`) key of an Application Gateway defined in `var.appgws` + variable, network interface that has this property defined will be added to the Application + Gateway's backend pool. + + For details on all properties refer to [module's documentation](../../modules/panorama/README.md#interfaces). EOF default = {} nullable = false type = map(object({ - name = string + name = string + vnet_key = string authentication = optional(object({ username = optional(string, "panadmin") password = optional(string) @@ -571,7 +738,6 @@ variable "vmseries" { identity_ids = optional(list(string)) allow_extension_operations = optional(bool) }) - vnet_key = string interfaces = list(object({ name = string subnet_key = string @@ -583,185 +749,26 @@ variable "vmseries" { application_gateway_key = optional(string) })) })) - validation { + validation { # virtual_machine.bootstrap_options & virtual_machine.bootstrap_package condition = alltrue([ for _, v in var.vmseries : v.virtual_machine.bootstrap_options != null && v.virtual_machine.bootstrap_package == null || v.virtual_machine.bootstrap_options == null && v.virtual_machine.bootstrap_package != null ]) - error_message = "Either `bootstrap_options` or `bootstrap_package` property can be set." + error_message = <<-EOF + Either `bootstrap_options` or `bootstrap_package` property can be set. + EOF } - validation { + validation { # virtual_machine.bootstrap_package condition = alltrue([ for _, v in var.vmseries : - v.virtual_machine.bootstrap_package.bootstrap_xml_template != null ? v.virtual_machine.bootstrap_package.private_snet_key != null && v.virtual_machine.bootstrap_package.public_snet_key != null : true - if v.virtual_machine.bootstrap_package != null + v.virtual_machine.bootstrap_package.bootstrap_xml_template != null ? ( + v.virtual_machine.bootstrap_package.private_snet_key != null && + v.virtual_machine.bootstrap_package.public_snet_key != null + ) : true if v.virtual_machine.bootstrap_package != null ]) - error_message = "The `private_snet_key` and `public_snet_key` are required when `bootstrap_xml_template` is set." + error_message = <<-EOF + The `private_snet_key` and `public_snet_key` are required when `bootstrap_xml_template` is set. + EOF } } - -### Application Gateway -variable "appgws" { - description = <<-EOF - A map defining all Application Gateways in the current deployment. - - For detailed documentation on how to configure this resource, for available properties, especially for the defaults, - refer to [module documentation](../../modules/appgw/README.md). - - **Note!** \ - The `rules` property is meant to bind together `backend_setting`, `redirect` or `url_path_map` (all 3 are mutually exclusive). - It represents the Rules section of an Application Gateway in Azure Portal. - - Below you can find a brief list of most important properties: - - - `name` - (`string`, required) the name of the Application Gateway, will be prefixed with `var.name_prefix`. - - `vnet_key` - (`string`, required) a key pointing to a VNET definition in the `var.vnets` map that stores the Subnet - described by `subnet_key`. - - `subnet_key` - (`string`, required) a key pointing to a Subnet definition in the `var.vnets` map, this has to be an - Application Gateway V2 dedicated subnet. - - `zones` - (`list`, optional, defaults to module defaults) parameter controlling if this is a zonal, or a non-zonal - deployment. - - `public_ip` - (`map`, required) defines a Public IP resource used by the Application Gateway instance, a newly created - Public IP will have it's name prefixes with `var.name_prefix`. - - `listeners` - (`map`, required) defines Application Gateway's Listeners, see - [module's documentation](../../modules/appgw/README.md#listeners) for details. - - `backend_pool` - (`map`, optional, defaults to module defaults) backend pool definition, when skipped an empty backend - will be created. - - `backend_settings` - (`map`, optional, mutually exclusive with `redirects` and `url_path_maps`) defines HTTP backend - settings, see [module's documentation](../../modules/appgw/README.md#backend_settings) for details. - - `probes` - (`map`, optional, defaults to module defaults) defines backend probes used check health of backends, see - [module's documentation](../../modules/appgw/README.md#probes) for details. - - `rewrites` - (`map`, optional, defaults to module defaults) defines rewrite rules, see - [module's documentation](../../modules/appgw/README.md#rewrites) for details. - - `redirects - (`map`, optional, mutually exclusive with `backend_settings` and `url_path_maps`) static redirects - definition, see [module's documentation](../../modules/appgw/README.md#redirects) for details. - - `url_path_maps - (`map`, optional, mutually exclusive with `backend_settings` and `redirects`) URL path maps definition, - see [module's documentation](../../modules/appgw/README.md#url_path_maps) for details. - - `rules - (`map`, required) Application Gateway Rules definition, bind together a `listener` with either - `backend_setting`, `redirect` or `url_path_map`, see - [module's documentation](../../modules/appgw/README.md#rules) for details. - EOF - type = map(object({ - name = string - vnet_key = string - subnet_key = string - zones = optional(list(string)) - public_ip = object({ - name = string - create = optional(bool, true) - resource_group_name = optional(string) - }) - domain_name_label = optional(string) - capacity = optional(object({ - static = optional(number) - autoscale = optional(object({ - min = number - max = number - })) - })) - enable_http2 = optional(bool) - waf = optional(object({ - prevention_mode = bool - rule_set_type = optional(string) - rule_set_version = optional(string) - })) - managed_identities = optional(list(string)) - global_ssl_policy = optional(object({ - type = optional(string) - name = optional(string) - min_protocol_version = optional(string) - cipher_suites = optional(list(string)) - })) - ssl_profiles = optional(map(object({ - name = string - ssl_policy_name = optional(string) - ssl_policy_min_protocol_version = optional(string) - ssl_policy_cipher_suites = optional(list(string)) - }))) - frontend_ip_configuration_name = optional(string) - listeners = map(object({ - name = string - port = number - protocol = optional(string) - host_names = optional(list(string)) - ssl_profile_name = optional(string) - ssl_certificate_path = optional(string) - ssl_certificate_pass = optional(string) - ssl_certificate_vault_id = optional(string) - custom_error_pages = optional(map(string)) - })) - backend_pool = optional(object({ - name = optional(string) - vmseries_ips = optional(list(string)) - })) - backend_settings = optional(map(object({ - name = string - port = number - protocol = string - path = optional(string) - hostname_from_backend = optional(string) - hostname = optional(string) - timeout = optional(number) - use_cookie_based_affinity = optional(bool) - affinity_cookie_name = optional(string) - probe = optional(string) - root_certs = optional(map(object({ - name = string - path = string - }))) - }))) - probes = optional(map(object({ - name = string - path = string - host = optional(string) - port = optional(number) - protocol = optional(string) - interval = optional(number) - timeout = optional(number) - threshold = optional(number) - match_code = optional(list(number)) - match_body = optional(string) - }))) - rewrites = optional(map(object({ - name = optional(string) - rules = optional(map(object({ - name = string - sequence = number - conditions = optional(map(object({ - pattern = string - ignore_case = optional(bool) - negate = optional(bool) - }))) - request_headers = optional(map(string)) - response_headers = optional(map(string)) - }))) - }))) - redirects = optional(map(object({ - name = string - type = string - target_listener_key = optional(string) - target_url = optional(string) - include_path = optional(bool) - include_query_string = optional(bool) - }))) - url_path_maps = optional(map(object({ - name = string - backend_key = string - path_rules = optional(map(object({ - paths = list(string) - backend_key = optional(string) - redirect_key = optional(string) - }))) - }))) - rules = map(object({ - name = string - priority = number - backend_key = optional(string) - listener_key = string - rewrite_key = optional(string) - url_path_map_key = optional(string) - redirect_key = optional(string) - })) - })) -} diff --git a/examples/common_vmseries_and_autoscale/README.md b/examples/common_vmseries_and_autoscale/README.md index b27f95a7..3760e04e 100644 --- a/examples/common_vmseries_and_autoscale/README.md +++ b/examples/common_vmseries_and_autoscale/README.md @@ -23,7 +23,7 @@ but a [dedicated one exists](../standalone\\_panorama/README.md). ## Reference Architecture Design -![simple](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/assets/2110772/aa2ae33a-fb46-4a1c-9811-98ea3b132297) +![simple](https://github.com/PaloAltoNetworks/terraform-azurerm-vmseries-modules/assets/6574404/a7c2452d-f926-49da-bf21-9d840282a0a2) This code implements: @@ -48,8 +48,7 @@ and may present scale limitations with all traffic flowing through a single set that occurs when traffic crosses virtual routers. This option is suitable for smaller scale deployments because inbound and outbound traffic flows occur on the same set of firewalls. However, the technical integration complexity is high. -![Common-VMSeries-with-autoscaling](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/assets/2110772/7d363d6a-b394-4851-99b9-03ce8abf379a) - +![Common-VMSeries-with-autoscaling](https://github.com/PaloAltoNetworks/terraform-azurerm-vmseries-modules/assets/6500664/b10403f9-795a-4501-a189-3c21d44fc9e7) This reference architecture consists of: @@ -203,8 +202,8 @@ terraform destroy Name | Type | Description --- | --- | --- -[`location`](#location) | `string` | The Azure region to use. [`resource_group_name`](#resource_group_name) | `string` | Name of the Resource Group. +[`location`](#location) | `string` | The Azure region to use. [`vnets`](#vnets) | `map` | A map defining VNETs. [`appgws`](#appgws) | `map` | A map defining all Application Gateways in the current deployment. @@ -213,11 +212,11 @@ Name | Type | Description Name | Type | Description --- | --- | --- -[`tags`](#tags) | `map` | Map of tags to assign to the created resources. [`name_prefix`](#name_prefix) | `string` | A prefix that will be added to all created resources. [`create_resource_group`](#create_resource_group) | `bool` | When set to `true` it will cause a Resource Group creation. +[`tags`](#tags) | `map` | Map of tags to assign to the created resources. [`natgws`](#natgws) | `map` | A map defining NAT Gateways. -[`load_balancers`](#load_balancers) | `map` | A map containing configuration for all (private and public) Load Balancers. +[`load_balancers`](#load_balancers) | `map` | A map containing configuration for all (both private and public) Load Balancers. [`ngfw_metrics`](#ngfw_metrics) | `object` | A map controlling metrics-relates resources. [`scale_sets`](#scale_sets) | `map` | A map defining Azure Virtual Machine Scale Sets based on Palo Alto Networks Next Generation Firewall image. @@ -246,11 +245,11 @@ Providers used in this module: Modules used in this module: Name | Version | Source | Description --- | --- | --- | --- -`vnet` | - | ../../modules/vnet | Manage the network required for the topology. +`vnet` | - | ../../modules/vnet | `natgw` | - | ../../modules/natgw | -`load_balancer` | - | ../../modules/loadbalancer | create load balancers, both internal and external -`ngfw_metrics` | - | ../../modules/ngfw_metrics | +`load_balancer` | - | ../../modules/loadbalancer | `appgw` | - | ../../modules/appgw | +`ngfw_metrics` | - | ../../modules/ngfw_metrics | `vmss` | - | ../../modules/vmss | @@ -266,46 +265,45 @@ Resources used in this module: -#### location -The Azure region to use. +#### resource_group_name + +Name of the Resource Group. Type: string [back to list](#modules-required-inputs) +#### location - -#### resource_group_name - -Name of the Resource Group. +The Azure region to use. Type: string [back to list](#modules-required-inputs) + #### vnets A map defining VNETs. For detailed documentation on each property refer to [module documentation](../../modules/vnet/README.md) -- `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, - `false` will source an existing VNET. -- `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be - a full resource name, including prefixes. -- `address_space` - (`list(string)`, required when `create_virtual_network = false`) a list of CIDRs for a newly - created VNET -- `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which - the VNET will reside or is sourced from +- `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, `false` will source + an existing VNET. +- `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be a + full resource name, including prefixes. +- `address_space` - (`list`, required when `create_virtual_network = false`) a list of CIDRs for a newly created VNET. +- `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which the + VNET will reside or is sourced from. - `create_subnets` - (`bool`, optional, defaults to `true`) if `true`, create Subnets inside the Virtual Network, - otherwise use source existing subnets + otherwise use source existing subnets. - `subnets` - (`map`, optional) map of Subnets to create or source, for details see - [VNET module documentation](../../modules/vnet/README.md#subnets) + [VNET module documentation](../../modules/vnet/README.md#subnets). - `network_security_groups` - (`map`, optional) map of Network Security Groups to create, for details see - [VNET module documentation](../../modules/vnet/README.md#network_security_groups) + [VNET module documentation](../../modules/vnet/README.md#network_security_groups). - `route_tables` - (`map`, optional) map of Route Tables to create, for details see - [VNET module documentation](../../modules/vnet/README.md#route_tables) + [VNET module documentation](../../modules/vnet/README.md#route_tables). Type: @@ -360,8 +358,6 @@ map(object({ - - #### appgws A map defining all Application Gateways in the current deployment. @@ -380,25 +376,25 @@ Below you can find a brief list of most important properties: described by `subnet_key`. - `subnet_key` - (`string`, required) a key pointing to a Subnet definition in the `var.vnets` map, this has to be an Application Gateway V2 dedicated subnet. -- `zones` - (`list`, optional, defaults to module defaults) parameter controlling if this is a zonal, or a non-zonal +- `zones` - (`list`, optional, defaults to module default) parameter controlling if this is a zonal, or a non-zonal deployment. - `public_ip` - (`map`, required) defines a Public IP resource used by the Application Gateway instance, a newly created Public IP will have it's name prefixes with `var.name_prefix`. - `listeners` - (`map`, required) defines Application Gateway's Listeners, see [module's documentation](../../modules/appgw/README.md#listeners) for details. -- `backend_pool` - (`map`, optional, defaults to module defaults) backend pool definition, when skipped an empty backend +- `backend_pool` - (`map`, optional, defaults to module default) backend pool definition, when skipped an empty backend will be created. - `backend_settings` - (`map`, optional, mutually exclusive with `redirects` and `url_path_maps`) defines HTTP backend settings, see [module's documentation](../../modules/appgw/README.md#backend_settings) for details. -- `probes` - (`map`, optional, defaults to module defaults) defines backend probes used check health of backends, see +- `probes` - (`map`, optional, defaults to module default) defines backend probes used check health of backends, see [module's documentation](../../modules/appgw/README.md#probes) for details. -- `rewrites` - (`map`, optional, defaults to module defaults) defines rewrite rules, see +- `rewrites` - (`map`, optional, defaults to module default) defines rewrite rules, see [module's documentation](../../modules/appgw/README.md#rewrites) for details. -- `redirects - (`map`, optional, mutually exclusive with `backend_settings` and `url_path_maps`) static redirects +- `redirects` - (`map`, optional, mutually exclusive with `backend_settings` and `url_path_maps`) static redirects definition, see [module's documentation](../../modules/appgw/README.md#redirects) for details. -- `url_path_maps - (`map`, optional, mutually exclusive with `backend_settings` and `redirects`) URL path maps definition, +- `url_path_maps` - (`map`, optional, mutually exclusive with `backend_settings` and `redirects`) URL path maps definition, see [module's documentation](../../modules/appgw/README.md#url_path_maps) for details. -- `rules - (`map`, required) Application Gateway Rules definition, bind together a `listener` with either +- `rules` - (`map`, required) Application Gateway Rules definition, bind together a `listener` with either `backend_setting`, `redirect` or `url_path_map`, see [module's documentation](../../modules/appgw/README.md#rules) for details. @@ -535,18 +531,9 @@ map(object({ -### Optional Inputs - -#### tags -Map of tags to assign to the created resources. - -Type: map(string) - -Default value: `map[]` - -[back to list](#modules-optional-inputs) +### Optional Inputs #### name_prefix @@ -587,6 +574,17 @@ Default value: `true` +#### tags + +Map of tags to assign to the created resources. + +Type: map(string) + +Default value: `map[]` + +[back to list](#modules-optional-inputs) + + #### natgws A map defining NAT Gateways. @@ -596,21 +594,21 @@ explicitly). Please refer to Microsoft documentation for notes on NAT Gateway's For detailed documentation on each property refer to [module documentation](../../modules/natgw/README.md). Following properties are supported: -- `create_natgw` - (`bool`, optional, defaults to `true`) create (`true`) or source an existing NAT Gateway (`false`), - created or sourced: the NAT Gateway will be assigned to a subnet created by the `vnet` module. -- `name` - (`string`, required) a name of a NAT Gateway. In case `create_natgw = false` this should be a full - resource name, including prefixes. -- `resource_group_name - (`string`, optional) name of a Resource Group hosting the NAT Gateway (newly created or the existing - one). -- `zone` - (`string`, optional) an Availability Zone in which the NAT Gateway will be placed, when skipped - AzureRM will pick a zone. -- `idle_timeout` - (`number`, optional, defults to 4) connection IDLE timeout in minutes, for newly created resources. -- `vnet_key` - (`string`, required) a name (key value) of a VNET defined in `var.vnets` that hosts a subnet this - NAT Gateway will be assigned to. -- `subnet_keys` - (`list(string)`, required) a list of subnets (key values) the NAT Gateway will be assigned to, defined - in `var.vnets` for a VNET described by `vnet_name`. -- `public_ip` - (`object`, optional) an object defining a public IP resource attached to the NAT Gateway. -- `public_ip_prefix` - (`object`, optional) an object defining a public IP prefix resource attached to the NAT Gatway. +- `name` - (`string`, required) a name of a NAT Gateway. In case `create_natgw = false` this should be a full + resource name, including prefixes. +- `vnet_key` - (`string`, required) a name (key value) of a VNET defined in `var.vnets` that hosts a subnet this + NAT Gateway will be assigned to. +- `subnet_keys` - (`list(string)`, required) a list of subnets (key values) the NAT Gateway will be assigned to, + defined in `var.vnets` for a VNET described by `vnet_name`. +- `create_natgw` - (`bool`, optional, defaults to `true`) create (`true`) or source an existing NAT Gateway (`false`), + created or sourced: the NAT Gateway will be assigned to a subnet created by the `vnet` module. +- `resource_group_name` - (`string`, optional) name of a Resource Group hosting the NAT Gateway (newly created or the existing + one). +- `zone` - (`string`, optional) an Availability Zone in which the NAT Gateway will be placed, when skipped + Azure will pick a zone. +- `idle_timeout` - (`number`, optional, defults to 4) connection IDLE timeout in minutes, for newly created resources. +- `public_ip` - (`object`, optional) an object defining a public IP resource attached to the NAT Gateway. +- `public_ip_prefix` - (`object`, optional) an object defining a public IP prefix resource attached to the NAT Gatway. Example: ``` @@ -632,13 +630,13 @@ Type: ```hcl map(object({ - create_natgw = optional(bool, true) name = string + vnet_key = string + subnet_keys = list(string) + create_natgw = optional(bool, true) resource_group_name = optional(string) zone = optional(string) idle_timeout = optional(number, 4) - vnet_key = string - subnet_keys = list(string) public_ip = optional(object({ create = bool name = string @@ -660,7 +658,7 @@ Default value: `map[]` #### load_balancers -A map containing configuration for all (private and public) Load Balancers. +A map containing configuration for all (both private and public) Load Balancers. This is a brief description of available properties. For a detailed one please refer to [module documentation](../../modules/loadbalancer/README.md). @@ -670,26 +668,29 @@ Following properties are available: - `name` - (`string`, required) a name of the Load Balancer. - `vnet_key` - (`string`, optional, defaults to `null`) a key pointing to a VNET definition in the `var.vnets` map that stores the Subnet described by `subnet_key`. -- `zones` - (`list`, optional, defaults to module defaults) a list of zones for Load Balancer's fronted IP +- `zones` - (`list`, optional, defaults to module default) a list of zones for Load Balancer's frontend IP configurations. -- `backend_name` - (`string`, optional, defaults to module defaults) a name of the backend pool to create. -- `health_probes` - (`map`, optional, defaults to `null`) a map defining health probes that will be used by - load balancing rules; please check +- `backend_name` - (`string`, optional, defaults to module default) a name of the backend pool to create. +- `health_probes` - (`map`, optional, defaults to `null`) a map defining health probes that will be used by load + balancing rules, please refer to [module documentation](../../modules/loadbalancer/README.md#health_probes) for more specific use cases and available properties. -- `nsg_auto_rules_settings` - (`map`, optional, defaults to `null`) a map defining a location of an existing NSG rule - that will be populated with `Allow` rules for each load balancing rule (`in_rules`); please check - [module documentation](../../modules/loadbalancer/README.md#nsg_auto_rules_settings) - for available properties; please note that in this example two additional properties are - available: - - `nsg_vnet_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to a VNET definition - in the `var.vnets` map that stores the NSG described by `nsg_key`. - - `nsg_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to an NSG definition - in the `var.vnets` map. -- `frontend_ips` - (`map`, optional, defaults to `{}`) a map containing frontend IP configuration with respective - `in_rules` and `out_rules` +- `nsg_auto_rules_settings` - (`map`, optional, defaults to `null`) a map defining a location of an existing NSG rule that will + be populated with `Allow` rules for each load balancing rule (`in_rules`), please refer to + [module documentation](../../modules/loadbalancer/README.md#nsg_auto_rules_settings) for + available properties. + + Please note that in this example two additional properties are available: + + - `nsg_vnet_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to a VNET definition in the + `var.vnets` map that stores the NSG described by `nsg_key`. + - `nsg_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to an NSG definition in the + `var.vnets` map. - Please refer to [module documentation](../../modules/loadbalancer/README.md#frontend_ips) for available properties. +- `frontend_ips` - (`map`, optional, defaults to `{}`) a map containing frontend IP configuration with respective + `in_rules` and `out_rules`, please refer to + [module documentation](../../modules/loadbalancer/README.md#frontend_ips) for available + properties. **Note!** \ In this example the `subnet_id` is not available directly, another property has been introduced instead: @@ -723,10 +724,10 @@ map(object({ })) frontend_ips = optional(map(object({ name = string + subnet_key = optional(string) public_ip_name = optional(string) create_public_ip = optional(bool, false) public_ip_resource_group_name = optional(string) - subnet_key = optional(string) private_ip_address = optional(string) gwlb_key = optional(string) in_rules = optional(map(object({ @@ -755,6 +756,7 @@ Default value: `map[]` [back to list](#modules-optional-inputs) + #### ngfw_metrics A map controlling metrics-relates resources. @@ -762,22 +764,22 @@ A map controlling metrics-relates resources. When set to explicit `null` (default) it will disable any metrics resources in this deployment. When defined it will either create or source a Log Analytics Workspace and create Application Insights instances (one per each -Scale Set). All instances will be automatically connected to the workspace. -The name of the Application Insights instance will be derived from the Scale Set name and suffixed with `-ai`. +Scale Set). All instances will be automatically connected to the workspace. The name of the Application Insights instance will +be derived from the Scale Set name and suffixed with `-ai`. All the settings available below are common to the Log Analytics Workspace and Application Insight instances. Following properties are available: -- `name` - (`string`, required) name of the (common) Log Analytics Workspace +- `name` - (`string`, required) name of the (common) Log Analytics Workspace. - `create_workspace` - (`bool`, optional, defaults to `true`) controls whether we create or source an existing Log - Analytics Workspace + Analytics Workspace. - `resource_group_name` - (`string`, optional, defaults to `var.resource_group_name`) name of the Resource Group hosting - the Log Analytics Workspace -- `sku` - (`string`, optional, defaults to module defaults) the SKU of the Log Analytics Workspace. -- `metrics_retention_in_days` - (`number`, optional, defaults to module defaults) workspace and insights data retention in - days, possible values are between 30 and 730. For sourced Workspaces this applies only to - the Application Insights instances. + the Log Analytics Workspace. +- `sku` - (`string`, optional, defaults to module default) the SKU of the Log Analytics Workspace. +- `metrics_retention_in_days` - (`number`, optional, defaults to module default) workspace and insights data retention in days, + possible values are between 30 and 730. For sourced Workspaces this applies only to the + Application Insights instances. Type: @@ -805,7 +807,10 @@ For details and defaults for available options please refer to the [`vmss`](../. The basic Scale Set configuration properties are as follows: -- `name` - (`string`, required) name of the scale set, will be prefixed with the value of `var.name_prefix` +- `name` - (`string`, required) name of the scale set, will be prefixed with the value of + `var.name_prefix`. +- `vnet_key` - (`string`, required) a key of a VNET defined in `var.vnets`. This is the VNET that hosts + subnets used to deploy network interfaces for VMs in this Scale Set. - `authentication` - (`map`, required) authentication setting for VMs deployed in this scale set. This map holds the firewall admin password. When this property is not set, the password will be autogenerated for you and @@ -815,74 +820,70 @@ The basic Scale Set configuration properties are as follows: The `disable_password_authentication` property is by default true. When using this value you have to specify at least one SSH key. You can however set this property to `true`. Then you have 2 options, either: - - do not specify anything else - a random password will be generated for you + - do not specify anything else, a random password will be generated for you. - specify at least one of `password` or `ssh_keys` properties. - For all properties and their default values see [module's documentation](../../modules/vmss/README.md#authentication). + For all properties and their default values refer to [module's documentation](../../modules/vmss/README.md#authentication). -- `image` - (`map`, required) properties defining a base image used to spawn VMs in this Scale Set. +- `image` - (`map`, required) properties defining a base image used to spawn VMs in this Scale Set. The + `image` property is required but there are only 2 properties (mutually exclusive) that have to + be set up, either: - The `image` property is required but there are only 2 properties (mutually exclusive) that have to be set up, either: + - `version` - (`string`, optional) describes the PAN-OS image version from Azure Marketplace. + - `custom_id` - (`string`, optional) absolute ID of your own custom PAN-OS image. - - `version` - (`string`) describes the PAN-OS image version from Azure's Marketplace - - `custom_id` - (`string`) absolute ID of your own custom PAN-OS image + For details on all properties refer to [module's documentation](../../modules/vmss/README.md#image). - For details on the other properties refer to [module's documentation](../../modules/vmss/README.md#image). +- `virtual_machine_scale_set` - (`map`, optional, defaults to module default) a map that groups most common Scale Set + configuration options: -- `virtual_machine_scale_set` - (`map`, optional, defaults to module defaults) a map that groups most common Scale Set - configuration options. + - `size` - (`string`, optional, defaults to module default) Azure VM size (type). Consult the *VM-Series + Deployment Guide* as only a few selected sizes are supported. + - `zones` - (`list`, optional, defaults to module default) a list of Availability Zones in which VMs from + this Scale Set will be created. + - `disk_type` - (`string`, optional, defaults to module default) type of Managed Disk which should be created, + possible values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected + `vm_size` values). + - `bootstrap_options` - (`string`, optional, defaults to module default) bootstrap options to pass to VM-Series instance. - Below we present only the most important ones, for the rest please refer to - [module's documentation](../../modules/vmss/README.md#virtual_machine_scale_set): - - - `size` - (`string`, optional, defaults to module defaults) Azure VM size (type). Consult the *VM-Series - Deployment Guide* as only a few selected sizes are supported - - `zones` - (`list`, optional, defaults to module defaults) a list of Availability Zones in which VMs from - this Scale Set will be created - - `disk_type` - (`string`, optional, defaults to module defaults) type of Managed Disk which should be created, - possible values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected - `vm_size` values) - - `bootstrap_options` - (`string`, optional, defaults to module defaults) bootstrap options to pass to VM-Series - instance + For details on all properties refer to [module's documentation](../../modules/vmss/README.md#virtual_machine_scale_set). - `autoscaling_configuration` - (`map`, optional, defaults to `{}`) a map that groups common autoscaling configuration, but not - the scaling profiles (metrics thresholds, etc) + the scaling profiles (metrics, thresholds, etc.). Most common properties are: + + - `default_count` - (`number`, optional, defaults to module default) minimum number of instances that should be present + in the scale set when the autoscaling engine cannot read the metrics or is otherwise unable to + compare the metrics to the thresholds. - Below we present only the most important properties, for the rest please refer to - [module's documentation](../../modules/vmss/README.md#autoscaling_configuration). + For details on all properties refer to [module's documentation](../../modules/vmss/README.md#autoscaling_configuration). - - `default_count` - (`number`, optional, defaults module defaults) minimum number of instances that should be present in - the scale set when the autoscaling engine cannot read the metrics or is otherwise unable to compare - the metrics to the thresholds +- `interfaces` - (`list`, required) configuration of all network interfaces, order does matter - the + 1st interface should be the management one. Following properties are available: -- `vnet_key` - (`string`, required) a key of a VNET defined in `var.vnets`. This is the VNET that hosts subnets - used to deploy network interfaces for VMs in this Scale Set -- `interfaces` - (`list`, required) configuration of all network interfaces, order does matter - the 1st - interface should be the management one. Following properties are available: - - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`) + - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`). - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in - `var.vnets` - - `create_public_ip` - (`bool`, optional, defaults to module defaults) create Public IP for an interface + `var.vnets`. + - `create_public_ip` - (`bool`, optional, defaults to module default) create Public IP for an interface. - `load_balancer_key` - (`string`, optional, defaults to `null`) key of a Load Balancer defined in the - `var.loadbalancers` variable, network interface that has this property defined will be - added to the Load Balancer's backend pool + `var.loadbalancers` variable, network interface that has this property defined will be added to + the Load Balancer's backend pool. - `application_gateway_key` - (`string`, optional, defaults to `null`) key of an Application Gateway defined in the `var.appgws`, network interface that has this property defined will be added to the Application - Gateways's backend pool + Gateways's backend pool. - `pip_domain_name_label` - (`string`, optional, defaults to `null`) prefix which should be used for the Domain Name Label - for each VM instance - -- `autoscaling_profiles` - (`list`, optional, defaults to `[]`) a list of autoscaling profiles, for details on available - configuration please refer to - [module's documentation](../../modules/vmss/README.md#autoscaling_profiles) + for each VM instance. +- `autoscaling_profiles` - (`list`, optional, defaults to `[]`) a list of autoscaling profiles, for details on available + properties please refer to + [module's documentation](../../modules/vmss/README.md#autoscaling_profiles). Type: ```hcl map(object({ - name = string + name = string + vnet_key = string authentication = object({ username = optional(string) password = optional(string) @@ -920,7 +921,6 @@ map(object({ notification_emails = optional(list(string), []) webhooks_uris = optional(map(string), {}) }), {}) - vnet_key = string interfaces = list(object({ name = string subnet_key = string @@ -972,6 +972,4 @@ Default value: `map[]` [back to list](#modules-optional-inputs) - - \ No newline at end of file diff --git a/examples/common_vmseries_and_autoscale/example.tfvars b/examples/common_vmseries_and_autoscale/example.tfvars index 1a9cc94b..7edeba58 100644 --- a/examples/common_vmseries_and_autoscale/example.tfvars +++ b/examples/common_vmseries_and_autoscale/example.tfvars @@ -1,4 +1,5 @@ -# --- GENERAL --- # +### GENERAL ### + location = "North Europe" resource_group_name = "autoscale-common" name_prefix = "example-" @@ -7,7 +8,8 @@ tags = { "CreatedWith" = "Terraform" } -# --- VNET PART --- # +### NETWORK ### + vnets = { "transit" = { name = "transit" @@ -123,8 +125,8 @@ vnets = { } } +### LOAD BALANCING ### -# --- LOAD BALANCING PART --- # load_balancers = { "public" = { name = "public-lb" @@ -168,9 +170,6 @@ load_balancers = { } } - - -# --- APPLICATION GATEWAYs --- # appgws = { public = { name = "appgw" @@ -218,14 +217,16 @@ appgws = { } } -# --- VMSERIES PART --- # +### VM-SERIES ### + ngfw_metrics = { name = "ngwf-log-analytics-wrksp" } scale_sets = { common = { - name = "common-vmss" + name = "common-vmss" + vnet_key = "transit" image = { version = "10.2.4" } @@ -239,7 +240,6 @@ scale_sets = { autoscaling_configuration = { default_count = 1 } - vnet_key = "transit" interfaces = [ { name = "management" diff --git a/examples/common_vmseries_and_autoscale/main.tf b/examples/common_vmseries_and_autoscale/main.tf index 9f208f66..151af28c 100644 --- a/examples/common_vmseries_and_autoscale/main.tf +++ b/examples/common_vmseries_and_autoscale/main.tf @@ -1,4 +1,5 @@ -# Generate a random password. +### Generate a random password ### + # https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password resource "random_password" "this" { count = anytrue([ @@ -27,7 +28,8 @@ locals { } } -# Create or source the Resource Group. +### Create or source a Resource Group ### + # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group resource "azurerm_resource_group" "this" { count = var.create_resource_group ? 1 : 0 @@ -47,7 +49,8 @@ locals { resource_group = var.create_resource_group ? azurerm_resource_group.this[0] : data.azurerm_resource_group.this[0] } -# Manage the network required for the topology. +### Manage the network required for the topology ### + module "vnet" { source = "../../modules/vnet" @@ -63,9 +66,11 @@ module "vnet" { create_subnets = each.value.create_subnets subnets = each.value.subnets - network_security_groups = { for k, v in each.value.network_security_groups : k => merge(v, { name = "${var.name_prefix}${v.name}" }) + network_security_groups = { + for k, v in each.value.network_security_groups : k => merge(v, { name = "${var.name_prefix}${v.name}" }) } - route_tables = { for k, v in each.value.route_tables : k => merge(v, { name = "${var.name_prefix}${v.name}" }) + route_tables = { + for k, v in each.value.route_tables : k => merge(v, { name = "${var.name_prefix}${v.name}" }) } tags = var.tags @@ -84,14 +89,19 @@ module "natgw" { idle_timeout = each.value.idle_timeout subnet_ids = { for v in each.value.subnet_keys : v => module.vnet[each.value.vnet_key].subnet_ids[v] } - public_ip = try(merge(each.value.public_ip, { name = "${each.value.public_ip.create ? var.name_prefix : ""}${each.value.public_ip.name}" }), null) - public_ip_prefix = try(merge(each.value.public_ip_prefix, { name = "${each.value.public_ip_prefix.create ? var.name_prefix : ""}${each.value.public_ip_prefix.name}" }), null) + public_ip = try(merge(each.value.public_ip, { + name = "${each.value.public_ip.create ? var.name_prefix : ""}${each.value.public_ip.name}" + }), null) + public_ip_prefix = try(merge(each.value.public_ip_prefix, { + name = "${each.value.public_ip_prefix.create ? var.name_prefix : ""}${each.value.public_ip_prefix.name}" + }), null) tags = var.tags depends_on = [module.vnet] } -# create load balancers, both internal and external +### Create Load Balancers, both internal and external ### + module "load_balancer" { source = "../../modules/loadbalancer" @@ -108,7 +118,8 @@ module "load_balancer" { nsg_auto_rules_settings = try( { nsg_name = try( - "${var.name_prefix}${var.vnets[each.value.nsg_auto_rules_settings.nsg_vnet_key].network_security_groups[each.value.nsg_auto_rules_settings.nsg_key].name}", + "${var.name_prefix}${var.vnets[each.value.nsg_auto_rules_settings.nsg_vnet_key].network_security_groups[ + each.value.nsg_auto_rules_settings.nsg_key].name}", each.value.nsg_auto_rules_settings.nsg_name ) nsg_resource_group_name = try( @@ -136,30 +147,7 @@ module "load_balancer" { depends_on = [module.vnet] } -module "ngfw_metrics" { - source = "../../modules/ngfw_metrics" - - count = var.ngfw_metrics != null ? 1 : 0 - - create_workspace = var.ngfw_metrics.create_workspace - - name = "${var.ngfw_metrics.create_workspace ? var.name_prefix : ""}${var.ngfw_metrics.name}" - resource_group_name = var.ngfw_metrics.create_workspace ? local.resource_group.name : coalesce(var.ngfw_metrics.resource_group_name, local.resource_group.name) - location = var.location - - log_analytics_workspace = { - sku = var.ngfw_metrics.sku - metrics_retention_in_days = var.ngfw_metrics.metrics_retention_in_days - } - - application_insights = { - for k, v in var.scale_sets : - k => { name = "${var.name_prefix}${v.name}-ai" } - if length(v.autoscaling_profiles) > 0 - } - - tags = var.tags -} +### Create Application Gateways ### module "appgw" { source = "../../modules/appgw" @@ -197,6 +185,35 @@ module "appgw" { depends_on = [module.vnet] } +### Create VM-Series VM Scale Sets and closely associated resources ### + +module "ngfw_metrics" { + source = "../../modules/ngfw_metrics" + + count = var.ngfw_metrics != null ? 1 : 0 + + create_workspace = var.ngfw_metrics.create_workspace + + name = "${var.ngfw_metrics.create_workspace ? var.name_prefix : ""}${var.ngfw_metrics.name}" + resource_group_name = var.ngfw_metrics.create_workspace ? local.resource_group.name : ( + coalesce(var.ngfw_metrics.resource_group_name, local.resource_group.name) + ) + location = var.location + + log_analytics_workspace = { + sku = var.ngfw_metrics.sku + metrics_retention_in_days = var.ngfw_metrics.metrics_retention_in_days + } + + application_insights = { + for k, v in var.scale_sets : + k => { name = "${var.name_prefix}${v.name}-ai" } + if length(v.autoscaling_profiles) > 0 + } + + tags = var.tags +} + module "vmss" { source = "../../modules/vmss" diff --git a/examples/common_vmseries_and_autoscale/variables.tf b/examples/common_vmseries_and_autoscale/variables.tf index c085b3f2..a18c7c0f 100644 --- a/examples/common_vmseries_and_autoscale/variables.tf +++ b/examples/common_vmseries_and_autoscale/variables.tf @@ -1,14 +1,4 @@ -### GENERAL -variable "tags" { - description = "Map of tags to assign to the created resources." - default = {} - type = map(string) -} - -variable "location" { - description = "The Azure region to use." - type = string -} +### GENERAL ### variable "name_prefix" { description = <<-EOF @@ -45,33 +35,41 @@ variable "resource_group_name" { type = string } +variable "location" { + description = "The Azure region to use." + type = string +} + +variable "tags" { + description = "Map of tags to assign to the created resources." + default = {} + type = map(string) +} +### NETWORK ### -### VNET variable "vnets" { description = <<-EOF A map defining VNETs. For detailed documentation on each property refer to [module documentation](../../modules/vnet/README.md) - - `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, - `false` will source an existing VNET. - - `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be - a full resource name, including prefixes. - - `address_space` - (`list(string)`, required when `create_virtual_network = false`) a list of CIDRs for a newly - created VNET - - `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which - the VNET will reside or is sourced from + - `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, `false` will source + an existing VNET. + - `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be a + full resource name, including prefixes. + - `address_space` - (`list`, required when `create_virtual_network = false`) a list of CIDRs for a newly created VNET. + - `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which the + VNET will reside or is sourced from. - `create_subnets` - (`bool`, optional, defaults to `true`) if `true`, create Subnets inside the Virtual Network, - otherwise use source existing subnets + otherwise use source existing subnets. - `subnets` - (`map`, optional) map of Subnets to create or source, for details see - [VNET module documentation](../../modules/vnet/README.md#subnets) + [VNET module documentation](../../modules/vnet/README.md#subnets). - `network_security_groups` - (`map`, optional) map of Network Security Groups to create, for details see - [VNET module documentation](../../modules/vnet/README.md#network_security_groups) + [VNET module documentation](../../modules/vnet/README.md#network_security_groups). - `route_tables` - (`map`, optional) map of Route Tables to create, for details see - [VNET module documentation](../../modules/vnet/README.md#route_tables) + [VNET module documentation](../../modules/vnet/README.md#route_tables). EOF - type = map(object({ name = string resource_group_name = optional(string) @@ -125,21 +123,21 @@ variable "natgws" { For detailed documentation on each property refer to [module documentation](../../modules/natgw/README.md). Following properties are supported: - - `create_natgw` - (`bool`, optional, defaults to `true`) create (`true`) or source an existing NAT Gateway (`false`), - created or sourced: the NAT Gateway will be assigned to a subnet created by the `vnet` module. - - `name` - (`string`, required) a name of a NAT Gateway. In case `create_natgw = false` this should be a full - resource name, including prefixes. - - `resource_group_name - (`string`, optional) name of a Resource Group hosting the NAT Gateway (newly created or the existing - one). - - `zone` - (`string`, optional) an Availability Zone in which the NAT Gateway will be placed, when skipped - AzureRM will pick a zone. - - `idle_timeout` - (`number`, optional, defults to 4) connection IDLE timeout in minutes, for newly created resources. - - `vnet_key` - (`string`, required) a name (key value) of a VNET defined in `var.vnets` that hosts a subnet this - NAT Gateway will be assigned to. - - `subnet_keys` - (`list(string)`, required) a list of subnets (key values) the NAT Gateway will be assigned to, defined - in `var.vnets` for a VNET described by `vnet_name`. - - `public_ip` - (`object`, optional) an object defining a public IP resource attached to the NAT Gateway. - - `public_ip_prefix` - (`object`, optional) an object defining a public IP prefix resource attached to the NAT Gatway. + - `name` - (`string`, required) a name of a NAT Gateway. In case `create_natgw = false` this should be a full + resource name, including prefixes. + - `vnet_key` - (`string`, required) a name (key value) of a VNET defined in `var.vnets` that hosts a subnet this + NAT Gateway will be assigned to. + - `subnet_keys` - (`list(string)`, required) a list of subnets (key values) the NAT Gateway will be assigned to, + defined in `var.vnets` for a VNET described by `vnet_name`. + - `create_natgw` - (`bool`, optional, defaults to `true`) create (`true`) or source an existing NAT Gateway (`false`), + created or sourced: the NAT Gateway will be assigned to a subnet created by the `vnet` module. + - `resource_group_name` - (`string`, optional) name of a Resource Group hosting the NAT Gateway (newly created or the existing + one). + - `zone` - (`string`, optional) an Availability Zone in which the NAT Gateway will be placed, when skipped + Azure will pick a zone. + - `idle_timeout` - (`number`, optional, defults to 4) connection IDLE timeout in minutes, for newly created resources. + - `public_ip` - (`object`, optional) an object defining a public IP resource attached to the NAT Gateway. + - `public_ip_prefix` - (`object`, optional) an object defining a public IP prefix resource attached to the NAT Gatway. Example: ``` @@ -158,13 +156,13 @@ variable "natgws" { EOF default = {} type = map(object({ - create_natgw = optional(bool, true) name = string + vnet_key = string + subnet_keys = list(string) + create_natgw = optional(bool, true) resource_group_name = optional(string) zone = optional(string) idle_timeout = optional(number, 4) - vnet_key = string - subnet_keys = list(string) public_ip = optional(object({ create = bool name = string @@ -179,12 +177,11 @@ variable "natgws" { })) } +### LOAD BALANCING ### - -### Load Balancing variable "load_balancers" { description = <<-EOF - A map containing configuration for all (private and public) Load Balancers. + A map containing configuration for all (both private and public) Load Balancers. This is a brief description of available properties. For a detailed one please refer to [module documentation](../../modules/loadbalancer/README.md). @@ -194,26 +191,29 @@ variable "load_balancers" { - `name` - (`string`, required) a name of the Load Balancer. - `vnet_key` - (`string`, optional, defaults to `null`) a key pointing to a VNET definition in the `var.vnets` map that stores the Subnet described by `subnet_key`. - - `zones` - (`list`, optional, defaults to module defaults) a list of zones for Load Balancer's fronted IP + - `zones` - (`list`, optional, defaults to module default) a list of zones for Load Balancer's frontend IP configurations. - - `backend_name` - (`string`, optional, defaults to module defaults) a name of the backend pool to create. - - `health_probes` - (`map`, optional, defaults to `null`) a map defining health probes that will be used by - load balancing rules; please check + - `backend_name` - (`string`, optional, defaults to module default) a name of the backend pool to create. + - `health_probes` - (`map`, optional, defaults to `null`) a map defining health probes that will be used by load + balancing rules, please refer to [module documentation](../../modules/loadbalancer/README.md#health_probes) for more specific use cases and available properties. - - `nsg_auto_rules_settings` - (`map`, optional, defaults to `null`) a map defining a location of an existing NSG rule - that will be populated with `Allow` rules for each load balancing rule (`in_rules`); please check - [module documentation](../../modules/loadbalancer/README.md#nsg_auto_rules_settings) - for available properties; please note that in this example two additional properties are - available: - - `nsg_vnet_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to a VNET definition - in the `var.vnets` map that stores the NSG described by `nsg_key`. - - `nsg_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to an NSG definition - in the `var.vnets` map. - - `frontend_ips` - (`map`, optional, defaults to `{}`) a map containing frontend IP configuration with respective - `in_rules` and `out_rules` + - `nsg_auto_rules_settings` - (`map`, optional, defaults to `null`) a map defining a location of an existing NSG rule that will + be populated with `Allow` rules for each load balancing rule (`in_rules`), please refer to + [module documentation](../../modules/loadbalancer/README.md#nsg_auto_rules_settings) for + available properties. + + Please note that in this example two additional properties are available: + + - `nsg_vnet_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to a VNET definition in the + `var.vnets` map that stores the NSG described by `nsg_key`. + - `nsg_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to an NSG definition in the + `var.vnets` map. - Please refer to [module documentation](../../modules/loadbalancer/README.md#frontend_ips) for available properties. + - `frontend_ips` - (`map`, optional, defaults to `{}`) a map containing frontend IP configuration with respective + `in_rules` and `out_rules`, please refer to + [module documentation](../../modules/loadbalancer/README.md#frontend_ips) for available + properties. **Note!** \ In this example the `subnet_id` is not available directly, another property has been introduced instead: @@ -245,10 +245,10 @@ variable "load_balancers" { })) frontend_ips = optional(map(object({ name = string + subnet_key = optional(string) public_ip_name = optional(string) create_public_ip = optional(bool, false) public_ip_resource_group_name = optional(string) - subnet_key = optional(string) private_ip_address = optional(string) gwlb_key = optional(string) in_rules = optional(map(object({ @@ -272,213 +272,6 @@ variable "load_balancers" { })) } -variable "ngfw_metrics" { - description = <<-EOF - A map controlling metrics-relates resources. - - When set to explicit `null` (default) it will disable any metrics resources in this deployment. - - When defined it will either create or source a Log Analytics Workspace and create Application Insights instances (one per each - Scale Set). All instances will be automatically connected to the workspace. - The name of the Application Insights instance will be derived from the Scale Set name and suffixed with `-ai`. - - All the settings available below are common to the Log Analytics Workspace and Application Insight instances. - - Following properties are available: - - - `name` - (`string`, required) name of the (common) Log Analytics Workspace - - `create_workspace` - (`bool`, optional, defaults to `true`) controls whether we create or source an existing Log - Analytics Workspace - - `resource_group_name` - (`string`, optional, defaults to `var.resource_group_name`) name of the Resource Group hosting - the Log Analytics Workspace - - `sku` - (`string`, optional, defaults to module defaults) the SKU of the Log Analytics Workspace. - - `metrics_retention_in_days` - (`number`, optional, defaults to module defaults) workspace and insights data retention in - days, possible values are between 30 and 730. For sourced Workspaces this applies only to - the Application Insights instances. - EOF - default = null - type = object({ - name = string - create_workspace = optional(bool, true) - resource_group_name = optional(string) - sku = optional(string) - metrics_retention_in_days = optional(number) - }) -} - -### VMSERIES - -variable "scale_sets" { - description = <<-EOF - A map defining Azure Virtual Machine Scale Sets based on Palo Alto Networks Next Generation Firewall image. - - For details and defaults for available options please refer to the [`vmss`](../../modules/vmss/README.md) module. - - The basic Scale Set configuration properties are as follows: - - - `name` - (`string`, required) name of the scale set, will be prefixed with the value of `var.name_prefix` - - `authentication` - (`map`, required) authentication setting for VMs deployed in this scale set. - - This map holds the firewall admin password. When this property is not set, the password will be autogenerated for you and - available in the Terraform outputs. - - **Note!** \ - The `disable_password_authentication` property is by default true. When using this value you have to specify at least one - SSH key. You can however set this property to `true`. Then you have 2 options, either: - - - do not specify anything else - a random password will be generated for you - - specify at least one of `password` or `ssh_keys` properties. - - For all properties and their default values see [module's documentation](../../modules/vmss/README.md#authentication). - - - `image` - (`map`, required) properties defining a base image used to spawn VMs in this Scale Set. - - The `image` property is required but there are only 2 properties (mutually exclusive) that have to be set up, either: - - - `version` - (`string`) describes the PAN-OS image version from Azure's Marketplace - - `custom_id` - (`string`) absolute ID of your own custom PAN-OS image - - For details on the other properties refer to [module's documentation](../../modules/vmss/README.md#image). - - - `virtual_machine_scale_set` - (`map`, optional, defaults to module defaults) a map that groups most common Scale Set - configuration options. - - Below we present only the most important ones, for the rest please refer to - [module's documentation](../../modules/vmss/README.md#virtual_machine_scale_set): - - - `size` - (`string`, optional, defaults to module defaults) Azure VM size (type). Consult the *VM-Series - Deployment Guide* as only a few selected sizes are supported - - `zones` - (`list`, optional, defaults to module defaults) a list of Availability Zones in which VMs from - this Scale Set will be created - - `disk_type` - (`string`, optional, defaults to module defaults) type of Managed Disk which should be created, - possible values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected - `vm_size` values) - - `bootstrap_options` - (`string`, optional, defaults to module defaults) bootstrap options to pass to VM-Series - instance - - - `autoscaling_configuration` - (`map`, optional, defaults to `{}`) a map that groups common autoscaling configuration, but not - the scaling profiles (metrics thresholds, etc) - - Below we present only the most important properties, for the rest please refer to - [module's documentation](../../modules/vmss/README.md#autoscaling_configuration). - - - `default_count` - (`number`, optional, defaults module defaults) minimum number of instances that should be present in - the scale set when the autoscaling engine cannot read the metrics or is otherwise unable to compare - the metrics to the thresholds - - - `vnet_key` - (`string`, required) a key of a VNET defined in `var.vnets`. This is the VNET that hosts subnets - used to deploy network interfaces for VMs in this Scale Set - - `interfaces` - (`list`, required) configuration of all network interfaces, order does matter - the 1st - interface should be the management one. Following properties are available: - - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`) - - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in - `var.vnets` - - `create_public_ip` - (`bool`, optional, defaults to module defaults) create Public IP for an interface - - `load_balancer_key` - (`string`, optional, defaults to `null`) key of a Load Balancer defined in the - `var.loadbalancers` variable, network interface that has this property defined will be - added to the Load Balancer's backend pool - - `application_gateway_key` - (`string`, optional, defaults to `null`) key of an Application Gateway defined in the - `var.appgws`, network interface that has this property defined will be added to the Application - Gateways's backend pool - - `pip_domain_name_label` - (`string`, optional, defaults to `null`) prefix which should be used for the Domain Name Label - for each VM instance - - - `autoscaling_profiles` - (`list`, optional, defaults to `[]`) a list of autoscaling profiles, for details on available - configuration please refer to - [module's documentation](../../modules/vmss/README.md#autoscaling_profiles) - - EOF - default = {} - nullable = false - type = map(object({ - name = string - authentication = object({ - username = optional(string) - password = optional(string) - disable_password_authentication = optional(bool, true) - ssh_keys = optional(list(string), []) - }) - image = object({ - version = optional(string) - publisher = optional(string) - offer = optional(string) - sku = optional(string) - enable_marketplace_plan = optional(bool) - custom_id = optional(string) - }) - virtual_machine_scale_set = optional(object({ - size = optional(string) - bootstrap_options = optional(string) - zones = optional(list(string)) - disk_type = optional(string) - accelerated_networking = optional(bool) - encryption_at_host_enabled = optional(bool) - overprovision = optional(bool) - platform_fault_domain_count = optional(number) - disk_encryption_set_id = optional(string) - enable_boot_diagnostics = optional(bool, true) - boot_diagnostics_storage_uri = optional(string) - identity_type = optional(string) - identity_ids = optional(list(string), []) - allow_extension_operations = optional(bool) - })) - autoscaling_configuration = optional(object({ - default_count = optional(number) - scale_in_policy = optional(string) - scale_in_force_deletion = optional(bool) - notification_emails = optional(list(string), []) - webhooks_uris = optional(map(string), {}) - }), {}) - vnet_key = string - interfaces = list(object({ - name = string - subnet_key = string - create_public_ip = optional(bool) - load_balancer_key = optional(string) - application_gateway_key = optional(string) - pip_domain_name_label = optional(string) - })) - autoscaling_profiles = optional(list(object({ - name = string - minimum_count = optional(number) - default_count = number - maximum_count = optional(number) - recurrence = optional(object({ - timezone = optional(string) - days = list(string) - start_time = string - end_time = string - })) - scale_rules = optional(list(object({ - name = string - scale_out_config = object({ - threshold = number - operator = optional(string) - grain_window_minutes = number - grain_aggregation_type = optional(string) - aggregation_window_minutes = number - aggregation_window_type = optional(string) - cooldown_window_minutes = number - change_count_by = optional(number) - }) - scale_in_config = object({ - threshold = number - operator = optional(string) - grain_window_minutes = optional(number) - grain_aggregation_type = optional(string) - aggregation_window_minutes = optional(number) - aggregation_window_type = optional(string) - cooldown_window_minutes = number - change_count_by = optional(number) - }) - })), []) - })), []) - })) -} - - - -### Application Gateway variable "appgws" { description = <<-EOF A map defining all Application Gateways in the current deployment. @@ -497,25 +290,25 @@ variable "appgws" { described by `subnet_key`. - `subnet_key` - (`string`, required) a key pointing to a Subnet definition in the `var.vnets` map, this has to be an Application Gateway V2 dedicated subnet. - - `zones` - (`list`, optional, defaults to module defaults) parameter controlling if this is a zonal, or a non-zonal + - `zones` - (`list`, optional, defaults to module default) parameter controlling if this is a zonal, or a non-zonal deployment. - `public_ip` - (`map`, required) defines a Public IP resource used by the Application Gateway instance, a newly created Public IP will have it's name prefixes with `var.name_prefix`. - `listeners` - (`map`, required) defines Application Gateway's Listeners, see [module's documentation](../../modules/appgw/README.md#listeners) for details. - - `backend_pool` - (`map`, optional, defaults to module defaults) backend pool definition, when skipped an empty backend + - `backend_pool` - (`map`, optional, defaults to module default) backend pool definition, when skipped an empty backend will be created. - `backend_settings` - (`map`, optional, mutually exclusive with `redirects` and `url_path_maps`) defines HTTP backend settings, see [module's documentation](../../modules/appgw/README.md#backend_settings) for details. - - `probes` - (`map`, optional, defaults to module defaults) defines backend probes used check health of backends, see + - `probes` - (`map`, optional, defaults to module default) defines backend probes used check health of backends, see [module's documentation](../../modules/appgw/README.md#probes) for details. - - `rewrites` - (`map`, optional, defaults to module defaults) defines rewrite rules, see + - `rewrites` - (`map`, optional, defaults to module default) defines rewrite rules, see [module's documentation](../../modules/appgw/README.md#rewrites) for details. - - `redirects - (`map`, optional, mutually exclusive with `backend_settings` and `url_path_maps`) static redirects + - `redirects` - (`map`, optional, mutually exclusive with `backend_settings` and `url_path_maps`) static redirects definition, see [module's documentation](../../modules/appgw/README.md#redirects) for details. - - `url_path_maps - (`map`, optional, mutually exclusive with `backend_settings` and `redirects`) URL path maps definition, + - `url_path_maps` - (`map`, optional, mutually exclusive with `backend_settings` and `redirects`) URL path maps definition, see [module's documentation](../../modules/appgw/README.md#url_path_maps) for details. - - `rules - (`map`, required) Application Gateway Rules definition, bind together a `listener` with either + - `rules` - (`map`, required) Application Gateway Rules definition, bind together a `listener` with either `backend_setting`, `redirect` or `url_path_map`, see [module's documentation](../../modules/appgw/README.md#rules) for details. EOF @@ -641,4 +434,206 @@ variable "appgws" { redirect_key = optional(string) })) })) -} \ No newline at end of file +} + +### VM-SERIES ### + +variable "ngfw_metrics" { + description = <<-EOF + A map controlling metrics-relates resources. + + When set to explicit `null` (default) it will disable any metrics resources in this deployment. + + When defined it will either create or source a Log Analytics Workspace and create Application Insights instances (one per each + Scale Set). All instances will be automatically connected to the workspace. The name of the Application Insights instance will + be derived from the Scale Set name and suffixed with `-ai`. + + All the settings available below are common to the Log Analytics Workspace and Application Insight instances. + + Following properties are available: + + - `name` - (`string`, required) name of the (common) Log Analytics Workspace. + - `create_workspace` - (`bool`, optional, defaults to `true`) controls whether we create or source an existing Log + Analytics Workspace. + - `resource_group_name` - (`string`, optional, defaults to `var.resource_group_name`) name of the Resource Group hosting + the Log Analytics Workspace. + - `sku` - (`string`, optional, defaults to module default) the SKU of the Log Analytics Workspace. + - `metrics_retention_in_days` - (`number`, optional, defaults to module default) workspace and insights data retention in days, + possible values are between 30 and 730. For sourced Workspaces this applies only to the + Application Insights instances. + EOF + default = null + type = object({ + name = string + create_workspace = optional(bool, true) + resource_group_name = optional(string) + sku = optional(string) + metrics_retention_in_days = optional(number) + }) +} + +variable "scale_sets" { + description = <<-EOF + A map defining Azure Virtual Machine Scale Sets based on Palo Alto Networks Next Generation Firewall image. + + For details and defaults for available options please refer to the [`vmss`](../../modules/vmss/README.md) module. + + The basic Scale Set configuration properties are as follows: + + - `name` - (`string`, required) name of the scale set, will be prefixed with the value of + `var.name_prefix`. + - `vnet_key` - (`string`, required) a key of a VNET defined in `var.vnets`. This is the VNET that hosts + subnets used to deploy network interfaces for VMs in this Scale Set. + - `authentication` - (`map`, required) authentication setting for VMs deployed in this scale set. + + This map holds the firewall admin password. When this property is not set, the password will be autogenerated for you and + available in the Terraform outputs. + + **Note!** \ + The `disable_password_authentication` property is by default true. When using this value you have to specify at least one + SSH key. You can however set this property to `true`. Then you have 2 options, either: + + - do not specify anything else, a random password will be generated for you. + - specify at least one of `password` or `ssh_keys` properties. + + For all properties and their default values refer to [module's documentation](../../modules/vmss/README.md#authentication). + + - `image` - (`map`, required) properties defining a base image used to spawn VMs in this Scale Set. The + `image` property is required but there are only 2 properties (mutually exclusive) that have to + be set up, either: + + - `version` - (`string`, optional) describes the PAN-OS image version from Azure Marketplace. + - `custom_id` - (`string`, optional) absolute ID of your own custom PAN-OS image. + + For details on all properties refer to [module's documentation](../../modules/vmss/README.md#image). + + - `virtual_machine_scale_set` - (`map`, optional, defaults to module default) a map that groups most common Scale Set + configuration options: + + - `size` - (`string`, optional, defaults to module default) Azure VM size (type). Consult the *VM-Series + Deployment Guide* as only a few selected sizes are supported. + - `zones` - (`list`, optional, defaults to module default) a list of Availability Zones in which VMs from + this Scale Set will be created. + - `disk_type` - (`string`, optional, defaults to module default) type of Managed Disk which should be created, + possible values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected + `vm_size` values). + - `bootstrap_options` - (`string`, optional, defaults to module default) bootstrap options to pass to VM-Series instance. + + For details on all properties refer to [module's documentation](../../modules/vmss/README.md#virtual_machine_scale_set). + + - `autoscaling_configuration` - (`map`, optional, defaults to `{}`) a map that groups common autoscaling configuration, but not + the scaling profiles (metrics, thresholds, etc.). Most common properties are: + + - `default_count` - (`number`, optional, defaults to module default) minimum number of instances that should be present + in the scale set when the autoscaling engine cannot read the metrics or is otherwise unable to + compare the metrics to the thresholds. + + For details on all properties refer to [module's documentation](../../modules/vmss/README.md#autoscaling_configuration). + + - `interfaces` - (`list`, required) configuration of all network interfaces, order does matter - the + 1st interface should be the management one. Following properties are available: + + - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`). + - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in + `var.vnets`. + - `create_public_ip` - (`bool`, optional, defaults to module default) create Public IP for an interface. + - `load_balancer_key` - (`string`, optional, defaults to `null`) key of a Load Balancer defined in the + `var.loadbalancers` variable, network interface that has this property defined will be added to + the Load Balancer's backend pool. + - `application_gateway_key` - (`string`, optional, defaults to `null`) key of an Application Gateway defined in the + `var.appgws`, network interface that has this property defined will be added to the Application + Gateways's backend pool. + - `pip_domain_name_label` - (`string`, optional, defaults to `null`) prefix which should be used for the Domain Name Label + for each VM instance. + + - `autoscaling_profiles` - (`list`, optional, defaults to `[]`) a list of autoscaling profiles, for details on available + properties please refer to + [module's documentation](../../modules/vmss/README.md#autoscaling_profiles). + EOF + default = {} + nullable = false + type = map(object({ + name = string + vnet_key = string + authentication = object({ + username = optional(string) + password = optional(string) + disable_password_authentication = optional(bool, true) + ssh_keys = optional(list(string), []) + }) + image = object({ + version = optional(string) + publisher = optional(string) + offer = optional(string) + sku = optional(string) + enable_marketplace_plan = optional(bool) + custom_id = optional(string) + }) + virtual_machine_scale_set = optional(object({ + size = optional(string) + bootstrap_options = optional(string) + zones = optional(list(string)) + disk_type = optional(string) + accelerated_networking = optional(bool) + encryption_at_host_enabled = optional(bool) + overprovision = optional(bool) + platform_fault_domain_count = optional(number) + disk_encryption_set_id = optional(string) + enable_boot_diagnostics = optional(bool, true) + boot_diagnostics_storage_uri = optional(string) + identity_type = optional(string) + identity_ids = optional(list(string), []) + allow_extension_operations = optional(bool) + })) + autoscaling_configuration = optional(object({ + default_count = optional(number) + scale_in_policy = optional(string) + scale_in_force_deletion = optional(bool) + notification_emails = optional(list(string), []) + webhooks_uris = optional(map(string), {}) + }), {}) + interfaces = list(object({ + name = string + subnet_key = string + create_public_ip = optional(bool) + load_balancer_key = optional(string) + application_gateway_key = optional(string) + pip_domain_name_label = optional(string) + })) + autoscaling_profiles = optional(list(object({ + name = string + minimum_count = optional(number) + default_count = number + maximum_count = optional(number) + recurrence = optional(object({ + timezone = optional(string) + days = list(string) + start_time = string + end_time = string + })) + scale_rules = optional(list(object({ + name = string + scale_out_config = object({ + threshold = number + operator = optional(string) + grain_window_minutes = number + grain_aggregation_type = optional(string) + aggregation_window_minutes = number + aggregation_window_type = optional(string) + cooldown_window_minutes = number + change_count_by = optional(number) + }) + scale_in_config = object({ + threshold = number + operator = optional(string) + grain_window_minutes = optional(number) + grain_aggregation_type = optional(string) + aggregation_window_minutes = optional(number) + aggregation_window_type = optional(string) + cooldown_window_minutes = number + change_count_by = optional(number) + }) + })), []) + })), []) + })) +} diff --git a/examples/dedicated_vmseries/README.md b/examples/dedicated_vmseries/README.md index ebf362f8..33755031 100644 --- a/examples/dedicated_vmseries/README.md +++ b/examples/dedicated_vmseries/README.md @@ -17,7 +17,7 @@ dedicated-inbound VM-Series; for a discussion of other options, please see the d ## Reference Architecture Design -![simple](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/assets/2110772/aa2ae33a-fb46-4a1c-9811-98ea3b132297) +![simple](https://github.com/PaloAltoNetworks/terraform-azurerm-vmseries-modules/assets/6574404/a7c2452d-f926-49da-bf21-9d840282a0a2) This code implements: @@ -41,8 +41,7 @@ The second set of VM-Series firewalls services all outbound, east-west, and ente choice offers increased scale and operational resiliency and reduces the chances of high bandwidth use from the inbound traffic flows affecting other traffic flows within the deployment. -![Detailed Topology Diagram](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/assets/2110772/3644469f-5f0f-44f9-8990-010c8bcf1cec) - +![Detailed Topology Diagram](https://user-images.githubusercontent.com/2110772/234920818-44e4082d-b445-4ffc-b0cb-174ef1e3c2ae.png) This reference architecture consists of: @@ -176,8 +175,8 @@ terraform destroy Name | Type | Description --- | --- | --- -[`location`](#location) | `string` | The Azure region to use. [`resource_group_name`](#resource_group_name) | `string` | Name of the Resource Group. +[`location`](#location) | `string` | The Azure region to use. [`vnets`](#vnets) | `map` | A map defining VNETs. [`appgws`](#appgws) | `map` | A map defining all Application Gateways in the current deployment. @@ -186,11 +185,11 @@ Name | Type | Description Name | Type | Description --- | --- | --- -[`tags`](#tags) | `map` | Map of tags to assign to the created resources. [`name_prefix`](#name_prefix) | `string` | A prefix that will be added to all created resources. [`create_resource_group`](#create_resource_group) | `bool` | When set to `true` it will cause a Resource Group creation. +[`tags`](#tags) | `map` | Map of tags to assign to the created resources. [`natgws`](#natgws) | `map` | A map defining NAT Gateways. -[`load_balancers`](#load_balancers) | `map` | A map containing configuration for all (private and public) Load Balancers. +[`load_balancers`](#load_balancers) | `map` | A map containing configuration for all (both private and public) Load Balancers. [`availability_sets`](#availability_sets) | `map` | A map defining availability sets. [`ngfw_metrics`](#ngfw_metrics) | `object` | A map controlling metrics-relates resources. [`bootstrap_storages`](#bootstrap_storages) | `map` | A map defining Azure Storage Accounts used to host file shares for bootstrapping NGFWs. @@ -228,13 +227,13 @@ Providers used in this module: Modules used in this module: Name | Version | Source | Description --- | --- | --- | --- -`vnet` | - | ../../modules/vnet | Manage the network required for the topology. +`vnet` | - | ../../modules/vnet | `natgw` | - | ../../modules/natgw | -`load_balancer` | - | ../../modules/loadbalancer | create load balancers, both internal and external -`ngfw_metrics` | - | ../../modules/ngfw_metrics | create the actual VM-Series VMs and resources +`load_balancer` | - | ../../modules/loadbalancer | +`appgw` | - | ../../modules/appgw | +`ngfw_metrics` | - | ../../modules/ngfw_metrics | `bootstrap` | - | ../../modules/bootstrap | `vmseries` | - | ../../modules/vmseries | -`appgw` | - | ../../modules/appgw | Resources used in this module: @@ -251,46 +250,45 @@ Resources used in this module: -#### location -The Azure region to use. +#### resource_group_name + +Name of the Resource Group. Type: string [back to list](#modules-required-inputs) +#### location - -#### resource_group_name - -Name of the Resource Group. +The Azure region to use. Type: string [back to list](#modules-required-inputs) + #### vnets A map defining VNETs. For detailed documentation on each property refer to [module documentation](../../modules/vnet/README.md) -- `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, - `false` will source an existing VNET. -- `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be - a full resource name, including prefixes. -- `address_space` - (`list(string)`, required when `create_virtual_network = false`) a list of CIDRs for a newly - created VNET -- `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which - the VNET will reside or is sourced from +- `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, `false` will source + an existing VNET. +- `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be a + full resource name, including prefixes. +- `address_space` - (`list`, required when `create_virtual_network = false`) a list of CIDRs for a newly created VNET. +- `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which the + VNET will reside or is sourced from. - `create_subnets` - (`bool`, optional, defaults to `true`) if `true`, create Subnets inside the Virtual Network, - otherwise use source existing subnets + otherwise use source existing subnets. - `subnets` - (`map`, optional) map of Subnets to create or source, for details see - [VNET module documentation](../../modules/vnet/README.md#subnets) + [VNET module documentation](../../modules/vnet/README.md#subnets). - `network_security_groups` - (`map`, optional) map of Network Security Groups to create, for details see - [VNET module documentation](../../modules/vnet/README.md#network_security_groups) + [VNET module documentation](../../modules/vnet/README.md#network_security_groups). - `route_tables` - (`map`, optional) map of Route Tables to create, for details see - [VNET module documentation](../../modules/vnet/README.md#route_tables) + [VNET module documentation](../../modules/vnet/README.md#route_tables). Type: @@ -345,10 +343,6 @@ map(object({ - - - - #### appgws A map defining all Application Gateways in the current deployment. @@ -367,25 +361,25 @@ Below you can find a brief list of most important properties: described by `subnet_key`. - `subnet_key` - (`string`, required) a key pointing to a Subnet definition in the `var.vnets` map, this has to be an Application Gateway V2 dedicated subnet. -- `zones` - (`list`, optional, defaults to module defaults) parameter controlling if this is a zonal, or a non-zonal +- `zones` - (`list`, optional, defaults to module default) parameter controlling if this is a zonal, or a non-zonal deployment. - `public_ip` - (`map`, required) defines a Public IP resource used by the Application Gateway instance, a newly created Public IP will have it's name prefixes with `var.name_prefix`. - `listeners` - (`map`, required) defines Application Gateway's Listeners, see [module's documentation](../../modules/appgw/README.md#listeners) for details. -- `backend_pool` - (`map`, optional, defaults to module defaults) backend pool definition, when skipped an empty backend +- `backend_pool` - (`map`, optional, defaults to module default) backend pool definition, when skipped an empty backend will be created. - `backend_settings` - (`map`, optional, mutually exclusive with `redirects` and `url_path_maps`) defines HTTP backend settings, see [module's documentation](../../modules/appgw/README.md#backend_settings) for details. -- `probes` - (`map`, optional, defaults to module defaults) defines backend probes used check health of backends, see +- `probes` - (`map`, optional, defaults to module default) defines backend probes used check health of backends, see [module's documentation](../../modules/appgw/README.md#probes) for details. -- `rewrites` - (`map`, optional, defaults to module defaults) defines rewrite rules, see +- `rewrites` - (`map`, optional, defaults to module default) defines rewrite rules, see [module's documentation](../../modules/appgw/README.md#rewrites) for details. -- `redirects - (`map`, optional, mutually exclusive with `backend_settings` and `url_path_maps`) static redirects +- `redirects` - (`map`, optional, mutually exclusive with `backend_settings` and `url_path_maps`) static redirects definition, see [module's documentation](../../modules/appgw/README.md#redirects) for details. -- `url_path_maps - (`map`, optional, mutually exclusive with `backend_settings` and `redirects`) URL path maps definition, +- `url_path_maps` - (`map`, optional, mutually exclusive with `backend_settings` and `redirects`) URL path maps definition, see [module's documentation](../../modules/appgw/README.md#url_path_maps) for details. -- `rules - (`map`, required) Application Gateway Rules definition, bind together a `listener` with either +- `rules` - (`map`, required) Application Gateway Rules definition, bind together a `listener` with either `backend_setting`, `redirect` or `url_path_map`, see [module's documentation](../../modules/appgw/README.md#rules) for details. @@ -522,18 +516,11 @@ map(object({ -### Optional Inputs - - -#### tags -Map of tags to assign to the created resources. -Type: map(string) -Default value: `map[]` -[back to list](#modules-optional-inputs) +### Optional Inputs #### name_prefix @@ -574,6 +561,17 @@ Default value: `true` +#### tags + +Map of tags to assign to the created resources. + +Type: map(string) + +Default value: `map[]` + +[back to list](#modules-optional-inputs) + + #### natgws A map defining NAT Gateways. @@ -583,21 +581,21 @@ explicitly). Please refer to Microsoft documentation for notes on NAT Gateway's For detailed documentation on each property refer to [module documentation](../../modules/natgw/README.md). Following properties are supported: -- `create_natgw` - (`bool`, optional, defaults to `true`) create (`true`) or source an existing NAT Gateway (`false`), - created or sourced: the NAT Gateway will be assigned to a subnet created by the `vnet` module. -- `name` - (`string`, required) a name of a NAT Gateway. In case `create_natgw = false` this should be a full - resource name, including prefixes. -- `resource_group_name - (`string`, optional) name of a Resource Group hosting the NAT Gateway (newly created or the existing - one). -- `zone` - (`string`, optional) an Availability Zone in which the NAT Gateway will be placed, when skipped - AzureRM will pick a zone. -- `idle_timeout` - (`number`, optional, defults to 4) connection IDLE timeout in minutes, for newly created resources. -- `vnet_key` - (`string`, required) a name (key value) of a VNET defined in `var.vnets` that hosts a subnet this - NAT Gateway will be assigned to. -- `subnet_keys` - (`list(string)`, required) a list of subnets (key values) the NAT Gateway will be assigned to, defined - in `var.vnets` for a VNET described by `vnet_name`. -- `public_ip` - (`object`, optional) an object defining a public IP resource attached to the NAT Gateway. -- `public_ip_prefix` - (`object`, optional) an object defining a public IP prefix resource attached to the NAT Gatway. +- `name` - (`string`, required) a name of a NAT Gateway. In case `create_natgw = false` this should be a full + resource name, including prefixes. +- `vnet_key` - (`string`, required) a name (key value) of a VNET defined in `var.vnets` that hosts a subnet this + NAT Gateway will be assigned to. +- `subnet_keys` - (`list(string)`, required) a list of subnets (key values) the NAT Gateway will be assigned to, + defined in `var.vnets` for a VNET described by `vnet_name`. +- `create_natgw` - (`bool`, optional, defaults to `true`) create (`true`) or source an existing NAT Gateway (`false`), + created or sourced: the NAT Gateway will be assigned to a subnet created by the `vnet` module. +- `resource_group_name` - (`string`, optional) name of a Resource Group hosting the NAT Gateway (newly created or the existing + one). +- `zone` - (`string`, optional) an Availability Zone in which the NAT Gateway will be placed, when skipped + Azure will pick a zone. +- `idle_timeout` - (`number`, optional, defults to 4) connection IDLE timeout in minutes, for newly created resources. +- `public_ip` - (`object`, optional) an object defining a public IP resource attached to the NAT Gateway. +- `public_ip_prefix` - (`object`, optional) an object defining a public IP prefix resource attached to the NAT Gatway. Example: ``` @@ -619,13 +617,13 @@ Type: ```hcl map(object({ - create_natgw = optional(bool, true) name = string + vnet_key = string + subnet_keys = list(string) + create_natgw = optional(bool, true) resource_group_name = optional(string) zone = optional(string) idle_timeout = optional(number, 4) - vnet_key = string - subnet_keys = list(string) public_ip = optional(object({ create = bool name = string @@ -647,7 +645,7 @@ Default value: `map[]` #### load_balancers -A map containing configuration for all (private and public) Load Balancers. +A map containing configuration for all (both private and public) Load Balancers. This is a brief description of available properties. For a detailed one please refer to [module documentation](../../modules/loadbalancer/README.md). @@ -657,26 +655,29 @@ Following properties are available: - `name` - (`string`, required) a name of the Load Balancer. - `vnet_key` - (`string`, optional, defaults to `null`) a key pointing to a VNET definition in the `var.vnets` map that stores the Subnet described by `subnet_key`. -- `zones` - (`list`, optional, defaults to module defaults) a list of zones for Load Balancer's fronted IP +- `zones` - (`list`, optional, defaults to module default) a list of zones for Load Balancer's frontend IP configurations. -- `backend_name` - (`string`, optional, defaults to module defaults) a name of the backend pool to create. -- `health_probes` - (`map`, optional, defaults to `null`) a map defining health probes that will be used by - load balancing rules; please check +- `backend_name` - (`string`, optional, defaults to module default) a name of the backend pool to create. +- `health_probes` - (`map`, optional, defaults to `null`) a map defining health probes that will be used by load + balancing rules, please refer to [module documentation](../../modules/loadbalancer/README.md#health_probes) for more specific use cases and available properties. -- `nsg_auto_rules_settings` - (`map`, optional, defaults to `null`) a map defining a location of an existing NSG rule - that will be populated with `Allow` rules for each load balancing rule (`in_rules`); please check - [module documentation](../../modules/loadbalancer/README.md#nsg_auto_rules_settings) - for available properties; please note that in this example two additional properties are - available: - - `nsg_vnet_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to a VNET definition - in the `var.vnets` map that stores the NSG described by `nsg_key`. - - `nsg_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to an NSG definition - in the `var.vnets` map. -- `frontend_ips` - (`map`, optional, defaults to `{}`) a map containing frontend IP configuration with respective - `in_rules` and `out_rules` +- `nsg_auto_rules_settings` - (`map`, optional, defaults to `null`) a map defining a location of an existing NSG rule that will + be populated with `Allow` rules for each load balancing rule (`in_rules`), please refer to + [module documentation](../../modules/loadbalancer/README.md#nsg_auto_rules_settings) for + available properties. + + Please note that in this example two additional properties are available: + + - `nsg_vnet_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to a VNET definition in the + `var.vnets` map that stores the NSG described by `nsg_key`. + - `nsg_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to an NSG definition in the + `var.vnets` map. - Please refer to [module documentation](../../modules/loadbalancer/README.md#frontend_ips) for available properties. +- `frontend_ips` - (`map`, optional, defaults to `{}`) a map containing frontend IP configuration with respective + `in_rules` and `out_rules`, please refer to + [module documentation](../../modules/loadbalancer/README.md#frontend_ips) for available + properties. **Note!** \ In this example the `subnet_id` is not available directly, another property has been introduced instead: @@ -710,10 +711,10 @@ map(object({ })) frontend_ips = optional(map(object({ name = string + subnet_key = optional(string) public_ip_name = optional(string) create_public_ip = optional(bool, false) public_ip_resource_group_name = optional(string) - subnet_key = optional(string) private_ip_address = optional(string) gwlb_key = optional(string) in_rules = optional(map(object({ @@ -742,17 +743,20 @@ Default value: `map[]` [back to list](#modules-optional-inputs) + #### availability_sets A map defining availability sets. Can be used to provide infrastructure high availability when zones cannot be used. Following properties are supported: -- `name` - name of the Application Insights. -- `update_domain_count` - specifies the number of update domains that are used, defaults to 5 (Azure defaults). -- `fault_domain_count` - specifies the number of fault domains that are used, defaults to 3 (Azure defaults). -Please keep in mind that Azure defaults are not working for each region (especially the small ones, w/o any Availability Zones). -Please verify how many update and fault domain are supported in a region before deploying this resource. +- `name` - (`string`, required) name of the Application Insights. +- `update_domain_count` - (`number`, optional, defaults to Azure default) specifies the number of update domains that are used. +- `fault_domain_count` - (`number`, optional, defaults to Azure default) specifies the number of fault domains that are used. + +**Note!** \ +Please keep in mind that Azure defaults are not working for every region (especially the small ones, without any Availability +Zones). Please verify how many update and fault domain are supported in a region before deploying this resource. Type: @@ -760,8 +764,8 @@ Type: ```hcl map(object({ name = string - update_domain_count = optional(number, 5) - fault_domain_count = optional(number, 3) + update_domain_count = optional(number) + fault_domain_count = optional(number) })) ``` @@ -777,22 +781,22 @@ A map controlling metrics-relates resources. When set to explicit `null` (default) it will disable any metrics resources in this deployment. When defined it will either create or source a Log Analytics Workspace and create Application Insights instances (one per each -Scale Set). All instances will be automatically connected to the workspace. -The name of the Application Insights instance will be derived from the Scale Set name and suffixed with `-ai`. +Scale Set). All instances will be automatically connected to the workspace. The name of the Application Insights instance will +be derived from the Scale Set name and suffixed with `-ai`. All the settings available below are common to the Log Analytics Workspace and Application Insight instances. Following properties are available: -- `name` - (`string`, required) name of the (common) Log Analytics Workspace +- `name` - (`string`, required) name of the (common) Log Analytics Workspace. - `create_workspace` - (`bool`, optional, defaults to `true`) controls whether we create or source an existing Log - Analytics Workspace + Analytics Workspace. - `resource_group_name` - (`string`, optional, defaults to `var.resource_group_name`) name of the Resource Group hosting - the Log Analytics Workspace -- `sku` - (`string`, optional, defaults to module defaults) the SKU of the Log Analytics Workspace. -- `metrics_retention_in_days` - (`number`, optional, defaults to module defaults) workspace and insights data retention in - days, possible values are between 30 and 730. For sourced Workspaces this applies only to - the Application Insights instances. + the Log Analytics Workspace. +- `sku` - (`string`, optional, defaults to module default) the SKU of the Log Analytics Workspace. +- `metrics_retention_in_days` - (`number`, optional, defaults to module default) workspace and insights data retention in days, + possible values are between 30 and 730. For sourced Workspaces this applies only to the + Application Insights instances. Type: @@ -821,43 +825,52 @@ You can create or re-use an existing Storage Account and/or File Share. For deta - `name` - (`string`, required) name of the Storage Account that will be created or sourced. - **Note** \ - For new Storage Accounts this name will not be prefixed with `var.name_prefix`. \ - Please note the limitations on naming. This has to be a globally unique name, between 3 and 63 chars, only lower-case - letters and numbers. + **Note** \ + For new Storage Accounts this name will not be prefixed with `var.name_prefix`. \ + Please note the limitations on naming. This has to be a globally unique name, between 3 and 63 chars, only lower-case letters + and numbers. -- `resource_group_name` - (`string`, optional, defaults to `null`) name of the Resource Group that hosts (sourced) or will - host (created) a Storage Account. When skipped the code will fall back to +- `resource_group_name` - (`string`, optional, defaults to `null`) name of the Resource Group that hosts (sourced) or + will host (created) a Storage Account. When skipped the code will fall back to `var.resource_group_name`. -- `storage_account` - (`map`, optional, defaults to `{}`) a map controlling basic Storage Account configuration, for - detailed documentation see - [module's documentation](../../modules/bootstrap/README.md#storage_account). The property you - should pay attention to is: - - `create` - (`bool`, optional, defaults to module defaults) controls if the Storage Account specified in - the `name` property will be created or sourced. +- `storage_account` - (`map`, optional, defaults to `{}`) a map controlling basic Storage Account configuration. + + The property you should pay attention to is: + + - `create` - (`bool`, optional, defaults to module default) controls if the Storage Account specified in the `name` property + will be created or sourced. + + For detailed documentation see [module's documentation](../../modules/bootstrap/README.md#storage_account). + - `storage_network_security` - (`map`, optional, defaults to `{}`) a map defining network security settings for a **new** - storage account, for details see - [module's documentation](../../modules/bootstrap/README.md#storage_network_security). Properties - worth mentioning are: - - `allowed_subnet_keys` - (`list`, optional, defaults to `[]`) a list of keys pointing to Subnet definitions in the - `var.vnets` map. These Subnets will have dedicated access to the Storage Account. For this to - work they also need to have the Storage Account Service Endpoint enabled. - - `vnet_key` - a key pointing to a VNET definition in the `var.vnets` map that stores the Subnets described - in `allowed_subnet_keys`. -- `file_shares_configuration` - (`map`, optional, defaults to `{}`) a map defining common File Share setting. For detailed - documentation see - [module's documentation](../../modules/bootstrap/README.md#file_shares_configuration). The - properties you should pay your attention to are: - - `create_file_shares` - (`bool`, optional, defaults to module defaults) controls if the File Shares defined in the + storage account. + + The properties you should pay attention to are: + + - `allowed_subnet_keys` - (`list`, optional, defaults to `[]`) a list of keys pointing to Subnet definitions in the + `var.vnets` map. These Subnets will have dedicated access to the Storage Account. For this to work + they also need to have the Storage Account Service Endpoint enabled. + - `vnet_key` - (`string`, optional) a key pointing to a VNET definition in the `var.vnets` map that stores the + Subnets described in `allowed_subnet_keys`. + + For detailed documentation see [module's documentation](../../modules/bootstrap/README.md#storage_network_security). + +- `file_shares_configuration` - (`map`, optional, defaults to `{}`) a map defining common File Share setting. + + The properties you should pay attention to are: + + - `create_file_shares` - (`bool`, optional, defaults to module default) controls if the File Shares defined in the `file_shares` property will be created or sourced. - - `disable_package_dirs_creation` - (`bool`, optional, defaults to module defaults) for sourced File Shares, controls if the + - `disable_package_dirs_creation` - (`bool`, optional, defaults to module default) for sourced File Shares, controls if the bootstrap package folder structure will be created. + + For detailed documentation see [module's documentation](../../modules/bootstrap/README.md#file_shares_configuration). + - `file_shares` - (`map`, optional, defaults to `{}`) a map that holds File Shares and bootstrap package configuration. For detailed description see [module's documentation](../../modules/bootstrap/README.md#file_shares). - Type: ```hcl @@ -900,129 +913,121 @@ Default value: `map[]` #### vmseries -A map defining Azure Virtual Machines based on Palo Alto Networks Next Generation Firewall image.. +A map defining Azure Virtual Machines based on Palo Alto Networks Next Generation Firewall image. For details and defaults for available options please refer to the [`vmseries`](../../modules/vmseries/README.md) module. The most basic properties are as follows: - `name` - (`string`, required) name of the VM, will be prefixed with the value of `var.name_prefix`. +- `vnet_key` - (`string`, required) a key of a VNET defined in `var.vnets`. This is the VNET that hosts subnets used to + deploy network interfaces for deployed VM. - `authentication` - (`map`, optional, defaults to example defaults) authentication settings for the deployed VM. - The `authentication` property is optional and holds the firewall admin access details. By default, standard username - `panadmin` will be set and a random password will be auto-generated for you (available in Terraform outputs). + The `authentication` property is optional and holds the firewall admin access details. By default, standard username + `panadmin` will be set and a random password will be auto-generated for you (available in Terraform outputs). - **Note!** \ - The `disable_password_authentication` property is by default `false` in this example. When using this value, you don't have - to specify anything but you can still additionally pass SSH keys for authentication. You can however set this property to - `true`, then you have to specify `ssh_keys` property. - - For all properties and their default values see [module's documentation](../../modules/vmseries/README.md#authentication). - -- `image` - (`map`, required) properties defining a base image used by the deployed VM. - - The `image` property is required but there are only 2 properties (mutually exclusive) that have to be set, either: - - - `version` - (`string`) describes the PAN-OS image version from Azure Marketplace. - - `custom_id` - (`string`) absolute ID of your own custom PAN-OS image. - - For details on the other properties refer to [module's documentation](../../modules/vmseries/README.md#image). - -- `virtual_machine` - (`map`, optional, defaults to module defaults) a map that groups most common VM configuration options. - - The most often used option are as follows: - - - `size` - (`string`, optional, defaults to module defaults) Azure VM size (type). Consult the *VM-Series Deployment - Guide* as only a few selected sizes are supported. - - `zone` - (`string`, optional, defaults to module defaults) the Availability Zone in which the VM and (if deployed) - public IP addresses will be created. - - `disk_type` - (`string`, optional, defaults to module defaults) type of a Managed Disk which should be created, possible - values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected `size` values). - - `bootstrap_options` - (`string`, optional, mutually exclusive with `bootstrap_package`) bootstrap options passed to PAN-OS - when launched for the 1st time, for details see module documentation. - - `bootstrap_package` - (`map`, optional, mutually exclusive with `bootstrap_options`) a map defining content of the - bootstrap package. - - **Note!** \ - At least one of `static_files`, `bootstrap_xml_template` or `bootstrap_package_path` is required. You can use a - combination of all 3. The `bootstrap_package_path` is the less important. For details on this mechanism and for details - on the other properties see the [`bootstrap` module documentation](../../modules/bootstrap/README.md). - - Following properties are available: - - - `bootstrap_storage_key` - (`string`, required) a key of a bootstrap storage defined in `var.bootstrap_storages` that - will host bootstrap packages. Each package will be hosted on a separate File Share. - The File Shares will be created automatically, one for each firewall. - - `static_files` - (`map`, optional, defaults to `{}`) a map containing files that will be copied to a File - Share, see [`file_shares.bootstrap_files`](../../modules/bootstrap/README.md#file_shares) - property documentation for details. - - `bootstrap_package_path` - (`string`, optional, defaults to `null`) a path to a folder containing a full bootstrap - package. - - `bootstrap_xml_template` - (`string`, optional, defaults to `null`) a path to a `bootstrap.xml` template. If this - example is using full bootstrap method, the sample templates are in - [`templates`](./templates) folder. - - The templates are used to provide `day0` like configuration which consists of: - - - network interfaces configuration. - - one or more (depending on the architecture) Virtual Routers configurations. This config contains static routes - required for the Load Balancer (and Application Gateway, if defined) health checks to work and routes that allow - Inbound and OBEW traffic. - - *any-any* security rule. - - an outbound NAT rule that will allow the Outbound traffic to flow to the internet. - - **Note!** \ - Day0 configuration is **not meant** to be **secure**. It's here marly to help with the basic firewall setup. - - When `bootstrap_xml_template` is set, one of the following properties might be required. - - - `private_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key - pointing to a private Subnet definition in `var.vnets` (the `vnet_key` property is used to - identify a VNET). The Subnet definition is used to calculate static routes for a private - Load Balancer health checks and for Inbound traffic. - - `public_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key - pointing to a public Subnet definition in `var.vnets` (the `vnet_key` property is used to - identify a VNET). The Subnet definition is used to calculate static routes for a public - Load Balancer health checks and for Outbound traffic. - - `ai_update_interval` - (`number`, optional, defaults to `5`) Application Insights update interval, used only when - `ngfw_metrics` module is defined and used in this example. The Application Insights - Instrumentation Key will be populated automatically. - - `intranet_cidr` - (`string`, optional, defaults to `null`) a CIDR of the Intranet - combined CIDR of all - private networks. When set it will override the private Subnet CIDR for inbound traffic - static routes. - - For details on the other properties refer to [module's documentation](../../modules/panorama/README.md#virtual_machine). + **Note!** \ + The `disable_password_authentication` property is by default `false` in this example. When using this value, you don't have + to specify anything but you can still additionally pass SSH keys for authentication. You can however set this property to + `true`, then you have to specify `ssh_keys` property. -- `vnet_key` - (`string`, required) a key of a VNET defined in `var.vnets`. This is the VNET that hosts subnets used to - deploy network interfaces for deployed VM. + For all properties and their default values see [module's documentation](../../modules/vmseries/README.md#authentication). -- `interfaces` - (`list`, required) configuration of all network interfaces - - **Note!** \ - Order of the interfaces does matter - the 1st interface is the management one. +- `image` - (`map`, required) properties defining a base image used by the deployed VM. The `image` property is + required but there are only 2 properties (mutually exclusive) that have to be set, either: - For details on available properties please see [module's documentation](../../modules/panorama/README.md#interfaces). + - `version` - (`string`, optional) describes the PAN-OS image version from Azure Marketplace. + - `custom_id` - (`string`, optional) absolute ID of your own custom PAN-OS image. - The most important ones are listed below: + For details on all properties refer to [module's documentation](../../modules/vmseries/README.md#image). - - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`). - - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in - `var.vnets`. Key identifying the VNET is defined in `virtual_machine.vnet_key` property. - - `create_public_ip` - (`bool`, optional, defaults to `false`) create a Public IP for an interface. - - `load_balancer_key` - (`string`, optional, defaults to `null`) key of a Load Balancer defined in `var.loadbalancers` - variable, network interface that has this property defined will be added to the Load - Balancer's backend pool. - - `application_gateway_key` - (`string`, optional, defaults to `null`) key of an Application Gateway defined in `var.appgws` - variable, network interface that has this property defined will be added to the Application - Gateway's backend pool. +- `virtual_machine` - (`map`, optional, defaults to module default) a map that groups most common VM configuration options. + Most common properties are: + - `size` - (`string`, optional, defaults to module default) Azure VM size (type). Consult the *VM-Series + Deployment Guide* as only a few selected sizes are supported. + - `zone` - (`string`, optional, defaults to module default) the Availability Zone in which the VM and (if + deployed) public IP addresses will be created. + - `disk_type` - (`string`, optional, defaults to module default) type of a Managed Disk which should be created, + possible values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected + `size` values). + - `bootstrap_options` - (`string`, optional, mutually exclusive with `bootstrap_package`) bootstrap options passed to PAN-OS + when launched for the 1st time, for details see module documentation. + - `bootstrap_package` - (`map`, optional, mutually exclusive with `bootstrap_options`) a map defining content of the + bootstrap package. + + **Note!** \ + At least one of `static_files`, `bootstrap_xml_template` or `bootstrap_package_path` is required. You can use a combination + of all 3. The `bootstrap_package_path` is the less important. For details on this mechanism and for details on the other + properties see the [`bootstrap` module documentation](../../modules/bootstrap/README.md). + + Following properties are available: + + - `bootstrap_storage_key` - (`string`, required) a key of a bootstrap storage defined in `var.bootstrap_storages` that + will host bootstrap packages. Each package will be hosted on a separate File Share. The File + Shares will be created automatically, one for each firewall. + - `static_files` - (`map`, optional, defaults to `{}`) a map containing files that will be copied to a File + Share, see [`file_shares.bootstrap_files`](../../modules/bootstrap/README.md#file_shares) + property documentation for details. + - `bootstrap_package_path` - (`string`, optional, defaults to `null`) a path to a folder containing a full bootstrap + package. + - `bootstrap_xml_template` - (`string`, optional, defaults to `null`) a path to a `bootstrap.xml` template. If this example + is using full bootstrap method, the sample templates are in [`templates`](./templates) folder. + + The templates are used to provide `day0` like configuration which consists of: + + - network interfaces configuration. + - one or more (depending on the architecture) Virtual Routers configurations. This config contains static routes + required for the Load Balancer (and Application Gateway, if defined) health checks to work and routes that allow + Inbound and OBEW traffic. + - *any-any* security rule. + - an outbound NAT rule that will allow the Outbound traffic to flow to the Internet. + + **Note!** \ + Day0 configuration is **not meant** to be **secure**. It's here merely to help with the basic firewall setup. When + `bootstrap_xml_template` is set, one of the following properties might be required. + + - `private_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key + pointing to a private Subnet definition in `var.vnets` (the `vnet_key` property is used to + identify a VNET). The Subnet definition is used to calculate static routes for a private + Load Balancer health checks and for Inbound traffic. + - `public_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key + pointing to a public Subnet definition in `var.vnets` (the `vnet_key` property is used to + identify a VNET). The Subnet definition is used to calculate static routes for a public + Load Balancer health checks and for Outbound traffic. + - `ai_update_interval` - (`number`, optional, defaults to `5`) Application Insights update interval, used only when + `ngfw_metrics` module is defined and used in this example. The Application Insights + Instrumentation Key will be populated automatically. + - `intranet_cidr` - (`string`, optional, defaults to `null`) a CIDR of the Intranet - combined CIDR of all + private networks. When set it will override the private Subnet CIDR for inbound traffic + static routes. + + For details on all properties refer to [module's documentation](../../modules/panorama/README.md#virtual_machine). + +- `interfaces` - (`list`, required) configuration of all network interfaces. Order of the interfaces does matter - the + 1st interface is the management one. Most common properties are: + + - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`). + - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in + `var.vnets`. Key identifying the VNET is defined in `virtual_machine.vnet_key` property. + - `create_public_ip` - (`bool`, optional, defaults to `false`) create a Public IP for an interface. + - `load_balancer_key` - (`string`, optional, defaults to `null`) key of a Load Balancer defined in `var.loadbalancers` + variable, network interface that has this property defined will be added to the Load Balancer's + backend pool. + - `application_gateway_key` - (`string`, optional, defaults to `null`) key of an Application Gateway defined in `var.appgws` + variable, network interface that has this property defined will be added to the Application + Gateway's backend pool. + + For details on all properties refer to [module's documentation](../../modules/panorama/README.md#interfaces). Type: ```hcl map(object({ - name = string + name = string + vnet_key = string authentication = optional(object({ username = optional(string, "panadmin") password = optional(string) @@ -1063,7 +1068,6 @@ map(object({ identity_ids = optional(list(string)) allow_extension_operations = optional(bool) }) - vnet_key = string interfaces = list(object({ name = string subnet_key = string @@ -1082,6 +1086,4 @@ Default value: `map[]` [back to list](#modules-optional-inputs) - - \ No newline at end of file diff --git a/examples/dedicated_vmseries/example.tfvars b/examples/dedicated_vmseries/example.tfvars index e522960b..932692a9 100644 --- a/examples/dedicated_vmseries/example.tfvars +++ b/examples/dedicated_vmseries/example.tfvars @@ -1,4 +1,5 @@ -# --- GENERAL --- # +### GENERAL ### + location = "North Europe" resource_group_name = "transit-vnet-dedicated" name_prefix = "example-" @@ -7,7 +8,8 @@ tags = { "CreatedWith" = "Terraform" } -# --- VNET PART --- # +### NETWORK ### + vnets = { "transit" = { name = "transit" @@ -109,8 +111,8 @@ vnets = { } } +### LOAD BALANCING ### -# --- LOAD BALANCING PART --- # load_balancers = { "public" = { name = "public-lb" @@ -154,7 +156,8 @@ load_balancers = { } } -# --- VMSERIES PART --- # +### VM-SERIES ### + ngfw_metrics = { name = "metrics" } @@ -172,7 +175,8 @@ bootstrap_storages = { vmseries = { "fw-in-1" = { - name = "inbound-firewall01" + name = "inbound-firewall01" + vnet_key = "transit" image = { version = "10.2.3" } @@ -187,7 +191,6 @@ vmseries = { public_snet_key = "public" } } - vnet_key = "transit" interfaces = [ { name = "vm-in-01-mgmt" @@ -207,7 +210,8 @@ vmseries = { ] } "fw-in-2" = { - name = "inbound-firewall02" + name = "inbound-firewall02" + vnet_key = "transit" image = { version = "10.2.3" } @@ -222,7 +226,6 @@ vmseries = { public_snet_key = "public" } } - vnet_key = "transit" interfaces = [ { name = "vm-in-02-mgmt" @@ -241,7 +244,8 @@ vmseries = { ] } "fw-obew-1" = { - name = "obew-firewall01" + name = "obew-firewall01" + vnet_key = "transit" image = { version = "10.2.3" } @@ -256,7 +260,6 @@ vmseries = { public_snet_key = "public" } } - vnet_key = "transit" interfaces = [ { name = "vm-obew-01-mgmt" @@ -276,7 +279,8 @@ vmseries = { ] } "fw-obew-2" = { - name = "obew-firewall02" + name = "obew-firewall02" + vnet_key = "transit" image = { version = "10.2.3" } @@ -291,7 +295,6 @@ vmseries = { public_snet_key = "public" } } - vnet_key = "transit" interfaces = [ { name = "vm-obew-02-mgmt" diff --git a/examples/dedicated_vmseries/main.tf b/examples/dedicated_vmseries/main.tf index ecee2c8d..29fd01d5 100644 --- a/examples/dedicated_vmseries/main.tf +++ b/examples/dedicated_vmseries/main.tf @@ -1,4 +1,5 @@ -# Generate a random password. +### Generate a random password ### + # https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password resource "random_password" "this" { count = anytrue([ @@ -26,7 +27,8 @@ locals { } } -# Create or source the Resource Group. +### Create or source a Resource Group ### + # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group resource "azurerm_resource_group" "this" { count = var.create_resource_group ? 1 : 0 @@ -46,7 +48,8 @@ locals { resource_group = var.create_resource_group ? azurerm_resource_group.this[0] : data.azurerm_resource_group.this[0] } -# Manage the network required for the topology. +### Manage the network required for the topology ### + module "vnet" { source = "../../modules/vnet" @@ -62,15 +65,16 @@ module "vnet" { create_subnets = each.value.create_subnets subnets = each.value.subnets - network_security_groups = { for k, v in each.value.network_security_groups : k => merge(v, { name = "${var.name_prefix}${v.name}" }) + network_security_groups = { + for k, v in each.value.network_security_groups : k => merge(v, { name = "${var.name_prefix}${v.name}" }) } - route_tables = { for k, v in each.value.route_tables : k => merge(v, { name = "${var.name_prefix}${v.name}" }) + route_tables = { + for k, v in each.value.route_tables : k => merge(v, { name = "${var.name_prefix}${v.name}" }) } tags = var.tags } - module "natgw" { source = "../../modules/natgw" @@ -84,15 +88,19 @@ module "natgw" { idle_timeout = each.value.idle_timeout subnet_ids = { for v in each.value.subnet_keys : v => module.vnet[each.value.vnet_key].subnet_ids[v] } - public_ip = try(merge(each.value.public_ip, { name = "${each.value.public_ip.create ? var.name_prefix : ""}${each.value.public_ip.name}" }), null) - public_ip_prefix = try(merge(each.value.public_ip_prefix, { name = "${each.value.public_ip_prefix.create ? var.name_prefix : ""}${each.value.public_ip_prefix.name}" }), null) + public_ip = try(merge(each.value.public_ip, { + name = "${each.value.public_ip.create ? var.name_prefix : ""}${each.value.public_ip.name}" + }), null) + public_ip_prefix = try(merge(each.value.public_ip_prefix, { + name = "${each.value.public_ip_prefix.create ? var.name_prefix : ""}${each.value.public_ip_prefix.name}" + }), null) tags = var.tags depends_on = [module.vnet] } +### Create Load Balancers, both internal and external ### -# create load balancers, both internal and external module "load_balancer" { source = "../../modules/loadbalancer" @@ -109,7 +117,8 @@ module "load_balancer" { nsg_auto_rules_settings = try( { nsg_name = try( - "${var.name_prefix}${var.vnets[each.value.nsg_auto_rules_settings.nsg_vnet_key].network_security_groups[each.value.nsg_auto_rules_settings.nsg_key].name}", + "${var.name_prefix}${var.vnets[each.value.nsg_auto_rules_settings.nsg_vnet_key].network_security_groups[ + each.value.nsg_auto_rules_settings.nsg_key].name}", each.value.nsg_auto_rules_settings.nsg_name ) nsg_resource_group_name = try( @@ -137,9 +146,65 @@ module "load_balancer" { depends_on = [module.vnet] } +### Create Application Gateways ### + +locals { + nics_with_appgw_key = flatten([ + for k, v in var.vmseries : [ + for nic in v.interfaces : { + vm_key = k + nic_name = nic.name + appgw_key = nic.application_gateway_key + } if nic.application_gateway_key != null + ]]) + + ips_4_nics_with_appgw_key = { + for v in local.nics_with_appgw_key : + v.appgw_key => module.vmseries[v.vm_key].interfaces["${var.name_prefix}${v.nic_name}"].private_ip_address... + } +} + +module "appgw" { + source = "../../modules/appgw" + + for_each = var.appgws + + name = "${var.name_prefix}${each.value.name}" + resource_group_name = local.resource_group.name + location = var.location + subnet_id = module.vnet[each.value.vnet_key].subnet_ids[each.value.subnet_key] + + zones = each.value.zones + public_ip = merge( + each.value.public_ip, + { name = "${each.value.public_ip.create ? var.name_prefix : ""}${each.value.public_ip.name}" } + ) + domain_name_label = each.value.domain_name_label + capacity = each.value.capacity + enable_http2 = each.value.enable_http2 + waf = each.value.waf + managed_identities = each.value.managed_identities + global_ssl_policy = each.value.global_ssl_policy + ssl_profiles = each.value.ssl_profiles + frontend_ip_configuration_name = each.value.frontend_ip_configuration_name + listeners = each.value.listeners + backend_pool = merge( + each.value.backend_pool, + length(local.ips_4_nics_with_appgw_key) == 0 ? {} : { vmseries_ips = local.ips_4_nics_with_appgw_key[each.key] } + ) + backend_settings = each.value.backend_settings + probes = each.value.probes + rewrites = each.value.rewrites + redirects = each.value.redirects + url_path_maps = each.value.url_path_maps + rules = each.value.rules + + tags = var.tags + depends_on = [module.vnet, module.vmseries] +} +### Create VM-Series VMs and closely associated resources ### -# create the actual VM-Series VMs and resources module "ngfw_metrics" { source = "../../modules/ngfw_metrics" @@ -147,9 +212,11 @@ module "ngfw_metrics" { create_workspace = var.ngfw_metrics.create_workspace - name = "${var.ngfw_metrics.create_workspace ? var.name_prefix : ""}${var.ngfw_metrics.name}" - resource_group_name = var.ngfw_metrics.create_workspace ? local.resource_group.name : coalesce(var.ngfw_metrics.resource_group_name, local.resource_group.name) - location = var.location + name = "${var.ngfw_metrics.create_workspace ? var.name_prefix : ""}${var.ngfw_metrics.name}" + resource_group_name = var.ngfw_metrics.create_workspace ? local.resource_group.name : ( + coalesce(var.ngfw_metrics.resource_group_name, local.resource_group.name) + ) + location = var.location log_analytics_workspace = { sku = var.ngfw_metrics.sku @@ -161,6 +228,7 @@ module "ngfw_metrics" { tags = var.tags } +# https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file resource "local_file" "bootstrap_xml" { for_each = { for k, v in var.vmseries : @@ -287,8 +355,10 @@ module "vmseries" { coalesce( each.value.virtual_machine.bootstrap_options, join(",", [ - "storage-account=${module.bootstrap[each.value.virtual_machine.bootstrap_package.bootstrap_storage_key].storage_account_name}", - "access-key=${module.bootstrap[each.value.virtual_machine.bootstrap_package.bootstrap_storage_key].storage_account_primary_access_key}", + "storage-account=${module.bootstrap[ + each.value.virtual_machine.bootstrap_package.bootstrap_storage_key].storage_account_name}", + "access-key=${module.bootstrap[ + each.value.virtual_machine.bootstrap_package.bootstrap_storage_key].storage_account_primary_access_key}", "file-share=${each.key}", "share-directory=None" ]), @@ -299,10 +369,12 @@ module "vmseries" { ) interfaces = [for v in each.value.interfaces : { - name = "${var.name_prefix}${v.name}" - subnet_id = module.vnet[each.value.vnet_key].subnet_ids[v.subnet_key] - create_public_ip = v.create_public_ip - public_ip_name = v.create_public_ip ? "${var.name_prefix}${coalesce(v.public_ip_name, "${v.name}-pip")}" : v.public_ip_name + name = "${var.name_prefix}${v.name}" + subnet_id = module.vnet[each.value.vnet_key].subnet_ids[v.subnet_key] + create_public_ip = v.create_public_ip + public_ip_name = v.create_public_ip ? "${ + var.name_prefix}${coalesce(v.public_ip_name, "${v.name}-pip") + }" : v.public_ip_name public_ip_resource_group_name = v.public_ip_resource_group_name private_ip_address = v.private_ip_address attach_to_lb_backend_pool = v.load_balancer_key != null @@ -318,60 +390,3 @@ module "vmseries" { module.bootstrap, ] } - -# Create Application Gateway - -locals { - nics_with_appgw_key = flatten([ - for k, v in var.vmseries : [ - for nic in v.interfaces : { - vm_key = k - nic_name = nic.name - appgw_key = nic.application_gateway_key - } if nic.application_gateway_key != null - ]]) - - ips_4_nics_with_appgw_key = { - for v in local.nics_with_appgw_key : - v.appgw_key => module.vmseries[v.vm_key].interfaces["${var.name_prefix}${v.nic_name}"].private_ip_address... - } -} - -module "appgw" { - source = "../../modules/appgw" - - for_each = var.appgws - - name = "${var.name_prefix}${each.value.name}" - resource_group_name = local.resource_group.name - location = var.location - subnet_id = module.vnet[each.value.vnet_key].subnet_ids[each.value.subnet_key] - - zones = each.value.zones - public_ip = merge( - each.value.public_ip, - { name = "${each.value.public_ip.create ? var.name_prefix : ""}${each.value.public_ip.name}" } - ) - domain_name_label = each.value.domain_name_label - capacity = each.value.capacity - enable_http2 = each.value.enable_http2 - waf = each.value.waf - managed_identities = each.value.managed_identities - global_ssl_policy = each.value.global_ssl_policy - ssl_profiles = each.value.ssl_profiles - frontend_ip_configuration_name = each.value.frontend_ip_configuration_name - listeners = each.value.listeners - backend_pool = merge( - each.value.backend_pool, - length(local.ips_4_nics_with_appgw_key) == 0 ? {} : { vmseries_ips = local.ips_4_nics_with_appgw_key[each.key] } - ) - backend_settings = each.value.backend_settings - probes = each.value.probes - rewrites = each.value.rewrites - redirects = each.value.redirects - url_path_maps = each.value.url_path_maps - rules = each.value.rules - - tags = var.tags - depends_on = [module.vnet, module.vmseries] -} diff --git a/examples/dedicated_vmseries/variables.tf b/examples/dedicated_vmseries/variables.tf index d401eaab..8a26966e 100644 --- a/examples/dedicated_vmseries/variables.tf +++ b/examples/dedicated_vmseries/variables.tf @@ -1,14 +1,4 @@ -### GENERAL -variable "tags" { - description = "Map of tags to assign to the created resources." - default = {} - type = map(string) -} - -variable "location" { - description = "The Azure region to use." - type = string -} +### GENERAL ### variable "name_prefix" { description = <<-EOF @@ -45,33 +35,41 @@ variable "resource_group_name" { type = string } +variable "location" { + description = "The Azure region to use." + type = string +} +variable "tags" { + description = "Map of tags to assign to the created resources." + default = {} + type = map(string) +} + +### NETWORK ### -### VNET variable "vnets" { description = <<-EOF A map defining VNETs. For detailed documentation on each property refer to [module documentation](../../modules/vnet/README.md) - - `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, - `false` will source an existing VNET. - - `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be - a full resource name, including prefixes. - - `address_space` - (`list(string)`, required when `create_virtual_network = false`) a list of CIDRs for a newly - created VNET - - `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which - the VNET will reside or is sourced from + - `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, `false` will source + an existing VNET. + - `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be a + full resource name, including prefixes. + - `address_space` - (`list`, required when `create_virtual_network = false`) a list of CIDRs for a newly created VNET. + - `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which the + VNET will reside or is sourced from. - `create_subnets` - (`bool`, optional, defaults to `true`) if `true`, create Subnets inside the Virtual Network, - otherwise use source existing subnets + otherwise use source existing subnets. - `subnets` - (`map`, optional) map of Subnets to create or source, for details see - [VNET module documentation](../../modules/vnet/README.md#subnets) + [VNET module documentation](../../modules/vnet/README.md#subnets). - `network_security_groups` - (`map`, optional) map of Network Security Groups to create, for details see - [VNET module documentation](../../modules/vnet/README.md#network_security_groups) + [VNET module documentation](../../modules/vnet/README.md#network_security_groups). - `route_tables` - (`map`, optional) map of Route Tables to create, for details see - [VNET module documentation](../../modules/vnet/README.md#route_tables) + [VNET module documentation](../../modules/vnet/README.md#route_tables). EOF - type = map(object({ name = string resource_group_name = optional(string) @@ -125,21 +123,21 @@ variable "natgws" { For detailed documentation on each property refer to [module documentation](../../modules/natgw/README.md). Following properties are supported: - - `create_natgw` - (`bool`, optional, defaults to `true`) create (`true`) or source an existing NAT Gateway (`false`), - created or sourced: the NAT Gateway will be assigned to a subnet created by the `vnet` module. - - `name` - (`string`, required) a name of a NAT Gateway. In case `create_natgw = false` this should be a full - resource name, including prefixes. - - `resource_group_name - (`string`, optional) name of a Resource Group hosting the NAT Gateway (newly created or the existing - one). - - `zone` - (`string`, optional) an Availability Zone in which the NAT Gateway will be placed, when skipped - AzureRM will pick a zone. - - `idle_timeout` - (`number`, optional, defults to 4) connection IDLE timeout in minutes, for newly created resources. - - `vnet_key` - (`string`, required) a name (key value) of a VNET defined in `var.vnets` that hosts a subnet this - NAT Gateway will be assigned to. - - `subnet_keys` - (`list(string)`, required) a list of subnets (key values) the NAT Gateway will be assigned to, defined - in `var.vnets` for a VNET described by `vnet_name`. - - `public_ip` - (`object`, optional) an object defining a public IP resource attached to the NAT Gateway. - - `public_ip_prefix` - (`object`, optional) an object defining a public IP prefix resource attached to the NAT Gatway. + - `name` - (`string`, required) a name of a NAT Gateway. In case `create_natgw = false` this should be a full + resource name, including prefixes. + - `vnet_key` - (`string`, required) a name (key value) of a VNET defined in `var.vnets` that hosts a subnet this + NAT Gateway will be assigned to. + - `subnet_keys` - (`list(string)`, required) a list of subnets (key values) the NAT Gateway will be assigned to, + defined in `var.vnets` for a VNET described by `vnet_name`. + - `create_natgw` - (`bool`, optional, defaults to `true`) create (`true`) or source an existing NAT Gateway (`false`), + created or sourced: the NAT Gateway will be assigned to a subnet created by the `vnet` module. + - `resource_group_name` - (`string`, optional) name of a Resource Group hosting the NAT Gateway (newly created or the existing + one). + - `zone` - (`string`, optional) an Availability Zone in which the NAT Gateway will be placed, when skipped + Azure will pick a zone. + - `idle_timeout` - (`number`, optional, defults to 4) connection IDLE timeout in minutes, for newly created resources. + - `public_ip` - (`object`, optional) an object defining a public IP resource attached to the NAT Gateway. + - `public_ip_prefix` - (`object`, optional) an object defining a public IP prefix resource attached to the NAT Gatway. Example: ``` @@ -158,13 +156,13 @@ variable "natgws" { EOF default = {} type = map(object({ - create_natgw = optional(bool, true) name = string + vnet_key = string + subnet_keys = list(string) + create_natgw = optional(bool, true) resource_group_name = optional(string) zone = optional(string) idle_timeout = optional(number, 4) - vnet_key = string - subnet_keys = list(string) public_ip = optional(object({ create = bool name = string @@ -179,12 +177,11 @@ variable "natgws" { })) } +### LOAD BALANCING ### - -### Load Balancing variable "load_balancers" { description = <<-EOF - A map containing configuration for all (private and public) Load Balancers. + A map containing configuration for all (both private and public) Load Balancers. This is a brief description of available properties. For a detailed one please refer to [module documentation](../../modules/loadbalancer/README.md). @@ -194,26 +191,29 @@ variable "load_balancers" { - `name` - (`string`, required) a name of the Load Balancer. - `vnet_key` - (`string`, optional, defaults to `null`) a key pointing to a VNET definition in the `var.vnets` map that stores the Subnet described by `subnet_key`. - - `zones` - (`list`, optional, defaults to module defaults) a list of zones for Load Balancer's fronted IP + - `zones` - (`list`, optional, defaults to module default) a list of zones for Load Balancer's frontend IP configurations. - - `backend_name` - (`string`, optional, defaults to module defaults) a name of the backend pool to create. - - `health_probes` - (`map`, optional, defaults to `null`) a map defining health probes that will be used by - load balancing rules; please check + - `backend_name` - (`string`, optional, defaults to module default) a name of the backend pool to create. + - `health_probes` - (`map`, optional, defaults to `null`) a map defining health probes that will be used by load + balancing rules, please refer to [module documentation](../../modules/loadbalancer/README.md#health_probes) for more specific use cases and available properties. - - `nsg_auto_rules_settings` - (`map`, optional, defaults to `null`) a map defining a location of an existing NSG rule - that will be populated with `Allow` rules for each load balancing rule (`in_rules`); please check - [module documentation](../../modules/loadbalancer/README.md#nsg_auto_rules_settings) - for available properties; please note that in this example two additional properties are - available: - - `nsg_vnet_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to a VNET definition - in the `var.vnets` map that stores the NSG described by `nsg_key`. - - `nsg_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to an NSG definition - in the `var.vnets` map. - - `frontend_ips` - (`map`, optional, defaults to `{}`) a map containing frontend IP configuration with respective - `in_rules` and `out_rules` + - `nsg_auto_rules_settings` - (`map`, optional, defaults to `null`) a map defining a location of an existing NSG rule that will + be populated with `Allow` rules for each load balancing rule (`in_rules`), please refer to + [module documentation](../../modules/loadbalancer/README.md#nsg_auto_rules_settings) for + available properties. + + Please note that in this example two additional properties are available: + + - `nsg_vnet_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to a VNET definition in the + `var.vnets` map that stores the NSG described by `nsg_key`. + - `nsg_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to an NSG definition in the + `var.vnets` map. - Please refer to [module documentation](../../modules/loadbalancer/README.md#frontend_ips) for available properties. + - `frontend_ips` - (`map`, optional, defaults to `{}`) a map containing frontend IP configuration with respective + `in_rules` and `out_rules`, please refer to + [module documentation](../../modules/loadbalancer/README.md#frontend_ips) for available + properties. **Note!** \ In this example the `subnet_id` is not available directly, another property has been introduced instead: @@ -245,10 +245,10 @@ variable "load_balancers" { })) frontend_ips = optional(map(object({ name = string + subnet_key = optional(string) public_ip_name = optional(string) create_public_ip = optional(bool, false) public_ip_resource_group_name = optional(string) - subnet_key = optional(string) private_ip_address = optional(string) gwlb_key = optional(string) in_rules = optional(map(object({ @@ -272,29 +272,195 @@ variable "load_balancers" { })) } +variable "appgws" { + description = <<-EOF + A map defining all Application Gateways in the current deployment. + + For detailed documentation on how to configure this resource, for available properties, especially for the defaults, + refer to [module documentation](../../modules/appgw/README.md). + + **Note!** \ + The `rules` property is meant to bind together `backend_setting`, `redirect` or `url_path_map` (all 3 are mutually exclusive). + It represents the Rules section of an Application Gateway in Azure Portal. + + Below you can find a brief list of most important properties: + + - `name` - (`string`, required) the name of the Application Gateway, will be prefixed with `var.name_prefix`. + - `vnet_key` - (`string`, required) a key pointing to a VNET definition in the `var.vnets` map that stores the Subnet + described by `subnet_key`. + - `subnet_key` - (`string`, required) a key pointing to a Subnet definition in the `var.vnets` map, this has to be an + Application Gateway V2 dedicated subnet. + - `zones` - (`list`, optional, defaults to module default) parameter controlling if this is a zonal, or a non-zonal + deployment. + - `public_ip` - (`map`, required) defines a Public IP resource used by the Application Gateway instance, a newly created + Public IP will have it's name prefixes with `var.name_prefix`. + - `listeners` - (`map`, required) defines Application Gateway's Listeners, see + [module's documentation](../../modules/appgw/README.md#listeners) for details. + - `backend_pool` - (`map`, optional, defaults to module default) backend pool definition, when skipped an empty backend + will be created. + - `backend_settings` - (`map`, optional, mutually exclusive with `redirects` and `url_path_maps`) defines HTTP backend + settings, see [module's documentation](../../modules/appgw/README.md#backend_settings) for details. + - `probes` - (`map`, optional, defaults to module default) defines backend probes used check health of backends, see + [module's documentation](../../modules/appgw/README.md#probes) for details. + - `rewrites` - (`map`, optional, defaults to module default) defines rewrite rules, see + [module's documentation](../../modules/appgw/README.md#rewrites) for details. + - `redirects` - (`map`, optional, mutually exclusive with `backend_settings` and `url_path_maps`) static redirects + definition, see [module's documentation](../../modules/appgw/README.md#redirects) for details. + - `url_path_maps` - (`map`, optional, mutually exclusive with `backend_settings` and `redirects`) URL path maps definition, + see [module's documentation](../../modules/appgw/README.md#url_path_maps) for details. + - `rules` - (`map`, required) Application Gateway Rules definition, bind together a `listener` with either + `backend_setting`, `redirect` or `url_path_map`, see + [module's documentation](../../modules/appgw/README.md#rules) for details. + EOF + type = map(object({ + name = string + vnet_key = string + subnet_key = string + zones = optional(list(string)) + public_ip = object({ + name = string + create = optional(bool, true) + resource_group_name = optional(string) + }) + domain_name_label = optional(string) + capacity = optional(object({ + static = optional(number) + autoscale = optional(object({ + min = number + max = number + })) + })) + enable_http2 = optional(bool) + waf = optional(object({ + prevention_mode = bool + rule_set_type = optional(string) + rule_set_version = optional(string) + })) + managed_identities = optional(list(string)) + global_ssl_policy = optional(object({ + type = optional(string) + name = optional(string) + min_protocol_version = optional(string) + cipher_suites = optional(list(string)) + })) + ssl_profiles = optional(map(object({ + name = string + ssl_policy_name = optional(string) + ssl_policy_min_protocol_version = optional(string) + ssl_policy_cipher_suites = optional(list(string)) + }))) + frontend_ip_configuration_name = optional(string) + listeners = map(object({ + name = string + port = number + protocol = optional(string) + host_names = optional(list(string)) + ssl_profile_name = optional(string) + ssl_certificate_path = optional(string) + ssl_certificate_pass = optional(string) + ssl_certificate_vault_id = optional(string) + custom_error_pages = optional(map(string)) + })) + backend_pool = optional(object({ + name = optional(string) + vmseries_ips = optional(list(string)) + })) + backend_settings = optional(map(object({ + name = string + port = number + protocol = string + path = optional(string) + hostname_from_backend = optional(string) + hostname = optional(string) + timeout = optional(number) + use_cookie_based_affinity = optional(bool) + affinity_cookie_name = optional(string) + probe = optional(string) + root_certs = optional(map(object({ + name = string + path = string + }))) + }))) + probes = optional(map(object({ + name = string + path = string + host = optional(string) + port = optional(number) + protocol = optional(string) + interval = optional(number) + timeout = optional(number) + threshold = optional(number) + match_code = optional(list(number)) + match_body = optional(string) + }))) + rewrites = optional(map(object({ + name = optional(string) + rules = optional(map(object({ + name = string + sequence = number + conditions = optional(map(object({ + pattern = string + ignore_case = optional(bool) + negate = optional(bool) + }))) + request_headers = optional(map(string)) + response_headers = optional(map(string)) + }))) + }))) + redirects = optional(map(object({ + name = string + type = string + target_listener_key = optional(string) + target_url = optional(string) + include_path = optional(bool) + include_query_string = optional(bool) + }))) + url_path_maps = optional(map(object({ + name = string + backend_key = string + path_rules = optional(map(object({ + paths = list(string) + backend_key = optional(string) + redirect_key = optional(string) + }))) + }))) + rules = map(object({ + name = string + priority = number + backend_key = optional(string) + listener_key = string + rewrite_key = optional(string) + url_path_map_key = optional(string) + redirect_key = optional(string) + })) + })) +} + +### VM-SERIES ### variable "availability_sets" { description = <<-EOF A map defining availability sets. Can be used to provide infrastructure high availability when zones cannot be used. Following properties are supported: - - `name` - name of the Application Insights. - - `update_domain_count` - specifies the number of update domains that are used, defaults to 5 (Azure defaults). - - `fault_domain_count` - specifies the number of fault domains that are used, defaults to 3 (Azure defaults). - Please keep in mind that Azure defaults are not working for each region (especially the small ones, w/o any Availability Zones). - Please verify how many update and fault domain are supported in a region before deploying this resource. + - `name` - (`string`, required) name of the Application Insights. + - `update_domain_count` - (`number`, optional, defaults to Azure default) specifies the number of update domains that are used. + - `fault_domain_count` - (`number`, optional, defaults to Azure default) specifies the number of fault domains that are used. + + **Note!** \ + Please keep in mind that Azure defaults are not working for every region (especially the small ones, without any Availability + Zones). Please verify how many update and fault domain are supported in a region before deploying this resource. EOF default = {} nullable = false type = map(object({ name = string - update_domain_count = optional(number, 5) - fault_domain_count = optional(number, 3) + update_domain_count = optional(number) + fault_domain_count = optional(number) })) } - variable "ngfw_metrics" { description = <<-EOF A map controlling metrics-relates resources. @@ -302,22 +468,22 @@ variable "ngfw_metrics" { When set to explicit `null` (default) it will disable any metrics resources in this deployment. When defined it will either create or source a Log Analytics Workspace and create Application Insights instances (one per each - Scale Set). All instances will be automatically connected to the workspace. - The name of the Application Insights instance will be derived from the Scale Set name and suffixed with `-ai`. + Scale Set). All instances will be automatically connected to the workspace. The name of the Application Insights instance will + be derived from the Scale Set name and suffixed with `-ai`. All the settings available below are common to the Log Analytics Workspace and Application Insight instances. Following properties are available: - - `name` - (`string`, required) name of the (common) Log Analytics Workspace + - `name` - (`string`, required) name of the (common) Log Analytics Workspace. - `create_workspace` - (`bool`, optional, defaults to `true`) controls whether we create or source an existing Log - Analytics Workspace + Analytics Workspace. - `resource_group_name` - (`string`, optional, defaults to `var.resource_group_name`) name of the Resource Group hosting - the Log Analytics Workspace - - `sku` - (`string`, optional, defaults to module defaults) the SKU of the Log Analytics Workspace. - - `metrics_retention_in_days` - (`number`, optional, defaults to module defaults) workspace and insights data retention in - days, possible values are between 30 and 730. For sourced Workspaces this applies only to - the Application Insights instances. + the Log Analytics Workspace. + - `sku` - (`string`, optional, defaults to module default) the SKU of the Log Analytics Workspace. + - `metrics_retention_in_days` - (`number`, optional, defaults to module default) workspace and insights data retention in days, + possible values are between 30 and 730. For sourced Workspaces this applies only to the + Application Insights instances. EOF default = null type = object({ @@ -338,41 +504,50 @@ variable "bootstrap_storages" { - `name` - (`string`, required) name of the Storage Account that will be created or sourced. - **Note** \ - For new Storage Accounts this name will not be prefixed with `var.name_prefix`. \ - Please note the limitations on naming. This has to be a globally unique name, between 3 and 63 chars, only lower-case - letters and numbers. + **Note** \ + For new Storage Accounts this name will not be prefixed with `var.name_prefix`. \ + Please note the limitations on naming. This has to be a globally unique name, between 3 and 63 chars, only lower-case letters + and numbers. - - `resource_group_name` - (`string`, optional, defaults to `null`) name of the Resource Group that hosts (sourced) or will - host (created) a Storage Account. When skipped the code will fall back to + - `resource_group_name` - (`string`, optional, defaults to `null`) name of the Resource Group that hosts (sourced) or + will host (created) a Storage Account. When skipped the code will fall back to `var.resource_group_name`. - - `storage_account` - (`map`, optional, defaults to `{}`) a map controlling basic Storage Account configuration, for - detailed documentation see - [module's documentation](../../modules/bootstrap/README.md#storage_account). The property you - should pay attention to is: - - `create` - (`bool`, optional, defaults to module defaults) controls if the Storage Account specified in - the `name` property will be created or sourced. + - `storage_account` - (`map`, optional, defaults to `{}`) a map controlling basic Storage Account configuration. + + The property you should pay attention to is: + + - `create` - (`bool`, optional, defaults to module default) controls if the Storage Account specified in the `name` property + will be created or sourced. + + For detailed documentation see [module's documentation](../../modules/bootstrap/README.md#storage_account). + - `storage_network_security` - (`map`, optional, defaults to `{}`) a map defining network security settings for a **new** - storage account, for details see - [module's documentation](../../modules/bootstrap/README.md#storage_network_security). Properties - worth mentioning are: - - `allowed_subnet_keys` - (`list`, optional, defaults to `[]`) a list of keys pointing to Subnet definitions in the - `var.vnets` map. These Subnets will have dedicated access to the Storage Account. For this to - work they also need to have the Storage Account Service Endpoint enabled. - - `vnet_key` - a key pointing to a VNET definition in the `var.vnets` map that stores the Subnets described - in `allowed_subnet_keys`. - - `file_shares_configuration` - (`map`, optional, defaults to `{}`) a map defining common File Share setting. For detailed - documentation see - [module's documentation](../../modules/bootstrap/README.md#file_shares_configuration). The - properties you should pay your attention to are: - - `create_file_shares` - (`bool`, optional, defaults to module defaults) controls if the File Shares defined in the + storage account. + + The properties you should pay attention to are: + + - `allowed_subnet_keys` - (`list`, optional, defaults to `[]`) a list of keys pointing to Subnet definitions in the + `var.vnets` map. These Subnets will have dedicated access to the Storage Account. For this to work + they also need to have the Storage Account Service Endpoint enabled. + - `vnet_key` - (`string`, optional) a key pointing to a VNET definition in the `var.vnets` map that stores the + Subnets described in `allowed_subnet_keys`. + + For detailed documentation see [module's documentation](../../modules/bootstrap/README.md#storage_network_security). + + - `file_shares_configuration` - (`map`, optional, defaults to `{}`) a map defining common File Share setting. + + The properties you should pay attention to are: + + - `create_file_shares` - (`bool`, optional, defaults to module default) controls if the File Shares defined in the `file_shares` property will be created or sourced. - - `disable_package_dirs_creation` - (`bool`, optional, defaults to module defaults) for sourced File Shares, controls if the + - `disable_package_dirs_creation` - (`bool`, optional, defaults to module default) for sourced File Shares, controls if the bootstrap package folder structure will be created. + + For detailed documentation see [module's documentation](../../modules/bootstrap/README.md#file_shares_configuration). + - `file_shares` - (`map`, optional, defaults to `{}`) a map that holds File Shares and bootstrap package configuration. For detailed description see [module's documentation](../../modules/bootstrap/README.md#file_shares). - EOF default = {} nullable = false @@ -410,127 +585,119 @@ variable "bootstrap_storages" { variable "vmseries" { description = <<-EOF - A map defining Azure Virtual Machines based on Palo Alto Networks Next Generation Firewall image.. + A map defining Azure Virtual Machines based on Palo Alto Networks Next Generation Firewall image. For details and defaults for available options please refer to the [`vmseries`](../../modules/vmseries/README.md) module. The most basic properties are as follows: - `name` - (`string`, required) name of the VM, will be prefixed with the value of `var.name_prefix`. + - `vnet_key` - (`string`, required) a key of a VNET defined in `var.vnets`. This is the VNET that hosts subnets used to + deploy network interfaces for deployed VM. - `authentication` - (`map`, optional, defaults to example defaults) authentication settings for the deployed VM. - The `authentication` property is optional and holds the firewall admin access details. By default, standard username - `panadmin` will be set and a random password will be auto-generated for you (available in Terraform outputs). + The `authentication` property is optional and holds the firewall admin access details. By default, standard username + `panadmin` will be set and a random password will be auto-generated for you (available in Terraform outputs). - **Note!** \ - The `disable_password_authentication` property is by default `false` in this example. When using this value, you don't have - to specify anything but you can still additionally pass SSH keys for authentication. You can however set this property to - `true`, then you have to specify `ssh_keys` property. - - For all properties and their default values see [module's documentation](../../modules/vmseries/README.md#authentication). - - - `image` - (`map`, required) properties defining a base image used by the deployed VM. - - The `image` property is required but there are only 2 properties (mutually exclusive) that have to be set, either: - - - `version` - (`string`) describes the PAN-OS image version from Azure Marketplace. - - `custom_id` - (`string`) absolute ID of your own custom PAN-OS image. - - For details on the other properties refer to [module's documentation](../../modules/vmseries/README.md#image). - - - `virtual_machine` - (`map`, optional, defaults to module defaults) a map that groups most common VM configuration options. - - The most often used option are as follows: - - - `size` - (`string`, optional, defaults to module defaults) Azure VM size (type). Consult the *VM-Series Deployment - Guide* as only a few selected sizes are supported. - - `zone` - (`string`, optional, defaults to module defaults) the Availability Zone in which the VM and (if deployed) - public IP addresses will be created. - - `disk_type` - (`string`, optional, defaults to module defaults) type of a Managed Disk which should be created, possible - values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected `size` values). - - `bootstrap_options` - (`string`, optional, mutually exclusive with `bootstrap_package`) bootstrap options passed to PAN-OS - when launched for the 1st time, for details see module documentation. - - `bootstrap_package` - (`map`, optional, mutually exclusive with `bootstrap_options`) a map defining content of the - bootstrap package. - - **Note!** \ - At least one of `static_files`, `bootstrap_xml_template` or `bootstrap_package_path` is required. You can use a - combination of all 3. The `bootstrap_package_path` is the less important. For details on this mechanism and for details - on the other properties see the [`bootstrap` module documentation](../../modules/bootstrap/README.md). - - Following properties are available: - - - `bootstrap_storage_key` - (`string`, required) a key of a bootstrap storage defined in `var.bootstrap_storages` that - will host bootstrap packages. Each package will be hosted on a separate File Share. - The File Shares will be created automatically, one for each firewall. - - `static_files` - (`map`, optional, defaults to `{}`) a map containing files that will be copied to a File - Share, see [`file_shares.bootstrap_files`](../../modules/bootstrap/README.md#file_shares) - property documentation for details. - - `bootstrap_package_path` - (`string`, optional, defaults to `null`) a path to a folder containing a full bootstrap - package. - - `bootstrap_xml_template` - (`string`, optional, defaults to `null`) a path to a `bootstrap.xml` template. If this - example is using full bootstrap method, the sample templates are in - [`templates`](./templates) folder. - - The templates are used to provide `day0` like configuration which consists of: - - - network interfaces configuration. - - one or more (depending on the architecture) Virtual Routers configurations. This config contains static routes - required for the Load Balancer (and Application Gateway, if defined) health checks to work and routes that allow - Inbound and OBEW traffic. - - *any-any* security rule. - - an outbound NAT rule that will allow the Outbound traffic to flow to the internet. - - **Note!** \ - Day0 configuration is **not meant** to be **secure**. It's here marly to help with the basic firewall setup. - - When `bootstrap_xml_template` is set, one of the following properties might be required. - - - `private_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key - pointing to a private Subnet definition in `var.vnets` (the `vnet_key` property is used to - identify a VNET). The Subnet definition is used to calculate static routes for a private - Load Balancer health checks and for Inbound traffic. - - `public_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key - pointing to a public Subnet definition in `var.vnets` (the `vnet_key` property is used to - identify a VNET). The Subnet definition is used to calculate static routes for a public - Load Balancer health checks and for Outbound traffic. - - `ai_update_interval` - (`number`, optional, defaults to `5`) Application Insights update interval, used only when - `ngfw_metrics` module is defined and used in this example. The Application Insights - Instrumentation Key will be populated automatically. - - `intranet_cidr` - (`string`, optional, defaults to `null`) a CIDR of the Intranet - combined CIDR of all - private networks. When set it will override the private Subnet CIDR for inbound traffic - static routes. - - For details on the other properties refer to [module's documentation](../../modules/panorama/README.md#virtual_machine). + **Note!** \ + The `disable_password_authentication` property is by default `false` in this example. When using this value, you don't have + to specify anything but you can still additionally pass SSH keys for authentication. You can however set this property to + `true`, then you have to specify `ssh_keys` property. - - `vnet_key` - (`string`, required) a key of a VNET defined in `var.vnets`. This is the VNET that hosts subnets used to - deploy network interfaces for deployed VM. + For all properties and their default values see [module's documentation](../../modules/vmseries/README.md#authentication). - - `interfaces` - (`list`, required) configuration of all network interfaces - - **Note!** \ - Order of the interfaces does matter - the 1st interface is the management one. + - `image` - (`map`, required) properties defining a base image used by the deployed VM. The `image` property is + required but there are only 2 properties (mutually exclusive) that have to be set, either: - For details on available properties please see [module's documentation](../../modules/panorama/README.md#interfaces). + - `version` - (`string`, optional) describes the PAN-OS image version from Azure Marketplace. + - `custom_id` - (`string`, optional) absolute ID of your own custom PAN-OS image. - The most important ones are listed below: + For details on all properties refer to [module's documentation](../../modules/vmseries/README.md#image). - - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`). - - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in - `var.vnets`. Key identifying the VNET is defined in `virtual_machine.vnet_key` property. - - `create_public_ip` - (`bool`, optional, defaults to `false`) create a Public IP for an interface. - - `load_balancer_key` - (`string`, optional, defaults to `null`) key of a Load Balancer defined in `var.loadbalancers` - variable, network interface that has this property defined will be added to the Load - Balancer's backend pool. - - `application_gateway_key` - (`string`, optional, defaults to `null`) key of an Application Gateway defined in `var.appgws` - variable, network interface that has this property defined will be added to the Application - Gateway's backend pool. + - `virtual_machine` - (`map`, optional, defaults to module default) a map that groups most common VM configuration options. + Most common properties are: + - `size` - (`string`, optional, defaults to module default) Azure VM size (type). Consult the *VM-Series + Deployment Guide* as only a few selected sizes are supported. + - `zone` - (`string`, optional, defaults to module default) the Availability Zone in which the VM and (if + deployed) public IP addresses will be created. + - `disk_type` - (`string`, optional, defaults to module default) type of a Managed Disk which should be created, + possible values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected + `size` values). + - `bootstrap_options` - (`string`, optional, mutually exclusive with `bootstrap_package`) bootstrap options passed to PAN-OS + when launched for the 1st time, for details see module documentation. + - `bootstrap_package` - (`map`, optional, mutually exclusive with `bootstrap_options`) a map defining content of the + bootstrap package. + + **Note!** \ + At least one of `static_files`, `bootstrap_xml_template` or `bootstrap_package_path` is required. You can use a combination + of all 3. The `bootstrap_package_path` is the less important. For details on this mechanism and for details on the other + properties see the [`bootstrap` module documentation](../../modules/bootstrap/README.md). + + Following properties are available: + + - `bootstrap_storage_key` - (`string`, required) a key of a bootstrap storage defined in `var.bootstrap_storages` that + will host bootstrap packages. Each package will be hosted on a separate File Share. The File + Shares will be created automatically, one for each firewall. + - `static_files` - (`map`, optional, defaults to `{}`) a map containing files that will be copied to a File + Share, see [`file_shares.bootstrap_files`](../../modules/bootstrap/README.md#file_shares) + property documentation for details. + - `bootstrap_package_path` - (`string`, optional, defaults to `null`) a path to a folder containing a full bootstrap + package. + - `bootstrap_xml_template` - (`string`, optional, defaults to `null`) a path to a `bootstrap.xml` template. If this example + is using full bootstrap method, the sample templates are in [`templates`](./templates) folder. + + The templates are used to provide `day0` like configuration which consists of: + + - network interfaces configuration. + - one or more (depending on the architecture) Virtual Routers configurations. This config contains static routes + required for the Load Balancer (and Application Gateway, if defined) health checks to work and routes that allow + Inbound and OBEW traffic. + - *any-any* security rule. + - an outbound NAT rule that will allow the Outbound traffic to flow to the Internet. + + **Note!** \ + Day0 configuration is **not meant** to be **secure**. It's here merely to help with the basic firewall setup. When + `bootstrap_xml_template` is set, one of the following properties might be required. + + - `private_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key + pointing to a private Subnet definition in `var.vnets` (the `vnet_key` property is used to + identify a VNET). The Subnet definition is used to calculate static routes for a private + Load Balancer health checks and for Inbound traffic. + - `public_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key + pointing to a public Subnet definition in `var.vnets` (the `vnet_key` property is used to + identify a VNET). The Subnet definition is used to calculate static routes for a public + Load Balancer health checks and for Outbound traffic. + - `ai_update_interval` - (`number`, optional, defaults to `5`) Application Insights update interval, used only when + `ngfw_metrics` module is defined and used in this example. The Application Insights + Instrumentation Key will be populated automatically. + - `intranet_cidr` - (`string`, optional, defaults to `null`) a CIDR of the Intranet - combined CIDR of all + private networks. When set it will override the private Subnet CIDR for inbound traffic + static routes. + + For details on all properties refer to [module's documentation](../../modules/panorama/README.md#virtual_machine). + + - `interfaces` - (`list`, required) configuration of all network interfaces. Order of the interfaces does matter - the + 1st interface is the management one. Most common properties are: + + - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`). + - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in + `var.vnets`. Key identifying the VNET is defined in `virtual_machine.vnet_key` property. + - `create_public_ip` - (`bool`, optional, defaults to `false`) create a Public IP for an interface. + - `load_balancer_key` - (`string`, optional, defaults to `null`) key of a Load Balancer defined in `var.loadbalancers` + variable, network interface that has this property defined will be added to the Load Balancer's + backend pool. + - `application_gateway_key` - (`string`, optional, defaults to `null`) key of an Application Gateway defined in `var.appgws` + variable, network interface that has this property defined will be added to the Application + Gateway's backend pool. + + For details on all properties refer to [module's documentation](../../modules/panorama/README.md#interfaces). EOF default = {} nullable = false type = map(object({ - name = string + name = string + vnet_key = string authentication = optional(object({ username = optional(string, "panadmin") password = optional(string) @@ -571,7 +738,6 @@ variable "vmseries" { identity_ids = optional(list(string)) allow_extension_operations = optional(bool) }) - vnet_key = string interfaces = list(object({ name = string subnet_key = string @@ -583,185 +749,26 @@ variable "vmseries" { application_gateway_key = optional(string) })) })) - validation { + validation { # virtual_machine.bootstrap_options & virtual_machine.bootstrap_package condition = alltrue([ for _, v in var.vmseries : v.virtual_machine.bootstrap_options != null && v.virtual_machine.bootstrap_package == null || v.virtual_machine.bootstrap_options == null && v.virtual_machine.bootstrap_package != null ]) - error_message = "Either `bootstrap_options` or `bootstrap_package` property can be set." + error_message = <<-EOF + Either `bootstrap_options` or `bootstrap_package` property can be set. + EOF } - validation { + validation { # virtual_machine.bootstrap_package condition = alltrue([ for _, v in var.vmseries : - v.virtual_machine.bootstrap_package.bootstrap_xml_template != null ? v.virtual_machine.bootstrap_package.private_snet_key != null && v.virtual_machine.bootstrap_package.public_snet_key != null : true - if v.virtual_machine.bootstrap_package != null + v.virtual_machine.bootstrap_package.bootstrap_xml_template != null ? ( + v.virtual_machine.bootstrap_package.private_snet_key != null && + v.virtual_machine.bootstrap_package.public_snet_key != null + ) : true if v.virtual_machine.bootstrap_package != null ]) - error_message = "The `private_snet_key` and `public_snet_key` are required when `bootstrap_xml_template` is set." + error_message = <<-EOF + The `private_snet_key` and `public_snet_key` are required when `bootstrap_xml_template` is set. + EOF } } - -### Application Gateway -variable "appgws" { - description = <<-EOF - A map defining all Application Gateways in the current deployment. - - For detailed documentation on how to configure this resource, for available properties, especially for the defaults, - refer to [module documentation](../../modules/appgw/README.md). - - **Note!** \ - The `rules` property is meant to bind together `backend_setting`, `redirect` or `url_path_map` (all 3 are mutually exclusive). - It represents the Rules section of an Application Gateway in Azure Portal. - - Below you can find a brief list of most important properties: - - - `name` - (`string`, required) the name of the Application Gateway, will be prefixed with `var.name_prefix`. - - `vnet_key` - (`string`, required) a key pointing to a VNET definition in the `var.vnets` map that stores the Subnet - described by `subnet_key`. - - `subnet_key` - (`string`, required) a key pointing to a Subnet definition in the `var.vnets` map, this has to be an - Application Gateway V2 dedicated subnet. - - `zones` - (`list`, optional, defaults to module defaults) parameter controlling if this is a zonal, or a non-zonal - deployment. - - `public_ip` - (`map`, required) defines a Public IP resource used by the Application Gateway instance, a newly created - Public IP will have it's name prefixes with `var.name_prefix`. - - `listeners` - (`map`, required) defines Application Gateway's Listeners, see - [module's documentation](../../modules/appgw/README.md#listeners) for details. - - `backend_pool` - (`map`, optional, defaults to module defaults) backend pool definition, when skipped an empty backend - will be created. - - `backend_settings` - (`map`, optional, mutually exclusive with `redirects` and `url_path_maps`) defines HTTP backend - settings, see [module's documentation](../../modules/appgw/README.md#backend_settings) for details. - - `probes` - (`map`, optional, defaults to module defaults) defines backend probes used check health of backends, see - [module's documentation](../../modules/appgw/README.md#probes) for details. - - `rewrites` - (`map`, optional, defaults to module defaults) defines rewrite rules, see - [module's documentation](../../modules/appgw/README.md#rewrites) for details. - - `redirects - (`map`, optional, mutually exclusive with `backend_settings` and `url_path_maps`) static redirects - definition, see [module's documentation](../../modules/appgw/README.md#redirects) for details. - - `url_path_maps - (`map`, optional, mutually exclusive with `backend_settings` and `redirects`) URL path maps definition, - see [module's documentation](../../modules/appgw/README.md#url_path_maps) for details. - - `rules - (`map`, required) Application Gateway Rules definition, bind together a `listener` with either - `backend_setting`, `redirect` or `url_path_map`, see - [module's documentation](../../modules/appgw/README.md#rules) for details. - EOF - type = map(object({ - name = string - vnet_key = string - subnet_key = string - zones = optional(list(string)) - public_ip = object({ - name = string - create = optional(bool, true) - resource_group_name = optional(string) - }) - domain_name_label = optional(string) - capacity = optional(object({ - static = optional(number) - autoscale = optional(object({ - min = number - max = number - })) - })) - enable_http2 = optional(bool) - waf = optional(object({ - prevention_mode = bool - rule_set_type = optional(string) - rule_set_version = optional(string) - })) - managed_identities = optional(list(string)) - global_ssl_policy = optional(object({ - type = optional(string) - name = optional(string) - min_protocol_version = optional(string) - cipher_suites = optional(list(string)) - })) - ssl_profiles = optional(map(object({ - name = string - ssl_policy_name = optional(string) - ssl_policy_min_protocol_version = optional(string) - ssl_policy_cipher_suites = optional(list(string)) - }))) - frontend_ip_configuration_name = optional(string) - listeners = map(object({ - name = string - port = number - protocol = optional(string) - host_names = optional(list(string)) - ssl_profile_name = optional(string) - ssl_certificate_path = optional(string) - ssl_certificate_pass = optional(string) - ssl_certificate_vault_id = optional(string) - custom_error_pages = optional(map(string)) - })) - backend_pool = optional(object({ - name = optional(string) - vmseries_ips = optional(list(string)) - })) - backend_settings = optional(map(object({ - name = string - port = number - protocol = string - path = optional(string) - hostname_from_backend = optional(string) - hostname = optional(string) - timeout = optional(number) - use_cookie_based_affinity = optional(bool) - affinity_cookie_name = optional(string) - probe = optional(string) - root_certs = optional(map(object({ - name = string - path = string - }))) - }))) - probes = optional(map(object({ - name = string - path = string - host = optional(string) - port = optional(number) - protocol = optional(string) - interval = optional(number) - timeout = optional(number) - threshold = optional(number) - match_code = optional(list(number)) - match_body = optional(string) - }))) - rewrites = optional(map(object({ - name = optional(string) - rules = optional(map(object({ - name = string - sequence = number - conditions = optional(map(object({ - pattern = string - ignore_case = optional(bool) - negate = optional(bool) - }))) - request_headers = optional(map(string)) - response_headers = optional(map(string)) - }))) - }))) - redirects = optional(map(object({ - name = string - type = string - target_listener_key = optional(string) - target_url = optional(string) - include_path = optional(bool) - include_query_string = optional(bool) - }))) - url_path_maps = optional(map(object({ - name = string - backend_key = string - path_rules = optional(map(object({ - paths = list(string) - backend_key = optional(string) - redirect_key = optional(string) - }))) - }))) - rules = map(object({ - name = string - priority = number - backend_key = optional(string) - listener_key = string - rewrite_key = optional(string) - url_path_map_key = optional(string) - redirect_key = optional(string) - })) - })) -} \ No newline at end of file diff --git a/examples/dedicated_vmseries_and_autoscale/README.md b/examples/dedicated_vmseries_and_autoscale/README.md index a102b1aa..5b2e2557 100644 --- a/examples/dedicated_vmseries_and_autoscale/README.md +++ b/examples/dedicated_vmseries_and_autoscale/README.md @@ -23,7 +23,7 @@ Panorama instance is not covered in this example, but a [dedicated one exists](. ## Reference Architecture Design -![simple](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/assets/2110772/aa2ae33a-fb46-4a1c-9811-98ea3b132297) +![simple](https://github.com/PaloAltoNetworks/terraform-azurerm-vmseries-modules/assets/6574404/a7c2452d-f926-49da-bf21-9d840282a0a2) This code implements: @@ -49,8 +49,7 @@ set of VM-Series firewalls services all outbound, east-west, and enterprise netw increased scale and operational resiliency and reduces the chances of high bandwidth use from the inbound traffic flows affecting other traffic flows within the deployment. -![Dedicated-VMSeries-with-autoscaling](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/assets/2110772/757005dc-3e24-4b39-8a69-7b3fbf9819cb) - +![Dedicated-VMSeries-with-autoscaling](https://github.com/PaloAltoNetworks/terraform-azurerm-vmseries-modules/assets/2110772/be84d4cb-c4c0-4e62-8bd7-8f5050215876) This reference architecture consists of: @@ -199,8 +198,8 @@ terraform destroy Name | Type | Description --- | --- | --- -[`location`](#location) | `string` | The Azure region to use. [`resource_group_name`](#resource_group_name) | `string` | Name of the Resource Group. +[`location`](#location) | `string` | The Azure region to use. [`vnets`](#vnets) | `map` | A map defining VNETs. [`appgws`](#appgws) | `map` | A map defining all Application Gateways in the current deployment. @@ -209,11 +208,11 @@ Name | Type | Description Name | Type | Description --- | --- | --- -[`tags`](#tags) | `map` | Map of tags to assign to the created resources. [`name_prefix`](#name_prefix) | `string` | A prefix that will be added to all created resources. [`create_resource_group`](#create_resource_group) | `bool` | When set to `true` it will cause a Resource Group creation. +[`tags`](#tags) | `map` | Map of tags to assign to the created resources. [`natgws`](#natgws) | `map` | A map defining NAT Gateways. -[`load_balancers`](#load_balancers) | `map` | A map containing configuration for all (private and public) Load Balancers. +[`load_balancers`](#load_balancers) | `map` | A map containing configuration for all (both private and public) Load Balancers. [`ngfw_metrics`](#ngfw_metrics) | `object` | A map controlling metrics-relates resources. [`scale_sets`](#scale_sets) | `map` | A map defining Azure Virtual Machine Scale Sets based on Palo Alto Networks Next Generation Firewall image. @@ -242,11 +241,11 @@ Providers used in this module: Modules used in this module: Name | Version | Source | Description --- | --- | --- | --- -`vnet` | - | ../../modules/vnet | Manage the network required for the topology. +`vnet` | - | ../../modules/vnet | `natgw` | - | ../../modules/natgw | -`load_balancer` | - | ../../modules/loadbalancer | create load balancers, both internal and external -`ngfw_metrics` | - | ../../modules/ngfw_metrics | +`load_balancer` | - | ../../modules/loadbalancer | `appgw` | - | ../../modules/appgw | +`ngfw_metrics` | - | ../../modules/ngfw_metrics | `vmss` | - | ../../modules/vmss | @@ -262,46 +261,45 @@ Resources used in this module: -#### location -The Azure region to use. +#### resource_group_name + +Name of the Resource Group. Type: string [back to list](#modules-required-inputs) +#### location - -#### resource_group_name - -Name of the Resource Group. +The Azure region to use. Type: string [back to list](#modules-required-inputs) + #### vnets A map defining VNETs. For detailed documentation on each property refer to [module documentation](../../modules/vnet/README.md) -- `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, - `false` will source an existing VNET. -- `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be - a full resource name, including prefixes. -- `address_space` - (`list(string)`, required when `create_virtual_network = false`) a list of CIDRs for a newly - created VNET -- `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which - the VNET will reside or is sourced from +- `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, `false` will source + an existing VNET. +- `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be a + full resource name, including prefixes. +- `address_space` - (`list`, required when `create_virtual_network = false`) a list of CIDRs for a newly created VNET. +- `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which the + VNET will reside or is sourced from. - `create_subnets` - (`bool`, optional, defaults to `true`) if `true`, create Subnets inside the Virtual Network, - otherwise use source existing subnets + otherwise use source existing subnets. - `subnets` - (`map`, optional) map of Subnets to create or source, for details see - [VNET module documentation](../../modules/vnet/README.md#subnets) + [VNET module documentation](../../modules/vnet/README.md#subnets). - `network_security_groups` - (`map`, optional) map of Network Security Groups to create, for details see - [VNET module documentation](../../modules/vnet/README.md#network_security_groups) + [VNET module documentation](../../modules/vnet/README.md#network_security_groups). - `route_tables` - (`map`, optional) map of Route Tables to create, for details see - [VNET module documentation](../../modules/vnet/README.md#route_tables) + [VNET module documentation](../../modules/vnet/README.md#route_tables). Type: @@ -356,8 +354,6 @@ map(object({ - - #### appgws A map defining all Application Gateways in the current deployment. @@ -376,25 +372,25 @@ Below you can find a brief list of most important properties: described by `subnet_key`. - `subnet_key` - (`string`, required) a key pointing to a Subnet definition in the `var.vnets` map, this has to be an Application Gateway V2 dedicated subnet. -- `zones` - (`list`, optional, defaults to module defaults) parameter controlling if this is a zonal, or a non-zonal +- `zones` - (`list`, optional, defaults to module default) parameter controlling if this is a zonal, or a non-zonal deployment. - `public_ip` - (`map`, required) defines a Public IP resource used by the Application Gateway instance, a newly created Public IP will have it's name prefixes with `var.name_prefix`. - `listeners` - (`map`, required) defines Application Gateway's Listeners, see [module's documentation](../../modules/appgw/README.md#listeners) for details. -- `backend_pool` - (`map`, optional, defaults to module defaults) backend pool definition, when skipped an empty backend +- `backend_pool` - (`map`, optional, defaults to module default) backend pool definition, when skipped an empty backend will be created. - `backend_settings` - (`map`, optional, mutually exclusive with `redirects` and `url_path_maps`) defines HTTP backend settings, see [module's documentation](../../modules/appgw/README.md#backend_settings) for details. -- `probes` - (`map`, optional, defaults to module defaults) defines backend probes used check health of backends, see +- `probes` - (`map`, optional, defaults to module default) defines backend probes used check health of backends, see [module's documentation](../../modules/appgw/README.md#probes) for details. -- `rewrites` - (`map`, optional, defaults to module defaults) defines rewrite rules, see +- `rewrites` - (`map`, optional, defaults to module default) defines rewrite rules, see [module's documentation](../../modules/appgw/README.md#rewrites) for details. -- `redirects - (`map`, optional, mutually exclusive with `backend_settings` and `url_path_maps`) static redirects +- `redirects` - (`map`, optional, mutually exclusive with `backend_settings` and `url_path_maps`) static redirects definition, see [module's documentation](../../modules/appgw/README.md#redirects) for details. -- `url_path_maps - (`map`, optional, mutually exclusive with `backend_settings` and `redirects`) URL path maps definition, +- `url_path_maps` - (`map`, optional, mutually exclusive with `backend_settings` and `redirects`) URL path maps definition, see [module's documentation](../../modules/appgw/README.md#url_path_maps) for details. -- `rules - (`map`, required) Application Gateway Rules definition, bind together a `listener` with either +- `rules` - (`map`, required) Application Gateway Rules definition, bind together a `listener` with either `backend_setting`, `redirect` or `url_path_map`, see [module's documentation](../../modules/appgw/README.md#rules) for details. @@ -531,18 +527,9 @@ map(object({ -### Optional Inputs - -#### tags -Map of tags to assign to the created resources. - -Type: map(string) - -Default value: `map[]` - -[back to list](#modules-optional-inputs) +### Optional Inputs #### name_prefix @@ -583,6 +570,17 @@ Default value: `true` +#### tags + +Map of tags to assign to the created resources. + +Type: map(string) + +Default value: `map[]` + +[back to list](#modules-optional-inputs) + + #### natgws A map defining NAT Gateways. @@ -592,21 +590,21 @@ explicitly). Please refer to Microsoft documentation for notes on NAT Gateway's For detailed documentation on each property refer to [module documentation](../../modules/natgw/README.md). Following properties are supported: -- `create_natgw` - (`bool`, optional, defaults to `true`) create (`true`) or source an existing NAT Gateway (`false`), - created or sourced: the NAT Gateway will be assigned to a subnet created by the `vnet` module. -- `name` - (`string`, required) a name of a NAT Gateway. In case `create_natgw = false` this should be a full - resource name, including prefixes. -- `resource_group_name - (`string`, optional) name of a Resource Group hosting the NAT Gateway (newly created or the existing - one). -- `zone` - (`string`, optional) an Availability Zone in which the NAT Gateway will be placed, when skipped - AzureRM will pick a zone. -- `idle_timeout` - (`number`, optional, defults to 4) connection IDLE timeout in minutes, for newly created resources. -- `vnet_key` - (`string`, required) a name (key value) of a VNET defined in `var.vnets` that hosts a subnet this - NAT Gateway will be assigned to. -- `subnet_keys` - (`list(string)`, required) a list of subnets (key values) the NAT Gateway will be assigned to, defined - in `var.vnets` for a VNET described by `vnet_name`. -- `public_ip` - (`object`, optional) an object defining a public IP resource attached to the NAT Gateway. -- `public_ip_prefix` - (`object`, optional) an object defining a public IP prefix resource attached to the NAT Gatway. +- `name` - (`string`, required) a name of a NAT Gateway. In case `create_natgw = false` this should be a full + resource name, including prefixes. +- `vnet_key` - (`string`, required) a name (key value) of a VNET defined in `var.vnets` that hosts a subnet this + NAT Gateway will be assigned to. +- `subnet_keys` - (`list(string)`, required) a list of subnets (key values) the NAT Gateway will be assigned to, + defined in `var.vnets` for a VNET described by `vnet_name`. +- `create_natgw` - (`bool`, optional, defaults to `true`) create (`true`) or source an existing NAT Gateway (`false`), + created or sourced: the NAT Gateway will be assigned to a subnet created by the `vnet` module. +- `resource_group_name` - (`string`, optional) name of a Resource Group hosting the NAT Gateway (newly created or the existing + one). +- `zone` - (`string`, optional) an Availability Zone in which the NAT Gateway will be placed, when skipped + Azure will pick a zone. +- `idle_timeout` - (`number`, optional, defults to 4) connection IDLE timeout in minutes, for newly created resources. +- `public_ip` - (`object`, optional) an object defining a public IP resource attached to the NAT Gateway. +- `public_ip_prefix` - (`object`, optional) an object defining a public IP prefix resource attached to the NAT Gatway. Example: ``` @@ -628,13 +626,13 @@ Type: ```hcl map(object({ - create_natgw = optional(bool, true) name = string + vnet_key = string + subnet_keys = list(string) + create_natgw = optional(bool, true) resource_group_name = optional(string) zone = optional(string) idle_timeout = optional(number, 4) - vnet_key = string - subnet_keys = list(string) public_ip = optional(object({ create = bool name = string @@ -656,7 +654,7 @@ Default value: `map[]` #### load_balancers -A map containing configuration for all (private and public) Load Balancers. +A map containing configuration for all (both private and public) Load Balancers. This is a brief description of available properties. For a detailed one please refer to [module documentation](../../modules/loadbalancer/README.md). @@ -666,26 +664,29 @@ Following properties are available: - `name` - (`string`, required) a name of the Load Balancer. - `vnet_key` - (`string`, optional, defaults to `null`) a key pointing to a VNET definition in the `var.vnets` map that stores the Subnet described by `subnet_key`. -- `zones` - (`list`, optional, defaults to module defaults) a list of zones for Load Balancer's fronted IP +- `zones` - (`list`, optional, defaults to module default) a list of zones for Load Balancer's frontend IP configurations. -- `backend_name` - (`string`, optional, defaults to module defaults) a name of the backend pool to create. -- `health_probes` - (`map`, optional, defaults to `null`) a map defining health probes that will be used by - load balancing rules; please check +- `backend_name` - (`string`, optional, defaults to module default) a name of the backend pool to create. +- `health_probes` - (`map`, optional, defaults to `null`) a map defining health probes that will be used by load + balancing rules, please refer to [module documentation](../../modules/loadbalancer/README.md#health_probes) for more specific use cases and available properties. -- `nsg_auto_rules_settings` - (`map`, optional, defaults to `null`) a map defining a location of an existing NSG rule - that will be populated with `Allow` rules for each load balancing rule (`in_rules`); please check - [module documentation](../../modules/loadbalancer/README.md#nsg_auto_rules_settings) - for available properties; please note that in this example two additional properties are - available: - - `nsg_vnet_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to a VNET definition - in the `var.vnets` map that stores the NSG described by `nsg_key`. - - `nsg_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to an NSG definition - in the `var.vnets` map. -- `frontend_ips` - (`map`, optional, defaults to `{}`) a map containing frontend IP configuration with respective - `in_rules` and `out_rules` +- `nsg_auto_rules_settings` - (`map`, optional, defaults to `null`) a map defining a location of an existing NSG rule that will + be populated with `Allow` rules for each load balancing rule (`in_rules`), please refer to + [module documentation](../../modules/loadbalancer/README.md#nsg_auto_rules_settings) for + available properties. + + Please note that in this example two additional properties are available: + + - `nsg_vnet_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to a VNET definition in the + `var.vnets` map that stores the NSG described by `nsg_key`. + - `nsg_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to an NSG definition in the + `var.vnets` map. - Please refer to [module documentation](../../modules/loadbalancer/README.md#frontend_ips) for available properties. +- `frontend_ips` - (`map`, optional, defaults to `{}`) a map containing frontend IP configuration with respective + `in_rules` and `out_rules`, please refer to + [module documentation](../../modules/loadbalancer/README.md#frontend_ips) for available + properties. **Note!** \ In this example the `subnet_id` is not available directly, another property has been introduced instead: @@ -719,10 +720,10 @@ map(object({ })) frontend_ips = optional(map(object({ name = string + subnet_key = optional(string) public_ip_name = optional(string) create_public_ip = optional(bool, false) public_ip_resource_group_name = optional(string) - subnet_key = optional(string) private_ip_address = optional(string) gwlb_key = optional(string) in_rules = optional(map(object({ @@ -751,6 +752,7 @@ Default value: `map[]` [back to list](#modules-optional-inputs) + #### ngfw_metrics A map controlling metrics-relates resources. @@ -758,22 +760,22 @@ A map controlling metrics-relates resources. When set to explicit `null` (default) it will disable any metrics resources in this deployment. When defined it will either create or source a Log Analytics Workspace and create Application Insights instances (one per each -Scale Set). All instances will be automatically connected to the workspace. -The name of the Application Insights instance will be derived from the Scale Set name and suffixed with `-ai`. +Scale Set). All instances will be automatically connected to the workspace. The name of the Application Insights instance will +be derived from the Scale Set name and suffixed with `-ai`. All the settings available below are common to the Log Analytics Workspace and Application Insight instances. Following properties are available: -- `name` - (`string`, required) name of the (common) Log Analytics Workspace +- `name` - (`string`, required) name of the (common) Log Analytics Workspace. - `create_workspace` - (`bool`, optional, defaults to `true`) controls whether we create or source an existing Log - Analytics Workspace + Analytics Workspace. - `resource_group_name` - (`string`, optional, defaults to `var.resource_group_name`) name of the Resource Group hosting - the Log Analytics Workspace -- `sku` - (`string`, optional, defaults to module defaults) the SKU of the Log Analytics Workspace. -- `metrics_retention_in_days` - (`number`, optional, defaults to module defaults) workspace and insights data retention in - days, possible values are between 30 and 730. For sourced Workspaces this applies only to - the Application Insights instances. + the Log Analytics Workspace. +- `sku` - (`string`, optional, defaults to module default) the SKU of the Log Analytics Workspace. +- `metrics_retention_in_days` - (`number`, optional, defaults to module default) workspace and insights data retention in days, + possible values are between 30 and 730. For sourced Workspaces this applies only to the + Application Insights instances. Type: @@ -801,7 +803,10 @@ For details and defaults for available options please refer to the [`vmss`](../. The basic Scale Set configuration properties are as follows: -- `name` - (`string`, required) name of the scale set, will be prefixed with the value of `var.name_prefix` +- `name` - (`string`, required) name of the scale set, will be prefixed with the value of + `var.name_prefix`. +- `vnet_key` - (`string`, required) a key of a VNET defined in `var.vnets`. This is the VNET that hosts + subnets used to deploy network interfaces for VMs in this Scale Set. - `authentication` - (`map`, required) authentication setting for VMs deployed in this scale set. This map holds the firewall admin password. When this property is not set, the password will be autogenerated for you and @@ -811,74 +816,70 @@ The basic Scale Set configuration properties are as follows: The `disable_password_authentication` property is by default true. When using this value you have to specify at least one SSH key. You can however set this property to `true`. Then you have 2 options, either: - - do not specify anything else - a random password will be generated for you + - do not specify anything else, a random password will be generated for you. - specify at least one of `password` or `ssh_keys` properties. - For all properties and their default values see [module's documentation](../../modules/vmss/README.md#authentication). + For all properties and their default values refer to [module's documentation](../../modules/vmss/README.md#authentication). -- `image` - (`map`, required) properties defining a base image used to spawn VMs in this Scale Set. +- `image` - (`map`, required) properties defining a base image used to spawn VMs in this Scale Set. The + `image` property is required but there are only 2 properties (mutually exclusive) that have to + be set up, either: - The `image` property is required but there are only 2 properties (mutually exclusive) that have to be set up, either: + - `version` - (`string`, optional) describes the PAN-OS image version from Azure Marketplace. + - `custom_id` - (`string`, optional) absolute ID of your own custom PAN-OS image. - - `version` - (`string`) describes the PAN-OS image version from Azure's Marketplace - - `custom_id` - (`string`) absolute ID of your own custom PAN-OS image + For details on all properties refer to [module's documentation](../../modules/vmss/README.md#image). - For details on the other properties refer to [module's documentation](../../modules/vmss/README.md#image). +- `virtual_machine_scale_set` - (`map`, optional, defaults to module default) a map that groups most common Scale Set + configuration options: -- `virtual_machine_scale_set` - (`map`, optional, defaults to module defaults) a map that groups most common Scale Set - configuration options. + - `size` - (`string`, optional, defaults to module default) Azure VM size (type). Consult the *VM-Series + Deployment Guide* as only a few selected sizes are supported. + - `zones` - (`list`, optional, defaults to module default) a list of Availability Zones in which VMs from + this Scale Set will be created. + - `disk_type` - (`string`, optional, defaults to module default) type of Managed Disk which should be created, + possible values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected + `vm_size` values). + - `bootstrap_options` - (`string`, optional, defaults to module default) bootstrap options to pass to VM-Series instance. - Below we present only the most important ones, for the rest please refer to - [module's documentation](../../modules/vmss/README.md#virtual_machine_scale_set): - - - `size` - (`string`, optional, defaults to module defaults) Azure VM size (type). Consult the *VM-Series - Deployment Guide* as only a few selected sizes are supported - - `zones` - (`list`, optional, defaults to module defaults) a list of Availability Zones in which VMs from - this Scale Set will be created - - `disk_type` - (`string`, optional, defaults to module defaults) type of Managed Disk which should be created, - possible values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected - `vm_size` values) - - `bootstrap_options` - (`string`, optional, defaults to module defaults) bootstrap options to pass to VM-Series - instance + For details on all properties refer to [module's documentation](../../modules/vmss/README.md#virtual_machine_scale_set). - `autoscaling_configuration` - (`map`, optional, defaults to `{}`) a map that groups common autoscaling configuration, but not - the scaling profiles (metrics thresholds, etc) + the scaling profiles (metrics, thresholds, etc.). Most common properties are: + + - `default_count` - (`number`, optional, defaults to module default) minimum number of instances that should be present + in the scale set when the autoscaling engine cannot read the metrics or is otherwise unable to + compare the metrics to the thresholds. - Below we present only the most important properties, for the rest please refer to - [module's documentation](../../modules/vmss/README.md#autoscaling_configuration). + For details on all properties refer to [module's documentation](../../modules/vmss/README.md#autoscaling_configuration). - - `default_count` - (`number`, optional, defaults module defaults) minimum number of instances that should be present in - the scale set when the autoscaling engine cannot read the metrics or is otherwise unable to compare - the metrics to the thresholds +- `interfaces` - (`list`, required) configuration of all network interfaces, order does matter - the + 1st interface should be the management one. Following properties are available: -- `vnet_key` - (`string`, required) a key of a VNET defined in `var.vnets`. This is the VNET that hosts subnets - used to deploy network interfaces for VMs in this Scale Set -- `interfaces` - (`list`, required) configuration of all network interfaces, order does matter - the 1st - interface should be the management one. Following properties are available: - - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`) + - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`). - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in - `var.vnets` - - `create_public_ip` - (`bool`, optional, defaults to module defaults) create Public IP for an interface + `var.vnets`. + - `create_public_ip` - (`bool`, optional, defaults to module default) create Public IP for an interface. - `load_balancer_key` - (`string`, optional, defaults to `null`) key of a Load Balancer defined in the - `var.loadbalancers` variable, network interface that has this property defined will be - added to the Load Balancer's backend pool + `var.loadbalancers` variable, network interface that has this property defined will be added to + the Load Balancer's backend pool. - `application_gateway_key` - (`string`, optional, defaults to `null`) key of an Application Gateway defined in the `var.appgws`, network interface that has this property defined will be added to the Application - Gateways's backend pool + Gateways's backend pool. - `pip_domain_name_label` - (`string`, optional, defaults to `null`) prefix which should be used for the Domain Name Label - for each VM instance - -- `autoscaling_profiles` - (`list`, optional, defaults to `[]`) a list of autoscaling profiles, for details on available - configuration please refer to - [module's documentation](../../modules/vmss/README.md#autoscaling_profiles) + for each VM instance. +- `autoscaling_profiles` - (`list`, optional, defaults to `[]`) a list of autoscaling profiles, for details on available + properties please refer to + [module's documentation](../../modules/vmss/README.md#autoscaling_profiles). Type: ```hcl map(object({ - name = string + name = string + vnet_key = string authentication = object({ username = optional(string) password = optional(string) @@ -916,7 +917,6 @@ map(object({ notification_emails = optional(list(string), []) webhooks_uris = optional(map(string), {}) }), {}) - vnet_key = string interfaces = list(object({ name = string subnet_key = string @@ -968,6 +968,4 @@ Default value: `map[]` [back to list](#modules-optional-inputs) - - \ No newline at end of file diff --git a/examples/dedicated_vmseries_and_autoscale/example.tfvars b/examples/dedicated_vmseries_and_autoscale/example.tfvars index 9fd03fde..5f6ca663 100644 --- a/examples/dedicated_vmseries_and_autoscale/example.tfvars +++ b/examples/dedicated_vmseries_and_autoscale/example.tfvars @@ -1,4 +1,5 @@ -# --- GENERAL --- # +### GENERAL ### + location = "North Europe" resource_group_name = "autoscale-dedicated" name_prefix = "example-" @@ -7,7 +8,8 @@ tags = { "CreatedWith" = "Terraform" } -# --- VNET PART --- # +### NETWORK ### + vnets = { "transit" = { name = "transit" @@ -122,9 +124,8 @@ natgws = { } } +### LOAD BALANCING ### - -# --- LOAD BALANCING PART --- # load_balancers = { "public" = { name = "public-lb" @@ -174,14 +175,16 @@ load_balancers = { } } -# --- VMSERIES PART --- # +### VM-SERIES ### + ngfw_metrics = { name = "ngwf-log-analytics-wrksp" } scale_sets = { inbound = { - name = "inbound-vmss" + name = "inbound-vmss" + vnet_key = "transit" image = { version = "10.2.4" } @@ -195,7 +198,6 @@ scale_sets = { autoscaling_configuration = { default_count = 2 } - vnet_key = "transit" interfaces = [ { name = "management" @@ -213,7 +215,8 @@ scale_sets = { ] } obew = { - name = "obew-vmss" + name = "obew-vmss" + vnet_key = "transit" image = { version = "10.2.4" } @@ -227,7 +230,6 @@ scale_sets = { autoscaling_configuration = { default_count = 2 } - vnet_key = "transit" interfaces = [ { name = "management" diff --git a/examples/dedicated_vmseries_and_autoscale/main.tf b/examples/dedicated_vmseries_and_autoscale/main.tf index 9f208f66..151af28c 100644 --- a/examples/dedicated_vmseries_and_autoscale/main.tf +++ b/examples/dedicated_vmseries_and_autoscale/main.tf @@ -1,4 +1,5 @@ -# Generate a random password. +### Generate a random password ### + # https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password resource "random_password" "this" { count = anytrue([ @@ -27,7 +28,8 @@ locals { } } -# Create or source the Resource Group. +### Create or source a Resource Group ### + # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group resource "azurerm_resource_group" "this" { count = var.create_resource_group ? 1 : 0 @@ -47,7 +49,8 @@ locals { resource_group = var.create_resource_group ? azurerm_resource_group.this[0] : data.azurerm_resource_group.this[0] } -# Manage the network required for the topology. +### Manage the network required for the topology ### + module "vnet" { source = "../../modules/vnet" @@ -63,9 +66,11 @@ module "vnet" { create_subnets = each.value.create_subnets subnets = each.value.subnets - network_security_groups = { for k, v in each.value.network_security_groups : k => merge(v, { name = "${var.name_prefix}${v.name}" }) + network_security_groups = { + for k, v in each.value.network_security_groups : k => merge(v, { name = "${var.name_prefix}${v.name}" }) } - route_tables = { for k, v in each.value.route_tables : k => merge(v, { name = "${var.name_prefix}${v.name}" }) + route_tables = { + for k, v in each.value.route_tables : k => merge(v, { name = "${var.name_prefix}${v.name}" }) } tags = var.tags @@ -84,14 +89,19 @@ module "natgw" { idle_timeout = each.value.idle_timeout subnet_ids = { for v in each.value.subnet_keys : v => module.vnet[each.value.vnet_key].subnet_ids[v] } - public_ip = try(merge(each.value.public_ip, { name = "${each.value.public_ip.create ? var.name_prefix : ""}${each.value.public_ip.name}" }), null) - public_ip_prefix = try(merge(each.value.public_ip_prefix, { name = "${each.value.public_ip_prefix.create ? var.name_prefix : ""}${each.value.public_ip_prefix.name}" }), null) + public_ip = try(merge(each.value.public_ip, { + name = "${each.value.public_ip.create ? var.name_prefix : ""}${each.value.public_ip.name}" + }), null) + public_ip_prefix = try(merge(each.value.public_ip_prefix, { + name = "${each.value.public_ip_prefix.create ? var.name_prefix : ""}${each.value.public_ip_prefix.name}" + }), null) tags = var.tags depends_on = [module.vnet] } -# create load balancers, both internal and external +### Create Load Balancers, both internal and external ### + module "load_balancer" { source = "../../modules/loadbalancer" @@ -108,7 +118,8 @@ module "load_balancer" { nsg_auto_rules_settings = try( { nsg_name = try( - "${var.name_prefix}${var.vnets[each.value.nsg_auto_rules_settings.nsg_vnet_key].network_security_groups[each.value.nsg_auto_rules_settings.nsg_key].name}", + "${var.name_prefix}${var.vnets[each.value.nsg_auto_rules_settings.nsg_vnet_key].network_security_groups[ + each.value.nsg_auto_rules_settings.nsg_key].name}", each.value.nsg_auto_rules_settings.nsg_name ) nsg_resource_group_name = try( @@ -136,30 +147,7 @@ module "load_balancer" { depends_on = [module.vnet] } -module "ngfw_metrics" { - source = "../../modules/ngfw_metrics" - - count = var.ngfw_metrics != null ? 1 : 0 - - create_workspace = var.ngfw_metrics.create_workspace - - name = "${var.ngfw_metrics.create_workspace ? var.name_prefix : ""}${var.ngfw_metrics.name}" - resource_group_name = var.ngfw_metrics.create_workspace ? local.resource_group.name : coalesce(var.ngfw_metrics.resource_group_name, local.resource_group.name) - location = var.location - - log_analytics_workspace = { - sku = var.ngfw_metrics.sku - metrics_retention_in_days = var.ngfw_metrics.metrics_retention_in_days - } - - application_insights = { - for k, v in var.scale_sets : - k => { name = "${var.name_prefix}${v.name}-ai" } - if length(v.autoscaling_profiles) > 0 - } - - tags = var.tags -} +### Create Application Gateways ### module "appgw" { source = "../../modules/appgw" @@ -197,6 +185,35 @@ module "appgw" { depends_on = [module.vnet] } +### Create VM-Series VM Scale Sets and closely associated resources ### + +module "ngfw_metrics" { + source = "../../modules/ngfw_metrics" + + count = var.ngfw_metrics != null ? 1 : 0 + + create_workspace = var.ngfw_metrics.create_workspace + + name = "${var.ngfw_metrics.create_workspace ? var.name_prefix : ""}${var.ngfw_metrics.name}" + resource_group_name = var.ngfw_metrics.create_workspace ? local.resource_group.name : ( + coalesce(var.ngfw_metrics.resource_group_name, local.resource_group.name) + ) + location = var.location + + log_analytics_workspace = { + sku = var.ngfw_metrics.sku + metrics_retention_in_days = var.ngfw_metrics.metrics_retention_in_days + } + + application_insights = { + for k, v in var.scale_sets : + k => { name = "${var.name_prefix}${v.name}-ai" } + if length(v.autoscaling_profiles) > 0 + } + + tags = var.tags +} + module "vmss" { source = "../../modules/vmss" diff --git a/examples/dedicated_vmseries_and_autoscale/variables.tf b/examples/dedicated_vmseries_and_autoscale/variables.tf index 5c90903a..a18c7c0f 100644 --- a/examples/dedicated_vmseries_and_autoscale/variables.tf +++ b/examples/dedicated_vmseries_and_autoscale/variables.tf @@ -1,14 +1,4 @@ -### GENERAL -variable "tags" { - description = "Map of tags to assign to the created resources." - default = {} - type = map(string) -} - -variable "location" { - description = "The Azure region to use." - type = string -} +### GENERAL ### variable "name_prefix" { description = <<-EOF @@ -45,33 +35,41 @@ variable "resource_group_name" { type = string } +variable "location" { + description = "The Azure region to use." + type = string +} + +variable "tags" { + description = "Map of tags to assign to the created resources." + default = {} + type = map(string) +} +### NETWORK ### -### VNET variable "vnets" { description = <<-EOF A map defining VNETs. For detailed documentation on each property refer to [module documentation](../../modules/vnet/README.md) - - `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, - `false` will source an existing VNET. - - `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be - a full resource name, including prefixes. - - `address_space` - (`list(string)`, required when `create_virtual_network = false`) a list of CIDRs for a newly - created VNET - - `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which - the VNET will reside or is sourced from + - `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, `false` will source + an existing VNET. + - `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be a + full resource name, including prefixes. + - `address_space` - (`list`, required when `create_virtual_network = false`) a list of CIDRs for a newly created VNET. + - `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which the + VNET will reside or is sourced from. - `create_subnets` - (`bool`, optional, defaults to `true`) if `true`, create Subnets inside the Virtual Network, - otherwise use source existing subnets + otherwise use source existing subnets. - `subnets` - (`map`, optional) map of Subnets to create or source, for details see - [VNET module documentation](../../modules/vnet/README.md#subnets) + [VNET module documentation](../../modules/vnet/README.md#subnets). - `network_security_groups` - (`map`, optional) map of Network Security Groups to create, for details see - [VNET module documentation](../../modules/vnet/README.md#network_security_groups) + [VNET module documentation](../../modules/vnet/README.md#network_security_groups). - `route_tables` - (`map`, optional) map of Route Tables to create, for details see - [VNET module documentation](../../modules/vnet/README.md#route_tables) + [VNET module documentation](../../modules/vnet/README.md#route_tables). EOF - type = map(object({ name = string resource_group_name = optional(string) @@ -125,21 +123,21 @@ variable "natgws" { For detailed documentation on each property refer to [module documentation](../../modules/natgw/README.md). Following properties are supported: - - `create_natgw` - (`bool`, optional, defaults to `true`) create (`true`) or source an existing NAT Gateway (`false`), - created or sourced: the NAT Gateway will be assigned to a subnet created by the `vnet` module. - - `name` - (`string`, required) a name of a NAT Gateway. In case `create_natgw = false` this should be a full - resource name, including prefixes. - - `resource_group_name - (`string`, optional) name of a Resource Group hosting the NAT Gateway (newly created or the existing - one). - - `zone` - (`string`, optional) an Availability Zone in which the NAT Gateway will be placed, when skipped - AzureRM will pick a zone. - - `idle_timeout` - (`number`, optional, defults to 4) connection IDLE timeout in minutes, for newly created resources. - - `vnet_key` - (`string`, required) a name (key value) of a VNET defined in `var.vnets` that hosts a subnet this - NAT Gateway will be assigned to. - - `subnet_keys` - (`list(string)`, required) a list of subnets (key values) the NAT Gateway will be assigned to, defined - in `var.vnets` for a VNET described by `vnet_name`. - - `public_ip` - (`object`, optional) an object defining a public IP resource attached to the NAT Gateway. - - `public_ip_prefix` - (`object`, optional) an object defining a public IP prefix resource attached to the NAT Gatway. + - `name` - (`string`, required) a name of a NAT Gateway. In case `create_natgw = false` this should be a full + resource name, including prefixes. + - `vnet_key` - (`string`, required) a name (key value) of a VNET defined in `var.vnets` that hosts a subnet this + NAT Gateway will be assigned to. + - `subnet_keys` - (`list(string)`, required) a list of subnets (key values) the NAT Gateway will be assigned to, + defined in `var.vnets` for a VNET described by `vnet_name`. + - `create_natgw` - (`bool`, optional, defaults to `true`) create (`true`) or source an existing NAT Gateway (`false`), + created or sourced: the NAT Gateway will be assigned to a subnet created by the `vnet` module. + - `resource_group_name` - (`string`, optional) name of a Resource Group hosting the NAT Gateway (newly created or the existing + one). + - `zone` - (`string`, optional) an Availability Zone in which the NAT Gateway will be placed, when skipped + Azure will pick a zone. + - `idle_timeout` - (`number`, optional, defults to 4) connection IDLE timeout in minutes, for newly created resources. + - `public_ip` - (`object`, optional) an object defining a public IP resource attached to the NAT Gateway. + - `public_ip_prefix` - (`object`, optional) an object defining a public IP prefix resource attached to the NAT Gatway. Example: ``` @@ -158,13 +156,13 @@ variable "natgws" { EOF default = {} type = map(object({ - create_natgw = optional(bool, true) name = string + vnet_key = string + subnet_keys = list(string) + create_natgw = optional(bool, true) resource_group_name = optional(string) zone = optional(string) idle_timeout = optional(number, 4) - vnet_key = string - subnet_keys = list(string) public_ip = optional(object({ create = bool name = string @@ -179,12 +177,11 @@ variable "natgws" { })) } +### LOAD BALANCING ### - -### Load Balancing variable "load_balancers" { description = <<-EOF - A map containing configuration for all (private and public) Load Balancers. + A map containing configuration for all (both private and public) Load Balancers. This is a brief description of available properties. For a detailed one please refer to [module documentation](../../modules/loadbalancer/README.md). @@ -194,26 +191,29 @@ variable "load_balancers" { - `name` - (`string`, required) a name of the Load Balancer. - `vnet_key` - (`string`, optional, defaults to `null`) a key pointing to a VNET definition in the `var.vnets` map that stores the Subnet described by `subnet_key`. - - `zones` - (`list`, optional, defaults to module defaults) a list of zones for Load Balancer's fronted IP + - `zones` - (`list`, optional, defaults to module default) a list of zones for Load Balancer's frontend IP configurations. - - `backend_name` - (`string`, optional, defaults to module defaults) a name of the backend pool to create. - - `health_probes` - (`map`, optional, defaults to `null`) a map defining health probes that will be used by - load balancing rules; please check + - `backend_name` - (`string`, optional, defaults to module default) a name of the backend pool to create. + - `health_probes` - (`map`, optional, defaults to `null`) a map defining health probes that will be used by load + balancing rules, please refer to [module documentation](../../modules/loadbalancer/README.md#health_probes) for more specific use cases and available properties. - - `nsg_auto_rules_settings` - (`map`, optional, defaults to `null`) a map defining a location of an existing NSG rule - that will be populated with `Allow` rules for each load balancing rule (`in_rules`); please check - [module documentation](../../modules/loadbalancer/README.md#nsg_auto_rules_settings) - for available properties; please note that in this example two additional properties are - available: - - `nsg_vnet_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to a VNET definition - in the `var.vnets` map that stores the NSG described by `nsg_key`. - - `nsg_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to an NSG definition - in the `var.vnets` map. - - `frontend_ips` - (`map`, optional, defaults to `{}`) a map containing frontend IP configuration with respective - `in_rules` and `out_rules` + - `nsg_auto_rules_settings` - (`map`, optional, defaults to `null`) a map defining a location of an existing NSG rule that will + be populated with `Allow` rules for each load balancing rule (`in_rules`), please refer to + [module documentation](../../modules/loadbalancer/README.md#nsg_auto_rules_settings) for + available properties. + + Please note that in this example two additional properties are available: + + - `nsg_vnet_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to a VNET definition in the + `var.vnets` map that stores the NSG described by `nsg_key`. + - `nsg_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to an NSG definition in the + `var.vnets` map. - Please refer to [module documentation](../../modules/loadbalancer/README.md#frontend_ips) for available properties. + - `frontend_ips` - (`map`, optional, defaults to `{}`) a map containing frontend IP configuration with respective + `in_rules` and `out_rules`, please refer to + [module documentation](../../modules/loadbalancer/README.md#frontend_ips) for available + properties. **Note!** \ In this example the `subnet_id` is not available directly, another property has been introduced instead: @@ -245,10 +245,10 @@ variable "load_balancers" { })) frontend_ips = optional(map(object({ name = string + subnet_key = optional(string) public_ip_name = optional(string) create_public_ip = optional(bool, false) public_ip_resource_group_name = optional(string) - subnet_key = optional(string) private_ip_address = optional(string) gwlb_key = optional(string) in_rules = optional(map(object({ @@ -272,213 +272,6 @@ variable "load_balancers" { })) } -variable "ngfw_metrics" { - description = <<-EOF - A map controlling metrics-relates resources. - - When set to explicit `null` (default) it will disable any metrics resources in this deployment. - - When defined it will either create or source a Log Analytics Workspace and create Application Insights instances (one per each - Scale Set). All instances will be automatically connected to the workspace. - The name of the Application Insights instance will be derived from the Scale Set name and suffixed with `-ai`. - - All the settings available below are common to the Log Analytics Workspace and Application Insight instances. - - Following properties are available: - - - `name` - (`string`, required) name of the (common) Log Analytics Workspace - - `create_workspace` - (`bool`, optional, defaults to `true`) controls whether we create or source an existing Log - Analytics Workspace - - `resource_group_name` - (`string`, optional, defaults to `var.resource_group_name`) name of the Resource Group hosting - the Log Analytics Workspace - - `sku` - (`string`, optional, defaults to module defaults) the SKU of the Log Analytics Workspace. - - `metrics_retention_in_days` - (`number`, optional, defaults to module defaults) workspace and insights data retention in - days, possible values are between 30 and 730. For sourced Workspaces this applies only to - the Application Insights instances. - EOF - default = null - type = object({ - name = string - create_workspace = optional(bool, true) - resource_group_name = optional(string) - sku = optional(string) - metrics_retention_in_days = optional(number) - }) -} - -### VMSERIES - -variable "scale_sets" { - description = <<-EOF - A map defining Azure Virtual Machine Scale Sets based on Palo Alto Networks Next Generation Firewall image. - - For details and defaults for available options please refer to the [`vmss`](../../modules/vmss/README.md) module. - - The basic Scale Set configuration properties are as follows: - - - `name` - (`string`, required) name of the scale set, will be prefixed with the value of `var.name_prefix` - - `authentication` - (`map`, required) authentication setting for VMs deployed in this scale set. - - This map holds the firewall admin password. When this property is not set, the password will be autogenerated for you and - available in the Terraform outputs. - - **Note!** \ - The `disable_password_authentication` property is by default true. When using this value you have to specify at least one - SSH key. You can however set this property to `true`. Then you have 2 options, either: - - - do not specify anything else - a random password will be generated for you - - specify at least one of `password` or `ssh_keys` properties. - - For all properties and their default values see [module's documentation](../../modules/vmss/README.md#authentication). - - - `image` - (`map`, required) properties defining a base image used to spawn VMs in this Scale Set. - - The `image` property is required but there are only 2 properties (mutually exclusive) that have to be set up, either: - - - `version` - (`string`) describes the PAN-OS image version from Azure's Marketplace - - `custom_id` - (`string`) absolute ID of your own custom PAN-OS image - - For details on the other properties refer to [module's documentation](../../modules/vmss/README.md#image). - - - `virtual_machine_scale_set` - (`map`, optional, defaults to module defaults) a map that groups most common Scale Set - configuration options. - - Below we present only the most important ones, for the rest please refer to - [module's documentation](../../modules/vmss/README.md#virtual_machine_scale_set): - - - `size` - (`string`, optional, defaults to module defaults) Azure VM size (type). Consult the *VM-Series - Deployment Guide* as only a few selected sizes are supported - - `zones` - (`list`, optional, defaults to module defaults) a list of Availability Zones in which VMs from - this Scale Set will be created - - `disk_type` - (`string`, optional, defaults to module defaults) type of Managed Disk which should be created, - possible values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected - `vm_size` values) - - `bootstrap_options` - (`string`, optional, defaults to module defaults) bootstrap options to pass to VM-Series - instance - - - `autoscaling_configuration` - (`map`, optional, defaults to `{}`) a map that groups common autoscaling configuration, but not - the scaling profiles (metrics thresholds, etc) - - Below we present only the most important properties, for the rest please refer to - [module's documentation](../../modules/vmss/README.md#autoscaling_configuration). - - - `default_count` - (`number`, optional, defaults module defaults) minimum number of instances that should be present in - the scale set when the autoscaling engine cannot read the metrics or is otherwise unable to compare - the metrics to the thresholds - - - `vnet_key` - (`string`, required) a key of a VNET defined in `var.vnets`. This is the VNET that hosts subnets - used to deploy network interfaces for VMs in this Scale Set - - `interfaces` - (`list`, required) configuration of all network interfaces, order does matter - the 1st - interface should be the management one. Following properties are available: - - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`) - - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in - `var.vnets` - - `create_public_ip` - (`bool`, optional, defaults to module defaults) create Public IP for an interface - - `load_balancer_key` - (`string`, optional, defaults to `null`) key of a Load Balancer defined in the - `var.loadbalancers` variable, network interface that has this property defined will be - added to the Load Balancer's backend pool - - `application_gateway_key` - (`string`, optional, defaults to `null`) key of an Application Gateway defined in the - `var.appgws`, network interface that has this property defined will be added to the Application - Gateways's backend pool - - `pip_domain_name_label` - (`string`, optional, defaults to `null`) prefix which should be used for the Domain Name Label - for each VM instance - - - `autoscaling_profiles` - (`list`, optional, defaults to `[]`) a list of autoscaling profiles, for details on available - configuration please refer to - [module's documentation](../../modules/vmss/README.md#autoscaling_profiles) - - EOF - default = {} - nullable = false - type = map(object({ - name = string - authentication = object({ - username = optional(string) - password = optional(string) - disable_password_authentication = optional(bool, true) - ssh_keys = optional(list(string), []) - }) - image = object({ - version = optional(string) - publisher = optional(string) - offer = optional(string) - sku = optional(string) - enable_marketplace_plan = optional(bool) - custom_id = optional(string) - }) - virtual_machine_scale_set = optional(object({ - size = optional(string) - bootstrap_options = optional(string) - zones = optional(list(string)) - disk_type = optional(string) - accelerated_networking = optional(bool) - encryption_at_host_enabled = optional(bool) - overprovision = optional(bool) - platform_fault_domain_count = optional(number) - disk_encryption_set_id = optional(string) - enable_boot_diagnostics = optional(bool, true) - boot_diagnostics_storage_uri = optional(string) - identity_type = optional(string) - identity_ids = optional(list(string), []) - allow_extension_operations = optional(bool) - })) - autoscaling_configuration = optional(object({ - default_count = optional(number) - scale_in_policy = optional(string) - scale_in_force_deletion = optional(bool) - notification_emails = optional(list(string), []) - webhooks_uris = optional(map(string), {}) - }), {}) - vnet_key = string - interfaces = list(object({ - name = string - subnet_key = string - create_public_ip = optional(bool) - load_balancer_key = optional(string) - application_gateway_key = optional(string) - pip_domain_name_label = optional(string) - })) - autoscaling_profiles = optional(list(object({ - name = string - minimum_count = optional(number) - default_count = number - maximum_count = optional(number) - recurrence = optional(object({ - timezone = optional(string) - days = list(string) - start_time = string - end_time = string - })) - scale_rules = optional(list(object({ - name = string - scale_out_config = object({ - threshold = number - operator = optional(string) - grain_window_minutes = number - grain_aggregation_type = optional(string) - aggregation_window_minutes = number - aggregation_window_type = optional(string) - cooldown_window_minutes = number - change_count_by = optional(number) - }) - scale_in_config = object({ - threshold = number - operator = optional(string) - grain_window_minutes = optional(number) - grain_aggregation_type = optional(string) - aggregation_window_minutes = optional(number) - aggregation_window_type = optional(string) - cooldown_window_minutes = number - change_count_by = optional(number) - }) - })), []) - })), []) - })) -} - - - -### Application Gateway variable "appgws" { description = <<-EOF A map defining all Application Gateways in the current deployment. @@ -497,25 +290,25 @@ variable "appgws" { described by `subnet_key`. - `subnet_key` - (`string`, required) a key pointing to a Subnet definition in the `var.vnets` map, this has to be an Application Gateway V2 dedicated subnet. - - `zones` - (`list`, optional, defaults to module defaults) parameter controlling if this is a zonal, or a non-zonal + - `zones` - (`list`, optional, defaults to module default) parameter controlling if this is a zonal, or a non-zonal deployment. - `public_ip` - (`map`, required) defines a Public IP resource used by the Application Gateway instance, a newly created Public IP will have it's name prefixes with `var.name_prefix`. - `listeners` - (`map`, required) defines Application Gateway's Listeners, see [module's documentation](../../modules/appgw/README.md#listeners) for details. - - `backend_pool` - (`map`, optional, defaults to module defaults) backend pool definition, when skipped an empty backend + - `backend_pool` - (`map`, optional, defaults to module default) backend pool definition, when skipped an empty backend will be created. - `backend_settings` - (`map`, optional, mutually exclusive with `redirects` and `url_path_maps`) defines HTTP backend settings, see [module's documentation](../../modules/appgw/README.md#backend_settings) for details. - - `probes` - (`map`, optional, defaults to module defaults) defines backend probes used check health of backends, see + - `probes` - (`map`, optional, defaults to module default) defines backend probes used check health of backends, see [module's documentation](../../modules/appgw/README.md#probes) for details. - - `rewrites` - (`map`, optional, defaults to module defaults) defines rewrite rules, see + - `rewrites` - (`map`, optional, defaults to module default) defines rewrite rules, see [module's documentation](../../modules/appgw/README.md#rewrites) for details. - - `redirects - (`map`, optional, mutually exclusive with `backend_settings` and `url_path_maps`) static redirects + - `redirects` - (`map`, optional, mutually exclusive with `backend_settings` and `url_path_maps`) static redirects definition, see [module's documentation](../../modules/appgw/README.md#redirects) for details. - - `url_path_maps - (`map`, optional, mutually exclusive with `backend_settings` and `redirects`) URL path maps definition, + - `url_path_maps` - (`map`, optional, mutually exclusive with `backend_settings` and `redirects`) URL path maps definition, see [module's documentation](../../modules/appgw/README.md#url_path_maps) for details. - - `rules - (`map`, required) Application Gateway Rules definition, bind together a `listener` with either + - `rules` - (`map`, required) Application Gateway Rules definition, bind together a `listener` with either `backend_setting`, `redirect` or `url_path_map`, see [module's documentation](../../modules/appgw/README.md#rules) for details. EOF @@ -642,3 +435,205 @@ variable "appgws" { })) })) } + +### VM-SERIES ### + +variable "ngfw_metrics" { + description = <<-EOF + A map controlling metrics-relates resources. + + When set to explicit `null` (default) it will disable any metrics resources in this deployment. + + When defined it will either create or source a Log Analytics Workspace and create Application Insights instances (one per each + Scale Set). All instances will be automatically connected to the workspace. The name of the Application Insights instance will + be derived from the Scale Set name and suffixed with `-ai`. + + All the settings available below are common to the Log Analytics Workspace and Application Insight instances. + + Following properties are available: + + - `name` - (`string`, required) name of the (common) Log Analytics Workspace. + - `create_workspace` - (`bool`, optional, defaults to `true`) controls whether we create or source an existing Log + Analytics Workspace. + - `resource_group_name` - (`string`, optional, defaults to `var.resource_group_name`) name of the Resource Group hosting + the Log Analytics Workspace. + - `sku` - (`string`, optional, defaults to module default) the SKU of the Log Analytics Workspace. + - `metrics_retention_in_days` - (`number`, optional, defaults to module default) workspace and insights data retention in days, + possible values are between 30 and 730. For sourced Workspaces this applies only to the + Application Insights instances. + EOF + default = null + type = object({ + name = string + create_workspace = optional(bool, true) + resource_group_name = optional(string) + sku = optional(string) + metrics_retention_in_days = optional(number) + }) +} + +variable "scale_sets" { + description = <<-EOF + A map defining Azure Virtual Machine Scale Sets based on Palo Alto Networks Next Generation Firewall image. + + For details and defaults for available options please refer to the [`vmss`](../../modules/vmss/README.md) module. + + The basic Scale Set configuration properties are as follows: + + - `name` - (`string`, required) name of the scale set, will be prefixed with the value of + `var.name_prefix`. + - `vnet_key` - (`string`, required) a key of a VNET defined in `var.vnets`. This is the VNET that hosts + subnets used to deploy network interfaces for VMs in this Scale Set. + - `authentication` - (`map`, required) authentication setting for VMs deployed in this scale set. + + This map holds the firewall admin password. When this property is not set, the password will be autogenerated for you and + available in the Terraform outputs. + + **Note!** \ + The `disable_password_authentication` property is by default true. When using this value you have to specify at least one + SSH key. You can however set this property to `true`. Then you have 2 options, either: + + - do not specify anything else, a random password will be generated for you. + - specify at least one of `password` or `ssh_keys` properties. + + For all properties and their default values refer to [module's documentation](../../modules/vmss/README.md#authentication). + + - `image` - (`map`, required) properties defining a base image used to spawn VMs in this Scale Set. The + `image` property is required but there are only 2 properties (mutually exclusive) that have to + be set up, either: + + - `version` - (`string`, optional) describes the PAN-OS image version from Azure Marketplace. + - `custom_id` - (`string`, optional) absolute ID of your own custom PAN-OS image. + + For details on all properties refer to [module's documentation](../../modules/vmss/README.md#image). + + - `virtual_machine_scale_set` - (`map`, optional, defaults to module default) a map that groups most common Scale Set + configuration options: + + - `size` - (`string`, optional, defaults to module default) Azure VM size (type). Consult the *VM-Series + Deployment Guide* as only a few selected sizes are supported. + - `zones` - (`list`, optional, defaults to module default) a list of Availability Zones in which VMs from + this Scale Set will be created. + - `disk_type` - (`string`, optional, defaults to module default) type of Managed Disk which should be created, + possible values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected + `vm_size` values). + - `bootstrap_options` - (`string`, optional, defaults to module default) bootstrap options to pass to VM-Series instance. + + For details on all properties refer to [module's documentation](../../modules/vmss/README.md#virtual_machine_scale_set). + + - `autoscaling_configuration` - (`map`, optional, defaults to `{}`) a map that groups common autoscaling configuration, but not + the scaling profiles (metrics, thresholds, etc.). Most common properties are: + + - `default_count` - (`number`, optional, defaults to module default) minimum number of instances that should be present + in the scale set when the autoscaling engine cannot read the metrics or is otherwise unable to + compare the metrics to the thresholds. + + For details on all properties refer to [module's documentation](../../modules/vmss/README.md#autoscaling_configuration). + + - `interfaces` - (`list`, required) configuration of all network interfaces, order does matter - the + 1st interface should be the management one. Following properties are available: + + - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`). + - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in + `var.vnets`. + - `create_public_ip` - (`bool`, optional, defaults to module default) create Public IP for an interface. + - `load_balancer_key` - (`string`, optional, defaults to `null`) key of a Load Balancer defined in the + `var.loadbalancers` variable, network interface that has this property defined will be added to + the Load Balancer's backend pool. + - `application_gateway_key` - (`string`, optional, defaults to `null`) key of an Application Gateway defined in the + `var.appgws`, network interface that has this property defined will be added to the Application + Gateways's backend pool. + - `pip_domain_name_label` - (`string`, optional, defaults to `null`) prefix which should be used for the Domain Name Label + for each VM instance. + + - `autoscaling_profiles` - (`list`, optional, defaults to `[]`) a list of autoscaling profiles, for details on available + properties please refer to + [module's documentation](../../modules/vmss/README.md#autoscaling_profiles). + EOF + default = {} + nullable = false + type = map(object({ + name = string + vnet_key = string + authentication = object({ + username = optional(string) + password = optional(string) + disable_password_authentication = optional(bool, true) + ssh_keys = optional(list(string), []) + }) + image = object({ + version = optional(string) + publisher = optional(string) + offer = optional(string) + sku = optional(string) + enable_marketplace_plan = optional(bool) + custom_id = optional(string) + }) + virtual_machine_scale_set = optional(object({ + size = optional(string) + bootstrap_options = optional(string) + zones = optional(list(string)) + disk_type = optional(string) + accelerated_networking = optional(bool) + encryption_at_host_enabled = optional(bool) + overprovision = optional(bool) + platform_fault_domain_count = optional(number) + disk_encryption_set_id = optional(string) + enable_boot_diagnostics = optional(bool, true) + boot_diagnostics_storage_uri = optional(string) + identity_type = optional(string) + identity_ids = optional(list(string), []) + allow_extension_operations = optional(bool) + })) + autoscaling_configuration = optional(object({ + default_count = optional(number) + scale_in_policy = optional(string) + scale_in_force_deletion = optional(bool) + notification_emails = optional(list(string), []) + webhooks_uris = optional(map(string), {}) + }), {}) + interfaces = list(object({ + name = string + subnet_key = string + create_public_ip = optional(bool) + load_balancer_key = optional(string) + application_gateway_key = optional(string) + pip_domain_name_label = optional(string) + })) + autoscaling_profiles = optional(list(object({ + name = string + minimum_count = optional(number) + default_count = number + maximum_count = optional(number) + recurrence = optional(object({ + timezone = optional(string) + days = list(string) + start_time = string + end_time = string + })) + scale_rules = optional(list(object({ + name = string + scale_out_config = object({ + threshold = number + operator = optional(string) + grain_window_minutes = number + grain_aggregation_type = optional(string) + aggregation_window_minutes = number + aggregation_window_type = optional(string) + cooldown_window_minutes = number + change_count_by = optional(number) + }) + scale_in_config = object({ + threshold = number + operator = optional(string) + grain_window_minutes = optional(number) + grain_aggregation_type = optional(string) + aggregation_window_minutes = optional(number) + aggregation_window_type = optional(string) + cooldown_window_minutes = number + change_count_by = optional(number) + }) + })), []) + })), []) + })) +} diff --git a/examples/gwlb_with_vmseries/README.md b/examples/gwlb_with_vmseries/README.md index 3b146381..26185cc3 100644 --- a/examples/gwlb_with_vmseries/README.md +++ b/examples/gwlb_with_vmseries/README.md @@ -82,8 +82,8 @@ terraform destroy Name | Type | Description --- | --- | --- -[`location`](#location) | `string` | The Azure region to use. [`resource_group_name`](#resource_group_name) | `string` | Name of the Resource Group. +[`location`](#location) | `string` | The Azure region to use. [`vnets`](#vnets) | `map` | A map defining VNETs. @@ -91,11 +91,11 @@ Name | Type | Description Name | Type | Description --- | --- | --- -[`tags`](#tags) | `map` | Map of tags to assign to the created resources. [`name_prefix`](#name_prefix) | `string` | A prefix that will be added to all created resources. [`create_resource_group`](#create_resource_group) | `bool` | When set to `true` it will cause a Resource Group creation. -[`load_balancers`](#load_balancers) | `map` | A map containing configuration for all (private and public) Load Balancers. -[`gateway_load_balancers`](#gateway_load_balancers) | `map` | Map with Gateway Load Balancer definitions. +[`tags`](#tags) | `map` | Map of tags to assign to the created resources. +[`load_balancers`](#load_balancers) | `map` | A map containing configuration for all (both private and public) Load Balancers. +[`gateway_load_balancers`](#gateway_load_balancers) | `map` | A map with Gateway Load Balancer (GWLB) definitions. [`availability_sets`](#availability_sets) | `map` | A map defining availability sets. [`ngfw_metrics`](#ngfw_metrics) | `object` | A map controlling metrics-relates resources. [`bootstrap_storages`](#bootstrap_storages) | `map` | A map defining Azure Storage Accounts used to host file shares for bootstrapping NGFWs. @@ -133,10 +133,10 @@ Providers used in this module: Modules used in this module: Name | Version | Source | Description --- | --- | --- | --- -`vnet` | - | ../../modules/vnet | Manage the network required for the topology. -`load_balancer` | - | ../../modules/loadbalancer | create load balancers, both internal and external -`gwlb` | - | ../../modules/gwlb | create Gateway Load Balancers -`ngfw_metrics` | - | ../../modules/ngfw_metrics | create the actual VM-Series VMs and resources +`vnet` | - | ../../modules/vnet | +`load_balancer` | - | ../../modules/loadbalancer | +`gwlb` | - | ../../modules/gwlb | +`ngfw_metrics` | - | ../../modules/ngfw_metrics | `bootstrap` | - | ../../modules/bootstrap | `vmseries` | - | ../../modules/vmseries | `appvm` | - | ../../modules/virtual_machine | @@ -156,46 +156,45 @@ Resources used in this module: -#### location -The Azure region to use. +#### resource_group_name + +Name of the Resource Group. Type: string [back to list](#modules-required-inputs) +#### location - -#### resource_group_name - -Name of the Resource Group. +The Azure region to use. Type: string [back to list](#modules-required-inputs) + #### vnets A map defining VNETs. - + For detailed documentation on each property refer to [module documentation](../../modules/vnet/README.md) -- `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, - `false` will source an existing VNET. -- `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be - a full resource name, including prefixes. -- `address_space` - (`list(string)`, required when `create_virtual_network = false`) a list of CIDRs for a newly - created VNET -- `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which - the VNET will reside or is sourced from +- `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, `false` will source + an existing VNET. +- `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be a + full resource name, including prefixes. +- `address_space` - (`list`, required when `create_virtual_network = false`) a list of CIDRs for a newly created VNET. +- `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which the + VNET will reside or is sourced from. - `create_subnets` - (`bool`, optional, defaults to `true`) if `true`, create Subnets inside the Virtual Network, - otherwise use source existing subnets + otherwise use source existing subnets. - `subnets` - (`map`, optional) map of Subnets to create or source, for details see - [VNET module documentation](../../modules/vnet/README.md#subnets) + [VNET module documentation](../../modules/vnet/README.md#subnets). - `network_security_groups` - (`map`, optional) map of Network Security Groups to create, for details see - [VNET module documentation](../../modules/vnet/README.md#network_security_groups) + [VNET module documentation](../../modules/vnet/README.md#network_security_groups). - `route_tables` - (`map`, optional) map of Route Tables to create, for details see - [VNET module documentation](../../modules/vnet/README.md#route_tables) + [VNET module documentation](../../modules/vnet/README.md#route_tables). Type: @@ -260,17 +259,6 @@ map(object({ ### Optional Inputs -#### tags - -Map of tags to assign to the created resources. - -Type: map(string) - -Default value: `map[]` - -[back to list](#modules-optional-inputs) - - #### name_prefix A prefix that will be added to all created resources. @@ -281,7 +269,7 @@ Example: ``` name_prefix = "test-" ``` - + **Note!** \ This prefix is not applied to existing resources. If you plan to reuse i.e. a VNET please specify it's full name, even if it is also prefixed with the same value as the one in this property. @@ -297,7 +285,7 @@ Default value: `` When set to `true` it will cause a Resource Group creation. Name of the newly specified RG is controlled by `resource_group_name`. - + When set to `false` the `resource_group_name` parameter is used to specify a name of an existing Resource Group. @@ -309,9 +297,20 @@ Default value: `true` +#### tags + +Map of tags to assign to the created resources. + +Type: map(string) + +Default value: `map[]` + +[back to list](#modules-optional-inputs) + + #### load_balancers -A map containing configuration for all (private and public) Load Balancers. +A map containing configuration for all (both private and public) Load Balancers. This is a brief description of available properties. For a detailed one please refer to [module documentation](../../modules/loadbalancer/README.md). @@ -321,26 +320,29 @@ Following properties are available: - `name` - (`string`, required) a name of the Load Balancer. - `vnet_key` - (`string`, optional, defaults to `null`) a key pointing to a VNET definition in the `var.vnets` map that stores the Subnet described by `subnet_key`. -- `zones` - (`list`, optional, defaults to module defaults) a list of zones for Load Balancer's fronted IP +- `zones` - (`list`, optional, defaults to module default) a list of zones for Load Balancer's frontend IP configurations. -- `backend_name` - (`string`, optional, defaults to module defaults) a name of the backend pool to create. -- `health_probes` - (`map`, optional, defaults to `null`) a map defining health probes that will be used by - load balancing rules; please check +- `backend_name` - (`string`, optional, defaults to module default) a name of the backend pool to create. +- `health_probes` - (`map`, optional, defaults to `null`) a map defining health probes that will be used by load + balancing rules, please refer to [module documentation](../../modules/loadbalancer/README.md#health_probes) for more specific use cases and available properties. -- `nsg_auto_rules_settings` - (`map`, optional, defaults to `null`) a map defining a location of an existing NSG rule - that will be populated with `Allow` rules for each load balancing rule (`in_rules`); please check - [module documentation](../../modules/loadbalancer/README.md#nsg_auto_rules_settings) - for available properties; please note that in this example two additional properties are - available: - - `nsg_vnet_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to a VNET definition - in the `var.vnets` map that stores the NSG described by `nsg_key`. - - `nsg_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to an NSG definition - in the `var.vnets` map. -- `frontend_ips` - (`map`, optional, defaults to `{}`) a map containing frontend IP configuration with respective - `in_rules` and `out_rules` +- `nsg_auto_rules_settings` - (`map`, optional, defaults to `null`) a map defining a location of an existing NSG rule that will + be populated with `Allow` rules for each load balancing rule (`in_rules`), please refer to + [module documentation](../../modules/loadbalancer/README.md#nsg_auto_rules_settings) for + available properties. + + Please note that in this example two additional properties are available: + + - `nsg_vnet_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to a VNET definition in the + `var.vnets` map that stores the NSG described by `nsg_key`. + - `nsg_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to an NSG definition in the + `var.vnets` map. - Please refer to [module documentation](../../modules/loadbalancer/README.md#frontend_ips) for available properties. +- `frontend_ips` - (`map`, optional, defaults to `{}`) a map containing frontend IP configuration with respective + `in_rules` and `out_rules`, please refer to + [module documentation](../../modules/loadbalancer/README.md#frontend_ips) for available + properties. **Note!** \ In this example the `subnet_id` is not available directly, another property has been introduced instead: @@ -374,10 +376,10 @@ map(object({ })) frontend_ips = optional(map(object({ name = string + subnet_key = optional(string) public_ip_name = optional(string) create_public_ip = optional(bool, false) public_ip_resource_group_name = optional(string) - subnet_key = optional(string) private_ip_address = optional(string) gwlb_key = optional(string) in_rules = optional(map(object({ @@ -408,18 +410,22 @@ Default value: `map[]` #### gateway_load_balancers -Map with Gateway Load Balancer definitions. +A map with Gateway Load Balancer (GWLB) definitions. Following settings are available: -- `name` - (`string`, required) name of the Gatewa Load Balancer Gateway. -- `frontend_ip` - (`object`, required) frontend IP configuration - (refer to [module documentation](../../modules/gwlb/README.md) for details) -- `health_probe - (`object`, optional) health probe settings - (refer to [module documentation](../../modules/gwlb/README.md) for details) -- `backends` - (`map`, optional) map of backends - (refer to [module documentation](../../modules/gwlb/README.md) for details) -- `lb_rule` - (`object`, optional) load balancer rule - (refer to [module documentation](../../modules/gwlb/README.md) for details) +- `name` - (`string`, required) name of the Gateway Load Balancer Gateway. +- `vnet_key` - (`string`, required) a name (key value) of a VNET defined in `var.vnets` that hosts a subnet this GWLB will + be assigned to. +- `subnet_key` - (`string`, required) a name (key value) of Subnet the GWLB will be assigned to, defined in `var.vnets` for + a VNET described by `vnet_name`. +- `frontend_ip` - (`object`, required) frontend IP configuration, refer to + [module's documentation](../../modules/gwlb/README.md) for details. +- `health_probe` - (`object`, optional) health probe settings, refer to + [module's documentation](../../modules/gwlb/README.md) for details. +- `backends` - (`map`, optional) map of backends, refer to + [module's documentation](../../modules/gwlb/README.md) for details. +- `lb_rule` - (`object`, optional) load balancer rule, refer to + [module's documentation](../../modules/gwlb/README.md) for details. Type: @@ -469,12 +475,14 @@ Default value: `map[]` A map defining availability sets. Can be used to provide infrastructure high availability when zones cannot be used. Following properties are supported: -- `name` - name of the Application Insights. -- `update_domain_count` - specifies the number of update domains that are used, defaults to 5 (Azure defaults). -- `fault_domain_count` - specifies the number of fault domains that are used, defaults to 3 (Azure defaults). -Please keep in mind that Azure defaults are not working for each region (especially the small ones, w/o any Availability Zones). -Please verify how many update and fault domain are supported in a region before deploying this resource. +- `name` - (`string`, required) name of the Application Insights. +- `update_domain_count` - (`number`, optional, defaults to Azure default) specifies the number of update domains that are used. +- `fault_domain_count` - (`number`, optional, defaults to Azure default) specifies the number of fault domains that are used. + +**Note!** \ +Please keep in mind that Azure defaults are not working for every region (especially the small ones, without any Availability +Zones). Please verify how many update and fault domain are supported in a region before deploying this resource. Type: @@ -482,8 +490,8 @@ Type: ```hcl map(object({ name = string - update_domain_count = optional(number, 5) - fault_domain_count = optional(number, 3) + update_domain_count = optional(number) + fault_domain_count = optional(number) })) ``` @@ -499,22 +507,22 @@ A map controlling metrics-relates resources. When set to explicit `null` (default) it will disable any metrics resources in this deployment. When defined it will either create or source a Log Analytics Workspace and create Application Insights instances (one per each -Scale Set). All instances will be automatically connected to the workspace. -The name of the Application Insights instance will be derived from the Scale Set name and suffixed with `-ai`. +Scale Set). All instances will be automatically connected to the workspace. The name of the Application Insights instance will +be derived from the Scale Set name and suffixed with `-ai`. All the settings available below are common to the Log Analytics Workspace and Application Insight instances. Following properties are available: -- `name` - (`string`, required) name of the (common) Log Analytics Workspace +- `name` - (`string`, required) name of the (common) Log Analytics Workspace. - `create_workspace` - (`bool`, optional, defaults to `true`) controls whether we create or source an existing Log - Analytics Workspace + Analytics Workspace. - `resource_group_name` - (`string`, optional, defaults to `var.resource_group_name`) name of the Resource Group hosting - the Log Analytics Workspace -- `sku` - (`string`, optional, defaults to module defaults) the SKU of the Log Analytics Workspace. -- `metrics_retention_in_days` - (`number`, optional, defaults to module defaults) workspace and insights data retention in - days, possible values are between 30 and 730. For sourced Workspaces this applies only to - the Application Insights instances. + the Log Analytics Workspace. +- `sku` - (`string`, optional, defaults to module default) the SKU of the Log Analytics Workspace. +- `metrics_retention_in_days` - (`number`, optional, defaults to module default) workspace and insights data retention in days, + possible values are between 30 and 730. For sourced Workspaces this applies only to the + Application Insights instances. Type: @@ -543,43 +551,52 @@ You can create or re-use an existing Storage Account and/or File Share. For deta - `name` - (`string`, required) name of the Storage Account that will be created or sourced. - **Note** \ - For new Storage Accounts this name will not be prefixed with `var.name_prefix`. \ - Please note the limitations on naming. This has to be a globally unique name, between 3 and 63 chars, only lower-case - letters and numbers. + **Note** \ + For new Storage Accounts this name will not be prefixed with `var.name_prefix`. \ + Please note the limitations on naming. This has to be a globally unique name, between 3 and 63 chars, only lower-case letters + and numbers. -- `resource_group_name` - (`string`, optional, defaults to `null`) name of the Resource Group that hosts (sourced) or will - host (created) a Storage Account. When skipped the code will fall back to +- `resource_group_name` - (`string`, optional, defaults to `null`) name of the Resource Group that hosts (sourced) or + will host (created) a Storage Account. When skipped the code will fall back to `var.resource_group_name`. -- `storage_account` - (`map`, optional, defaults to `{}`) a map controlling basic Storage Account configuration, for - detailed documentation see - [module's documentation](../../modules/bootstrap/README.md#storage_account). The property you - should pay attention to is: - - `create` - (`bool`, optional, defaults to module defaults) controls if the Storage Account specified in - the `name` property will be created or sourced. +- `storage_account` - (`map`, optional, defaults to `{}`) a map controlling basic Storage Account configuration. + + The property you should pay attention to is: + + - `create` - (`bool`, optional, defaults to module default) controls if the Storage Account specified in the `name` property + will be created or sourced. + + For detailed documentation see [module's documentation](../../modules/bootstrap/README.md#storage_account). + - `storage_network_security` - (`map`, optional, defaults to `{}`) a map defining network security settings for a **new** - storage account, for details see - [module's documentation](../../modules/bootstrap/README.md#storage_network_security). Properties - worth mentioning are: - - `allowed_subnet_keys` - (`list`, optional, defaults to `[]`) a list of keys pointing to Subnet definitions in the - `var.vnets` map. These Subnets will have dedicated access to the Storage Account. For this to - work they also need to have the Storage Account Service Endpoint enabled. - - `vnet_key` - a key pointing to a VNET definition in the `var.vnets` map that stores the Subnets described - in `allowed_subnet_keys`. -- `file_shares_configuration` - (`map`, optional, defaults to `{}`) a map defining common File Share setting. For detailed - documentation see - [module's documentation](../../modules/bootstrap/README.md#file_shares_configuration). The - properties you should pay your attention to are: - - `create_file_shares` - (`bool`, optional, defaults to module defaults) controls if the File Shares defined in the + storage account. + + The properties you should pay attention to are: + + - `allowed_subnet_keys` - (`list`, optional, defaults to `[]`) a list of keys pointing to Subnet definitions in the + `var.vnets` map. These Subnets will have dedicated access to the Storage Account. For this to work + they also need to have the Storage Account Service Endpoint enabled. + - `vnet_key` - (`string`, optional) a key pointing to a VNET definition in the `var.vnets` map that stores the + Subnets described in `allowed_subnet_keys`. + + For detailed documentation see [module's documentation](../../modules/bootstrap/README.md#storage_network_security). + +- `file_shares_configuration` - (`map`, optional, defaults to `{}`) a map defining common File Share setting. + + The properties you should pay attention to are: + + - `create_file_shares` - (`bool`, optional, defaults to module default) controls if the File Shares defined in the `file_shares` property will be created or sourced. - - `disable_package_dirs_creation` - (`bool`, optional, defaults to module defaults) for sourced File Shares, controls if the + - `disable_package_dirs_creation` - (`bool`, optional, defaults to module default) for sourced File Shares, controls if the bootstrap package folder structure will be created. + + For detailed documentation see [module's documentation](../../modules/bootstrap/README.md#file_shares_configuration). + - `file_shares` - (`map`, optional, defaults to `{}`) a map that holds File Shares and bootstrap package configuration. For detailed description see [module's documentation](../../modules/bootstrap/README.md#file_shares). - Type: ```hcl @@ -622,123 +639,121 @@ Default value: `map[]` #### vmseries -A map defining Azure Virtual Machines based on Palo Alto Networks Next Generation Firewall image.. +A map defining Azure Virtual Machines based on Palo Alto Networks Next Generation Firewall image. For details and defaults for available options please refer to the [`vmseries`](../../modules/vmseries/README.md) module. The most basic properties are as follows: - `name` - (`string`, required) name of the VM, will be prefixed with the value of `var.name_prefix`. +- `vnet_key` - (`string`, required) a key of a VNET defined in `var.vnets`. This is the VNET that hosts subnets used to + deploy network interfaces for deployed VM. - `authentication` - (`map`, optional, defaults to example defaults) authentication settings for the deployed VM. - The `authentication` property is optional and holds the firewall admin access details. By default, standard username - `panadmin` will be set and a random password will be auto-generated for you (available in Terraform outputs). + The `authentication` property is optional and holds the firewall admin access details. By default, standard username + `panadmin` will be set and a random password will be auto-generated for you (available in Terraform outputs). - **Note!** \ - The `disable_password_authentication` property is by default `false` in this example. When using this value, you don't have - to specify anything but you can still additionally pass SSH keys for authentication. You can however set this property to - `true`, then you have to specify `ssh_keys` property. - - For all properties and their default values see [module's documentation](../../modules/vmseries/README.md#authentication). - -- `image` - (`map`, required) properties defining a base image used by the deployed VM. - - The `image` property is required but there are only 2 properties (mutually exclusive) that have to be set, either: - - - `version` - (`string`) describes the PAN-OS image version from Azure Marketplace. - - `custom_id` - (`string`) absolute ID of your own custom PAN-OS image. - - For details on the other properties refer to [module's documentation](../../modules/vmseries/README.md#image). - -- `virtual_machine` - (`map`, optional, defaults to module defaults) a map that groups most common VM configuration options. - - The most often used option are as follows: - - - `vnet_key` - (`string`, required) a key of a VNET defined in `var.vnets`. This is the VNET that hosts subnets used to - deploy network interfaces for deployed VM. - - `size` - (`string`, optional, defaults to module defaults) Azure VM size (type). Consult the *VM-Series Deployment - Guide* as only a few selected sizes are supported. - - `zone` - (`string`, optional, defaults to module defaults) the Availability Zone in which the VM and (if deployed) - public IP addresses will be created. - - `disk_type` - (`string`, optional, defaults to module defaults) type of a Managed Disk which should be created, possible - values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected `size` values). - - `bootstrap_options` - (`string`, optional, mutually exclusive with `bootstrap_package`) bootstrap options passed to PAN-OS - when launched for the 1st time, for details see module documentation. - - `bootstrap_package` - (`map`, optional, mutually exclusive with `bootstrap_options`) a map defining content of the - bootstrap package. - - **Note!** \ - At least one of `static_files`, `bootstrap_xml_template` or `bootstrap_package_path` is required. You can use a - combination of all 3. The `bootstrap_package_path` is the less important. For details on this mechanism and for details - on the other properties see the [`bootstrap` module documentation](../../modules/bootstrap/README.md). - - Following properties are available: - - - `bootstrap_storage_key` - (`string`, required) a key of a bootstrap storage defined in `var.bootstrap_storages` that - will host bootstrap packages. Each package will be hosted on a separate File Share. - The File Shares will be created automatically, one for each firewall. - - `static_files` - (`map`, optional, defaults to `{}`) a map containing files that will be copied to a File - Share, see [`file_shares.bootstrap_files`](../../modules/bootstrap/README.md#file_shares) - property documentation for details. - - `bootstrap_package_path` - (`string`, optional, defaults to `null`) a path to a folder containing a full bootstrap - package. - - `bootstrap_xml_template` - (`string`, optional, defaults to `null`) a path to a `bootstrap.xml` template. If this - example is using full bootstrap method, the sample templates are in - [`templates`](./templates) folder. - - The templates are used to provide `day0` like configuration which consists of: - - - network interfaces configuration. - - one or more (depending on the architecture) Virtual Routers configurations. This config contains static routes - required for the Load Balancer (and Application Gateway, if defined) health checks to work and routes that allow - Inbound and OBEW traffic. - - *any-any* security rule. - - an outbound NAT rule that will allow the Outbound traffic to flow to the internet. - - **Note!** \ - Day0 configuration is **not meant** to be **secure**. It's here marly to help with the basic firewall setup. - - When `bootstrap_xml_template` is set, one of the following properties might be required. - - - `data_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key - pointing to a data Subnet definition in `var.vnets` (the `vnet_key` property is used to - identify a VNET). The Subnet definition is used to calculate static routes for a data - Load Balancer health checks. - - `ai_update_interval` - (`number`, optional, defaults to `5`) Application Insights update interval, used only when - `ngfw_metrics` module is defined and used in this example. The Application Insights - Instrumentation Key will be populated automatically. - - `intranet_cidr` - (`string`, optional, defaults to `null`) a CIDR of the Intranet - combined CIDR of all - private networks. When set it will override the private Subnet CIDR for inbound traffic - static routes. - - For details on the other properties refer to [module's documentation](../../modules/panorama/README.md#virtual_machine). - -- `interfaces` - (`list`, required) configuration of all network interfaces + **Note!** \ + The `disable_password_authentication` property is by default `false` in this example. When using this value, you don't have + to specify anything but you can still additionally pass SSH keys for authentication. You can however set this property to + `true`, then you have to specify `ssh_keys` property. - **Note!** \ - Order of the interfaces does matter - the 1st interface is the management one. + For all properties and their default values see [module's documentation](../../modules/vmseries/README.md#authentication). - For details on available properties please see [module's documentation](../../modules/panorama/README.md#interfaces). +- `image` - (`map`, required) properties defining a base image used by the deployed VM. The `image` property is + required but there are only 2 properties (mutually exclusive) that have to be set, either: - The most important ones are listed below: + - `version` - (`string`, optional) describes the PAN-OS image version from Azure Marketplace. + - `custom_id` - (`string`, optional) absolute ID of your own custom PAN-OS image. - - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`). - - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in - `var.vnets`. Key identifying the VNET is defined in `virtual_machine.vnet_key` property. - - `create_public_ip` - (`bool`, optional, defaults to `false`) create a Public IP for an interface. - - `load_balancer_key` - (`string`, optional, defaults to `null`) key of a Load Balancer defined in `var.loadbalancers` - variable, network interface that has this property defined will be added to the Load Balancer's - backend pool - - `add_to_appgw_backend` - (`bool`, optional, defaults to `false`) when set an interface's private IP address will be added - to the Application Gateway's backend pool. + For details on all properties refer to [module's documentation](../../modules/vmseries/README.md#image). +- `virtual_machine` - (`map`, optional, defaults to module default) a map that groups most common VM configuration options. + Most common properties are: + + - `size` - (`string`, optional, defaults to module default) Azure VM size (type). Consult the *VM-Series + Deployment Guide* as only a few selected sizes are supported. + - `zone` - (`string`, optional, defaults to module default) the Availability Zone in which the VM and (if + deployed) public IP addresses will be created. + - `disk_type` - (`string`, optional, defaults to module default) type of a Managed Disk which should be created, + possible values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected + `size` values). + - `bootstrap_options` - (`string`, optional, mutually exclusive with `bootstrap_package`) bootstrap options passed to PAN-OS + when launched for the 1st time, for details see module documentation. + - `bootstrap_package` - (`map`, optional, mutually exclusive with `bootstrap_options`) a map defining content of the + bootstrap package. + + **Note!** \ + At least one of `static_files`, `bootstrap_xml_template` or `bootstrap_package_path` is required. You can use a combination + of all 3. The `bootstrap_package_path` is the less important. For details on this mechanism and for details on the other + properties see the [`bootstrap` module documentation](../../modules/bootstrap/README.md). + + Following properties are available: + + - `bootstrap_storage_key` - (`string`, required) a key of a bootstrap storage defined in `var.bootstrap_storages` that + will host bootstrap packages. Each package will be hosted on a separate File Share. The File + Shares will be created automatically, one for each firewall. + - `static_files` - (`map`, optional, defaults to `{}`) a map containing files that will be copied to a File + Share, see [`file_shares.bootstrap_files`](../../modules/bootstrap/README.md#file_shares) + property documentation for details. + - `bootstrap_package_path` - (`string`, optional, defaults to `null`) a path to a folder containing a full bootstrap + package. + - `bootstrap_xml_template` - (`string`, optional, defaults to `null`) a path to a `bootstrap.xml` template. If this example + is using full bootstrap method, the sample templates are in [`templates`](./templates) folder. + + The templates are used to provide `day0` like configuration which consists of: + + - network interfaces configuration. + - one or more (depending on the architecture) Virtual Routers configurations. This config contains static routes + required for the Load Balancer (and Application Gateway, if defined) health checks to work and routes that allow + Inbound and OBEW traffic. + - *any-any* security rule. + - an outbound NAT rule that will allow the Outbound traffic to flow to the Internet. + + **Note!** \ + Day0 configuration is **not meant** to be **secure**. It's here merely to help with the basic firewall setup. When + `bootstrap_xml_template` is set, one of the following properties might be required. + + - `private_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key + pointing to a private Subnet definition in `var.vnets` (the `vnet_key` property is used to + identify a VNET). The Subnet definition is used to calculate static routes for a private + Load Balancer health checks and for Inbound traffic. + - `public_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key + pointing to a public Subnet definition in `var.vnets` (the `vnet_key` property is used to + identify a VNET). The Subnet definition is used to calculate static routes for a public + Load Balancer health checks and for Outbound traffic. + - `ai_update_interval` - (`number`, optional, defaults to `5`) Application Insights update interval, used only when + `ngfw_metrics` module is defined and used in this example. The Application Insights + Instrumentation Key will be populated automatically. + - `intranet_cidr` - (`string`, optional, defaults to `null`) a CIDR of the Intranet - combined CIDR of all + private networks. When set it will override the private Subnet CIDR for inbound traffic + static routes. + + For details on all properties refer to [module's documentation](../../modules/panorama/README.md#virtual_machine). + +- `interfaces` - (`list`, required) configuration of all network interfaces. Order of the interfaces does matter - the + 1st interface is the management one. Most common properties are: + + - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`). + - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in + `var.vnets`. Key identifying the VNET is defined in `virtual_machine.vnet_key` property. + - `create_public_ip` - (`bool`, optional, defaults to `false`) create a Public IP for an interface. + - `load_balancer_key` - (`string`, optional, defaults to `null`) key of a Load Balancer defined in `var.loadbalancers` + variable, network interface that has this property defined will be added to the Load Balancer's + backend pool. + - `application_gateway_key` - (`string`, optional, defaults to `null`) key of an Application Gateway defined in `var.appgws` + variable, network interface that has this property defined will be added to the Application + Gateway's backend pool. + + For details on all properties refer to [module's documentation](../../modules/panorama/README.md#interfaces). Type: ```hcl map(object({ - name = string + name = string + vnet_key = string authentication = optional(object({ username = optional(string, "panadmin") password = optional(string) @@ -754,7 +769,6 @@ map(object({ custom_id = optional(string) }) virtual_machine = object({ - vnet_key = string size = optional(string) bootstrap_options = optional(string) bootstrap_package = optional(object({ @@ -762,21 +776,23 @@ map(object({ static_files = optional(map(string), {}) bootstrap_package_path = optional(string) bootstrap_xml_template = optional(string) - data_snet_key = optional(string) + private_snet_key = optional(string) + public_snet_key = optional(string) ai_update_interval = optional(number, 5) intranet_cidr = optional(string) })) - zone = string - disk_type = optional(string) - disk_name = optional(string) - avset_key = optional(string) - accelerated_networking = optional(bool) - encryption_at_host_enabled = optional(bool) - disk_encryption_set_id = optional(string) - diagnostics_storage_uri = optional(string) - identity_type = optional(string) - identity_ids = optional(list(string)) - allow_extension_operations = optional(bool) + zone = string + disk_type = optional(string) + disk_name = optional(string) + avset_key = optional(string) + accelerated_networking = optional(bool) + encryption_at_host_enabled = optional(bool) + disk_encryption_set_id = optional(string) + enable_boot_diagnostics = optional(bool, true) + boot_diagnostics_storage_uri = optional(string) + identity_type = optional(string) + identity_ids = optional(list(string)) + allow_extension_operations = optional(bool) }) interfaces = list(object({ name = string @@ -786,9 +802,7 @@ map(object({ public_ip_resource_group_name = optional(string) private_ip_address = optional(string) load_balancer_key = optional(string) - gwlb_key = optional(string) - gwlb_backend_key = optional(string) - add_to_appgw_backend = optional(bool, false) + application_gateway_key = optional(string) })) })) ``` @@ -809,5 +823,4 @@ Default value: `map[]` [back to list](#modules-optional-inputs) - \ No newline at end of file diff --git a/examples/gwlb_with_vmseries/example.tfvars b/examples/gwlb_with_vmseries/example.tfvars index a6f462ea..9be9a153 100644 --- a/examples/gwlb_with_vmseries/example.tfvars +++ b/examples/gwlb_with_vmseries/example.tfvars @@ -1,4 +1,5 @@ -# --- GENERAL --- # +### GENERAL ### + location = "North Europe" resource_group_name = "gwlb" name_prefix = "example-" @@ -7,7 +8,8 @@ tags = { "CreatedWith" = "Terraform" } -# --- VNET PART --- # +### NETWORK ### + vnets = { "transit" = { name = "transit" @@ -102,7 +104,8 @@ vnets = { } } -# --- LOAD BALANCING PART --- # +### LOAD BALANCING ### + load_balancers = { "app1" = { name = "app1-lb" @@ -142,7 +145,6 @@ load_balancers = { } } -# --- GWLB PART --- # gateway_load_balancers = { gwlb = { name = "vmseries-gwlb" @@ -184,7 +186,8 @@ gateway_load_balancers = { } } -# --- VMSERIES PART --- # +### VM-SERIES ### + bootstrap_storages = { "bootstrap" = { name = "examplegwlbbootstrap" @@ -198,14 +201,14 @@ bootstrap_storages = { vmseries = { "fw-1" = { - name = "firewall01" + name = "firewall01" + vnet_key = "transit" image = { version = "10.2.3" } virtual_machine = { - vnet_key = "transit" - size = "Standard_DS3_v2" - zone = 1 + size = "Standard_DS3_v2" + zone = 1 bootstrap_package = { bootstrap_storage_key = "bootstrap" static_files = { "files/init-cfg.txt" = "config/init-cfg.txt" } @@ -228,14 +231,14 @@ vmseries = { ] } "fw-2" = { - name = "firewall02" + name = "firewall02" + vnet_key = "transit" image = { version = "10.2.3" } virtual_machine = { - vnet_key = "transit" - size = "Standard_DS3_v2" - zone = 2 + size = "Standard_DS3_v2" + zone = 2 bootstrap_package = { bootstrap_storage_key = "bootstrap" static_files = { "files/init-cfg.txt" = "config/init-cfg.txt" } @@ -259,7 +262,8 @@ vmseries = { } } -# --- APPLICATION VM PART --- # +### TEST INFRASTRUCTURE ### + appvms = { app1vm01 = { name = "app1-vm01" @@ -277,4 +281,4 @@ sudo systemctl enable nginx echo "Backend VM is $(hostname)" | sudo tee /var/www/html/index.html SCRIPT } -} \ No newline at end of file +} diff --git a/examples/gwlb_with_vmseries/main.tf b/examples/gwlb_with_vmseries/main.tf index 8761e2c4..8fb34ab9 100644 --- a/examples/gwlb_with_vmseries/main.tf +++ b/examples/gwlb_with_vmseries/main.tf @@ -1,4 +1,5 @@ -# Generate a random password. +### Generate a random password ### + # https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password resource "random_password" "this" { count = anytrue([ @@ -26,7 +27,8 @@ locals { } } -# Create or source the Resource Group. +### Create or source a Resource Group ### + # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group resource "azurerm_resource_group" "this" { count = var.create_resource_group ? 1 : 0 @@ -46,7 +48,8 @@ locals { resource_group = var.create_resource_group ? azurerm_resource_group.this[0] : data.azurerm_resource_group.this[0] } -# Manage the network required for the topology. +### Manage the network required for the topology ### + module "vnet" { source = "../../modules/vnet" @@ -62,15 +65,18 @@ module "vnet" { create_subnets = each.value.create_subnets subnets = each.value.subnets - network_security_groups = { for k, v in each.value.network_security_groups : k => merge(v, { name = "${var.name_prefix}${v.name}" }) + network_security_groups = { + for k, v in each.value.network_security_groups : k => merge(v, { name = "${var.name_prefix}${v.name}" }) } - route_tables = { for k, v in each.value.route_tables : k => merge(v, { name = "${var.name_prefix}${v.name}" }) + route_tables = { + for k, v in each.value.route_tables : k => merge(v, { name = "${var.name_prefix}${v.name}" }) } tags = var.tags } -# create load balancers, both internal and external +### Create Load Balancers, both internal and external ### + module "load_balancer" { source = "../../modules/loadbalancer" @@ -87,7 +93,8 @@ module "load_balancer" { nsg_auto_rules_settings = try( { nsg_name = try( - "${var.name_prefix}${var.vnets[each.value.nsg_auto_rules_settings.nsg_vnet_key].network_security_groups[each.value.nsg_auto_rules_settings.nsg_key].name}", + "${var.name_prefix}${var.vnets[each.value.nsg_auto_rules_settings.nsg_vnet_key].network_security_groups[ + each.value.nsg_auto_rules_settings.nsg_key].name}", each.value.nsg_auto_rules_settings.nsg_name ) nsg_resource_group_name = try( @@ -116,7 +123,8 @@ module "load_balancer" { depends_on = [module.vnet] } -# create Gateway Load Balancers +### Create Gateway Load Balancers ### + module "gwlb" { for_each = var.gateway_load_balancers source = "../../modules/gwlb" @@ -141,7 +149,8 @@ module "gwlb" { } -# create the actual VM-Series VMs and resources +### Create VM-Series VMs and closely associated resources ### + module "ngfw_metrics" { source = "../../modules/ngfw_metrics" @@ -149,9 +158,11 @@ module "ngfw_metrics" { create_workspace = var.ngfw_metrics.create_workspace - name = "${var.ngfw_metrics.create_workspace ? var.name_prefix : ""}${var.ngfw_metrics.name}" - resource_group_name = var.ngfw_metrics.create_workspace ? local.resource_group.name : coalesce(var.ngfw_metrics.resource_group_name, local.resource_group.name) - location = var.location + name = "${var.ngfw_metrics.create_workspace ? var.name_prefix : ""}${var.ngfw_metrics.name}" + resource_group_name = var.ngfw_metrics.create_workspace ? local.resource_group.name : ( + coalesce(var.ngfw_metrics.resource_group_name, local.resource_group.name) + ) + location = var.location log_analytics_workspace = { sku = var.ngfw_metrics.sku @@ -163,6 +174,7 @@ module "ngfw_metrics" { tags = var.tags } +# https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file resource "local_file" "bootstrap_xml" { for_each = { for k, v in var.vmseries : @@ -275,8 +287,10 @@ module "vmseries" { coalesce( each.value.virtual_machine.bootstrap_options, join(",", [ - "storage-account=${module.bootstrap[each.value.virtual_machine.bootstrap_package.bootstrap_storage_key].storage_account_name}", - "access-key=${module.bootstrap[each.value.virtual_machine.bootstrap_package.bootstrap_storage_key].storage_account_primary_access_key}", + "storage-account=${module.bootstrap[ + each.value.virtual_machine.bootstrap_package.bootstrap_storage_key].storage_account_name}", + "access-key=${module.bootstrap[ + each.value.virtual_machine.bootstrap_package.bootstrap_storage_key].storage_account_primary_access_key}", "file-share=${each.key}", "share-directory=None" ]), @@ -287,10 +301,12 @@ module "vmseries" { ) interfaces = [for v in each.value.interfaces : { - name = "${var.name_prefix}${v.name}" - subnet_id = module.vnet[each.value.virtual_machine.vnet_key].subnet_ids[v.subnet_key] - create_public_ip = v.create_public_ip - public_ip_name = v.create_public_ip ? "${var.name_prefix}${coalesce(v.public_ip_name, "${v.name}-pip")}" : v.public_ip_name + name = "${var.name_prefix}${v.name}" + subnet_id = module.vnet[each.value.virtual_machine.vnet_key].subnet_ids[v.subnet_key] + create_public_ip = v.create_public_ip + public_ip_name = v.create_public_ip ? "${var.name_prefix}${ + coalesce(v.public_ip_name, "${v.name}-pip") + }" : v.public_ip_name public_ip_resource_group_name = v.public_ip_resource_group_name private_ip_address = v.private_ip_address attach_to_lb_backend_pool = v.load_balancer_key != null || v.gwlb_key != null @@ -312,6 +328,8 @@ module "vmseries" { ] } +### Create test infrastructure ### + module "appvm" { for_each = var.appvms source = "../../modules/virtual_machine" @@ -340,4 +358,4 @@ module "appvm" { accelerated_networking = try(each.value.accelerated_networking, false) tags = var.tags -} \ No newline at end of file +} diff --git a/examples/gwlb_with_vmseries/variables.tf b/examples/gwlb_with_vmseries/variables.tf index 0528cb25..ac29cf18 100644 --- a/examples/gwlb_with_vmseries/variables.tf +++ b/examples/gwlb_with_vmseries/variables.tf @@ -1,14 +1,4 @@ -### GENERAL -variable "tags" { - description = "Map of tags to assign to the created resources." - default = {} - type = map(string) -} - -variable "location" { - description = "The Azure region to use." - type = string -} +### GENERAL ### variable "name_prefix" { description = <<-EOF @@ -20,7 +10,7 @@ variable "name_prefix" { ``` name_prefix = "test-" ``` - + **Note!** \ This prefix is not applied to existing resources. If you plan to reuse i.e. a VNET please specify it's full name, even if it is also prefixed with the same value as the one in this property. @@ -33,7 +23,7 @@ variable "create_resource_group" { description = <<-EOF When set to `true` it will cause a Resource Group creation. Name of the newly specified RG is controlled by `resource_group_name`. - + When set to `false` the `resource_group_name` parameter is used to specify a name of an existing Resource Group. EOF default = true @@ -45,32 +35,41 @@ variable "resource_group_name" { type = string } +variable "location" { + description = "The Azure region to use." + type = string +} + +variable "tags" { + description = "Map of tags to assign to the created resources." + default = {} + type = map(string) +} + +### NETWORK ### -### VNET variable "vnets" { description = <<-EOF A map defining VNETs. - + For detailed documentation on each property refer to [module documentation](../../modules/vnet/README.md) - - `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, - `false` will source an existing VNET. - - `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be - a full resource name, including prefixes. - - `address_space` - (`list(string)`, required when `create_virtual_network = false`) a list of CIDRs for a newly - created VNET - - `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which - the VNET will reside or is sourced from + - `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, `false` will source + an existing VNET. + - `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be a + full resource name, including prefixes. + - `address_space` - (`list`, required when `create_virtual_network = false`) a list of CIDRs for a newly created VNET. + - `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which the + VNET will reside or is sourced from. - `create_subnets` - (`bool`, optional, defaults to `true`) if `true`, create Subnets inside the Virtual Network, - otherwise use source existing subnets + otherwise use source existing subnets. - `subnets` - (`map`, optional) map of Subnets to create or source, for details see - [VNET module documentation](../../modules/vnet/README.md#subnets) + [VNET module documentation](../../modules/vnet/README.md#subnets). - `network_security_groups` - (`map`, optional) map of Network Security Groups to create, for details see - [VNET module documentation](../../modules/vnet/README.md#network_security_groups) + [VNET module documentation](../../modules/vnet/README.md#network_security_groups). - `route_tables` - (`map`, optional) map of Route Tables to create, for details see - [VNET module documentation](../../modules/vnet/README.md#route_tables) + [VNET module documentation](../../modules/vnet/README.md#route_tables). EOF - type = map(object({ name = string resource_group_name = optional(string) @@ -115,11 +114,11 @@ variable "vnets" { })) } +### LOAD BALANCING ### -### Load Balancing variable "load_balancers" { description = <<-EOF - A map containing configuration for all (private and public) Load Balancers. + A map containing configuration for all (both private and public) Load Balancers. This is a brief description of available properties. For a detailed one please refer to [module documentation](../../modules/loadbalancer/README.md). @@ -129,26 +128,29 @@ variable "load_balancers" { - `name` - (`string`, required) a name of the Load Balancer. - `vnet_key` - (`string`, optional, defaults to `null`) a key pointing to a VNET definition in the `var.vnets` map that stores the Subnet described by `subnet_key`. - - `zones` - (`list`, optional, defaults to module defaults) a list of zones for Load Balancer's fronted IP + - `zones` - (`list`, optional, defaults to module default) a list of zones for Load Balancer's frontend IP configurations. - - `backend_name` - (`string`, optional, defaults to module defaults) a name of the backend pool to create. - - `health_probes` - (`map`, optional, defaults to `null`) a map defining health probes that will be used by - load balancing rules; please check + - `backend_name` - (`string`, optional, defaults to module default) a name of the backend pool to create. + - `health_probes` - (`map`, optional, defaults to `null`) a map defining health probes that will be used by load + balancing rules, please refer to [module documentation](../../modules/loadbalancer/README.md#health_probes) for more specific use cases and available properties. - - `nsg_auto_rules_settings` - (`map`, optional, defaults to `null`) a map defining a location of an existing NSG rule - that will be populated with `Allow` rules for each load balancing rule (`in_rules`); please check - [module documentation](../../modules/loadbalancer/README.md#nsg_auto_rules_settings) - for available properties; please note that in this example two additional properties are - available: - - `nsg_vnet_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to a VNET definition - in the `var.vnets` map that stores the NSG described by `nsg_key`. - - `nsg_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to an NSG definition - in the `var.vnets` map. - - `frontend_ips` - (`map`, optional, defaults to `{}`) a map containing frontend IP configuration with respective - `in_rules` and `out_rules` + - `nsg_auto_rules_settings` - (`map`, optional, defaults to `null`) a map defining a location of an existing NSG rule that will + be populated with `Allow` rules for each load balancing rule (`in_rules`), please refer to + [module documentation](../../modules/loadbalancer/README.md#nsg_auto_rules_settings) for + available properties. + + Please note that in this example two additional properties are available: + + - `nsg_vnet_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to a VNET definition in the + `var.vnets` map that stores the NSG described by `nsg_key`. + - `nsg_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to an NSG definition in the + `var.vnets` map. - Please refer to [module documentation](../../modules/loadbalancer/README.md#frontend_ips) for available properties. + - `frontend_ips` - (`map`, optional, defaults to `{}`) a map containing frontend IP configuration with respective + `in_rules` and `out_rules`, please refer to + [module documentation](../../modules/loadbalancer/README.md#frontend_ips) for available + properties. **Note!** \ In this example the `subnet_id` is not available directly, another property has been introduced instead: @@ -180,10 +182,10 @@ variable "load_balancers" { })) frontend_ips = optional(map(object({ name = string + subnet_key = optional(string) public_ip_name = optional(string) create_public_ip = optional(bool, false) public_ip_resource_group_name = optional(string) - subnet_key = optional(string) private_ip_address = optional(string) gwlb_key = optional(string) in_rules = optional(map(object({ @@ -207,22 +209,24 @@ variable "load_balancers" { })) } - -### GWLB variable "gateway_load_balancers" { description = <<-EOF - Map with Gateway Load Balancer definitions. + A map with Gateway Load Balancer (GWLB) definitions. Following settings are available: - - `name` - (`string`, required) name of the Gatewa Load Balancer Gateway. - - `frontend_ip` - (`object`, required) frontend IP configuration - (refer to [module documentation](../../modules/gwlb/README.md) for details) - - `health_probe - (`object`, optional) health probe settings - (refer to [module documentation](../../modules/gwlb/README.md) for details) - - `backends` - (`map`, optional) map of backends - (refer to [module documentation](../../modules/gwlb/README.md) for details) - - `lb_rule` - (`object`, optional) load balancer rule - (refer to [module documentation](../../modules/gwlb/README.md) for details) + - `name` - (`string`, required) name of the Gateway Load Balancer Gateway. + - `vnet_key` - (`string`, required) a name (key value) of a VNET defined in `var.vnets` that hosts a subnet this GWLB will + be assigned to. + - `subnet_key` - (`string`, required) a name (key value) of Subnet the GWLB will be assigned to, defined in `var.vnets` for + a VNET described by `vnet_name`. + - `frontend_ip` - (`object`, required) frontend IP configuration, refer to + [module's documentation](../../modules/gwlb/README.md) for details. + - `health_probe` - (`object`, optional) health probe settings, refer to + [module's documentation](../../modules/gwlb/README.md) for details. + - `backends` - (`map`, optional) map of backends, refer to + [module's documentation](../../modules/gwlb/README.md) for details. + - `lb_rule` - (`object`, optional) load balancer rule, refer to + [module's documentation](../../modules/gwlb/README.md) for details. EOF default = {} type = map(object({ @@ -259,29 +263,31 @@ variable "gateway_load_balancers" { })) } +### VM-SERIES ### variable "availability_sets" { description = <<-EOF A map defining availability sets. Can be used to provide infrastructure high availability when zones cannot be used. Following properties are supported: - - `name` - name of the Application Insights. - - `update_domain_count` - specifies the number of update domains that are used, defaults to 5 (Azure defaults). - - `fault_domain_count` - specifies the number of fault domains that are used, defaults to 3 (Azure defaults). - Please keep in mind that Azure defaults are not working for each region (especially the small ones, w/o any Availability Zones). - Please verify how many update and fault domain are supported in a region before deploying this resource. + - `name` - (`string`, required) name of the Application Insights. + - `update_domain_count` - (`number`, optional, defaults to Azure default) specifies the number of update domains that are used. + - `fault_domain_count` - (`number`, optional, defaults to Azure default) specifies the number of fault domains that are used. + + **Note!** \ + Please keep in mind that Azure defaults are not working for every region (especially the small ones, without any Availability + Zones). Please verify how many update and fault domain are supported in a region before deploying this resource. EOF default = {} nullable = false type = map(object({ name = string - update_domain_count = optional(number, 5) - fault_domain_count = optional(number, 3) + update_domain_count = optional(number) + fault_domain_count = optional(number) })) } - variable "ngfw_metrics" { description = <<-EOF A map controlling metrics-relates resources. @@ -289,22 +295,22 @@ variable "ngfw_metrics" { When set to explicit `null` (default) it will disable any metrics resources in this deployment. When defined it will either create or source a Log Analytics Workspace and create Application Insights instances (one per each - Scale Set). All instances will be automatically connected to the workspace. - The name of the Application Insights instance will be derived from the Scale Set name and suffixed with `-ai`. + Scale Set). All instances will be automatically connected to the workspace. The name of the Application Insights instance will + be derived from the Scale Set name and suffixed with `-ai`. All the settings available below are common to the Log Analytics Workspace and Application Insight instances. Following properties are available: - - `name` - (`string`, required) name of the (common) Log Analytics Workspace + - `name` - (`string`, required) name of the (common) Log Analytics Workspace. - `create_workspace` - (`bool`, optional, defaults to `true`) controls whether we create or source an existing Log - Analytics Workspace + Analytics Workspace. - `resource_group_name` - (`string`, optional, defaults to `var.resource_group_name`) name of the Resource Group hosting - the Log Analytics Workspace - - `sku` - (`string`, optional, defaults to module defaults) the SKU of the Log Analytics Workspace. - - `metrics_retention_in_days` - (`number`, optional, defaults to module defaults) workspace and insights data retention in - days, possible values are between 30 and 730. For sourced Workspaces this applies only to - the Application Insights instances. + the Log Analytics Workspace. + - `sku` - (`string`, optional, defaults to module default) the SKU of the Log Analytics Workspace. + - `metrics_retention_in_days` - (`number`, optional, defaults to module default) workspace and insights data retention in days, + possible values are between 30 and 730. For sourced Workspaces this applies only to the + Application Insights instances. EOF default = null type = object({ @@ -316,7 +322,6 @@ variable "ngfw_metrics" { }) } - variable "bootstrap_storages" { description = <<-EOF A map defining Azure Storage Accounts used to host file shares for bootstrapping NGFWs. @@ -326,41 +331,50 @@ variable "bootstrap_storages" { - `name` - (`string`, required) name of the Storage Account that will be created or sourced. - **Note** \ - For new Storage Accounts this name will not be prefixed with `var.name_prefix`. \ - Please note the limitations on naming. This has to be a globally unique name, between 3 and 63 chars, only lower-case - letters and numbers. + **Note** \ + For new Storage Accounts this name will not be prefixed with `var.name_prefix`. \ + Please note the limitations on naming. This has to be a globally unique name, between 3 and 63 chars, only lower-case letters + and numbers. - - `resource_group_name` - (`string`, optional, defaults to `null`) name of the Resource Group that hosts (sourced) or will - host (created) a Storage Account. When skipped the code will fall back to + - `resource_group_name` - (`string`, optional, defaults to `null`) name of the Resource Group that hosts (sourced) or + will host (created) a Storage Account. When skipped the code will fall back to `var.resource_group_name`. - - `storage_account` - (`map`, optional, defaults to `{}`) a map controlling basic Storage Account configuration, for - detailed documentation see - [module's documentation](../../modules/bootstrap/README.md#storage_account). The property you - should pay attention to is: - - `create` - (`bool`, optional, defaults to module defaults) controls if the Storage Account specified in - the `name` property will be created or sourced. + - `storage_account` - (`map`, optional, defaults to `{}`) a map controlling basic Storage Account configuration. + + The property you should pay attention to is: + + - `create` - (`bool`, optional, defaults to module default) controls if the Storage Account specified in the `name` property + will be created or sourced. + + For detailed documentation see [module's documentation](../../modules/bootstrap/README.md#storage_account). + - `storage_network_security` - (`map`, optional, defaults to `{}`) a map defining network security settings for a **new** - storage account, for details see - [module's documentation](../../modules/bootstrap/README.md#storage_network_security). Properties - worth mentioning are: - - `allowed_subnet_keys` - (`list`, optional, defaults to `[]`) a list of keys pointing to Subnet definitions in the - `var.vnets` map. These Subnets will have dedicated access to the Storage Account. For this to - work they also need to have the Storage Account Service Endpoint enabled. - - `vnet_key` - a key pointing to a VNET definition in the `var.vnets` map that stores the Subnets described - in `allowed_subnet_keys`. - - `file_shares_configuration` - (`map`, optional, defaults to `{}`) a map defining common File Share setting. For detailed - documentation see - [module's documentation](../../modules/bootstrap/README.md#file_shares_configuration). The - properties you should pay your attention to are: - - `create_file_shares` - (`bool`, optional, defaults to module defaults) controls if the File Shares defined in the + storage account. + + The properties you should pay attention to are: + + - `allowed_subnet_keys` - (`list`, optional, defaults to `[]`) a list of keys pointing to Subnet definitions in the + `var.vnets` map. These Subnets will have dedicated access to the Storage Account. For this to work + they also need to have the Storage Account Service Endpoint enabled. + - `vnet_key` - (`string`, optional) a key pointing to a VNET definition in the `var.vnets` map that stores the + Subnets described in `allowed_subnet_keys`. + + For detailed documentation see [module's documentation](../../modules/bootstrap/README.md#storage_network_security). + + - `file_shares_configuration` - (`map`, optional, defaults to `{}`) a map defining common File Share setting. + + The properties you should pay attention to are: + + - `create_file_shares` - (`bool`, optional, defaults to module default) controls if the File Shares defined in the `file_shares` property will be created or sourced. - - `disable_package_dirs_creation` - (`bool`, optional, defaults to module defaults) for sourced File Shares, controls if the + - `disable_package_dirs_creation` - (`bool`, optional, defaults to module default) for sourced File Shares, controls if the bootstrap package folder structure will be created. + + For detailed documentation see [module's documentation](../../modules/bootstrap/README.md#file_shares_configuration). + - `file_shares` - (`map`, optional, defaults to `{}`) a map that holds File Shares and bootstrap package configuration. For detailed description see [module's documentation](../../modules/bootstrap/README.md#file_shares). - EOF default = {} nullable = false @@ -396,125 +410,121 @@ variable "bootstrap_storages" { })) } - -### VM-Series variable "vmseries" { description = <<-EOF - A map defining Azure Virtual Machines based on Palo Alto Networks Next Generation Firewall image.. + A map defining Azure Virtual Machines based on Palo Alto Networks Next Generation Firewall image. For details and defaults for available options please refer to the [`vmseries`](../../modules/vmseries/README.md) module. The most basic properties are as follows: - `name` - (`string`, required) name of the VM, will be prefixed with the value of `var.name_prefix`. + - `vnet_key` - (`string`, required) a key of a VNET defined in `var.vnets`. This is the VNET that hosts subnets used to + deploy network interfaces for deployed VM. - `authentication` - (`map`, optional, defaults to example defaults) authentication settings for the deployed VM. - The `authentication` property is optional and holds the firewall admin access details. By default, standard username - `panadmin` will be set and a random password will be auto-generated for you (available in Terraform outputs). + The `authentication` property is optional and holds the firewall admin access details. By default, standard username + `panadmin` will be set and a random password will be auto-generated for you (available in Terraform outputs). - **Note!** \ - The `disable_password_authentication` property is by default `false` in this example. When using this value, you don't have - to specify anything but you can still additionally pass SSH keys for authentication. You can however set this property to - `true`, then you have to specify `ssh_keys` property. - - For all properties and their default values see [module's documentation](../../modules/vmseries/README.md#authentication). - - - `image` - (`map`, required) properties defining a base image used by the deployed VM. - - The `image` property is required but there are only 2 properties (mutually exclusive) that have to be set, either: - - - `version` - (`string`) describes the PAN-OS image version from Azure Marketplace. - - `custom_id` - (`string`) absolute ID of your own custom PAN-OS image. - - For details on the other properties refer to [module's documentation](../../modules/vmseries/README.md#image). - - - `virtual_machine` - (`map`, optional, defaults to module defaults) a map that groups most common VM configuration options. - - The most often used option are as follows: - - - `vnet_key` - (`string`, required) a key of a VNET defined in `var.vnets`. This is the VNET that hosts subnets used to - deploy network interfaces for deployed VM. - - `size` - (`string`, optional, defaults to module defaults) Azure VM size (type). Consult the *VM-Series Deployment - Guide* as only a few selected sizes are supported. - - `zone` - (`string`, optional, defaults to module defaults) the Availability Zone in which the VM and (if deployed) - public IP addresses will be created. - - `disk_type` - (`string`, optional, defaults to module defaults) type of a Managed Disk which should be created, possible - values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected `size` values). - - `bootstrap_options` - (`string`, optional, mutually exclusive with `bootstrap_package`) bootstrap options passed to PAN-OS - when launched for the 1st time, for details see module documentation. - - `bootstrap_package` - (`map`, optional, mutually exclusive with `bootstrap_options`) a map defining content of the - bootstrap package. - - **Note!** \ - At least one of `static_files`, `bootstrap_xml_template` or `bootstrap_package_path` is required. You can use a - combination of all 3. The `bootstrap_package_path` is the less important. For details on this mechanism and for details - on the other properties see the [`bootstrap` module documentation](../../modules/bootstrap/README.md). - - Following properties are available: - - - `bootstrap_storage_key` - (`string`, required) a key of a bootstrap storage defined in `var.bootstrap_storages` that - will host bootstrap packages. Each package will be hosted on a separate File Share. - The File Shares will be created automatically, one for each firewall. - - `static_files` - (`map`, optional, defaults to `{}`) a map containing files that will be copied to a File - Share, see [`file_shares.bootstrap_files`](../../modules/bootstrap/README.md#file_shares) - property documentation for details. - - `bootstrap_package_path` - (`string`, optional, defaults to `null`) a path to a folder containing a full bootstrap - package. - - `bootstrap_xml_template` - (`string`, optional, defaults to `null`) a path to a `bootstrap.xml` template. If this - example is using full bootstrap method, the sample templates are in - [`templates`](./templates) folder. - - The templates are used to provide `day0` like configuration which consists of: - - - network interfaces configuration. - - one or more (depending on the architecture) Virtual Routers configurations. This config contains static routes - required for the Load Balancer (and Application Gateway, if defined) health checks to work and routes that allow - Inbound and OBEW traffic. - - *any-any* security rule. - - an outbound NAT rule that will allow the Outbound traffic to flow to the internet. - - **Note!** \ - Day0 configuration is **not meant** to be **secure**. It's here marly to help with the basic firewall setup. - - When `bootstrap_xml_template` is set, one of the following properties might be required. - - - `data_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key - pointing to a data Subnet definition in `var.vnets` (the `vnet_key` property is used to - identify a VNET). The Subnet definition is used to calculate static routes for a data - Load Balancer health checks. - - `ai_update_interval` - (`number`, optional, defaults to `5`) Application Insights update interval, used only when - `ngfw_metrics` module is defined and used in this example. The Application Insights - Instrumentation Key will be populated automatically. - - `intranet_cidr` - (`string`, optional, defaults to `null`) a CIDR of the Intranet - combined CIDR of all - private networks. When set it will override the private Subnet CIDR for inbound traffic - static routes. - - For details on the other properties refer to [module's documentation](../../modules/panorama/README.md#virtual_machine). - - - `interfaces` - (`list`, required) configuration of all network interfaces + **Note!** \ + The `disable_password_authentication` property is by default `false` in this example. When using this value, you don't have + to specify anything but you can still additionally pass SSH keys for authentication. You can however set this property to + `true`, then you have to specify `ssh_keys` property. - **Note!** \ - Order of the interfaces does matter - the 1st interface is the management one. + For all properties and their default values see [module's documentation](../../modules/vmseries/README.md#authentication). + + - `image` - (`map`, required) properties defining a base image used by the deployed VM. The `image` property is + required but there are only 2 properties (mutually exclusive) that have to be set, either: + + - `version` - (`string`, optional) describes the PAN-OS image version from Azure Marketplace. + - `custom_id` - (`string`, optional) absolute ID of your own custom PAN-OS image. - For details on available properties please see [module's documentation](../../modules/panorama/README.md#interfaces). + For details on all properties refer to [module's documentation](../../modules/vmseries/README.md#image). - The most important ones are listed below: + - `virtual_machine` - (`map`, optional, defaults to module default) a map that groups most common VM configuration options. + Most common properties are: - - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`). - - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in - `var.vnets`. Key identifying the VNET is defined in `virtual_machine.vnet_key` property. - - `create_public_ip` - (`bool`, optional, defaults to `false`) create a Public IP for an interface. - - `load_balancer_key` - (`string`, optional, defaults to `null`) key of a Load Balancer defined in `var.loadbalancers` - variable, network interface that has this property defined will be added to the Load Balancer's - backend pool - - `add_to_appgw_backend` - (`bool`, optional, defaults to `false`) when set an interface's private IP address will be added - to the Application Gateway's backend pool. + - `size` - (`string`, optional, defaults to module default) Azure VM size (type). Consult the *VM-Series + Deployment Guide* as only a few selected sizes are supported. + - `zone` - (`string`, optional, defaults to module default) the Availability Zone in which the VM and (if + deployed) public IP addresses will be created. + - `disk_type` - (`string`, optional, defaults to module default) type of a Managed Disk which should be created, + possible values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected + `size` values). + - `bootstrap_options` - (`string`, optional, mutually exclusive with `bootstrap_package`) bootstrap options passed to PAN-OS + when launched for the 1st time, for details see module documentation. + - `bootstrap_package` - (`map`, optional, mutually exclusive with `bootstrap_options`) a map defining content of the + bootstrap package. + **Note!** \ + At least one of `static_files`, `bootstrap_xml_template` or `bootstrap_package_path` is required. You can use a combination + of all 3. The `bootstrap_package_path` is the less important. For details on this mechanism and for details on the other + properties see the [`bootstrap` module documentation](../../modules/bootstrap/README.md). + + Following properties are available: + + - `bootstrap_storage_key` - (`string`, required) a key of a bootstrap storage defined in `var.bootstrap_storages` that + will host bootstrap packages. Each package will be hosted on a separate File Share. The File + Shares will be created automatically, one for each firewall. + - `static_files` - (`map`, optional, defaults to `{}`) a map containing files that will be copied to a File + Share, see [`file_shares.bootstrap_files`](../../modules/bootstrap/README.md#file_shares) + property documentation for details. + - `bootstrap_package_path` - (`string`, optional, defaults to `null`) a path to a folder containing a full bootstrap + package. + - `bootstrap_xml_template` - (`string`, optional, defaults to `null`) a path to a `bootstrap.xml` template. If this example + is using full bootstrap method, the sample templates are in [`templates`](./templates) folder. + + The templates are used to provide `day0` like configuration which consists of: + + - network interfaces configuration. + - one or more (depending on the architecture) Virtual Routers configurations. This config contains static routes + required for the Load Balancer (and Application Gateway, if defined) health checks to work and routes that allow + Inbound and OBEW traffic. + - *any-any* security rule. + - an outbound NAT rule that will allow the Outbound traffic to flow to the Internet. + + **Note!** \ + Day0 configuration is **not meant** to be **secure**. It's here merely to help with the basic firewall setup. When + `bootstrap_xml_template` is set, one of the following properties might be required. + + - `private_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key + pointing to a private Subnet definition in `var.vnets` (the `vnet_key` property is used to + identify a VNET). The Subnet definition is used to calculate static routes for a private + Load Balancer health checks and for Inbound traffic. + - `public_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key + pointing to a public Subnet definition in `var.vnets` (the `vnet_key` property is used to + identify a VNET). The Subnet definition is used to calculate static routes for a public + Load Balancer health checks and for Outbound traffic. + - `ai_update_interval` - (`number`, optional, defaults to `5`) Application Insights update interval, used only when + `ngfw_metrics` module is defined and used in this example. The Application Insights + Instrumentation Key will be populated automatically. + - `intranet_cidr` - (`string`, optional, defaults to `null`) a CIDR of the Intranet - combined CIDR of all + private networks. When set it will override the private Subnet CIDR for inbound traffic + static routes. + + For details on all properties refer to [module's documentation](../../modules/panorama/README.md#virtual_machine). + + - `interfaces` - (`list`, required) configuration of all network interfaces. Order of the interfaces does matter - the + 1st interface is the management one. Most common properties are: + + - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`). + - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in + `var.vnets`. Key identifying the VNET is defined in `virtual_machine.vnet_key` property. + - `create_public_ip` - (`bool`, optional, defaults to `false`) create a Public IP for an interface. + - `load_balancer_key` - (`string`, optional, defaults to `null`) key of a Load Balancer defined in `var.loadbalancers` + variable, network interface that has this property defined will be added to the Load Balancer's + backend pool. + - `application_gateway_key` - (`string`, optional, defaults to `null`) key of an Application Gateway defined in `var.appgws` + variable, network interface that has this property defined will be added to the Application + Gateway's backend pool. + + For details on all properties refer to [module's documentation](../../modules/panorama/README.md#interfaces). EOF default = {} nullable = false type = map(object({ - name = string + name = string + vnet_key = string authentication = optional(object({ username = optional(string, "panadmin") password = optional(string) @@ -530,7 +540,6 @@ variable "vmseries" { custom_id = optional(string) }) virtual_machine = object({ - vnet_key = string size = optional(string) bootstrap_options = optional(string) bootstrap_package = optional(object({ @@ -538,21 +547,23 @@ variable "vmseries" { static_files = optional(map(string), {}) bootstrap_package_path = optional(string) bootstrap_xml_template = optional(string) - data_snet_key = optional(string) + private_snet_key = optional(string) + public_snet_key = optional(string) ai_update_interval = optional(number, 5) intranet_cidr = optional(string) })) - zone = string - disk_type = optional(string) - disk_name = optional(string) - avset_key = optional(string) - accelerated_networking = optional(bool) - encryption_at_host_enabled = optional(bool) - disk_encryption_set_id = optional(string) - diagnostics_storage_uri = optional(string) - identity_type = optional(string) - identity_ids = optional(list(string)) - allow_extension_operations = optional(bool) + zone = string + disk_type = optional(string) + disk_name = optional(string) + avset_key = optional(string) + accelerated_networking = optional(bool) + encryption_at_host_enabled = optional(bool) + disk_encryption_set_id = optional(string) + enable_boot_diagnostics = optional(bool, true) + boot_diagnostics_storage_uri = optional(string) + identity_type = optional(string) + identity_ids = optional(list(string)) + allow_extension_operations = optional(bool) }) interfaces = list(object({ name = string @@ -562,31 +573,35 @@ variable "vmseries" { public_ip_resource_group_name = optional(string) private_ip_address = optional(string) load_balancer_key = optional(string) - gwlb_key = optional(string) - gwlb_backend_key = optional(string) - add_to_appgw_backend = optional(bool, false) + application_gateway_key = optional(string) })) })) - validation { + validation { # virtual_machine.bootstrap_options & virtual_machine.bootstrap_package condition = alltrue([ for _, v in var.vmseries : v.virtual_machine.bootstrap_options != null && v.virtual_machine.bootstrap_package == null || v.virtual_machine.bootstrap_options == null && v.virtual_machine.bootstrap_package != null ]) - error_message = "Either `bootstrap_options` or `bootstrap_package` property can be set." + error_message = <<-EOF + Either `bootstrap_options` or `bootstrap_package` property can be set. + EOF } - validation { + validation { # virtual_machine.bootstrap_package condition = alltrue([ for _, v in var.vmseries : - v.virtual_machine.bootstrap_package.bootstrap_xml_template != null ? v.virtual_machine.bootstrap_package.data_snet_key != null : true - if v.virtual_machine.bootstrap_package != null + v.virtual_machine.bootstrap_package.bootstrap_xml_template != null ? ( + v.virtual_machine.bootstrap_package.private_snet_key != null && + v.virtual_machine.bootstrap_package.public_snet_key != null + ) : true if v.virtual_machine.bootstrap_package != null ]) - error_message = "The `data_snet_key` is required when `bootstrap_xml_template` is set." + error_message = <<-EOF + The `private_snet_key` and `public_snet_key` are required when `bootstrap_xml_template` is set. + EOF } } +### TEST INFRASTRUCTURE ### -### Application VMs variable "appvms" { description = <<-EOF Configuration for sample application VMs. diff --git a/examples/standalone_panorama/README.md b/examples/standalone_panorama/README.md index 63422e70..7b965bb6 100644 --- a/examples/standalone_panorama/README.md +++ b/examples/standalone_panorama/README.md @@ -24,8 +24,7 @@ This is a non zonal deployment. The deployed infrastructure consists of: - a Network Security Group to give access to Panorama's public interface - a Panorama appliance with a public IP assigned to the management interface -![standalone-panorama](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/assets/2110772/b2dadd69-f5b5-4ac4-b356-467ef79cbb0b) - +![standalone-panorama](https://github.com/PaloAltoNetworks/terraform-azurerm-vmseries-modules/assets/2110772/a2394f73-c0a8-4878-8693-825356abbd23) ## Prerequisites @@ -125,8 +124,8 @@ terraform destroy Name | Type | Description --- | --- | --- -[`location`](#location) | `string` | The Azure region to use. [`resource_group_name`](#resource_group_name) | `string` | Name of the Resource Group. +[`location`](#location) | `string` | The Azure region to use. [`vnets`](#vnets) | `map` | A map defining VNETs. @@ -134,10 +133,9 @@ Name | Type | Description Name | Type | Description --- | --- | --- -[`tags`](#tags) | `map` | Map of tags to assign to the created resources. [`name_prefix`](#name_prefix) | `string` | A prefix that will be added to all created resources. [`create_resource_group`](#create_resource_group) | `bool` | When set to `true` it will cause a Resource Group creation. -[`enable_zones`](#enable_zones) | `bool` | If `true`, enable zone support for resources. +[`tags`](#tags) | `map` | Map of tags to assign to the created resources. [`availability_sets`](#availability_sets) | `map` | A map defining availability sets. [`panoramas`](#panoramas) | `map` | A map defining Azure Virtual Machine based on Palo Alto Networks Panorama image. @@ -168,7 +166,7 @@ Providers used in this module: Modules used in this module: Name | Version | Source | Description --- | --- | --- | --- -`vnet` | - | ../../modules/vnet | Manage the network required for the topology. +`vnet` | - | ../../modules/vnet | `panorama` | - | ../../modules/panorama | @@ -185,19 +183,18 @@ Resources used in this module: -#### location -The Azure region to use. +#### resource_group_name + +Name of the Resource Group. Type: string [back to list](#modules-required-inputs) +#### location - -#### resource_group_name - -Name of the Resource Group. +The Azure region to use. Type: string @@ -210,22 +207,21 @@ A map defining VNETs. For detailed documentation on each property refer to [module documentation](../../modules/vnet/README.md) -- `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, - `false` will source an existing VNET. -- `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be - a full resource name, including prefixes. -- `address_space` - (`list(string)`, required when `create_virtual_network = false`) a list of CIDRs for a newly - created VNET -- `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which - the VNET will reside or is sourced from +- `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, `false` will source + an existing VNET. +- `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be a + full resource name, including prefixes. +- `address_space` - (`list`, required when `create_virtual_network = false`) a list of CIDRs for a newly created VNET. +- `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which the + VNET will reside or is sourced from. - `create_subnets` - (`bool`, optional, defaults to `true`) if `true`, create Subnets inside the Virtual Network, - otherwise use source existing subnets + otherwise use source existing subnets. - `subnets` - (`map`, optional) map of Subnets to create or source, for details see - [VNET module documentation](../../modules/vnet/README.md#subnets) + [VNET module documentation](../../modules/vnet/README.md#subnets). - `network_security_groups` - (`map`, optional) map of Network Security Groups to create, for details see - [VNET module documentation](../../modules/vnet/README.md#network_security_groups) + [VNET module documentation](../../modules/vnet/README.md#network_security_groups). - `route_tables` - (`map`, optional) map of Route Tables to create, for details see - [VNET module documentation](../../modules/vnet/README.md#route_tables) + [VNET module documentation](../../modules/vnet/README.md#route_tables). Type: @@ -237,8 +233,7 @@ map(object({ create_virtual_network = optional(bool, true) address_space = optional(list(string)) network_security_groups = optional(map(object({ - name = string - disable_bgp_route_propagation = optional(bool) + name = string rules = optional(map(object({ name = string priority = number @@ -256,7 +251,8 @@ map(object({ })), {}) })), {}) route_tables = optional(map(object({ - name = string + name = string + disable_bgp_route_propagation = optional(bool) routes = map(object({ name = string address_prefix = string @@ -285,21 +281,11 @@ map(object({ ### Optional Inputs -#### tags - -Map of tags to assign to the created resources. - -Type: map(string) - -Default value: `map[]` - -[back to list](#modules-optional-inputs) - - #### name_prefix A prefix that will be added to all created resources. -There is no default delimiter applied between the prefix and the resource name. Please include the delimiter in the actual prefix. +There is no default delimiter applied between the prefix and the resource name. +Please include the delimiter in the actual prefix. Example: ``` @@ -307,7 +293,8 @@ name_prefix = "test-" ``` **Note!** \ -This prefix is not applied to existing resources. If you plan to reuse i.e. a VNET please specify it's full name, even if it is also prefixed with the same value as the one in this property. +This prefix is not applied to existing resources. If you plan to reuse i.e. a VNET please specify it's full name, +even if it is also prefixed with the same value as the one in this property. Type: string @@ -318,7 +305,9 @@ Default value: `` #### create_resource_group -When set to `true` it will cause a Resource Group creation. Name of the newly specified RG is controlled by `resource_group_name`. +When set to `true` it will cause a Resource Group creation. +Name of the newly specified RG is controlled by `resource_group_name`. + When set to `false` the `resource_group_name` parameter is used to specify a name of an existing Resource Group. @@ -329,13 +318,14 @@ Default value: `true` [back to list](#modules-optional-inputs) -#### enable_zones -If `true`, enable zone support for resources. +#### tags -Type: bool +Map of tags to assign to the created resources. -Default value: `true` +Type: map(string) + +Default value: `map[]` [back to list](#modules-optional-inputs) @@ -345,12 +335,14 @@ Default value: `true` A map defining availability sets. Can be used to provide infrastructure high availability when zones cannot be used. Following properties are supported: -- `name` - name of the Application Insights. -- `update_domain_count` - specifies the number of update domains that are used, defaults to 5 (Azure defaults). -- `fault_domain_count` - specifies the number of fault domains that are used, defaults to 3 (Azure defaults). -Please keep in mind that Azure defaults are not working for each region (especially small ones, w/o any Availability Zones). -Please verify how many update and fault domains are supported in a region before deploying this resource. +- `name` - (`string`, required) name of the Application Insights. +- `update_domain_count` - (`number`, optional, defaults to Azure default) specifies the number of update domains that are used. +- `fault_domain_count` - (`number`, optional, defaults to Azure default) specifies the number of fault domains that are used. + +**Note!** \ +Please keep in mind that Azure defaults are not working for every region (especially the small ones, without any Availability +Zones). Please verify how many update and fault domain are supported in a region before deploying this resource. Type: @@ -358,8 +350,8 @@ Type: ```hcl map(object({ name = string - update_domain_count = optional(number, 5) - fault_domain_count = optional(number, 3) + update_domain_count = optional(number) + fault_domain_count = optional(number) })) ``` @@ -377,68 +369,64 @@ For details and defaults for available options please refer to the [`panorama`]( The basic Panorama VM configuration properties are as follows: - `name` - (`string`, required) name of the VM, will be prefixed with the value of `var.name_prefix`. +- `vnet_key` - (`string`, required) a key of a VNET defined in `var.vnets`. This is the VNET that hosts subnets used to + deploy network interfaces for deployed VM. - `authentication` - (`map`, optional, defaults to example defaults) authentication settings for the deployed VM. - The `authentication` property is optional and holds the firewall admin access details. By default, standard username - `panadmin` will be set and a random password will be auto-generated for you (available in Terraform outputs). - - **Note!** \ - The `disable_password_authentication` property is by default `false` in this example. When using this value, you don't have - to specify anything but you can still additionally pass SSH keys for authentication. You can however set this property to - `true`, then you have to specify `ssh_keys` property. - - For all properties and their default values see [module's documentation](../../modules/panorama/README.md#authentication). + The `authentication` property is optional and holds the firewall admin access details. By default, standard username + `panadmin` will be set and a random password will be auto-generated for you (available in Terraform outputs). -- `image` - (`map`, required) properties defining a base image used by the deployed VM. + **Note!** \ + The `disable_password_authentication` property is by default `false` in this example. When using this value, you don't have + to specify anything but you can still additionally pass SSH keys for authentication. You can however set this property to + `true`, then you have to specify `ssh_keys` property. - The `image` property is required but there are only 2 properties (mutually exclusive) that have to be set, either: + For all properties and their default values see [module's documentation](../../modules/panorama/README.md#authentication). - - `version` - (`string`) describes the PAN-OS image version from Azure Marketplace. - - `custom_id` - (`string`) absolute ID of your own custom PAN-OS image. +- `image` - (`map`, required) properties defining a base image used by the deployed VM. The `image` property is + required but there are only 2 properties (mutually exclusive) that have to be set, either: - For details on the other properties refer to [module's documentation](../../modules/panorama/README.md#image). + - `version` - (`string`, optional) describes the PAN-OS image version from Azure Marketplace. + - `custom_id` - (`string`, optional) absolute ID of your own custom PAN-OS image. -- `virtual_machine` - (`map`, optional, defaults to module defaults) a map that groups most common VM configuration options. + For details on all properties refer to [module's documentation](../../modules/panorama/README.md#image). - Following properties are available: +- `virtual_machine` - (`map`, optional, defaults to module defaults) a map that groups most common VM configuration options. + Most common properties are: - - `size` - (`string`, optional, defaults to module defaults) Azure VM size (type). Consult the *VM-Series Deployment - Guide* as only a few selected sizes are supported. - - `zone` - (`string`, optional, defaults to module defaults) the Availability Zone in which the VM will be created. - - `disk_type` - (`string`, optional, defaults to module defaults) type of a Managed Disk which should be created, possible - values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected `size` values). + - `size` - (`string`, optional, defaults to module defaults) Azure VM size (type). Consult the *VM-Series Deployment + Guide* as only a few selected sizes are supported. + - `zone` - (`string`, optional, defaults to module defaults) the Availability Zone in which the VM will be created. + - `disk_type` - (`string`, optional, defaults to module defaults) type of a Managed Disk which should be created, possible + values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected `size` values). - For details on the other properties refer to [module's documentation](../../modules/panorama/README.md#virtual_machine). + For details on all properties refer to [module's documentation](../../modules/panorama/README.md#virtual_machine). -- `vnet_key` - (`string`, required) a key of a VNET defined in `var.vnets`. This is the VNET that hosts subnets used to - deploy network interfaces for deployed VM. - `interfaces` - (`list`, required) configuration of all network interfaces, order does matter - the 1st - interface should be the management one. - - Following properties are available: + interface should be the management one. Most common properties are: - - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`). - - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in - `var.vnets`. - - `create_public_ip` - (`bool`, optional, defaults to module defaults) create a Public IP for an interface. + - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`). + - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in + `var.vnets`. + - `create_public_ip` - (`bool`, optional, defaults to module defaults) create a Public IP for an interface. - For details on the other properties refer to [module's documentation](../../modules/panorama/README.md#interfaces). + For details on all properties refer to [module's documentation](../../modules/panorama/README.md#interfaces). -- `logging_disks` - (`map`, optional, defaults to `null`) configuration of additional data disks for Panorama logs. - - Following properties are available: +- `logging_disks` - (`map`, optional, defaults to `null`) configuration of additional data disks for Panorama logs. Most + common properties are: - - `name` - (`string`, required) the Managed Disk name. - - `lun` - (`string`, required) the Logical Unit Number of the Data Disk, which needs to be unique within the VM. + - `name` - (`string`, required) the Managed Disk name. + - `lun` - (`string`, required) the Logical Unit Number of the Data Disk, which needs to be unique within the VM. - For details on the other properties refer to [module's documentation](../../modules/panorama/README.md#logging_disks). + For details on all properties refer to [module's documentation](../../modules/panorama/README.md#logging_disks). Type: ```hcl map(object({ - name = string + name = string + vnet_key = string authentication = object({ username = optional(string, "panadmin") password = optional(string) @@ -465,7 +453,6 @@ map(object({ identity_type = optional(string) identity_ids = optional(list(string)) }) - vnet_key = string interfaces = list(object({ name = string subnet_key = string @@ -488,5 +475,4 @@ Default value: `map[]` [back to list](#modules-optional-inputs) - \ No newline at end of file diff --git a/examples/standalone_panorama/example.tfvars b/examples/standalone_panorama/example.tfvars index 3d32e6cd..1589f06f 100644 --- a/examples/standalone_panorama/example.tfvars +++ b/examples/standalone_panorama/example.tfvars @@ -1,4 +1,5 @@ -# --- GENERAL --- # +### GENERAL ### + location = "North Europe" resource_group_name = "panorama" name_prefix = "example-" @@ -9,9 +10,8 @@ tags = { } enable_zones = false +### NETWORK ### - -# --- VNET PART --- # vnets = { "vnet" = { name = "panorama-vnet" @@ -44,11 +44,12 @@ vnets = { } } -# --- PANORAMA PART --- # +### PANORAMA ### panoramas = { "pn-1" = { - name = "panorama01" + name = "panorama01" + vnet_key = "vnet" authentication = { disable_password_authentication = false #ssh_keys = ["~/.ssh/id_rsa.pub"] @@ -61,7 +62,6 @@ panoramas = { zone = null disk_name = "panorama-os-disk" } - vnet_key = "vnet" interfaces = [ { name = "management" diff --git a/examples/standalone_panorama/main.tf b/examples/standalone_panorama/main.tf index 5a26246f..470f0ff6 100644 --- a/examples/standalone_panorama/main.tf +++ b/examples/standalone_panorama/main.tf @@ -1,4 +1,5 @@ -# Generate a random password. +### Generate a random password ### + # https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password resource "random_password" "this" { count = anytrue([ @@ -26,7 +27,8 @@ locals { } } -# Create or source the Resource Group. +### Create or source a Resource Group ### + # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group resource "azurerm_resource_group" "this" { count = var.create_resource_group ? 1 : 0 @@ -46,7 +48,8 @@ locals { resource_group = var.create_resource_group ? azurerm_resource_group.this[0] : data.azurerm_resource_group.this[0] } -# Manage the network required for the topology. +### Manage the network required for the topology ### + module "vnet" { source = "../../modules/vnet" @@ -62,15 +65,17 @@ module "vnet" { create_subnets = each.value.create_subnets subnets = each.value.subnets - network_security_groups = { for k, v in each.value.network_security_groups : k => merge(v, { name = "${var.name_prefix}${v.name}" }) + network_security_groups = { + for k, v in each.value.network_security_groups : k => merge(v, { name = "${var.name_prefix}${v.name}" }) } - route_tables = { for k, v in each.value.route_tables : k => merge(v, { name = "${var.name_prefix}${v.name}" }) + route_tables = { + for k, v in each.value.route_tables : k => merge(v, { name = "${var.name_prefix}${v.name}" }) } tags = var.tags } -# Create Panorama virtual appliance +### Create Panorama VMs and closely associated resources ### resource "azurerm_availability_set" "this" { for_each = var.availability_sets @@ -104,10 +109,12 @@ module "panorama" { ) interfaces = [for v in each.value.interfaces : { - name = "${var.name_prefix}${v.name}" - subnet_id = module.vnet[each.value.vnet_key].subnet_ids[v.subnet_key] - create_public_ip = v.create_public_ip - public_ip_name = v.create_public_ip ? "${var.name_prefix}${coalesce(v.public_ip_name, "${each.value.name}-pip")}" : v.public_ip_name + name = "${var.name_prefix}${v.name}" + subnet_id = module.vnet[each.value.vnet_key].subnet_ids[v.subnet_key] + create_public_ip = v.create_public_ip + public_ip_name = v.create_public_ip ? "${var.name_prefix}${ + coalesce(v.public_ip_name, "${each.value.name}-pip") + }" : v.public_ip_name public_ip_resource_group_name = v.public_ip_resource_group_name private_ip_address = v.private_ip_address }] diff --git a/examples/standalone_panorama/outputs.tf b/examples/standalone_panorama/outputs.tf index 08ab57b6..07cf32c3 100644 --- a/examples/standalone_panorama/outputs.tf +++ b/examples/standalone_panorama/outputs.tf @@ -11,4 +11,4 @@ output "password" { output "panorama_mgmt_ips" { value = { for k, v in module.panorama : k => v.mgmt_ip_address } -} \ No newline at end of file +} diff --git a/examples/standalone_panorama/variables.tf b/examples/standalone_panorama/variables.tf index 3e91c4cb..6587dc54 100644 --- a/examples/standalone_panorama/variables.tf +++ b/examples/standalone_panorama/variables.tf @@ -1,19 +1,10 @@ -### GENERAL -variable "tags" { - description = "Map of tags to assign to the created resources." - default = {} - type = map(string) -} - -variable "location" { - description = "The Azure region to use." - type = string -} +### GENERAL ### variable "name_prefix" { description = <<-EOF A prefix that will be added to all created resources. - There is no default delimiter applied between the prefix and the resource name. Please include the delimiter in the actual prefix. + There is no default delimiter applied between the prefix and the resource name. + Please include the delimiter in the actual prefix. Example: ``` @@ -21,7 +12,8 @@ variable "name_prefix" { ``` **Note!** \ - This prefix is not applied to existing resources. If you plan to reuse i.e. a VNET please specify it's full name, even if it is also prefixed with the same value as the one in this property. + This prefix is not applied to existing resources. If you plan to reuse i.e. a VNET please specify it's full name, + even if it is also prefixed with the same value as the one in this property. EOF default = "" type = string @@ -29,7 +21,9 @@ variable "name_prefix" { variable "create_resource_group" { description = <<-EOF - When set to `true` it will cause a Resource Group creation. Name of the newly specified RG is controlled by `resource_group_name`. + When set to `true` it will cause a Resource Group creation. + Name of the newly specified RG is controlled by `resource_group_name`. + When set to `false` the `resource_group_name` parameter is used to specify a name of an existing Resource Group. EOF default = true @@ -41,36 +35,40 @@ variable "resource_group_name" { type = string } -variable "enable_zones" { - description = "If `true`, enable zone support for resources." - default = true - type = bool +variable "location" { + description = "The Azure region to use." + type = string } +variable "tags" { + description = "Map of tags to assign to the created resources." + default = {} + type = map(string) +} + +### NETWORK ### -### VNET variable "vnets" { description = <<-EOF A map defining VNETs. For detailed documentation on each property refer to [module documentation](../../modules/vnet/README.md) - - `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, - `false` will source an existing VNET. - - `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be - a full resource name, including prefixes. - - `address_space` - (`list(string)`, required when `create_virtual_network = false`) a list of CIDRs for a newly - created VNET - - `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which - the VNET will reside or is sourced from + - `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, `false` will source + an existing VNET. + - `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be a + full resource name, including prefixes. + - `address_space` - (`list`, required when `create_virtual_network = false`) a list of CIDRs for a newly created VNET. + - `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which the + VNET will reside or is sourced from. - `create_subnets` - (`bool`, optional, defaults to `true`) if `true`, create Subnets inside the Virtual Network, - otherwise use source existing subnets + otherwise use source existing subnets. - `subnets` - (`map`, optional) map of Subnets to create or source, for details see - [VNET module documentation](../../modules/vnet/README.md#subnets) + [VNET module documentation](../../modules/vnet/README.md#subnets). - `network_security_groups` - (`map`, optional) map of Network Security Groups to create, for details see - [VNET module documentation](../../modules/vnet/README.md#network_security_groups) + [VNET module documentation](../../modules/vnet/README.md#network_security_groups). - `route_tables` - (`map`, optional) map of Route Tables to create, for details see - [VNET module documentation](../../modules/vnet/README.md#route_tables) + [VNET module documentation](../../modules/vnet/README.md#route_tables). EOF type = map(object({ name = string @@ -78,8 +76,7 @@ variable "vnets" { create_virtual_network = optional(bool, true) address_space = optional(list(string)) network_security_groups = optional(map(object({ - name = string - disable_bgp_route_propagation = optional(bool) + name = string rules = optional(map(object({ name = string priority = number @@ -97,7 +94,8 @@ variable "vnets" { })), {}) })), {}) route_tables = optional(map(object({ - name = string + name = string + disable_bgp_route_propagation = optional(bool) routes = map(object({ name = string address_prefix = string @@ -116,26 +114,28 @@ variable "vnets" { })) } +### PANORAMA ### -### PANORAMA variable "availability_sets" { description = <<-EOF A map defining availability sets. Can be used to provide infrastructure high availability when zones cannot be used. Following properties are supported: - - `name` - name of the Application Insights. - - `update_domain_count` - specifies the number of update domains that are used, defaults to 5 (Azure defaults). - - `fault_domain_count` - specifies the number of fault domains that are used, defaults to 3 (Azure defaults). - Please keep in mind that Azure defaults are not working for each region (especially small ones, w/o any Availability Zones). - Please verify how many update and fault domains are supported in a region before deploying this resource. + - `name` - (`string`, required) name of the Application Insights. + - `update_domain_count` - (`number`, optional, defaults to Azure default) specifies the number of update domains that are used. + - `fault_domain_count` - (`number`, optional, defaults to Azure default) specifies the number of fault domains that are used. + + **Note!** \ + Please keep in mind that Azure defaults are not working for every region (especially the small ones, without any Availability + Zones). Please verify how many update and fault domain are supported in a region before deploying this resource. EOF default = {} nullable = false type = map(object({ name = string - update_domain_count = optional(number, 5) - fault_domain_count = optional(number, 3) + update_domain_count = optional(number) + fault_domain_count = optional(number) })) } @@ -148,66 +148,62 @@ variable "panoramas" { The basic Panorama VM configuration properties are as follows: - `name` - (`string`, required) name of the VM, will be prefixed with the value of `var.name_prefix`. + - `vnet_key` - (`string`, required) a key of a VNET defined in `var.vnets`. This is the VNET that hosts subnets used to + deploy network interfaces for deployed VM. - `authentication` - (`map`, optional, defaults to example defaults) authentication settings for the deployed VM. - The `authentication` property is optional and holds the firewall admin access details. By default, standard username - `panadmin` will be set and a random password will be auto-generated for you (available in Terraform outputs). - - **Note!** \ - The `disable_password_authentication` property is by default `false` in this example. When using this value, you don't have - to specify anything but you can still additionally pass SSH keys for authentication. You can however set this property to - `true`, then you have to specify `ssh_keys` property. + The `authentication` property is optional and holds the firewall admin access details. By default, standard username + `panadmin` will be set and a random password will be auto-generated for you (available in Terraform outputs). - For all properties and their default values see [module's documentation](../../modules/panorama/README.md#authentication). + **Note!** \ + The `disable_password_authentication` property is by default `false` in this example. When using this value, you don't have + to specify anything but you can still additionally pass SSH keys for authentication. You can however set this property to + `true`, then you have to specify `ssh_keys` property. - - `image` - (`map`, required) properties defining a base image used by the deployed VM. + For all properties and their default values see [module's documentation](../../modules/panorama/README.md#authentication). - The `image` property is required but there are only 2 properties (mutually exclusive) that have to be set, either: + - `image` - (`map`, required) properties defining a base image used by the deployed VM. The `image` property is + required but there are only 2 properties (mutually exclusive) that have to be set, either: - - `version` - (`string`) describes the PAN-OS image version from Azure Marketplace. - - `custom_id` - (`string`) absolute ID of your own custom PAN-OS image. + - `version` - (`string`, optional) describes the PAN-OS image version from Azure Marketplace. + - `custom_id` - (`string`, optional) absolute ID of your own custom PAN-OS image. - For details on the other properties refer to [module's documentation](../../modules/panorama/README.md#image). + For details on all properties refer to [module's documentation](../../modules/panorama/README.md#image). - - `virtual_machine` - (`map`, optional, defaults to module defaults) a map that groups most common VM configuration options. + - `virtual_machine` - (`map`, optional, defaults to module defaults) a map that groups most common VM configuration options. + Most common properties are: - Following properties are available: - - - `size` - (`string`, optional, defaults to module defaults) Azure VM size (type). Consult the *VM-Series Deployment - Guide* as only a few selected sizes are supported. - - `zone` - (`string`, optional, defaults to module defaults) the Availability Zone in which the VM will be created. - - `disk_type` - (`string`, optional, defaults to module defaults) type of a Managed Disk which should be created, possible - values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected `size` values). + - `size` - (`string`, optional, defaults to module defaults) Azure VM size (type). Consult the *VM-Series Deployment + Guide* as only a few selected sizes are supported. + - `zone` - (`string`, optional, defaults to module defaults) the Availability Zone in which the VM will be created. + - `disk_type` - (`string`, optional, defaults to module defaults) type of a Managed Disk which should be created, possible + values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected `size` values). - For details on the other properties refer to [module's documentation](../../modules/panorama/README.md#virtual_machine). + For details on all properties refer to [module's documentation](../../modules/panorama/README.md#virtual_machine). - - `vnet_key` - (`string`, required) a key of a VNET defined in `var.vnets`. This is the VNET that hosts subnets used to - deploy network interfaces for deployed VM. - `interfaces` - (`list`, required) configuration of all network interfaces, order does matter - the 1st - interface should be the management one. - - Following properties are available: + interface should be the management one. Most common properties are: - - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`). - - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in - `var.vnets`. - - `create_public_ip` - (`bool`, optional, defaults to module defaults) create a Public IP for an interface. + - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`). + - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in + `var.vnets`. + - `create_public_ip` - (`bool`, optional, defaults to module defaults) create a Public IP for an interface. - For details on the other properties refer to [module's documentation](../../modules/panorama/README.md#interfaces). + For details on all properties refer to [module's documentation](../../modules/panorama/README.md#interfaces). - - `logging_disks` - (`map`, optional, defaults to `null`) configuration of additional data disks for Panorama logs. - - Following properties are available: + - `logging_disks` - (`map`, optional, defaults to `null`) configuration of additional data disks for Panorama logs. Most + common properties are: - - `name` - (`string`, required) the Managed Disk name. - - `lun` - (`string`, required) the Logical Unit Number of the Data Disk, which needs to be unique within the VM. + - `name` - (`string`, required) the Managed Disk name. + - `lun` - (`string`, required) the Logical Unit Number of the Data Disk, which needs to be unique within the VM. - For details on the other properties refer to [module's documentation](../../modules/panorama/README.md#logging_disks). + For details on all properties refer to [module's documentation](../../modules/panorama/README.md#logging_disks). EOF default = {} nullable = false type = map(object({ - name = string + name = string + vnet_key = string authentication = object({ username = optional(string, "panadmin") password = optional(string) @@ -234,7 +230,6 @@ variable "panoramas" { identity_type = optional(string) identity_ids = optional(list(string)) }) - vnet_key = string interfaces = list(object({ name = string subnet_key = string diff --git a/examples/standalone_vmseries/README.md b/examples/standalone_vmseries/README.md index c44da705..8147af19 100644 --- a/examples/standalone_vmseries/README.md +++ b/examples/standalone_vmseries/README.md @@ -115,8 +115,8 @@ terraform destroy Name | Type | Description --- | --- | --- -[`location`](#location) | `string` | The Azure region to use. [`resource_group_name`](#resource_group_name) | `string` | Name of the Resource Group. +[`location`](#location) | `string` | The Azure region to use. [`vnets`](#vnets) | `map` | A map defining VNETs. [`appgws`](#appgws) | `map` | A map defining all Application Gateways in the current deployment. @@ -125,11 +125,11 @@ Name | Type | Description Name | Type | Description --- | --- | --- -[`tags`](#tags) | `map` | Map of tags to assign to the created resources. [`name_prefix`](#name_prefix) | `string` | A prefix that will be added to all created resources. [`create_resource_group`](#create_resource_group) | `bool` | When set to `true` it will cause a Resource Group creation. +[`tags`](#tags) | `map` | Map of tags to assign to the created resources. [`natgws`](#natgws) | `map` | A map defining NAT Gateways. -[`load_balancers`](#load_balancers) | `map` | A map containing configuration for all (private and public) Load Balancers. +[`load_balancers`](#load_balancers) | `map` | A map containing configuration for all (both private and public) Load Balancers. [`availability_sets`](#availability_sets) | `map` | A map defining availability sets. [`ngfw_metrics`](#ngfw_metrics) | `object` | A map controlling metrics-relates resources. [`bootstrap_storages`](#bootstrap_storages) | `map` | A map defining Azure Storage Accounts used to host file shares for bootstrapping NGFWs. @@ -167,13 +167,13 @@ Providers used in this module: Modules used in this module: Name | Version | Source | Description --- | --- | --- | --- -`vnet` | - | ../../modules/vnet | Manage the network required for the topology. +`vnet` | - | ../../modules/vnet | `natgw` | - | ../../modules/natgw | -`load_balancer` | - | ../../modules/loadbalancer | create load balancers, both internal and external -`ngfw_metrics` | - | ../../modules/ngfw_metrics | create the actual VM-Series VMs and resources +`load_balancer` | - | ../../modules/loadbalancer | +`appgw` | - | ../../modules/appgw | +`ngfw_metrics` | - | ../../modules/ngfw_metrics | `bootstrap` | - | ../../modules/bootstrap | `vmseries` | - | ../../modules/vmseries | -`appgw` | - | ../../modules/appgw | Resources used in this module: @@ -190,46 +190,45 @@ Resources used in this module: -#### location -The Azure region to use. +#### resource_group_name + +Name of the Resource Group. Type: string [back to list](#modules-required-inputs) +#### location - -#### resource_group_name - -Name of the Resource Group. +The Azure region to use. Type: string [back to list](#modules-required-inputs) + #### vnets A map defining VNETs. For detailed documentation on each property refer to [module documentation](../../modules/vnet/README.md) -- `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, - `false` will source an existing VNET. -- `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be - a full resource name, including prefixes. -- `address_space` - (`list(string)`, required when `create_virtual_network = false`) a list of CIDRs for a newly - created VNET -- `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which - the VNET will reside or is sourced from +- `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, `false` will source + an existing VNET. +- `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be a + full resource name, including prefixes. +- `address_space` - (`list`, required when `create_virtual_network = false`) a list of CIDRs for a newly created VNET. +- `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which the + VNET will reside or is sourced from. - `create_subnets` - (`bool`, optional, defaults to `true`) if `true`, create Subnets inside the Virtual Network, - otherwise use source existing subnets + otherwise use source existing subnets. - `subnets` - (`map`, optional) map of Subnets to create or source, for details see - [VNET module documentation](../../modules/vnet/README.md#subnets) + [VNET module documentation](../../modules/vnet/README.md#subnets). - `network_security_groups` - (`map`, optional) map of Network Security Groups to create, for details see - [VNET module documentation](../../modules/vnet/README.md#network_security_groups) + [VNET module documentation](../../modules/vnet/README.md#network_security_groups). - `route_tables` - (`map`, optional) map of Route Tables to create, for details see - [VNET module documentation](../../modules/vnet/README.md#route_tables) + [VNET module documentation](../../modules/vnet/README.md#route_tables). Type: @@ -284,10 +283,6 @@ map(object({ - - - - #### appgws A map defining all Application Gateways in the current deployment. @@ -306,25 +301,25 @@ Below you can find a brief list of most important properties: described by `subnet_key`. - `subnet_key` - (`string`, required) a key pointing to a Subnet definition in the `var.vnets` map, this has to be an Application Gateway V2 dedicated subnet. -- `zones` - (`list`, optional, defaults to module defaults) parameter controlling if this is a zonal, or a non-zonal +- `zones` - (`list`, optional, defaults to module default) parameter controlling if this is a zonal, or a non-zonal deployment. - `public_ip` - (`map`, required) defines a Public IP resource used by the Application Gateway instance, a newly created Public IP will have it's name prefixes with `var.name_prefix`. - `listeners` - (`map`, required) defines Application Gateway's Listeners, see [module's documentation](../../modules/appgw/README.md#listeners) for details. -- `backend_pool` - (`map`, optional, defaults to module defaults) backend pool definition, when skipped an empty backend +- `backend_pool` - (`map`, optional, defaults to module default) backend pool definition, when skipped an empty backend will be created. - `backend_settings` - (`map`, optional, mutually exclusive with `redirects` and `url_path_maps`) defines HTTP backend settings, see [module's documentation](../../modules/appgw/README.md#backend_settings) for details. -- `probes` - (`map`, optional, defaults to module defaults) defines backend probes used check health of backends, see +- `probes` - (`map`, optional, defaults to module default) defines backend probes used check health of backends, see [module's documentation](../../modules/appgw/README.md#probes) for details. -- `rewrites` - (`map`, optional, defaults to module defaults) defines rewrite rules, see +- `rewrites` - (`map`, optional, defaults to module default) defines rewrite rules, see [module's documentation](../../modules/appgw/README.md#rewrites) for details. -- `redirects - (`map`, optional, mutually exclusive with `backend_settings` and `url_path_maps`) static redirects +- `redirects` - (`map`, optional, mutually exclusive with `backend_settings` and `url_path_maps`) static redirects definition, see [module's documentation](../../modules/appgw/README.md#redirects) for details. -- `url_path_maps - (`map`, optional, mutually exclusive with `backend_settings` and `redirects`) URL path maps definition, +- `url_path_maps` - (`map`, optional, mutually exclusive with `backend_settings` and `redirects`) URL path maps definition, see [module's documentation](../../modules/appgw/README.md#url_path_maps) for details. -- `rules - (`map`, required) Application Gateway Rules definition, bind together a `listener` with either +- `rules` - (`map`, required) Application Gateway Rules definition, bind together a `listener` with either `backend_setting`, `redirect` or `url_path_map`, see [module's documentation](../../modules/appgw/README.md#rules) for details. @@ -461,18 +456,11 @@ map(object({ -### Optional Inputs - - -#### tags -Map of tags to assign to the created resources. -Type: map(string) -Default value: `map[]` -[back to list](#modules-optional-inputs) +### Optional Inputs #### name_prefix @@ -513,6 +501,17 @@ Default value: `true` +#### tags + +Map of tags to assign to the created resources. + +Type: map(string) + +Default value: `map[]` + +[back to list](#modules-optional-inputs) + + #### natgws A map defining NAT Gateways. @@ -522,21 +521,21 @@ explicitly). Please refer to Microsoft documentation for notes on NAT Gateway's For detailed documentation on each property refer to [module documentation](../../modules/natgw/README.md). Following properties are supported: -- `create_natgw` - (`bool`, optional, defaults to `true`) create (`true`) or source an existing NAT Gateway (`false`), - created or sourced: the NAT Gateway will be assigned to a subnet created by the `vnet` module. -- `name` - (`string`, required) a name of a NAT Gateway. In case `create_natgw = false` this should be a full - resource name, including prefixes. -- `resource_group_name - (`string`, optional) name of a Resource Group hosting the NAT Gateway (newly created or the existing - one). -- `zone` - (`string`, optional) an Availability Zone in which the NAT Gateway will be placed, when skipped - AzureRM will pick a zone. -- `idle_timeout` - (`number`, optional, defults to 4) connection IDLE timeout in minutes, for newly created resources. -- `vnet_key` - (`string`, required) a name (key value) of a VNET defined in `var.vnets` that hosts a subnet this - NAT Gateway will be assigned to. -- `subnet_keys` - (`list(string)`, required) a list of subnets (key values) the NAT Gateway will be assigned to, defined - in `var.vnets` for a VNET described by `vnet_name`. -- `public_ip` - (`object`, optional) an object defining a public IP resource attached to the NAT Gateway. -- `public_ip_prefix` - (`object`, optional) an object defining a public IP prefix resource attached to the NAT Gatway. +- `name` - (`string`, required) a name of a NAT Gateway. In case `create_natgw = false` this should be a full + resource name, including prefixes. +- `vnet_key` - (`string`, required) a name (key value) of a VNET defined in `var.vnets` that hosts a subnet this + NAT Gateway will be assigned to. +- `subnet_keys` - (`list(string)`, required) a list of subnets (key values) the NAT Gateway will be assigned to, + defined in `var.vnets` for a VNET described by `vnet_name`. +- `create_natgw` - (`bool`, optional, defaults to `true`) create (`true`) or source an existing NAT Gateway (`false`), + created or sourced: the NAT Gateway will be assigned to a subnet created by the `vnet` module. +- `resource_group_name` - (`string`, optional) name of a Resource Group hosting the NAT Gateway (newly created or the existing + one). +- `zone` - (`string`, optional) an Availability Zone in which the NAT Gateway will be placed, when skipped + Azure will pick a zone. +- `idle_timeout` - (`number`, optional, defults to 4) connection IDLE timeout in minutes, for newly created resources. +- `public_ip` - (`object`, optional) an object defining a public IP resource attached to the NAT Gateway. +- `public_ip_prefix` - (`object`, optional) an object defining a public IP prefix resource attached to the NAT Gatway. Example: ``` @@ -558,13 +557,13 @@ Type: ```hcl map(object({ - create_natgw = optional(bool, true) name = string + vnet_key = string + subnet_keys = list(string) + create_natgw = optional(bool, true) resource_group_name = optional(string) zone = optional(string) idle_timeout = optional(number, 4) - vnet_key = string - subnet_keys = list(string) public_ip = optional(object({ create = bool name = string @@ -586,7 +585,7 @@ Default value: `map[]` #### load_balancers -A map containing configuration for all (private and public) Load Balancers. +A map containing configuration for all (both private and public) Load Balancers. This is a brief description of available properties. For a detailed one please refer to [module documentation](../../modules/loadbalancer/README.md). @@ -596,26 +595,29 @@ Following properties are available: - `name` - (`string`, required) a name of the Load Balancer. - `vnet_key` - (`string`, optional, defaults to `null`) a key pointing to a VNET definition in the `var.vnets` map that stores the Subnet described by `subnet_key`. -- `zones` - (`list`, optional, defaults to module defaults) a list of zones for Load Balancer's fronted IP +- `zones` - (`list`, optional, defaults to module default) a list of zones for Load Balancer's frontend IP configurations. -- `backend_name` - (`string`, optional, defaults to module defaults) a name of the backend pool to create. -- `health_probes` - (`map`, optional, defaults to `null`) a map defining health probes that will be used by - load balancing rules; please check +- `backend_name` - (`string`, optional, defaults to module default) a name of the backend pool to create. +- `health_probes` - (`map`, optional, defaults to `null`) a map defining health probes that will be used by load + balancing rules, please refer to [module documentation](../../modules/loadbalancer/README.md#health_probes) for more specific use cases and available properties. -- `nsg_auto_rules_settings` - (`map`, optional, defaults to `null`) a map defining a location of an existing NSG rule - that will be populated with `Allow` rules for each load balancing rule (`in_rules`); please check - [module documentation](../../modules/loadbalancer/README.md#nsg_auto_rules_settings) - for available properties; please note that in this example two additional properties are - available: - - `nsg_vnet_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to a VNET definition - in the `var.vnets` map that stores the NSG described by `nsg_key`. - - `nsg_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to an NSG definition - in the `var.vnets` map. -- `frontend_ips` - (`map`, optional, defaults to `{}`) a map containing frontend IP configuration with respective - `in_rules` and `out_rules` +- `nsg_auto_rules_settings` - (`map`, optional, defaults to `null`) a map defining a location of an existing NSG rule that will + be populated with `Allow` rules for each load balancing rule (`in_rules`), please refer to + [module documentation](../../modules/loadbalancer/README.md#nsg_auto_rules_settings) for + available properties. + + Please note that in this example two additional properties are available: + + - `nsg_vnet_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to a VNET definition in the + `var.vnets` map that stores the NSG described by `nsg_key`. + - `nsg_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to an NSG definition in the + `var.vnets` map. - Please refer to [module documentation](../../modules/loadbalancer/README.md#frontend_ips) for available properties. +- `frontend_ips` - (`map`, optional, defaults to `{}`) a map containing frontend IP configuration with respective + `in_rules` and `out_rules`, please refer to + [module documentation](../../modules/loadbalancer/README.md#frontend_ips) for available + properties. **Note!** \ In this example the `subnet_id` is not available directly, another property has been introduced instead: @@ -649,10 +651,10 @@ map(object({ })) frontend_ips = optional(map(object({ name = string + subnet_key = optional(string) public_ip_name = optional(string) create_public_ip = optional(bool, false) public_ip_resource_group_name = optional(string) - subnet_key = optional(string) private_ip_address = optional(string) gwlb_key = optional(string) in_rules = optional(map(object({ @@ -681,17 +683,20 @@ Default value: `map[]` [back to list](#modules-optional-inputs) + #### availability_sets A map defining availability sets. Can be used to provide infrastructure high availability when zones cannot be used. Following properties are supported: -- `name` - name of the Application Insights. -- `update_domain_count` - specifies the number of update domains that are used, defaults to 5 (Azure defaults). -- `fault_domain_count` - specifies the number of fault domains that are used, defaults to 3 (Azure defaults). -Please keep in mind that Azure defaults are not working for each region (especially the small ones, w/o any Availability Zones). -Please verify how many update and fault domain are supported in a region before deploying this resource. +- `name` - (`string`, required) name of the Application Insights. +- `update_domain_count` - (`number`, optional, defaults to Azure default) specifies the number of update domains that are used. +- `fault_domain_count` - (`number`, optional, defaults to Azure default) specifies the number of fault domains that are used. + +**Note!** \ +Please keep in mind that Azure defaults are not working for every region (especially the small ones, without any Availability +Zones). Please verify how many update and fault domain are supported in a region before deploying this resource. Type: @@ -699,8 +704,8 @@ Type: ```hcl map(object({ name = string - update_domain_count = optional(number, 5) - fault_domain_count = optional(number, 3) + update_domain_count = optional(number) + fault_domain_count = optional(number) })) ``` @@ -716,22 +721,22 @@ A map controlling metrics-relates resources. When set to explicit `null` (default) it will disable any metrics resources in this deployment. When defined it will either create or source a Log Analytics Workspace and create Application Insights instances (one per each -Scale Set). All instances will be automatically connected to the workspace. -The name of the Application Insights instance will be derived from the Scale Set name and suffixed with `-ai`. +Scale Set). All instances will be automatically connected to the workspace. The name of the Application Insights instance will +be derived from the Scale Set name and suffixed with `-ai`. All the settings available below are common to the Log Analytics Workspace and Application Insight instances. Following properties are available: -- `name` - (`string`, required) name of the (common) Log Analytics Workspace +- `name` - (`string`, required) name of the (common) Log Analytics Workspace. - `create_workspace` - (`bool`, optional, defaults to `true`) controls whether we create or source an existing Log - Analytics Workspace + Analytics Workspace. - `resource_group_name` - (`string`, optional, defaults to `var.resource_group_name`) name of the Resource Group hosting - the Log Analytics Workspace -- `sku` - (`string`, optional, defaults to module defaults) the SKU of the Log Analytics Workspace. -- `metrics_retention_in_days` - (`number`, optional, defaults to module defaults) workspace and insights data retention in - days, possible values are between 30 and 730. For sourced Workspaces this applies only to - the Application Insights instances. + the Log Analytics Workspace. +- `sku` - (`string`, optional, defaults to module default) the SKU of the Log Analytics Workspace. +- `metrics_retention_in_days` - (`number`, optional, defaults to module default) workspace and insights data retention in days, + possible values are between 30 and 730. For sourced Workspaces this applies only to the + Application Insights instances. Type: @@ -760,43 +765,52 @@ You can create or re-use an existing Storage Account and/or File Share. For deta - `name` - (`string`, required) name of the Storage Account that will be created or sourced. - **Note** \ - For new Storage Accounts this name will not be prefixed with `var.name_prefix`. \ - Please note the limitations on naming. This has to be a globally unique name, between 3 and 63 chars, only lower-case - letters and numbers. + **Note** \ + For new Storage Accounts this name will not be prefixed with `var.name_prefix`. \ + Please note the limitations on naming. This has to be a globally unique name, between 3 and 63 chars, only lower-case letters + and numbers. -- `resource_group_name` - (`string`, optional, defaults to `null`) name of the Resource Group that hosts (sourced) or will - host (created) a Storage Account. When skipped the code will fall back to +- `resource_group_name` - (`string`, optional, defaults to `null`) name of the Resource Group that hosts (sourced) or + will host (created) a Storage Account. When skipped the code will fall back to `var.resource_group_name`. -- `storage_account` - (`map`, optional, defaults to `{}`) a map controlling basic Storage Account configuration, for - detailed documentation see - [module's documentation](../../modules/bootstrap/README.md#storage_account). The property you - should pay attention to is: - - `create` - (`bool`, optional, defaults to module defaults) controls if the Storage Account specified in - the `name` property will be created or sourced. +- `storage_account` - (`map`, optional, defaults to `{}`) a map controlling basic Storage Account configuration. + + The property you should pay attention to is: + + - `create` - (`bool`, optional, defaults to module default) controls if the Storage Account specified in the `name` property + will be created or sourced. + + For detailed documentation see [module's documentation](../../modules/bootstrap/README.md#storage_account). + - `storage_network_security` - (`map`, optional, defaults to `{}`) a map defining network security settings for a **new** - storage account, for details see - [module's documentation](../../modules/bootstrap/README.md#storage_network_security). Properties - worth mentioning are: - - `allowed_subnet_keys` - (`list`, optional, defaults to `[]`) a list of keys pointing to Subnet definitions in the - `var.vnets` map. These Subnets will have dedicated access to the Storage Account. For this to - work they also need to have the Storage Account Service Endpoint enabled. - - `vnet_key` - a key pointing to a VNET definition in the `var.vnets` map that stores the Subnets described - in `allowed_subnet_keys`. -- `file_shares_configuration` - (`map`, optional, defaults to `{}`) a map defining common File Share setting. For detailed - documentation see - [module's documentation](../../modules/bootstrap/README.md#file_shares_configuration). The - properties you should pay your attention to are: - - `create_file_shares` - (`bool`, optional, defaults to module defaults) controls if the File Shares defined in the + storage account. + + The properties you should pay attention to are: + + - `allowed_subnet_keys` - (`list`, optional, defaults to `[]`) a list of keys pointing to Subnet definitions in the + `var.vnets` map. These Subnets will have dedicated access to the Storage Account. For this to work + they also need to have the Storage Account Service Endpoint enabled. + - `vnet_key` - (`string`, optional) a key pointing to a VNET definition in the `var.vnets` map that stores the + Subnets described in `allowed_subnet_keys`. + + For detailed documentation see [module's documentation](../../modules/bootstrap/README.md#storage_network_security). + +- `file_shares_configuration` - (`map`, optional, defaults to `{}`) a map defining common File Share setting. + + The properties you should pay attention to are: + + - `create_file_shares` - (`bool`, optional, defaults to module default) controls if the File Shares defined in the `file_shares` property will be created or sourced. - - `disable_package_dirs_creation` - (`bool`, optional, defaults to module defaults) for sourced File Shares, controls if the + - `disable_package_dirs_creation` - (`bool`, optional, defaults to module default) for sourced File Shares, controls if the bootstrap package folder structure will be created. + + For detailed documentation see [module's documentation](../../modules/bootstrap/README.md#file_shares_configuration). + - `file_shares` - (`map`, optional, defaults to `{}`) a map that holds File Shares and bootstrap package configuration. For detailed description see [module's documentation](../../modules/bootstrap/README.md#file_shares). - Type: ```hcl @@ -839,129 +853,121 @@ Default value: `map[]` #### vmseries -A map defining Azure Virtual Machines based on Palo Alto Networks Next Generation Firewall image.. +A map defining Azure Virtual Machines based on Palo Alto Networks Next Generation Firewall image. For details and defaults for available options please refer to the [`vmseries`](../../modules/vmseries/README.md) module. The most basic properties are as follows: - `name` - (`string`, required) name of the VM, will be prefixed with the value of `var.name_prefix`. +- `vnet_key` - (`string`, required) a key of a VNET defined in `var.vnets`. This is the VNET that hosts subnets used to + deploy network interfaces for deployed VM. - `authentication` - (`map`, optional, defaults to example defaults) authentication settings for the deployed VM. - The `authentication` property is optional and holds the firewall admin access details. By default, standard username - `panadmin` will be set and a random password will be auto-generated for you (available in Terraform outputs). + The `authentication` property is optional and holds the firewall admin access details. By default, standard username + `panadmin` will be set and a random password will be auto-generated for you (available in Terraform outputs). - **Note!** \ - The `disable_password_authentication` property is by default `false` in this example. When using this value, you don't have - to specify anything but you can still additionally pass SSH keys for authentication. You can however set this property to - `true`, then you have to specify `ssh_keys` property. - - For all properties and their default values see [module's documentation](../../modules/vmseries/README.md#authentication). - -- `image` - (`map`, required) properties defining a base image used by the deployed VM. - - The `image` property is required but there are only 2 properties (mutually exclusive) that have to be set, either: - - - `version` - (`string`) describes the PAN-OS image version from Azure Marketplace. - - `custom_id` - (`string`) absolute ID of your own custom PAN-OS image. - - For details on the other properties refer to [module's documentation](../../modules/vmseries/README.md#image). - -- `virtual_machine` - (`map`, optional, defaults to module defaults) a map that groups most common VM configuration options. - - The most often used option are as follows: - - - `size` - (`string`, optional, defaults to module defaults) Azure VM size (type). Consult the *VM-Series Deployment - Guide* as only a few selected sizes are supported. - - `zone` - (`string`, optional, defaults to module defaults) the Availability Zone in which the VM and (if deployed) - public IP addresses will be created. - - `disk_type` - (`string`, optional, defaults to module defaults) type of a Managed Disk which should be created, possible - values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected `size` values). - - `bootstrap_options` - (`string`, optional, mutually exclusive with `bootstrap_package`) bootstrap options passed to PAN-OS - when launched for the 1st time, for details see module documentation. - - `bootstrap_package` - (`map`, optional, mutually exclusive with `bootstrap_options`) a map defining content of the - bootstrap package. - - **Note!** \ - At least one of `static_files`, `bootstrap_xml_template` or `bootstrap_package_path` is required. You can use a - combination of all 3. The `bootstrap_package_path` is the less important. For details on this mechanism and for details - on the other properties see the [`bootstrap` module documentation](../../modules/bootstrap/README.md). - - Following properties are available: - - - `bootstrap_storage_key` - (`string`, required) a key of a bootstrap storage defined in `var.bootstrap_storages` that - will host bootstrap packages. Each package will be hosted on a separate File Share. - The File Shares will be created automatically, one for each firewall. - - `static_files` - (`map`, optional, defaults to `{}`) a map containing files that will be copied to a File - Share, see [`file_shares.bootstrap_files`](../../modules/bootstrap/README.md#file_shares) - property documentation for details. - - `bootstrap_package_path` - (`string`, optional, defaults to `null`) a path to a folder containing a full bootstrap - package. - - `bootstrap_xml_template` - (`string`, optional, defaults to `null`) a path to a `bootstrap.xml` template. If this - example is using full bootstrap method, the sample templates are in - [`templates`](./templates) folder. - - The templates are used to provide `day0` like configuration which consists of: - - - network interfaces configuration. - - one or more (depending on the architecture) Virtual Routers configurations. This config contains static routes - required for the Load Balancer (and Application Gateway, if defined) health checks to work and routes that allow - Inbound and OBEW traffic. - - *any-any* security rule. - - an outbound NAT rule that will allow the Outbound traffic to flow to the internet. - - **Note!** \ - Day0 configuration is **not meant** to be **secure**. It's here marly to help with the basic firewall setup. - - When `bootstrap_xml_template` is set, one of the following properties might be required. - - - `private_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key - pointing to a private Subnet definition in `var.vnets` (the `vnet_key` property is used to - identify a VNET). The Subnet definition is used to calculate static routes for a private - Load Balancer health checks and for Inbound traffic. - - `public_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key - pointing to a public Subnet definition in `var.vnets` (the `vnet_key` property is used to - identify a VNET). The Subnet definition is used to calculate static routes for a public - Load Balancer health checks and for Outbound traffic. - - `ai_update_interval` - (`number`, optional, defaults to `5`) Application Insights update interval, used only when - `ngfw_metrics` module is defined and used in this example. The Application Insights - Instrumentation Key will be populated automatically. - - `intranet_cidr` - (`string`, optional, defaults to `null`) a CIDR of the Intranet - combined CIDR of all - private networks. When set it will override the private Subnet CIDR for inbound traffic - static routes. - - For details on the other properties refer to [module's documentation](../../modules/panorama/README.md#virtual_machine). + **Note!** \ + The `disable_password_authentication` property is by default `false` in this example. When using this value, you don't have + to specify anything but you can still additionally pass SSH keys for authentication. You can however set this property to + `true`, then you have to specify `ssh_keys` property. -- `vnet_key` - (`string`, required) a key of a VNET defined in `var.vnets`. This is the VNET that hosts subnets used to - deploy network interfaces for deployed VM. + For all properties and their default values see [module's documentation](../../modules/vmseries/README.md#authentication). -- `interfaces` - (`list`, required) configuration of all network interfaces - - **Note!** \ - Order of the interfaces does matter - the 1st interface is the management one. +- `image` - (`map`, required) properties defining a base image used by the deployed VM. The `image` property is + required but there are only 2 properties (mutually exclusive) that have to be set, either: - For details on available properties please see [module's documentation](../../modules/panorama/README.md#interfaces). + - `version` - (`string`, optional) describes the PAN-OS image version from Azure Marketplace. + - `custom_id` - (`string`, optional) absolute ID of your own custom PAN-OS image. - The most important ones are listed below: + For details on all properties refer to [module's documentation](../../modules/vmseries/README.md#image). - - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`). - - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in - `var.vnets`. Key identifying the VNET is defined in `virtual_machine.vnet_key` property. - - `create_public_ip` - (`bool`, optional, defaults to `false`) create a Public IP for an interface. - - `load_balancer_key` - (`string`, optional, defaults to `null`) key of a Load Balancer defined in `var.loadbalancers` - variable, network interface that has this property defined will be added to the Load - Balancer's backend pool. - - `application_gateway_key` - (`string`, optional, defaults to `null`) key of an Application Gateway defined in `var.appgws` - variable, network interface that has this property defined will be added to the Application - Gateway's backend pool. +- `virtual_machine` - (`map`, optional, defaults to module default) a map that groups most common VM configuration options. + Most common properties are: + - `size` - (`string`, optional, defaults to module default) Azure VM size (type). Consult the *VM-Series + Deployment Guide* as only a few selected sizes are supported. + - `zone` - (`string`, optional, defaults to module default) the Availability Zone in which the VM and (if + deployed) public IP addresses will be created. + - `disk_type` - (`string`, optional, defaults to module default) type of a Managed Disk which should be created, + possible values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected + `size` values). + - `bootstrap_options` - (`string`, optional, mutually exclusive with `bootstrap_package`) bootstrap options passed to PAN-OS + when launched for the 1st time, for details see module documentation. + - `bootstrap_package` - (`map`, optional, mutually exclusive with `bootstrap_options`) a map defining content of the + bootstrap package. + + **Note!** \ + At least one of `static_files`, `bootstrap_xml_template` or `bootstrap_package_path` is required. You can use a combination + of all 3. The `bootstrap_package_path` is the less important. For details on this mechanism and for details on the other + properties see the [`bootstrap` module documentation](../../modules/bootstrap/README.md). + + Following properties are available: + + - `bootstrap_storage_key` - (`string`, required) a key of a bootstrap storage defined in `var.bootstrap_storages` that + will host bootstrap packages. Each package will be hosted on a separate File Share. The File + Shares will be created automatically, one for each firewall. + - `static_files` - (`map`, optional, defaults to `{}`) a map containing files that will be copied to a File + Share, see [`file_shares.bootstrap_files`](../../modules/bootstrap/README.md#file_shares) + property documentation for details. + - `bootstrap_package_path` - (`string`, optional, defaults to `null`) a path to a folder containing a full bootstrap + package. + - `bootstrap_xml_template` - (`string`, optional, defaults to `null`) a path to a `bootstrap.xml` template. If this example + is using full bootstrap method, the sample templates are in [`templates`](./templates) folder. + + The templates are used to provide `day0` like configuration which consists of: + + - network interfaces configuration. + - one or more (depending on the architecture) Virtual Routers configurations. This config contains static routes + required for the Load Balancer (and Application Gateway, if defined) health checks to work and routes that allow + Inbound and OBEW traffic. + - *any-any* security rule. + - an outbound NAT rule that will allow the Outbound traffic to flow to the Internet. + + **Note!** \ + Day0 configuration is **not meant** to be **secure**. It's here merely to help with the basic firewall setup. When + `bootstrap_xml_template` is set, one of the following properties might be required. + + - `private_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key + pointing to a private Subnet definition in `var.vnets` (the `vnet_key` property is used to + identify a VNET). The Subnet definition is used to calculate static routes for a private + Load Balancer health checks and for Inbound traffic. + - `public_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key + pointing to a public Subnet definition in `var.vnets` (the `vnet_key` property is used to + identify a VNET). The Subnet definition is used to calculate static routes for a public + Load Balancer health checks and for Outbound traffic. + - `ai_update_interval` - (`number`, optional, defaults to `5`) Application Insights update interval, used only when + `ngfw_metrics` module is defined and used in this example. The Application Insights + Instrumentation Key will be populated automatically. + - `intranet_cidr` - (`string`, optional, defaults to `null`) a CIDR of the Intranet - combined CIDR of all + private networks. When set it will override the private Subnet CIDR for inbound traffic + static routes. + + For details on all properties refer to [module's documentation](../../modules/panorama/README.md#virtual_machine). + +- `interfaces` - (`list`, required) configuration of all network interfaces. Order of the interfaces does matter - the + 1st interface is the management one. Most common properties are: + + - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`). + - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in + `var.vnets`. Key identifying the VNET is defined in `virtual_machine.vnet_key` property. + - `create_public_ip` - (`bool`, optional, defaults to `false`) create a Public IP for an interface. + - `load_balancer_key` - (`string`, optional, defaults to `null`) key of a Load Balancer defined in `var.loadbalancers` + variable, network interface that has this property defined will be added to the Load Balancer's + backend pool. + - `application_gateway_key` - (`string`, optional, defaults to `null`) key of an Application Gateway defined in `var.appgws` + variable, network interface that has this property defined will be added to the Application + Gateway's backend pool. + + For details on all properties refer to [module's documentation](../../modules/panorama/README.md#interfaces). Type: ```hcl map(object({ - name = string + name = string + vnet_key = string authentication = optional(object({ username = optional(string, "panadmin") password = optional(string) @@ -1002,7 +1008,6 @@ map(object({ identity_ids = optional(list(string)) allow_extension_operations = optional(bool) }) - vnet_key = string interfaces = list(object({ name = string subnet_key = string @@ -1021,6 +1026,4 @@ Default value: `map[]` [back to list](#modules-optional-inputs) - - \ No newline at end of file diff --git a/examples/standalone_vmseries/example.tfvars b/examples/standalone_vmseries/example.tfvars index 972460b8..951ea7f0 100644 --- a/examples/standalone_vmseries/example.tfvars +++ b/examples/standalone_vmseries/example.tfvars @@ -1,4 +1,5 @@ -# --- GENERAL --- # +### GENERAL ### + location = "North Europe" resource_group_name = "vmseries-standalone" name_prefix = "example-" @@ -7,7 +8,8 @@ tags = { "CreatedWith" = "Terraform" } -# --- VNET PART --- # +### NETWORK ### + vnets = { "transit" = { name = "transit" @@ -40,11 +42,12 @@ vnets = { } } +### VM-SERIES ### -# --- VMSERIES PART --- # vmseries = { "fw-1" = { - name = "firewall01" + name = "firewall01" + vnet_key = "transit" image = { version = "10.2.3" } @@ -52,7 +55,6 @@ vmseries = { bootstrap_options = "type=dhcp-client" zone = null } - vnet_key = "transit" interfaces = [ { name = "vm-mgmt" diff --git a/examples/standalone_vmseries/main.tf b/examples/standalone_vmseries/main.tf index f69aa3bc..29fd01d5 100644 --- a/examples/standalone_vmseries/main.tf +++ b/examples/standalone_vmseries/main.tf @@ -1,4 +1,5 @@ -# Generate a random password. +### Generate a random password ### + # https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password resource "random_password" "this" { count = anytrue([ @@ -26,7 +27,8 @@ locals { } } -# Create or source the Resource Group. +### Create or source a Resource Group ### + # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group resource "azurerm_resource_group" "this" { count = var.create_resource_group ? 1 : 0 @@ -46,7 +48,8 @@ locals { resource_group = var.create_resource_group ? azurerm_resource_group.this[0] : data.azurerm_resource_group.this[0] } -# Manage the network required for the topology. +### Manage the network required for the topology ### + module "vnet" { source = "../../modules/vnet" @@ -62,15 +65,16 @@ module "vnet" { create_subnets = each.value.create_subnets subnets = each.value.subnets - network_security_groups = { for k, v in each.value.network_security_groups : k => merge(v, { name = "${var.name_prefix}${v.name}" }) + network_security_groups = { + for k, v in each.value.network_security_groups : k => merge(v, { name = "${var.name_prefix}${v.name}" }) } - route_tables = { for k, v in each.value.route_tables : k => merge(v, { name = "${var.name_prefix}${v.name}" }) + route_tables = { + for k, v in each.value.route_tables : k => merge(v, { name = "${var.name_prefix}${v.name}" }) } tags = var.tags } - module "natgw" { source = "../../modules/natgw" @@ -84,15 +88,19 @@ module "natgw" { idle_timeout = each.value.idle_timeout subnet_ids = { for v in each.value.subnet_keys : v => module.vnet[each.value.vnet_key].subnet_ids[v] } - public_ip = try(merge(each.value.public_ip, { name = "${each.value.public_ip.create ? var.name_prefix : ""}${each.value.public_ip.name}" }), null) - public_ip_prefix = try(merge(each.value.public_ip_prefix, { name = "${each.value.public_ip_prefix.create ? var.name_prefix : ""}${each.value.public_ip_prefix.name}" }), null) + public_ip = try(merge(each.value.public_ip, { + name = "${each.value.public_ip.create ? var.name_prefix : ""}${each.value.public_ip.name}" + }), null) + public_ip_prefix = try(merge(each.value.public_ip_prefix, { + name = "${each.value.public_ip_prefix.create ? var.name_prefix : ""}${each.value.public_ip_prefix.name}" + }), null) tags = var.tags depends_on = [module.vnet] } +### Create Load Balancers, both internal and external ### -# create load balancers, both internal and external module "load_balancer" { source = "../../modules/loadbalancer" @@ -109,7 +117,8 @@ module "load_balancer" { nsg_auto_rules_settings = try( { nsg_name = try( - "${var.name_prefix}${var.vnets[each.value.nsg_auto_rules_settings.nsg_vnet_key].network_security_groups[each.value.nsg_auto_rules_settings.nsg_key].name}", + "${var.name_prefix}${var.vnets[each.value.nsg_auto_rules_settings.nsg_vnet_key].network_security_groups[ + each.value.nsg_auto_rules_settings.nsg_key].name}", each.value.nsg_auto_rules_settings.nsg_name ) nsg_resource_group_name = try( @@ -137,9 +146,65 @@ module "load_balancer" { depends_on = [module.vnet] } +### Create Application Gateways ### + +locals { + nics_with_appgw_key = flatten([ + for k, v in var.vmseries : [ + for nic in v.interfaces : { + vm_key = k + nic_name = nic.name + appgw_key = nic.application_gateway_key + } if nic.application_gateway_key != null + ]]) + + ips_4_nics_with_appgw_key = { + for v in local.nics_with_appgw_key : + v.appgw_key => module.vmseries[v.vm_key].interfaces["${var.name_prefix}${v.nic_name}"].private_ip_address... + } +} + +module "appgw" { + source = "../../modules/appgw" + + for_each = var.appgws + + name = "${var.name_prefix}${each.value.name}" + resource_group_name = local.resource_group.name + location = var.location + subnet_id = module.vnet[each.value.vnet_key].subnet_ids[each.value.subnet_key] + + zones = each.value.zones + public_ip = merge( + each.value.public_ip, + { name = "${each.value.public_ip.create ? var.name_prefix : ""}${each.value.public_ip.name}" } + ) + domain_name_label = each.value.domain_name_label + capacity = each.value.capacity + enable_http2 = each.value.enable_http2 + waf = each.value.waf + managed_identities = each.value.managed_identities + global_ssl_policy = each.value.global_ssl_policy + ssl_profiles = each.value.ssl_profiles + frontend_ip_configuration_name = each.value.frontend_ip_configuration_name + listeners = each.value.listeners + backend_pool = merge( + each.value.backend_pool, + length(local.ips_4_nics_with_appgw_key) == 0 ? {} : { vmseries_ips = local.ips_4_nics_with_appgw_key[each.key] } + ) + backend_settings = each.value.backend_settings + probes = each.value.probes + rewrites = each.value.rewrites + redirects = each.value.redirects + url_path_maps = each.value.url_path_maps + rules = each.value.rules + + tags = var.tags + depends_on = [module.vnet, module.vmseries] +} +### Create VM-Series VMs and closely associated resources ### -# create the actual VM-Series VMs and resources module "ngfw_metrics" { source = "../../modules/ngfw_metrics" @@ -147,9 +212,11 @@ module "ngfw_metrics" { create_workspace = var.ngfw_metrics.create_workspace - name = "${var.ngfw_metrics.create_workspace ? var.name_prefix : ""}${var.ngfw_metrics.name}" - resource_group_name = var.ngfw_metrics.create_workspace ? local.resource_group.name : coalesce(var.ngfw_metrics.resource_group_name, local.resource_group.name) - location = var.location + name = "${var.ngfw_metrics.create_workspace ? var.name_prefix : ""}${var.ngfw_metrics.name}" + resource_group_name = var.ngfw_metrics.create_workspace ? local.resource_group.name : ( + coalesce(var.ngfw_metrics.resource_group_name, local.resource_group.name) + ) + location = var.location log_analytics_workspace = { sku = var.ngfw_metrics.sku @@ -161,10 +228,11 @@ module "ngfw_metrics" { tags = var.tags } +# https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file resource "local_file" "bootstrap_xml" { for_each = { for k, v in var.vmseries : - k => v.virtual_machine + k => merge(v.virtual_machine, { vnet_key = v.vnet_key }) if try(v.virtual_machine.bootstrap_package.bootstrap_xml_template != null, false) } @@ -254,6 +322,7 @@ module "bootstrap" { tags = var.tags } +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/availability_set resource "azurerm_availability_set" "this" { for_each = var.availability_sets @@ -286,8 +355,10 @@ module "vmseries" { coalesce( each.value.virtual_machine.bootstrap_options, join(",", [ - "storage-account=${module.bootstrap[each.value.virtual_machine.bootstrap_package.bootstrap_storage_key].storage_account_name}", - "access-key=${module.bootstrap[each.value.virtual_machine.bootstrap_package.bootstrap_storage_key].storage_account_primary_access_key}", + "storage-account=${module.bootstrap[ + each.value.virtual_machine.bootstrap_package.bootstrap_storage_key].storage_account_name}", + "access-key=${module.bootstrap[ + each.value.virtual_machine.bootstrap_package.bootstrap_storage_key].storage_account_primary_access_key}", "file-share=${each.key}", "share-directory=None" ]), @@ -298,10 +369,12 @@ module "vmseries" { ) interfaces = [for v in each.value.interfaces : { - name = "${var.name_prefix}${v.name}" - subnet_id = module.vnet[each.value.vnet_key].subnet_ids[v.subnet_key] - create_public_ip = v.create_public_ip - public_ip_name = v.create_public_ip ? "${var.name_prefix}${coalesce(v.public_ip_name, "${v.name}-pip")}" : v.public_ip_name + name = "${var.name_prefix}${v.name}" + subnet_id = module.vnet[each.value.vnet_key].subnet_ids[v.subnet_key] + create_public_ip = v.create_public_ip + public_ip_name = v.create_public_ip ? "${ + var.name_prefix}${coalesce(v.public_ip_name, "${v.name}-pip") + }" : v.public_ip_name public_ip_resource_group_name = v.public_ip_resource_group_name private_ip_address = v.private_ip_address attach_to_lb_backend_pool = v.load_balancer_key != null @@ -317,60 +390,3 @@ module "vmseries" { module.bootstrap, ] } - -# Create Application Gateway - -locals { - nics_with_appgw_key = flatten([ - for k, v in var.vmseries : [ - for nic in v.interfaces : { - vm_key = k - nic_name = nic.name - appgw_key = nic.application_gateway_key - } if nic.application_gateway_key != null - ]]) - - ips_4_nics_with_appgw_key = { - for v in local.nics_with_appgw_key : - v.appgw_key => module.vmseries[v.vm_key].interfaces["${var.name_prefix}${v.nic_name}"].private_ip_address... - } -} - -module "appgw" { - source = "../../modules/appgw" - - for_each = var.appgws - - name = "${var.name_prefix}${each.value.name}" - resource_group_name = local.resource_group.name - location = var.location - subnet_id = module.vnet[each.value.vnet_key].subnet_ids[each.value.subnet_key] - - zones = each.value.zones - public_ip = merge( - each.value.public_ip, - { name = "${each.value.public_ip.create ? var.name_prefix : ""}${each.value.public_ip.name}" } - ) - domain_name_label = each.value.domain_name_label - capacity = each.value.capacity - enable_http2 = each.value.enable_http2 - waf = each.value.waf - managed_identities = each.value.managed_identities - global_ssl_policy = each.value.global_ssl_policy - ssl_profiles = each.value.ssl_profiles - frontend_ip_configuration_name = each.value.frontend_ip_configuration_name - listeners = each.value.listeners - backend_pool = merge( - each.value.backend_pool, - length(local.ips_4_nics_with_appgw_key) == 0 ? {} : { vmseries_ips = local.ips_4_nics_with_appgw_key[each.key] } - ) - backend_settings = each.value.backend_settings - probes = each.value.probes - rewrites = each.value.rewrites - redirects = each.value.redirects - url_path_maps = each.value.url_path_maps - rules = each.value.rules - - tags = var.tags - depends_on = [module.vnet, module.vmseries] -} diff --git a/examples/standalone_vmseries/variables.tf b/examples/standalone_vmseries/variables.tf index d401eaab..8a26966e 100644 --- a/examples/standalone_vmseries/variables.tf +++ b/examples/standalone_vmseries/variables.tf @@ -1,14 +1,4 @@ -### GENERAL -variable "tags" { - description = "Map of tags to assign to the created resources." - default = {} - type = map(string) -} - -variable "location" { - description = "The Azure region to use." - type = string -} +### GENERAL ### variable "name_prefix" { description = <<-EOF @@ -45,33 +35,41 @@ variable "resource_group_name" { type = string } +variable "location" { + description = "The Azure region to use." + type = string +} +variable "tags" { + description = "Map of tags to assign to the created resources." + default = {} + type = map(string) +} + +### NETWORK ### -### VNET variable "vnets" { description = <<-EOF A map defining VNETs. For detailed documentation on each property refer to [module documentation](../../modules/vnet/README.md) - - `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, - `false` will source an existing VNET. - - `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be - a full resource name, including prefixes. - - `address_space` - (`list(string)`, required when `create_virtual_network = false`) a list of CIDRs for a newly - created VNET - - `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which - the VNET will reside or is sourced from + - `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, `false` will source + an existing VNET. + - `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be a + full resource name, including prefixes. + - `address_space` - (`list`, required when `create_virtual_network = false`) a list of CIDRs for a newly created VNET. + - `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which the + VNET will reside or is sourced from. - `create_subnets` - (`bool`, optional, defaults to `true`) if `true`, create Subnets inside the Virtual Network, - otherwise use source existing subnets + otherwise use source existing subnets. - `subnets` - (`map`, optional) map of Subnets to create or source, for details see - [VNET module documentation](../../modules/vnet/README.md#subnets) + [VNET module documentation](../../modules/vnet/README.md#subnets). - `network_security_groups` - (`map`, optional) map of Network Security Groups to create, for details see - [VNET module documentation](../../modules/vnet/README.md#network_security_groups) + [VNET module documentation](../../modules/vnet/README.md#network_security_groups). - `route_tables` - (`map`, optional) map of Route Tables to create, for details see - [VNET module documentation](../../modules/vnet/README.md#route_tables) + [VNET module documentation](../../modules/vnet/README.md#route_tables). EOF - type = map(object({ name = string resource_group_name = optional(string) @@ -125,21 +123,21 @@ variable "natgws" { For detailed documentation on each property refer to [module documentation](../../modules/natgw/README.md). Following properties are supported: - - `create_natgw` - (`bool`, optional, defaults to `true`) create (`true`) or source an existing NAT Gateway (`false`), - created or sourced: the NAT Gateway will be assigned to a subnet created by the `vnet` module. - - `name` - (`string`, required) a name of a NAT Gateway. In case `create_natgw = false` this should be a full - resource name, including prefixes. - - `resource_group_name - (`string`, optional) name of a Resource Group hosting the NAT Gateway (newly created or the existing - one). - - `zone` - (`string`, optional) an Availability Zone in which the NAT Gateway will be placed, when skipped - AzureRM will pick a zone. - - `idle_timeout` - (`number`, optional, defults to 4) connection IDLE timeout in minutes, for newly created resources. - - `vnet_key` - (`string`, required) a name (key value) of a VNET defined in `var.vnets` that hosts a subnet this - NAT Gateway will be assigned to. - - `subnet_keys` - (`list(string)`, required) a list of subnets (key values) the NAT Gateway will be assigned to, defined - in `var.vnets` for a VNET described by `vnet_name`. - - `public_ip` - (`object`, optional) an object defining a public IP resource attached to the NAT Gateway. - - `public_ip_prefix` - (`object`, optional) an object defining a public IP prefix resource attached to the NAT Gatway. + - `name` - (`string`, required) a name of a NAT Gateway. In case `create_natgw = false` this should be a full + resource name, including prefixes. + - `vnet_key` - (`string`, required) a name (key value) of a VNET defined in `var.vnets` that hosts a subnet this + NAT Gateway will be assigned to. + - `subnet_keys` - (`list(string)`, required) a list of subnets (key values) the NAT Gateway will be assigned to, + defined in `var.vnets` for a VNET described by `vnet_name`. + - `create_natgw` - (`bool`, optional, defaults to `true`) create (`true`) or source an existing NAT Gateway (`false`), + created or sourced: the NAT Gateway will be assigned to a subnet created by the `vnet` module. + - `resource_group_name` - (`string`, optional) name of a Resource Group hosting the NAT Gateway (newly created or the existing + one). + - `zone` - (`string`, optional) an Availability Zone in which the NAT Gateway will be placed, when skipped + Azure will pick a zone. + - `idle_timeout` - (`number`, optional, defults to 4) connection IDLE timeout in minutes, for newly created resources. + - `public_ip` - (`object`, optional) an object defining a public IP resource attached to the NAT Gateway. + - `public_ip_prefix` - (`object`, optional) an object defining a public IP prefix resource attached to the NAT Gatway. Example: ``` @@ -158,13 +156,13 @@ variable "natgws" { EOF default = {} type = map(object({ - create_natgw = optional(bool, true) name = string + vnet_key = string + subnet_keys = list(string) + create_natgw = optional(bool, true) resource_group_name = optional(string) zone = optional(string) idle_timeout = optional(number, 4) - vnet_key = string - subnet_keys = list(string) public_ip = optional(object({ create = bool name = string @@ -179,12 +177,11 @@ variable "natgws" { })) } +### LOAD BALANCING ### - -### Load Balancing variable "load_balancers" { description = <<-EOF - A map containing configuration for all (private and public) Load Balancers. + A map containing configuration for all (both private and public) Load Balancers. This is a brief description of available properties. For a detailed one please refer to [module documentation](../../modules/loadbalancer/README.md). @@ -194,26 +191,29 @@ variable "load_balancers" { - `name` - (`string`, required) a name of the Load Balancer. - `vnet_key` - (`string`, optional, defaults to `null`) a key pointing to a VNET definition in the `var.vnets` map that stores the Subnet described by `subnet_key`. - - `zones` - (`list`, optional, defaults to module defaults) a list of zones for Load Balancer's fronted IP + - `zones` - (`list`, optional, defaults to module default) a list of zones for Load Balancer's frontend IP configurations. - - `backend_name` - (`string`, optional, defaults to module defaults) a name of the backend pool to create. - - `health_probes` - (`map`, optional, defaults to `null`) a map defining health probes that will be used by - load balancing rules; please check + - `backend_name` - (`string`, optional, defaults to module default) a name of the backend pool to create. + - `health_probes` - (`map`, optional, defaults to `null`) a map defining health probes that will be used by load + balancing rules, please refer to [module documentation](../../modules/loadbalancer/README.md#health_probes) for more specific use cases and available properties. - - `nsg_auto_rules_settings` - (`map`, optional, defaults to `null`) a map defining a location of an existing NSG rule - that will be populated with `Allow` rules for each load balancing rule (`in_rules`); please check - [module documentation](../../modules/loadbalancer/README.md#nsg_auto_rules_settings) - for available properties; please note that in this example two additional properties are - available: - - `nsg_vnet_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to a VNET definition - in the `var.vnets` map that stores the NSG described by `nsg_key`. - - `nsg_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to an NSG definition - in the `var.vnets` map. - - `frontend_ips` - (`map`, optional, defaults to `{}`) a map containing frontend IP configuration with respective - `in_rules` and `out_rules` + - `nsg_auto_rules_settings` - (`map`, optional, defaults to `null`) a map defining a location of an existing NSG rule that will + be populated with `Allow` rules for each load balancing rule (`in_rules`), please refer to + [module documentation](../../modules/loadbalancer/README.md#nsg_auto_rules_settings) for + available properties. + + Please note that in this example two additional properties are available: + + - `nsg_vnet_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to a VNET definition in the + `var.vnets` map that stores the NSG described by `nsg_key`. + - `nsg_key` - (`string`, optional, mutually exclusive with `nsg_name`) a key pointing to an NSG definition in the + `var.vnets` map. - Please refer to [module documentation](../../modules/loadbalancer/README.md#frontend_ips) for available properties. + - `frontend_ips` - (`map`, optional, defaults to `{}`) a map containing frontend IP configuration with respective + `in_rules` and `out_rules`, please refer to + [module documentation](../../modules/loadbalancer/README.md#frontend_ips) for available + properties. **Note!** \ In this example the `subnet_id` is not available directly, another property has been introduced instead: @@ -245,10 +245,10 @@ variable "load_balancers" { })) frontend_ips = optional(map(object({ name = string + subnet_key = optional(string) public_ip_name = optional(string) create_public_ip = optional(bool, false) public_ip_resource_group_name = optional(string) - subnet_key = optional(string) private_ip_address = optional(string) gwlb_key = optional(string) in_rules = optional(map(object({ @@ -272,29 +272,195 @@ variable "load_balancers" { })) } +variable "appgws" { + description = <<-EOF + A map defining all Application Gateways in the current deployment. + + For detailed documentation on how to configure this resource, for available properties, especially for the defaults, + refer to [module documentation](../../modules/appgw/README.md). + + **Note!** \ + The `rules` property is meant to bind together `backend_setting`, `redirect` or `url_path_map` (all 3 are mutually exclusive). + It represents the Rules section of an Application Gateway in Azure Portal. + + Below you can find a brief list of most important properties: + + - `name` - (`string`, required) the name of the Application Gateway, will be prefixed with `var.name_prefix`. + - `vnet_key` - (`string`, required) a key pointing to a VNET definition in the `var.vnets` map that stores the Subnet + described by `subnet_key`. + - `subnet_key` - (`string`, required) a key pointing to a Subnet definition in the `var.vnets` map, this has to be an + Application Gateway V2 dedicated subnet. + - `zones` - (`list`, optional, defaults to module default) parameter controlling if this is a zonal, or a non-zonal + deployment. + - `public_ip` - (`map`, required) defines a Public IP resource used by the Application Gateway instance, a newly created + Public IP will have it's name prefixes with `var.name_prefix`. + - `listeners` - (`map`, required) defines Application Gateway's Listeners, see + [module's documentation](../../modules/appgw/README.md#listeners) for details. + - `backend_pool` - (`map`, optional, defaults to module default) backend pool definition, when skipped an empty backend + will be created. + - `backend_settings` - (`map`, optional, mutually exclusive with `redirects` and `url_path_maps`) defines HTTP backend + settings, see [module's documentation](../../modules/appgw/README.md#backend_settings) for details. + - `probes` - (`map`, optional, defaults to module default) defines backend probes used check health of backends, see + [module's documentation](../../modules/appgw/README.md#probes) for details. + - `rewrites` - (`map`, optional, defaults to module default) defines rewrite rules, see + [module's documentation](../../modules/appgw/README.md#rewrites) for details. + - `redirects` - (`map`, optional, mutually exclusive with `backend_settings` and `url_path_maps`) static redirects + definition, see [module's documentation](../../modules/appgw/README.md#redirects) for details. + - `url_path_maps` - (`map`, optional, mutually exclusive with `backend_settings` and `redirects`) URL path maps definition, + see [module's documentation](../../modules/appgw/README.md#url_path_maps) for details. + - `rules` - (`map`, required) Application Gateway Rules definition, bind together a `listener` with either + `backend_setting`, `redirect` or `url_path_map`, see + [module's documentation](../../modules/appgw/README.md#rules) for details. + EOF + type = map(object({ + name = string + vnet_key = string + subnet_key = string + zones = optional(list(string)) + public_ip = object({ + name = string + create = optional(bool, true) + resource_group_name = optional(string) + }) + domain_name_label = optional(string) + capacity = optional(object({ + static = optional(number) + autoscale = optional(object({ + min = number + max = number + })) + })) + enable_http2 = optional(bool) + waf = optional(object({ + prevention_mode = bool + rule_set_type = optional(string) + rule_set_version = optional(string) + })) + managed_identities = optional(list(string)) + global_ssl_policy = optional(object({ + type = optional(string) + name = optional(string) + min_protocol_version = optional(string) + cipher_suites = optional(list(string)) + })) + ssl_profiles = optional(map(object({ + name = string + ssl_policy_name = optional(string) + ssl_policy_min_protocol_version = optional(string) + ssl_policy_cipher_suites = optional(list(string)) + }))) + frontend_ip_configuration_name = optional(string) + listeners = map(object({ + name = string + port = number + protocol = optional(string) + host_names = optional(list(string)) + ssl_profile_name = optional(string) + ssl_certificate_path = optional(string) + ssl_certificate_pass = optional(string) + ssl_certificate_vault_id = optional(string) + custom_error_pages = optional(map(string)) + })) + backend_pool = optional(object({ + name = optional(string) + vmseries_ips = optional(list(string)) + })) + backend_settings = optional(map(object({ + name = string + port = number + protocol = string + path = optional(string) + hostname_from_backend = optional(string) + hostname = optional(string) + timeout = optional(number) + use_cookie_based_affinity = optional(bool) + affinity_cookie_name = optional(string) + probe = optional(string) + root_certs = optional(map(object({ + name = string + path = string + }))) + }))) + probes = optional(map(object({ + name = string + path = string + host = optional(string) + port = optional(number) + protocol = optional(string) + interval = optional(number) + timeout = optional(number) + threshold = optional(number) + match_code = optional(list(number)) + match_body = optional(string) + }))) + rewrites = optional(map(object({ + name = optional(string) + rules = optional(map(object({ + name = string + sequence = number + conditions = optional(map(object({ + pattern = string + ignore_case = optional(bool) + negate = optional(bool) + }))) + request_headers = optional(map(string)) + response_headers = optional(map(string)) + }))) + }))) + redirects = optional(map(object({ + name = string + type = string + target_listener_key = optional(string) + target_url = optional(string) + include_path = optional(bool) + include_query_string = optional(bool) + }))) + url_path_maps = optional(map(object({ + name = string + backend_key = string + path_rules = optional(map(object({ + paths = list(string) + backend_key = optional(string) + redirect_key = optional(string) + }))) + }))) + rules = map(object({ + name = string + priority = number + backend_key = optional(string) + listener_key = string + rewrite_key = optional(string) + url_path_map_key = optional(string) + redirect_key = optional(string) + })) + })) +} + +### VM-SERIES ### variable "availability_sets" { description = <<-EOF A map defining availability sets. Can be used to provide infrastructure high availability when zones cannot be used. Following properties are supported: - - `name` - name of the Application Insights. - - `update_domain_count` - specifies the number of update domains that are used, defaults to 5 (Azure defaults). - - `fault_domain_count` - specifies the number of fault domains that are used, defaults to 3 (Azure defaults). - Please keep in mind that Azure defaults are not working for each region (especially the small ones, w/o any Availability Zones). - Please verify how many update and fault domain are supported in a region before deploying this resource. + - `name` - (`string`, required) name of the Application Insights. + - `update_domain_count` - (`number`, optional, defaults to Azure default) specifies the number of update domains that are used. + - `fault_domain_count` - (`number`, optional, defaults to Azure default) specifies the number of fault domains that are used. + + **Note!** \ + Please keep in mind that Azure defaults are not working for every region (especially the small ones, without any Availability + Zones). Please verify how many update and fault domain are supported in a region before deploying this resource. EOF default = {} nullable = false type = map(object({ name = string - update_domain_count = optional(number, 5) - fault_domain_count = optional(number, 3) + update_domain_count = optional(number) + fault_domain_count = optional(number) })) } - variable "ngfw_metrics" { description = <<-EOF A map controlling metrics-relates resources. @@ -302,22 +468,22 @@ variable "ngfw_metrics" { When set to explicit `null` (default) it will disable any metrics resources in this deployment. When defined it will either create or source a Log Analytics Workspace and create Application Insights instances (one per each - Scale Set). All instances will be automatically connected to the workspace. - The name of the Application Insights instance will be derived from the Scale Set name and suffixed with `-ai`. + Scale Set). All instances will be automatically connected to the workspace. The name of the Application Insights instance will + be derived from the Scale Set name and suffixed with `-ai`. All the settings available below are common to the Log Analytics Workspace and Application Insight instances. Following properties are available: - - `name` - (`string`, required) name of the (common) Log Analytics Workspace + - `name` - (`string`, required) name of the (common) Log Analytics Workspace. - `create_workspace` - (`bool`, optional, defaults to `true`) controls whether we create or source an existing Log - Analytics Workspace + Analytics Workspace. - `resource_group_name` - (`string`, optional, defaults to `var.resource_group_name`) name of the Resource Group hosting - the Log Analytics Workspace - - `sku` - (`string`, optional, defaults to module defaults) the SKU of the Log Analytics Workspace. - - `metrics_retention_in_days` - (`number`, optional, defaults to module defaults) workspace and insights data retention in - days, possible values are between 30 and 730. For sourced Workspaces this applies only to - the Application Insights instances. + the Log Analytics Workspace. + - `sku` - (`string`, optional, defaults to module default) the SKU of the Log Analytics Workspace. + - `metrics_retention_in_days` - (`number`, optional, defaults to module default) workspace and insights data retention in days, + possible values are between 30 and 730. For sourced Workspaces this applies only to the + Application Insights instances. EOF default = null type = object({ @@ -338,41 +504,50 @@ variable "bootstrap_storages" { - `name` - (`string`, required) name of the Storage Account that will be created or sourced. - **Note** \ - For new Storage Accounts this name will not be prefixed with `var.name_prefix`. \ - Please note the limitations on naming. This has to be a globally unique name, between 3 and 63 chars, only lower-case - letters and numbers. + **Note** \ + For new Storage Accounts this name will not be prefixed with `var.name_prefix`. \ + Please note the limitations on naming. This has to be a globally unique name, between 3 and 63 chars, only lower-case letters + and numbers. - - `resource_group_name` - (`string`, optional, defaults to `null`) name of the Resource Group that hosts (sourced) or will - host (created) a Storage Account. When skipped the code will fall back to + - `resource_group_name` - (`string`, optional, defaults to `null`) name of the Resource Group that hosts (sourced) or + will host (created) a Storage Account. When skipped the code will fall back to `var.resource_group_name`. - - `storage_account` - (`map`, optional, defaults to `{}`) a map controlling basic Storage Account configuration, for - detailed documentation see - [module's documentation](../../modules/bootstrap/README.md#storage_account). The property you - should pay attention to is: - - `create` - (`bool`, optional, defaults to module defaults) controls if the Storage Account specified in - the `name` property will be created or sourced. + - `storage_account` - (`map`, optional, defaults to `{}`) a map controlling basic Storage Account configuration. + + The property you should pay attention to is: + + - `create` - (`bool`, optional, defaults to module default) controls if the Storage Account specified in the `name` property + will be created or sourced. + + For detailed documentation see [module's documentation](../../modules/bootstrap/README.md#storage_account). + - `storage_network_security` - (`map`, optional, defaults to `{}`) a map defining network security settings for a **new** - storage account, for details see - [module's documentation](../../modules/bootstrap/README.md#storage_network_security). Properties - worth mentioning are: - - `allowed_subnet_keys` - (`list`, optional, defaults to `[]`) a list of keys pointing to Subnet definitions in the - `var.vnets` map. These Subnets will have dedicated access to the Storage Account. For this to - work they also need to have the Storage Account Service Endpoint enabled. - - `vnet_key` - a key pointing to a VNET definition in the `var.vnets` map that stores the Subnets described - in `allowed_subnet_keys`. - - `file_shares_configuration` - (`map`, optional, defaults to `{}`) a map defining common File Share setting. For detailed - documentation see - [module's documentation](../../modules/bootstrap/README.md#file_shares_configuration). The - properties you should pay your attention to are: - - `create_file_shares` - (`bool`, optional, defaults to module defaults) controls if the File Shares defined in the + storage account. + + The properties you should pay attention to are: + + - `allowed_subnet_keys` - (`list`, optional, defaults to `[]`) a list of keys pointing to Subnet definitions in the + `var.vnets` map. These Subnets will have dedicated access to the Storage Account. For this to work + they also need to have the Storage Account Service Endpoint enabled. + - `vnet_key` - (`string`, optional) a key pointing to a VNET definition in the `var.vnets` map that stores the + Subnets described in `allowed_subnet_keys`. + + For detailed documentation see [module's documentation](../../modules/bootstrap/README.md#storage_network_security). + + - `file_shares_configuration` - (`map`, optional, defaults to `{}`) a map defining common File Share setting. + + The properties you should pay attention to are: + + - `create_file_shares` - (`bool`, optional, defaults to module default) controls if the File Shares defined in the `file_shares` property will be created or sourced. - - `disable_package_dirs_creation` - (`bool`, optional, defaults to module defaults) for sourced File Shares, controls if the + - `disable_package_dirs_creation` - (`bool`, optional, defaults to module default) for sourced File Shares, controls if the bootstrap package folder structure will be created. + + For detailed documentation see [module's documentation](../../modules/bootstrap/README.md#file_shares_configuration). + - `file_shares` - (`map`, optional, defaults to `{}`) a map that holds File Shares and bootstrap package configuration. For detailed description see [module's documentation](../../modules/bootstrap/README.md#file_shares). - EOF default = {} nullable = false @@ -410,127 +585,119 @@ variable "bootstrap_storages" { variable "vmseries" { description = <<-EOF - A map defining Azure Virtual Machines based on Palo Alto Networks Next Generation Firewall image.. + A map defining Azure Virtual Machines based on Palo Alto Networks Next Generation Firewall image. For details and defaults for available options please refer to the [`vmseries`](../../modules/vmseries/README.md) module. The most basic properties are as follows: - `name` - (`string`, required) name of the VM, will be prefixed with the value of `var.name_prefix`. + - `vnet_key` - (`string`, required) a key of a VNET defined in `var.vnets`. This is the VNET that hosts subnets used to + deploy network interfaces for deployed VM. - `authentication` - (`map`, optional, defaults to example defaults) authentication settings for the deployed VM. - The `authentication` property is optional and holds the firewall admin access details. By default, standard username - `panadmin` will be set and a random password will be auto-generated for you (available in Terraform outputs). + The `authentication` property is optional and holds the firewall admin access details. By default, standard username + `panadmin` will be set and a random password will be auto-generated for you (available in Terraform outputs). - **Note!** \ - The `disable_password_authentication` property is by default `false` in this example. When using this value, you don't have - to specify anything but you can still additionally pass SSH keys for authentication. You can however set this property to - `true`, then you have to specify `ssh_keys` property. - - For all properties and their default values see [module's documentation](../../modules/vmseries/README.md#authentication). - - - `image` - (`map`, required) properties defining a base image used by the deployed VM. - - The `image` property is required but there are only 2 properties (mutually exclusive) that have to be set, either: - - - `version` - (`string`) describes the PAN-OS image version from Azure Marketplace. - - `custom_id` - (`string`) absolute ID of your own custom PAN-OS image. - - For details on the other properties refer to [module's documentation](../../modules/vmseries/README.md#image). - - - `virtual_machine` - (`map`, optional, defaults to module defaults) a map that groups most common VM configuration options. - - The most often used option are as follows: - - - `size` - (`string`, optional, defaults to module defaults) Azure VM size (type). Consult the *VM-Series Deployment - Guide* as only a few selected sizes are supported. - - `zone` - (`string`, optional, defaults to module defaults) the Availability Zone in which the VM and (if deployed) - public IP addresses will be created. - - `disk_type` - (`string`, optional, defaults to module defaults) type of a Managed Disk which should be created, possible - values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected `size` values). - - `bootstrap_options` - (`string`, optional, mutually exclusive with `bootstrap_package`) bootstrap options passed to PAN-OS - when launched for the 1st time, for details see module documentation. - - `bootstrap_package` - (`map`, optional, mutually exclusive with `bootstrap_options`) a map defining content of the - bootstrap package. - - **Note!** \ - At least one of `static_files`, `bootstrap_xml_template` or `bootstrap_package_path` is required. You can use a - combination of all 3. The `bootstrap_package_path` is the less important. For details on this mechanism and for details - on the other properties see the [`bootstrap` module documentation](../../modules/bootstrap/README.md). - - Following properties are available: - - - `bootstrap_storage_key` - (`string`, required) a key of a bootstrap storage defined in `var.bootstrap_storages` that - will host bootstrap packages. Each package will be hosted on a separate File Share. - The File Shares will be created automatically, one for each firewall. - - `static_files` - (`map`, optional, defaults to `{}`) a map containing files that will be copied to a File - Share, see [`file_shares.bootstrap_files`](../../modules/bootstrap/README.md#file_shares) - property documentation for details. - - `bootstrap_package_path` - (`string`, optional, defaults to `null`) a path to a folder containing a full bootstrap - package. - - `bootstrap_xml_template` - (`string`, optional, defaults to `null`) a path to a `bootstrap.xml` template. If this - example is using full bootstrap method, the sample templates are in - [`templates`](./templates) folder. - - The templates are used to provide `day0` like configuration which consists of: - - - network interfaces configuration. - - one or more (depending on the architecture) Virtual Routers configurations. This config contains static routes - required for the Load Balancer (and Application Gateway, if defined) health checks to work and routes that allow - Inbound and OBEW traffic. - - *any-any* security rule. - - an outbound NAT rule that will allow the Outbound traffic to flow to the internet. - - **Note!** \ - Day0 configuration is **not meant** to be **secure**. It's here marly to help with the basic firewall setup. - - When `bootstrap_xml_template` is set, one of the following properties might be required. - - - `private_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key - pointing to a private Subnet definition in `var.vnets` (the `vnet_key` property is used to - identify a VNET). The Subnet definition is used to calculate static routes for a private - Load Balancer health checks and for Inbound traffic. - - `public_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key - pointing to a public Subnet definition in `var.vnets` (the `vnet_key` property is used to - identify a VNET). The Subnet definition is used to calculate static routes for a public - Load Balancer health checks and for Outbound traffic. - - `ai_update_interval` - (`number`, optional, defaults to `5`) Application Insights update interval, used only when - `ngfw_metrics` module is defined and used in this example. The Application Insights - Instrumentation Key will be populated automatically. - - `intranet_cidr` - (`string`, optional, defaults to `null`) a CIDR of the Intranet - combined CIDR of all - private networks. When set it will override the private Subnet CIDR for inbound traffic - static routes. - - For details on the other properties refer to [module's documentation](../../modules/panorama/README.md#virtual_machine). + **Note!** \ + The `disable_password_authentication` property is by default `false` in this example. When using this value, you don't have + to specify anything but you can still additionally pass SSH keys for authentication. You can however set this property to + `true`, then you have to specify `ssh_keys` property. - - `vnet_key` - (`string`, required) a key of a VNET defined in `var.vnets`. This is the VNET that hosts subnets used to - deploy network interfaces for deployed VM. + For all properties and their default values see [module's documentation](../../modules/vmseries/README.md#authentication). - - `interfaces` - (`list`, required) configuration of all network interfaces - - **Note!** \ - Order of the interfaces does matter - the 1st interface is the management one. + - `image` - (`map`, required) properties defining a base image used by the deployed VM. The `image` property is + required but there are only 2 properties (mutually exclusive) that have to be set, either: - For details on available properties please see [module's documentation](../../modules/panorama/README.md#interfaces). + - `version` - (`string`, optional) describes the PAN-OS image version from Azure Marketplace. + - `custom_id` - (`string`, optional) absolute ID of your own custom PAN-OS image. - The most important ones are listed below: + For details on all properties refer to [module's documentation](../../modules/vmseries/README.md#image). - - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`). - - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in - `var.vnets`. Key identifying the VNET is defined in `virtual_machine.vnet_key` property. - - `create_public_ip` - (`bool`, optional, defaults to `false`) create a Public IP for an interface. - - `load_balancer_key` - (`string`, optional, defaults to `null`) key of a Load Balancer defined in `var.loadbalancers` - variable, network interface that has this property defined will be added to the Load - Balancer's backend pool. - - `application_gateway_key` - (`string`, optional, defaults to `null`) key of an Application Gateway defined in `var.appgws` - variable, network interface that has this property defined will be added to the Application - Gateway's backend pool. + - `virtual_machine` - (`map`, optional, defaults to module default) a map that groups most common VM configuration options. + Most common properties are: + - `size` - (`string`, optional, defaults to module default) Azure VM size (type). Consult the *VM-Series + Deployment Guide* as only a few selected sizes are supported. + - `zone` - (`string`, optional, defaults to module default) the Availability Zone in which the VM and (if + deployed) public IP addresses will be created. + - `disk_type` - (`string`, optional, defaults to module default) type of a Managed Disk which should be created, + possible values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS` (works only for selected + `size` values). + - `bootstrap_options` - (`string`, optional, mutually exclusive with `bootstrap_package`) bootstrap options passed to PAN-OS + when launched for the 1st time, for details see module documentation. + - `bootstrap_package` - (`map`, optional, mutually exclusive with `bootstrap_options`) a map defining content of the + bootstrap package. + + **Note!** \ + At least one of `static_files`, `bootstrap_xml_template` or `bootstrap_package_path` is required. You can use a combination + of all 3. The `bootstrap_package_path` is the less important. For details on this mechanism and for details on the other + properties see the [`bootstrap` module documentation](../../modules/bootstrap/README.md). + + Following properties are available: + + - `bootstrap_storage_key` - (`string`, required) a key of a bootstrap storage defined in `var.bootstrap_storages` that + will host bootstrap packages. Each package will be hosted on a separate File Share. The File + Shares will be created automatically, one for each firewall. + - `static_files` - (`map`, optional, defaults to `{}`) a map containing files that will be copied to a File + Share, see [`file_shares.bootstrap_files`](../../modules/bootstrap/README.md#file_shares) + property documentation for details. + - `bootstrap_package_path` - (`string`, optional, defaults to `null`) a path to a folder containing a full bootstrap + package. + - `bootstrap_xml_template` - (`string`, optional, defaults to `null`) a path to a `bootstrap.xml` template. If this example + is using full bootstrap method, the sample templates are in [`templates`](./templates) folder. + + The templates are used to provide `day0` like configuration which consists of: + + - network interfaces configuration. + - one or more (depending on the architecture) Virtual Routers configurations. This config contains static routes + required for the Load Balancer (and Application Gateway, if defined) health checks to work and routes that allow + Inbound and OBEW traffic. + - *any-any* security rule. + - an outbound NAT rule that will allow the Outbound traffic to flow to the Internet. + + **Note!** \ + Day0 configuration is **not meant** to be **secure**. It's here merely to help with the basic firewall setup. When + `bootstrap_xml_template` is set, one of the following properties might be required. + + - `private_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key + pointing to a private Subnet definition in `var.vnets` (the `vnet_key` property is used to + identify a VNET). The Subnet definition is used to calculate static routes for a private + Load Balancer health checks and for Inbound traffic. + - `public_snet_key` - (`string`, required only when `bootstrap_xml_template` is set, defaults to `null`) a key + pointing to a public Subnet definition in `var.vnets` (the `vnet_key` property is used to + identify a VNET). The Subnet definition is used to calculate static routes for a public + Load Balancer health checks and for Outbound traffic. + - `ai_update_interval` - (`number`, optional, defaults to `5`) Application Insights update interval, used only when + `ngfw_metrics` module is defined and used in this example. The Application Insights + Instrumentation Key will be populated automatically. + - `intranet_cidr` - (`string`, optional, defaults to `null`) a CIDR of the Intranet - combined CIDR of all + private networks. When set it will override the private Subnet CIDR for inbound traffic + static routes. + + For details on all properties refer to [module's documentation](../../modules/panorama/README.md#virtual_machine). + + - `interfaces` - (`list`, required) configuration of all network interfaces. Order of the interfaces does matter - the + 1st interface is the management one. Most common properties are: + + - `name` - (`string`, required) name of the network interface (will be prefixed with `var.name_prefix`). + - `subnet_key` - (`string`, required) a key of a subnet to which the interface will be assigned as defined in + `var.vnets`. Key identifying the VNET is defined in `virtual_machine.vnet_key` property. + - `create_public_ip` - (`bool`, optional, defaults to `false`) create a Public IP for an interface. + - `load_balancer_key` - (`string`, optional, defaults to `null`) key of a Load Balancer defined in `var.loadbalancers` + variable, network interface that has this property defined will be added to the Load Balancer's + backend pool. + - `application_gateway_key` - (`string`, optional, defaults to `null`) key of an Application Gateway defined in `var.appgws` + variable, network interface that has this property defined will be added to the Application + Gateway's backend pool. + + For details on all properties refer to [module's documentation](../../modules/panorama/README.md#interfaces). EOF default = {} nullable = false type = map(object({ - name = string + name = string + vnet_key = string authentication = optional(object({ username = optional(string, "panadmin") password = optional(string) @@ -571,7 +738,6 @@ variable "vmseries" { identity_ids = optional(list(string)) allow_extension_operations = optional(bool) }) - vnet_key = string interfaces = list(object({ name = string subnet_key = string @@ -583,185 +749,26 @@ variable "vmseries" { application_gateway_key = optional(string) })) })) - validation { + validation { # virtual_machine.bootstrap_options & virtual_machine.bootstrap_package condition = alltrue([ for _, v in var.vmseries : v.virtual_machine.bootstrap_options != null && v.virtual_machine.bootstrap_package == null || v.virtual_machine.bootstrap_options == null && v.virtual_machine.bootstrap_package != null ]) - error_message = "Either `bootstrap_options` or `bootstrap_package` property can be set." + error_message = <<-EOF + Either `bootstrap_options` or `bootstrap_package` property can be set. + EOF } - validation { + validation { # virtual_machine.bootstrap_package condition = alltrue([ for _, v in var.vmseries : - v.virtual_machine.bootstrap_package.bootstrap_xml_template != null ? v.virtual_machine.bootstrap_package.private_snet_key != null && v.virtual_machine.bootstrap_package.public_snet_key != null : true - if v.virtual_machine.bootstrap_package != null + v.virtual_machine.bootstrap_package.bootstrap_xml_template != null ? ( + v.virtual_machine.bootstrap_package.private_snet_key != null && + v.virtual_machine.bootstrap_package.public_snet_key != null + ) : true if v.virtual_machine.bootstrap_package != null ]) - error_message = "The `private_snet_key` and `public_snet_key` are required when `bootstrap_xml_template` is set." + error_message = <<-EOF + The `private_snet_key` and `public_snet_key` are required when `bootstrap_xml_template` is set. + EOF } } - -### Application Gateway -variable "appgws" { - description = <<-EOF - A map defining all Application Gateways in the current deployment. - - For detailed documentation on how to configure this resource, for available properties, especially for the defaults, - refer to [module documentation](../../modules/appgw/README.md). - - **Note!** \ - The `rules` property is meant to bind together `backend_setting`, `redirect` or `url_path_map` (all 3 are mutually exclusive). - It represents the Rules section of an Application Gateway in Azure Portal. - - Below you can find a brief list of most important properties: - - - `name` - (`string`, required) the name of the Application Gateway, will be prefixed with `var.name_prefix`. - - `vnet_key` - (`string`, required) a key pointing to a VNET definition in the `var.vnets` map that stores the Subnet - described by `subnet_key`. - - `subnet_key` - (`string`, required) a key pointing to a Subnet definition in the `var.vnets` map, this has to be an - Application Gateway V2 dedicated subnet. - - `zones` - (`list`, optional, defaults to module defaults) parameter controlling if this is a zonal, or a non-zonal - deployment. - - `public_ip` - (`map`, required) defines a Public IP resource used by the Application Gateway instance, a newly created - Public IP will have it's name prefixes with `var.name_prefix`. - - `listeners` - (`map`, required) defines Application Gateway's Listeners, see - [module's documentation](../../modules/appgw/README.md#listeners) for details. - - `backend_pool` - (`map`, optional, defaults to module defaults) backend pool definition, when skipped an empty backend - will be created. - - `backend_settings` - (`map`, optional, mutually exclusive with `redirects` and `url_path_maps`) defines HTTP backend - settings, see [module's documentation](../../modules/appgw/README.md#backend_settings) for details. - - `probes` - (`map`, optional, defaults to module defaults) defines backend probes used check health of backends, see - [module's documentation](../../modules/appgw/README.md#probes) for details. - - `rewrites` - (`map`, optional, defaults to module defaults) defines rewrite rules, see - [module's documentation](../../modules/appgw/README.md#rewrites) for details. - - `redirects - (`map`, optional, mutually exclusive with `backend_settings` and `url_path_maps`) static redirects - definition, see [module's documentation](../../modules/appgw/README.md#redirects) for details. - - `url_path_maps - (`map`, optional, mutually exclusive with `backend_settings` and `redirects`) URL path maps definition, - see [module's documentation](../../modules/appgw/README.md#url_path_maps) for details. - - `rules - (`map`, required) Application Gateway Rules definition, bind together a `listener` with either - `backend_setting`, `redirect` or `url_path_map`, see - [module's documentation](../../modules/appgw/README.md#rules) for details. - EOF - type = map(object({ - name = string - vnet_key = string - subnet_key = string - zones = optional(list(string)) - public_ip = object({ - name = string - create = optional(bool, true) - resource_group_name = optional(string) - }) - domain_name_label = optional(string) - capacity = optional(object({ - static = optional(number) - autoscale = optional(object({ - min = number - max = number - })) - })) - enable_http2 = optional(bool) - waf = optional(object({ - prevention_mode = bool - rule_set_type = optional(string) - rule_set_version = optional(string) - })) - managed_identities = optional(list(string)) - global_ssl_policy = optional(object({ - type = optional(string) - name = optional(string) - min_protocol_version = optional(string) - cipher_suites = optional(list(string)) - })) - ssl_profiles = optional(map(object({ - name = string - ssl_policy_name = optional(string) - ssl_policy_min_protocol_version = optional(string) - ssl_policy_cipher_suites = optional(list(string)) - }))) - frontend_ip_configuration_name = optional(string) - listeners = map(object({ - name = string - port = number - protocol = optional(string) - host_names = optional(list(string)) - ssl_profile_name = optional(string) - ssl_certificate_path = optional(string) - ssl_certificate_pass = optional(string) - ssl_certificate_vault_id = optional(string) - custom_error_pages = optional(map(string)) - })) - backend_pool = optional(object({ - name = optional(string) - vmseries_ips = optional(list(string)) - })) - backend_settings = optional(map(object({ - name = string - port = number - protocol = string - path = optional(string) - hostname_from_backend = optional(string) - hostname = optional(string) - timeout = optional(number) - use_cookie_based_affinity = optional(bool) - affinity_cookie_name = optional(string) - probe = optional(string) - root_certs = optional(map(object({ - name = string - path = string - }))) - }))) - probes = optional(map(object({ - name = string - path = string - host = optional(string) - port = optional(number) - protocol = optional(string) - interval = optional(number) - timeout = optional(number) - threshold = optional(number) - match_code = optional(list(number)) - match_body = optional(string) - }))) - rewrites = optional(map(object({ - name = optional(string) - rules = optional(map(object({ - name = string - sequence = number - conditions = optional(map(object({ - pattern = string - ignore_case = optional(bool) - negate = optional(bool) - }))) - request_headers = optional(map(string)) - response_headers = optional(map(string)) - }))) - }))) - redirects = optional(map(object({ - name = string - type = string - target_listener_key = optional(string) - target_url = optional(string) - include_path = optional(bool) - include_query_string = optional(bool) - }))) - url_path_maps = optional(map(object({ - name = string - backend_key = string - path_rules = optional(map(object({ - paths = list(string) - backend_key = optional(string) - redirect_key = optional(string) - }))) - }))) - rules = map(object({ - name = string - priority = number - backend_key = optional(string) - listener_key = string - rewrite_key = optional(string) - url_path_map_key = optional(string) - redirect_key = optional(string) - })) - })) -} \ No newline at end of file diff --git a/examples/virtual_network_gateway/README.md b/examples/virtual_network_gateway/README.md index df4acc39..70fea9e5 100644 --- a/examples/virtual_network_gateway/README.md +++ b/examples/virtual_network_gateway/README.md @@ -9,8 +9,8 @@ The `README` is also in new, document-style format. Name | Type | Description --- | --- | --- -[`location`](#location) | `string` | The Azure region to use. [`resource_group_name`](#resource_group_name) | `string` | Name of the Resource Group. +[`location`](#location) | `string` | The Azure region to use. [`vnets`](#vnets) | `map` | A map defining VNETs. @@ -18,10 +18,10 @@ Name | Type | Description Name | Type | Description --- | --- | --- -[`tags`](#tags) | `map` | Map of tags to assign to the created resources. [`name_prefix`](#name_prefix) | `string` | A prefix that will be added to all created resources. [`create_resource_group`](#create_resource_group) | `bool` | When set to `true` it will cause a Resource Group creation. -[`virtual_network_gateways`](#virtual_network_gateways) | `map` | Map of virtual_network_gateways to create. +[`tags`](#tags) | `map` | Map of tags to assign to the created resources. +[`virtual_network_gateways`](#virtual_network_gateways) | `map` | Map of Virtual Network Gateways to create. @@ -46,7 +46,7 @@ Modules used in this module: Name | Version | Source | Description --- | --- | --- | --- `vnet` | - | ../../modules/vnet | -`vng` | - | ../../modules/virtual_network_gateway | Create virtual network gateway +`vng` | - | ../../modules/virtual_network_gateway | Resources used in this module: @@ -60,46 +60,45 @@ Resources used in this module: -#### location -The Azure region to use. +#### resource_group_name + +Name of the Resource Group. Type: string [back to list](#modules-required-inputs) +#### location - -#### resource_group_name - -Name of the Resource Group. +The Azure region to use. Type: string [back to list](#modules-required-inputs) + #### vnets A map defining VNETs. For detailed documentation on each property refer to [module documentation](../../modules/vnet/README.md) -- `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, - `false` will source an existing VNET. -- `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be - a full resource name, including prefixes. -- `address_space` - (`list(string)`, required when `create_virtual_network = false`) a list of CIDRs for a newly - created VNET -- `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which - the VNET will reside or is sourced from +- `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, `false` will source + an existing VNET. +- `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be a + full resource name, including prefixes. +- `address_space` - (`list`, required when `create_virtual_network = false`) a list of CIDRs for a newly created VNET. +- `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which the + VNET will reside or is sourced from. - `create_subnets` - (`bool`, optional, defaults to `true`) if `true`, create Subnets inside the Virtual Network, - otherwise use source existing subnets + otherwise use source existing subnets. - `subnets` - (`map`, optional) map of Subnets to create or source, for details see - [VNET module documentation](../../modules/vnet/README.md#subnets) + [VNET module documentation](../../modules/vnet/README.md#subnets). - `network_security_groups` - (`map`, optional) map of Network Security Groups to create, for details see - [VNET module documentation](../../modules/vnet/README.md#network_security_groups) + [VNET module documentation](../../modules/vnet/README.md#network_security_groups). - `route_tables` - (`map`, optional) map of Route Tables to create, for details see - [VNET module documentation](../../modules/vnet/README.md#route_tables) + [VNET module documentation](../../modules/vnet/README.md#route_tables). Type: @@ -158,28 +157,20 @@ map(object({ ### Optional Inputs -#### tags - -Map of tags to assign to the created resources. - -Type: map(string) - -Default value: `map[]` - -[back to list](#modules-optional-inputs) - - #### name_prefix A prefix that will be added to all created resources. -There is no default delimiter applied between the prefix and the resource name. Please include the delimiter in the actual prefix. +There is no default delimiter applied between the prefix and the resource name. +Please include the delimiter in the actual prefix. Example: -```hcl +``` name_prefix = "test-" ``` -NOTICE. This prefix is not applied to existing resources. If you plan to reuse i.e. a VNET please specify it's full name, even if it is also prefixed with the same value as the one in this property. +**Note!** \ +This prefix is not applied to existing resources. If you plan to reuse i.e. a VNET please specify it's full name, +even if it is also prefixed with the same value as the one in this property. Type: string @@ -190,7 +181,9 @@ Default value: `` #### create_resource_group -When set to `true` it will cause a Resource Group creation. Name of the newly specified RG is controlled by `resource_group_name`. +When set to `true` it will cause a Resource Group creation. +Name of the newly specified RG is controlled by `resource_group_name`. + When set to `false` the `resource_group_name` parameter is used to specify a name of an existing Resource Group. @@ -202,9 +195,20 @@ Default value: `true` +#### tags + +Map of tags to assign to the created resources. + +Type: map(string) + +Default value: `map[]` + +[back to list](#modules-optional-inputs) + + #### virtual_network_gateways -Map of virtual_network_gateways to create. +Map of Virtual Network Gateways to create. Type: diff --git a/examples/virtual_network_gateway/example.tfvars b/examples/virtual_network_gateway/example.tfvars index b774e6b2..c222b56b 100644 --- a/examples/virtual_network_gateway/example.tfvars +++ b/examples/virtual_network_gateway/example.tfvars @@ -1,4 +1,5 @@ -# --- GENERAL --- # +### GENERAL ### + location = "North Europe" resource_group_name = "vng" name_prefix = "example-" @@ -7,8 +8,8 @@ tags = { "CreatedWith" = "Terraform" } +### NETWORK ### -# --- VNET PART --- # vnets = { transit = { name = "transit" @@ -60,7 +61,8 @@ vnets = { } } -# --- VNG PART --- # +### VIRTUAL NETWORK GATEWAY ### + virtual_network_gateways = { expressroute = { name = "expressroute" diff --git a/examples/virtual_network_gateway/main.tf b/examples/virtual_network_gateway/main.tf index 959871c6..85ed5850 100644 --- a/examples/virtual_network_gateway/main.tf +++ b/examples/virtual_network_gateway/main.tf @@ -1,4 +1,5 @@ -# Create or source the Resource Group. +### Generate a random password ### + # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group resource "azurerm_resource_group" "this" { count = var.create_resource_group ? 1 : 0 @@ -8,6 +9,8 @@ resource "azurerm_resource_group" "this" { tags = var.tags } +### Create or source a Resource Group ### + # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/resource_group data "azurerm_resource_group" "this" { count = var.create_resource_group ? 0 : 1 @@ -18,6 +21,8 @@ locals { resource_group = var.create_resource_group ? azurerm_resource_group.this[0] : data.azurerm_resource_group.this[0] } +### Manage the network required for the topology ### + module "vnet" { source = "../../modules/vnet" @@ -33,15 +38,18 @@ module "vnet" { create_subnets = each.value.create_subnets subnets = each.value.subnets - network_security_groups = { for k, v in each.value.network_security_groups : k => merge(v, { name = "${var.name_prefix}${v.name}" }) + network_security_groups = { + for k, v in each.value.network_security_groups : k => merge(v, { name = "${var.name_prefix}${v.name}" }) } - route_tables = { for k, v in each.value.route_tables : k => merge(v, { name = "${var.name_prefix}${v.name}" }) + route_tables = { + for k, v in each.value.route_tables : k => merge(v, { name = "${var.name_prefix}${v.name}" }) } tags = var.tags } -# Create virtual network gateway +### Create Virtual Network Gateways ### + module "vng" { source = "../../modules/virtual_network_gateway" @@ -66,4 +74,4 @@ module "vng" { vpn_clients = each.value.vpn_clients tags = var.tags -} \ No newline at end of file +} diff --git a/examples/virtual_network_gateway/outputs.tf b/examples/virtual_network_gateway/outputs.tf index 469cc0fd..2ce3480a 100644 --- a/examples/virtual_network_gateway/outputs.tf +++ b/examples/virtual_network_gateway/outputs.tf @@ -6,4 +6,4 @@ output "vng_public_ips" { output "vng_ipsec_policy" { description = "IPsec policy used for Virtual Network Gateway connection" value = length(var.virtual_network_gateways) > 0 ? { for k, v in module.vng : k => v.ipsec_policy } : null -} \ No newline at end of file +} diff --git a/examples/virtual_network_gateway/variables.tf b/examples/virtual_network_gateway/variables.tf index 7a933bc1..1173e6a7 100644 --- a/examples/virtual_network_gateway/variables.tf +++ b/examples/virtual_network_gateway/variables.tf @@ -1,26 +1,19 @@ -### GENERAL -variable "tags" { - description = "Map of tags to assign to the created resources." - default = {} - type = map(string) -} - -variable "location" { - description = "The Azure region to use." - type = string -} +### GENERAL ### variable "name_prefix" { description = <<-EOF A prefix that will be added to all created resources. - There is no default delimiter applied between the prefix and the resource name. Please include the delimiter in the actual prefix. + There is no default delimiter applied between the prefix and the resource name. + Please include the delimiter in the actual prefix. Example: - ```hcl + ``` name_prefix = "test-" ``` - NOTICE. This prefix is not applied to existing resources. If you plan to reuse i.e. a VNET please specify it's full name, even if it is also prefixed with the same value as the one in this property. + **Note!** \ + This prefix is not applied to existing resources. If you plan to reuse i.e. a VNET please specify it's full name, + even if it is also prefixed with the same value as the one in this property. EOF default = "" type = string @@ -28,7 +21,9 @@ variable "name_prefix" { variable "create_resource_group" { description = <<-EOF - When set to `true` it will cause a Resource Group creation. Name of the newly specified RG is controlled by `resource_group_name`. + When set to `true` it will cause a Resource Group creation. + Name of the newly specified RG is controlled by `resource_group_name`. + When set to `false` the `resource_group_name` parameter is used to specify a name of an existing Resource Group. EOF default = true @@ -40,32 +35,41 @@ variable "resource_group_name" { type = string } +variable "location" { + description = "The Azure region to use." + type = string +} + +variable "tags" { + description = "Map of tags to assign to the created resources." + default = {} + type = map(string) +} + +### NETWORK ### -### VNET variable "vnets" { description = <<-EOF A map defining VNETs. For detailed documentation on each property refer to [module documentation](../../modules/vnet/README.md) - - `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, - `false` will source an existing VNET. - - `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be - a full resource name, including prefixes. - - `address_space` - (`list(string)`, required when `create_virtual_network = false`) a list of CIDRs for a newly - created VNET - - `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which - the VNET will reside or is sourced from + - `create_virtual_network` - (`bool`, optional, defaults to `true`) when set to `true` will create a VNET, `false` will source + an existing VNET. + - `name` - (`string`, required) a name of a VNET. In case `create_virtual_network = false` this should be a + full resource name, including prefixes. + - `address_space` - (`list`, required when `create_virtual_network = false`) a list of CIDRs for a newly created VNET. + - `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which the + VNET will reside or is sourced from. - `create_subnets` - (`bool`, optional, defaults to `true`) if `true`, create Subnets inside the Virtual Network, - otherwise use source existing subnets + otherwise use source existing subnets. - `subnets` - (`map`, optional) map of Subnets to create or source, for details see - [VNET module documentation](../../modules/vnet/README.md#subnets) + [VNET module documentation](../../modules/vnet/README.md#subnets). - `network_security_groups` - (`map`, optional) map of Network Security Groups to create, for details see - [VNET module documentation](../../modules/vnet/README.md#network_security_groups) + [VNET module documentation](../../modules/vnet/README.md#network_security_groups). - `route_tables` - (`map`, optional) map of Route Tables to create, for details see - [VNET module documentation](../../modules/vnet/README.md#route_tables) + [VNET module documentation](../../modules/vnet/README.md#route_tables). EOF - type = map(object({ name = string resource_group_name = optional(string) @@ -110,9 +114,10 @@ variable "vnets" { })) } -### Virtual Network Gateway +### VIRTUAL NETWORK GATEWAY ### + variable "virtual_network_gateways" { - description = "Map of virtual_network_gateways to create." + description = "Map of Virtual Network Gateways to create." default = {} nullable = false type = map(object({ From 33a8940597fe2d58949a1b9153977f0cb6b3d87a Mon Sep 17 00:00:00 2001 From: Adrian Celebanski Date: Tue, 5 Mar 2024 20:40:02 +0100 Subject: [PATCH 3/5] Fix modules code style --- modules/appgw/README.md | 5 +- modules/appgw/main.tf | 24 ++-- modules/bootstrap/README.md | 2 +- modules/bootstrap/main.tf | 14 ++- modules/gwlb/outputs.tf | 2 +- modules/loadbalancer/README.md | 4 +- modules/loadbalancer/main.tf | 41 ++++--- modules/loadbalancer/outputs.tf | 5 +- modules/name_templater/main.tf | 2 +- modules/name_templater/outputs.tf | 2 +- modules/ngfw_metrics/main.tf | 10 +- modules/panorama/README.md | 1 + modules/panorama/outputs.tf | 4 +- modules/virtual_machine/main.tf | 6 +- modules/virtual_machine/outputs.tf | 13 ++- modules/virtual_machine/variables.tf | 92 +++++++++++---- modules/virtual_network_gateway/README.md | 2 +- modules/virtual_network_gateway/outputs.tf | 2 +- modules/vmseries/README.md | 12 +- modules/vmseries/main.tf | 2 +- modules/vmseries/outputs.tf | 8 +- modules/vmseries/variables.tf | 10 +- modules/vmss/README.md | 2 +- modules/vmss/main.tf | 125 +++++++++++++++------ modules/vmss/outputs.tf | 2 +- modules/vnet_peering/README.md | 1 - modules/vnet_peering/main.tf | 2 +- modules/vnet_peering/outputs.tf | 2 +- modules/vnet_peering/variables.tf | 2 +- modules/vnet_peering/versions.tf | 2 +- 30 files changed, 277 insertions(+), 124 deletions(-) diff --git a/modules/appgw/README.md b/modules/appgw/README.md index 515035c3..03187352 100644 --- a/modules/appgw/README.md +++ b/modules/appgw/README.md @@ -9,8 +9,9 @@ In order to use module `appgw`, you need to deploy `azurerm_resource_group` and Then you can use below code as an example of calling module to create Application Gateway: ```hcl -module "Application Gateway" { - source = "PaloAltoNetworks/swfw-modules/azurerm//modules/appgw" +# Create Application Gateay +module "appgw" { + source = "../../modules/appgw" for_each = var.appgws diff --git a/modules/appgw/main.tf b/modules/appgw/main.tf index aacbc7fc..79141b9b 100644 --- a/modules/appgw/main.tf +++ b/modules/appgw/main.tf @@ -91,7 +91,7 @@ resource "azurerm_application_gateway" "this" { public_ip_address_id = try(azurerm_public_ip.this[0].id, data.azurerm_public_ip.this[0].id) } - # There is only a single backend - the VMSeries private IPs assigned to untrusted NICs + # There is only a single backend - the VM-Series private IPs assigned to untrusted NICs backend_address_pool { name = var.backend_pool.name ip_addresses = var.backend_pool.vmseries_ips @@ -285,11 +285,15 @@ resource "azurerm_application_gateway" "this" { for_each = url_path_map.value.path_rules content { - name = path_rule.key - paths = path_rule.value.paths - backend_address_pool_name = path_rule.value.backend_key != null ? var.backend_pool.name : null - backend_http_settings_name = path_rule.value.backend_key != null ? var.backend_settings[path_rule.value.backend_key].name : null - redirect_configuration_name = path_rule.value.redirect_key != null ? var.redirects[path_rule.value.redirect_key].name : null + name = path_rule.key + paths = path_rule.value.paths + backend_address_pool_name = path_rule.value.backend_key != null ? var.backend_pool.name : null + backend_http_settings_name = path_rule.value.backend_key != null ? ( + var.backend_settings[path_rule.value.backend_key].name + ) : null + redirect_configuration_name = path_rule.value.redirect_key != null ? ( + var.redirects[path_rule.value.redirect_key].name + ) : null } } } @@ -317,7 +321,9 @@ resource "azurerm_application_gateway" "this" { request_routing_rule.value.rewrite_key != null ? var.rewrites[request_routing_rule.value.rewrite_key].name : null ) url_path_map_name = ( - request_routing_rule.value.url_path_map_key != null ? var.url_path_maps[request_routing_rule.value.url_path_map_key].name : null + request_routing_rule.value.url_path_map_key != null ? ( + var.url_path_maps[request_routing_rule.value.url_path_map_key].name + ) : null ) } } @@ -326,7 +332,9 @@ resource "azurerm_application_gateway" "this" { precondition { condition = var.probes != null ? alltrue(flatten([ for k, probe in var.probes : probe.host != null || alltrue(flatten([ - for b, backend in var.backend_settings : backend.probe_key == k ? backend.hostname != null || backend.hostname_from_backend : true + for b, backend in var.backend_settings : backend.probe_key == k ? ( + backend.hostname != null || backend.hostname_from_backend + ) : true ])) ])) : true error_message = < 0 || length(var.storage_network_security.allowed_subnet_ids) > 0 ? "Deny" : "Allow" + storage_account_id = azurerm_storage_account.this[0].id + default_action = length(var.storage_network_security.allowed_public_ips) > 0 || ( + length(var.storage_network_security.allowed_subnet_ids) > 0 + ) ? "Deny" : "Allow" ip_rules = var.storage_network_security.allowed_public_ips virtual_network_subnet_ids = var.storage_network_security.allowed_subnet_ids } @@ -67,7 +69,9 @@ data "azurerm_storage_share" "this" { } locals { - file_shares = var.file_shares_configuration.create_file_shares ? azurerm_storage_share.this : data.azurerm_storage_share.this + file_shares = var.file_shares_configuration.create_file_shares ? ( + azurerm_storage_share.this + ) : data.azurerm_storage_share.this package_folders = ["content", "config", "software", "plugins", "license"] } @@ -127,8 +131,8 @@ locals { } } - # 3. Compare both packages using destinations. There is no real comparison being made. We simply merge both maps, the latter one - # takes precedence (we simply use the mechanism of the `merge` function). + # 3. Compare both packages using destinations. There is no real comparison being made. We simply merge both maps, the latter + # one takes precedence (we simply use the mechanism of the `merge` function). inverted_filenames = { for k, _ in var.file_shares : k => merge(local.bootstrap_filenames[k], local.inverted_files[k]) } diff --git a/modules/gwlb/outputs.tf b/modules/gwlb/outputs.tf index 729fc2d4..2168db7f 100644 --- a/modules/gwlb/outputs.tf +++ b/modules/gwlb/outputs.tf @@ -6,4 +6,4 @@ output "backend_pool_ids" { output "frontend_ip_config_id" { description = "Frontend IP configuration identifier." value = azurerm_lb.this.frontend_ip_configuration[0].id -} \ No newline at end of file +} diff --git a/modules/loadbalancer/README.md b/modules/loadbalancer/README.md index 2d044303..05c0c112 100644 --- a/modules/loadbalancer/README.md +++ b/modules/loadbalancer/README.md @@ -110,7 +110,9 @@ Name | Type | Description Name | Description --- | --- `backend_pool_id` | The identifier of the backend pool. -`frontend_ip_configs` | Map of IP addresses, one per each entry of `frontend_ips` input. Contains public IP address for the frontends that have it, private IP address otherwise. +`frontend_ip_configs` | Map of IP addresses, one per each entry of `frontend_ips` input. Contains public IP address for the frontends that have it, +private IP address otherwise. + `health_probe` | The health probe object. ## Module's Nameplate diff --git a/modules/loadbalancer/main.tf b/modules/loadbalancer/main.tf index 0f23661b..ca63cfaf 100644 --- a/modules/loadbalancer/main.tf +++ b/modules/loadbalancer/main.tf @@ -1,6 +1,6 @@ locals { - # Decide how the backend machines access internet. If outbound rules are defined use them instead of the default route. - # This is an inbound rule setting, applicable to all inbound rules as you cannot mix SNAT with Outbound rules for a single backend. + # Decide how the backend machines access internet. If outbound rules are defined use them instead of the default route. This is + # an inbound rule setting, applicable to all inbound rules as you cannot mix SNAT with Outbound rules for a single backend. disable_outbound_snat = anytrue([for _, v in var.frontend_ips : length(v.out_rules) != 0]) # Calculate inbound rules @@ -63,8 +63,10 @@ resource "azurerm_lb" "this" { for_each = var.frontend_ips iterator = frontend_ip content { - name = frontend_ip.value.name - public_ip_address_id = frontend_ip.value.create_public_ip ? azurerm_public_ip.this[frontend_ip.key].id : try(data.azurerm_public_ip.this[frontend_ip.key].id, null) + name = frontend_ip.value.name + public_ip_address_id = frontend_ip.value.create_public_ip ? ( + azurerm_public_ip.this[frontend_ip.key].id + ) : try(data.azurerm_public_ip.this[frontend_ip.key].id, null) subnet_id = frontend_ip.value.subnet_id private_ip_address_allocation = frontend_ip.value.private_ip_address != null ? "Static" : null private_ip_address = frontend_ip.value.private_ip_address @@ -83,7 +85,10 @@ resource "azurerm_lb" "this" { [for _, fip in var.frontend_ips : fip.subnet_id != null] ) ) - error_message = "All frontends have to be of the same type, either public or private. Please check module's documentation (Usage section) for details." + error_message = <<-EOF + All frontends have to be of the same type, either public or private. Please check module's documentation (Usage section) + for details. + EOF } } } @@ -123,9 +128,11 @@ resource "azurerm_lb_probe" "this" { loadbalancer_id = azurerm_lb.this.id - name = each.value.name - protocol = each.value.protocol - port = contains(["Http", "Https"], each.value.protocol) && each.value.port == null ? local.default_http_probe_port[each.value.protocol] : each.value.port + name = each.value.name + protocol = each.value.protocol + port = contains(["Http", "Https"], each.value.protocol) && each.value.port == null ? ( + local.default_http_probe_port[each.value.protocol] + ) : each.value.port probe_threshold = each.value.probe_threshold interval_in_seconds = each.value.interval_in_seconds request_path = each.value.protocol != "Tcp" ? each.value.request_path : null @@ -175,10 +182,13 @@ resource "azurerm_lb_outbound_rule" "this" { locals { # Map of all frontend IP addresses, public or private. frontend_addresses = { - for k, v in var.frontend_ips : k => try(data.azurerm_public_ip.this[k].ip_address, azurerm_public_ip.this[k].ip_address, v.private_ip_address) + for k, v in var.frontend_ips : k => try( + data.azurerm_public_ip.this[k].ip_address, azurerm_public_ip.this[k].ip_address, v.private_ip_address + ) } - # A map of hashes calculated for each inbound rule. Used to calculate NSG inbound rules priority index if modules is also used to automatically manage NSG rules. + # A map of hashes calculated for each inbound rule. Used to calculate NSG inbound rules priority index if modules is also used + # to automatically manage NSG rules. rules_hash = { for k, v in local.in_rules : k => substr(sha256("${local.frontend_addresses[v.fipkey]}:${v.rule.port}"), 0, 4) @@ -193,7 +203,8 @@ resource "azurerm_network_security_rule" "this" { name = "allow-inbound-ips-${each.key}" network_security_group_name = var.nsg_auto_rules_settings.nsg_name resource_group_name = coalesce(var.nsg_auto_rules_settings.nsg_resource_group_name, var.resource_group_name) - description = "Auto-generated for load balancer ${var.name} port ${each.value.rule.protocol}/${coalesce(each.value.rule.backend_port, each.value.rule.port)}: allowed IPs: ${join(",", var.nsg_auto_rules_settings.source_ips)}" + description = "Auto-generated for load balancer ${var.name} port ${each.value.rule.protocol}/${coalesce( + each.value.rule.backend_port, each.value.rule.port)}: allowed IPs: ${join(",", var.nsg_auto_rules_settings.source_ips)}" direction = "Inbound" access = "Allow" @@ -203,10 +214,12 @@ resource "azurerm_network_security_rule" "this" { source_address_prefixes = var.nsg_auto_rules_settings.source_ips destination_address_prefix = local.frontend_addresses[each.value.fipkey] - # For the priority, we add this %10 so that the numbering would be a bit more sparse instead of sequential. - # This helps tremendously when a mass of indexes shifts by +1 or -1 and prevents problems when we need to shift rules reusing already used priority index. + # For the priority, we add this %10 so that the numbering would be a bit more sparse instead of sequential. This helps + # tremendously when a mass of indexes shifts by +1 or -1 and prevents problems when we need to shift rules reusing already used + # priority index. priority = coalesce( each.value.rule.nsg_priority, - index(keys(local.in_rules), each.key) * 10 + parseint(local.rules_hash[each.key], 16) % 10 + var.nsg_auto_rules_settings.base_priority + index(keys(local.in_rules), each.key) * 10 + parseint( + local.rules_hash[each.key], 16) % 10 + var.nsg_auto_rules_settings.base_priority ) } diff --git a/modules/loadbalancer/outputs.tf b/modules/loadbalancer/outputs.tf index a525587e..fb03b34a 100644 --- a/modules/loadbalancer/outputs.tf +++ b/modules/loadbalancer/outputs.tf @@ -4,7 +4,10 @@ output "backend_pool_id" { } output "frontend_ip_configs" { - description = "Map of IP addresses, one per each entry of `frontend_ips` input. Contains public IP address for the frontends that have it, private IP address otherwise." + description = <<-EOF + Map of IP addresses, one per each entry of `frontend_ips` input. Contains public IP address for the frontends that have it, + private IP address otherwise. + EOF value = local.frontend_addresses } diff --git a/modules/name_templater/main.tf b/modules/name_templater/main.tf index f3d0d6cf..66c3601c 100644 --- a/modules/name_templater/main.tf +++ b/modules/name_templater/main.tf @@ -31,4 +31,4 @@ locals { template_trimmed = trim(local.template_randomized, var.name_template.delimiter) -} \ No newline at end of file +} diff --git a/modules/name_templater/outputs.tf b/modules/name_templater/outputs.tf index 25971ef1..a7964c07 100644 --- a/modules/name_templater/outputs.tf +++ b/modules/name_templater/outputs.tf @@ -1,4 +1,4 @@ output "template" { description = "A template string that can be used with `format` function to generate a resource name." value = local.template_trimmed -} \ No newline at end of file +} diff --git a/modules/ngfw_metrics/main.tf b/modules/ngfw_metrics/main.tf index a41d5191..db2127b4 100644 --- a/modules/ngfw_metrics/main.tf +++ b/modules/ngfw_metrics/main.tf @@ -28,9 +28,13 @@ resource "azurerm_application_insights" "this" { resource_group_name = coalesce(each.value.resource_group_name, var.resource_group_name) location = var.location - workspace_id = var.create_workspace ? azurerm_log_analytics_workspace.this[0].id : data.azurerm_log_analytics_workspace.this[0].id - application_type = "other" - retention_in_days = each.value.metrics_retention_in_days == null ? var.log_analytics_workspace.metrics_retention_in_days : each.value.metrics_retention_in_days + workspace_id = var.create_workspace ? ( + azurerm_log_analytics_workspace.this[0].id + ) : data.azurerm_log_analytics_workspace.this[0].id + application_type = "other" + retention_in_days = each.value.metrics_retention_in_days == null ? ( + var.log_analytics_workspace.metrics_retention_in_days + ) : each.value.metrics_retention_in_days tags = var.tags } diff --git a/modules/panorama/README.md b/modules/panorama/README.md index b3f781c4..df2918d3 100644 --- a/modules/panorama/README.md +++ b/modules/panorama/README.md @@ -45,6 +45,7 @@ Name | Type | Description Name | Description --- | --- `mgmt_ip_address` | Panorama management IP address. If `public_ip` was `true`, it is a public IP address, otherwise a private IP address. + `interfaces` | Map of VM-Series network interfaces. Keys are equal to var.interfaces `name` properties. ## Module's Nameplate diff --git a/modules/panorama/outputs.tf b/modules/panorama/outputs.tf index 03f2ffd5..5655c631 100644 --- a/modules/panorama/outputs.tf +++ b/modules/panorama/outputs.tf @@ -1,5 +1,7 @@ output "mgmt_ip_address" { - description = "Panorama management IP address. If `public_ip` was `true`, it is a public IP address, otherwise a private IP address." + description = <<-EOF + Panorama management IP address. If `public_ip` was `true`, it is a public IP address, otherwise a private IP address. + EOF value = try( azurerm_public_ip.this[var.interfaces[0].name].ip_address, azurerm_network_interface.this[var.interfaces[0].name].ip_configuration[0].private_ip_address diff --git a/modules/virtual_machine/main.tf b/modules/virtual_machine/main.tf index 6ac29247..b6941840 100644 --- a/modules/virtual_machine/main.tf +++ b/modules/virtual_machine/main.tf @@ -34,7 +34,9 @@ resource "azurerm_network_interface" "this" { subnet_id = var.interfaces[count.index].subnet_id private_ip_address_allocation = try(var.interfaces[count.index].private_ip_address, null) != null ? "Static" : "Dynamic" private_ip_address = try(var.interfaces[count.index].private_ip_address, null) - public_ip_address_id = try(azurerm_public_ip.this[count.index].id, var.interfaces[count.index].public_ip_address_id, null) + public_ip_address_id = try( + azurerm_public_ip.this[count.index].id, var.interfaces[count.index].public_ip_address_id, null + ) } } @@ -134,4 +136,4 @@ resource "azurerm_virtual_machine" "this" { type = var.identity_type identity_ids = var.identity_ids } -} \ No newline at end of file +} diff --git a/modules/virtual_machine/outputs.tf b/modules/virtual_machine/outputs.tf index d3bf04b5..6b8a0ec8 100644 --- a/modules/virtual_machine/outputs.tf +++ b/modules/virtual_machine/outputs.tf @@ -4,11 +4,18 @@ output "public_ips" { } output "interfaces" { - description = "List of interfaces. The elements of the list are `azurerm_network_interface` objects. The order is the same as `interfaces` input." + description = <<-EOF + List of interfaces. The elements of the list are `azurerm_network_interface` objects. The order is the same as `interfaces` + input. + EOF value = azurerm_network_interface.this } output "principal_id" { - description = "The oid of Azure Service Principal of the created virtual machine. Usable only if `identity_type` contains SystemAssigned." - value = var.identity_type != null && var.identity_type != "" ? azurerm_virtual_machine.this.identity[0].principal_id : null + description = <<-EOF + The oid of Azure Service Principal of the created virtual machine. Usable only if `identity_type` contains SystemAssigned. + EOF + value = var.identity_type != null && var.identity_type != "" ? ( + azurerm_virtual_machine.this.identity[0].principal_id + ) : null } diff --git a/modules/virtual_machine/variables.tf b/modules/virtual_machine/variables.tf index aa94a11f..e58f92f7 100644 --- a/modules/virtual_machine/variables.tf +++ b/modules/virtual_machine/variables.tf @@ -14,13 +14,19 @@ variable "name" { } variable "enable_zones" { - description = "If false, the input `avzone` is ignored and also all created Public IP addresses default to not to use Availability Zones (the `No-Zone` setting). It is intended for the regions that do not yet support Availability Zones." + description = <<-EOF + If false, the input `avzone` is ignored and also all created Public IP addresses default to not to use Availability Zones (the + `No-Zone` setting). It is intended for the regions that do not yet support Availability Zones. + EOF default = true type = bool } variable "avzone" { - description = "The availability zone to use, for example \"1\", \"2\", \"3\". Ignored if `enable_zones` is false. Conflicts with `avset_id`, in which case use `avzone = null`." + description = <<-EOF + The availability zone to use, for example \"1\", \"2\", \"3\". Ignored if `enable_zones` is false. Conflicts with `avset_id`, + in which case use `avzone = null`. + EOF default = "1" type = string } @@ -49,12 +55,19 @@ variable "interfaces" { - `subnet_id` - (required|string) Identifier of an existing subnet to create interface in. - `private_ip_address` - (optional|string) Static private IP to asssign to the interface. If null, dynamic one is allocated. - `public_ip_address_id` - (optional|string) Identifier of an existing public IP to associate. - - `create_public_ip` - (optional|bool) If true, create a public IP for the interface and ignore the `public_ip_address_id`. Default is false. - - `availability_zone` - (optional|string) Availability zone to create public IP in. If not specified, set based on `avzone` and `enable_zones`. - - `enable_ip_forwarding` - (optional|bool) If true, the network interface will not discard packets sent to an IP address other than the one assigned. If false, the network interface only accepts traffic destined to its IP address. - - `enable_backend_pool` - (optional|bool) If true, associate interface with backend pool specified with `lb_backend_pool_id`. Default is false. - - `lb_backend_pool_id` - (optional|string) Identifier of an existing backend pool to associate interface with. Required if `enable_backend_pool` is true. - - `tags` - (optional|map) Tags to assign to the interface and public IP (if created). Overrides contents of `tags` variable. + - `create_public_ip` - (optional|bool) If true, create a public IP for the interface and ignore the `public_ip_address_id`. + Default is false. + - `availability_zone` - (optional|string) Availability zone to create public IP in. If not specified, set based on `avzone` + and `enable_zones`. + - `enable_ip_forwarding` - (optional|bool) If true, the network interface will not discard packets sent to an IP address other + than the one assigned. If false, the network interface only accepts traffic destined to its IP + address. + - `enable_backend_pool` - (optional|bool) If true, associate interface with backend pool specified with `lb_backend_pool_id`. + Default is false. + - `lb_backend_pool_id` - (optional|string) Identifier of an existing backend pool to associate interface with. Required if + `enable_backend_pool` is true. + - `tags` - (optional|map) Tags to assign to the interface and public IP (if created). Overrides contents of + `tags` variable. Example: @@ -78,24 +91,36 @@ variable "interfaces" { } variable "bootstrap_storage_account" { - description = "Existing storage account object for bootstrapping and for holding small-sized boot diagnostics. Usually the object is passed from a bootstrap module's output." + description = <<-EOF + Existing storage account object for bootstrapping and for holding small-sized boot diagnostics. Usually the object is passed + from a bootstrap module's output. + EOF default = null type = any } variable "bootstrap_share_name" { - description = "Azure File Share holding the bootstrap data. Should reside on `bootstrap_storage_account`. Bootstrapping is omitted if `bootstrap_share_name` is left at null." + description = <<-EOF + Azure File Share holding the bootstrap data. Should reside on `bootstrap_storage_account`. Bootstrapping is omitted if + `bootstrap_share_name` is left at null. + EOF default = null type = string } variable "username" { - description = "Initial administrative username to use for the virtual machine. Mind the [Azure-imposed restrictions](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/faq#what-are-the-username-requirements-when-creating-a-vm)." + description = <<-EOF + Initial administrative username to use for the virtual machine. Mind the + [Azure-imposed restrictions](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/faq#what-are-the-username-requirements-when-creating-a-vm). + EOF type = string } variable "password" { - description = "Initial administrative password to use for the virtual machine. If not defined the `ssh_key` variable must be specified. Mind the [Azure-imposed restrictions](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/faq#what-are-the-password-requirements-when-creating-a-vm)." + description = <<-EOF + Initial administrative password to use for the virtual machine. If not defined the `ssh_key` variable must be specified. Mind + the [Azure-imposed restrictions](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/faq#what-are-the-password-requirements-when-creating-a-vm). + EOF default = null type = string sensitive = true @@ -103,9 +128,11 @@ variable "password" { variable "ssh_keys" { description = <<-EOF - A list of initial administrative SSH public keys that allow key-pair authentication. If not defined the `password` variable must be specified. + A list of initial administrative SSH public keys that allow key-pair authentication. If not defined the `password` variable + must be specified. - This is a list of strings, so each item should be the actual public key value. If you would like to load them from files instead, following method is available: + This is a list of strings, so each item should be the actual public key value. If you would like to load them from files + instead, following method is available: ``` [ @@ -119,7 +146,10 @@ variable "ssh_keys" { } variable "managed_disk_type" { - description = "Type of OS Managed Disk to create for the virtual machine. Possible values are `Standard_LRS`, `StandardSSD_LRS` or `Premium_LRS`. The `Premium_LRS` works only for selected `vm_size` values, details in Azure docs." + description = <<-EOF + Type of OS Managed Disk to create for the virtual machine. Possible values are `Standard_LRS`, `StandardSSD_LRS` or + `Premium_LRS`. The `Premium_LRS` works only for selected `vm_size` values, details in Azure docs. + EOF default = "StandardSSD_LRS" type = string } @@ -137,7 +167,11 @@ variable "vm_size" { } variable "custom_image_id" { - description = "Absolute ID of your own Custom Image to be used for creating a new virtual machine. If set, the `username`, `password`, `img_version`, `img_publisher`, `img_offer`, `img_sku` inputs are all ignored (these are used only for published images, not custom ones)." + description = <<-EOF + Absolute ID of your own Custom Image to be used for creating a new virtual machine. If set, the `username`, `password`, + `img_version`, `img_publisher`, `img_offer`, `img_sku` inputs are all ignored (these are used only for published images, not + custom ones). + EOF default = null type = string } @@ -161,19 +195,27 @@ variable "img_sku" { } variable "img_version" { - description = "Virtual machine image version - list available for a default `img_offer` with `az vm image list -o table --publisher foo --offer bar --all`" + description = <<-EOF + Virtual machine image version - list available for a default `img_offer` with + `az vm image list -o table --publisher foo --offer bar --all`. + EOF default = "latest" type = string } variable "enable_plan" { - description = "Enable usage of the Offer/Plan on Azure Marketplace. Even plan sku \"byol\", which means \"bring your own license\", still requires accepting on the Marketplace (as of 2021). Can be set to `false` when using a custom image." + description = <<-EOF + Enable usage of the Offer/Plan on Azure Marketplace. Even plan sku \"byol\", which means \"bring your own license\", still + requires accepting on the Marketplace (as of 2021). Can be set to `false` when using a custom image. + EOF default = false type = bool } variable "vm_os_simple" { - description = "Allows user to specify a simple name for the OS required and auto populate the publisher, offer, sku parameters" + description = <<-EOF + Allows user to specify a simple name for the OS required and auto populate the publisher, offer, sku parameters. + EOF default = "UbuntuServer" type = string } @@ -181,7 +223,7 @@ variable "vm_os_simple" { variable "standard_os" { description = <<-EOF - Definition of the standard OS with "SimpleName" = "publisher,offer,sku" + Definition of the standard OS with "SimpleName" = "publisher,offer,sku". EOF default = { "UbuntuServer" = "Canonical,UbuntuServer,18.04-LTS" @@ -202,19 +244,23 @@ variable "tags" { } variable "identity_type" { - description = "See the [provider documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine#identity_type)." + description = <<-EOF + See the [provider documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine#identity_type). + EOF default = "SystemAssigned" type = string } variable "identity_ids" { - description = "See the [provider documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine#identity_ids)." + description = <<-EOF + See the [provider documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine#identity_ids). + EOF default = null type = list(string) } variable "accelerated_networking" { - description = "Enable Azure accelerated networking (SR-IOV) for all network interfaces" + description = "Enable Azure accelerated networking (SR-IOV) for all network interfaces." default = true type = bool } diff --git a/modules/virtual_network_gateway/README.md b/modules/virtual_network_gateway/README.md index eba170a6..0872a3a1 100644 --- a/modules/virtual_network_gateway/README.md +++ b/modules/virtual_network_gateway/README.md @@ -406,7 +406,7 @@ Type: string An ID of a Subnet in which the Virtual Network Gateway will be created. -This has to be a dedicated Subnet names `GatewaySubnet`. +This has to be a dedicated Subnet named `GatewaySubnet`. Type: string diff --git a/modules/virtual_network_gateway/outputs.tf b/modules/virtual_network_gateway/outputs.tf index 6e99cbf0..5fc7308e 100644 --- a/modules/virtual_network_gateway/outputs.tf +++ b/modules/virtual_network_gateway/outputs.tf @@ -16,4 +16,4 @@ output "ipsec_policy" { ipsec_integrity = v.ipsec_policy[0].ipsec_integrity pfs_group = v.ipsec_policy[0].pfs_group } if length(v.ipsec_policy) > 0 } -} \ No newline at end of file +} diff --git a/modules/vmseries/README.md b/modules/vmseries/README.md index 5d21468b..9adf39a8 100644 --- a/modules/vmseries/README.md +++ b/modules/vmseries/README.md @@ -58,9 +58,11 @@ Name | Type | Description Name | Description --- | --- `mgmt_ip_address` | VM-Series management IP address. If `create_public_ip` was `true`, it is a public IP address, otherwise a private IP address. + `interfaces` | Map of VM-Series network interfaces. Keys are equal to var.interfaces `name` properties. `principal_id` | The ID of Azure Service Principal of the created VM-Series. Usable only if `identity_type` contains SystemAssigned. + ## Module's Nameplate @@ -206,13 +208,13 @@ List of either required or important properties: - `disk_name` - (`string`, optional, defaults to VM name + `-disk` suffix) name od the OS disk. - `bootstrap_options` - bootstrap options to pass to VM-Series instance. - Proper syntax is a string of semicolon separated properties, for example: + Proper syntax is a string of semicolon separated properties, for example: - ```hcl - bootstrap_options = "type=dhcp-client;panorama-server=1.2.3.4" - ``` + ```hcl + bootstrap_options = "type=dhcp-client;panorama-server=1.2.3.4" + ``` - For more details on bootstrapping [see documentation](https://docs.paloaltonetworks.com/vm-series/10-2/vm-series-deployment/bootstrap-the-vm-series-firewall/create-the-init-cfgtxt-file/init-cfgtxt-file-components). + For more details on bootstrapping [see documentation](https://docs.paloaltonetworks.com/vm-series/10-2/vm-series-deployment/bootstrap-the-vm-series-firewall/create-the-init-cfgtxt-file/init-cfgtxt-file-components). List of other, optional properties: diff --git a/modules/vmseries/main.tf b/modules/vmseries/main.tf index f94640bf..202a44e0 100644 --- a/modules/vmseries/main.tf +++ b/modules/vmseries/main.tf @@ -130,4 +130,4 @@ resource "azurerm_network_interface_backend_address_pool_association" "this" { azurerm_network_interface.this, azurerm_linux_virtual_machine.this ] -} \ No newline at end of file +} diff --git a/modules/vmseries/outputs.tf b/modules/vmseries/outputs.tf index ee9edf3b..c251e634 100644 --- a/modules/vmseries/outputs.tf +++ b/modules/vmseries/outputs.tf @@ -1,5 +1,7 @@ output "mgmt_ip_address" { - description = "VM-Series management IP address. If `create_public_ip` was `true`, it is a public IP address, otherwise a private IP address." + description = <<-EOF + VM-Series management IP address. If `create_public_ip` was `true`, it is a public IP address, otherwise a private IP address. + EOF value = try( azurerm_public_ip.this[var.interfaces[0].name].ip_address, azurerm_network_interface.this[var.interfaces[0].name].ip_configuration[0].private_ip_address @@ -12,6 +14,8 @@ output "interfaces" { } output "principal_id" { - description = "The ID of Azure Service Principal of the created VM-Series. Usable only if `identity_type` contains SystemAssigned." + description = <<-EOF + The ID of Azure Service Principal of the created VM-Series. Usable only if `identity_type` contains SystemAssigned. + EOF value = var.virtual_machine.identity_type != null ? azurerm_linux_virtual_machine.this.identity[0].principal_id : null } diff --git a/modules/vmseries/variables.tf b/modules/vmseries/variables.tf index c18aace5..d57252bf 100644 --- a/modules/vmseries/variables.tf +++ b/modules/vmseries/variables.tf @@ -105,13 +105,13 @@ variable "virtual_machine" { - `disk_name` - (`string`, optional, defaults to VM name + `-disk` suffix) name od the OS disk. - `bootstrap_options` - bootstrap options to pass to VM-Series instance. - Proper syntax is a string of semicolon separated properties, for example: + Proper syntax is a string of semicolon separated properties, for example: - ```hcl - bootstrap_options = "type=dhcp-client;panorama-server=1.2.3.4" - ``` + ```hcl + bootstrap_options = "type=dhcp-client;panorama-server=1.2.3.4" + ``` - For more details on bootstrapping [see documentation](https://docs.paloaltonetworks.com/vm-series/10-2/vm-series-deployment/bootstrap-the-vm-series-firewall/create-the-init-cfgtxt-file/init-cfgtxt-file-components). + For more details on bootstrapping [see documentation](https://docs.paloaltonetworks.com/vm-series/10-2/vm-series-deployment/bootstrap-the-vm-series-firewall/create-the-init-cfgtxt-file/init-cfgtxt-file-components). List of other, optional properties: diff --git a/modules/vmss/README.md b/modules/vmss/README.md index 29e0736f..1a5ed992 100644 --- a/modules/vmss/README.md +++ b/modules/vmss/README.md @@ -61,7 +61,7 @@ Below you can find a simple example deploying a Scale Set w/o autoscaling, using ```hcl module "vmss" { - source = "PaloAltoNetworks/swfw-modules/azurerm//modules/vmss" + source = "PaloAltoNetworks/vmseries-modules/azurerm//modules/vmss" name = "ngfw-vmss" resource_group_name = "hub-rg" diff --git a/modules/vmss/main.tf b/modules/vmss/main.tf index 90bbc696..1d994d27 100644 --- a/modules/vmss/main.tf +++ b/modules/vmss/main.tf @@ -50,16 +50,18 @@ resource "azurerm_linux_virtual_machine_scale_set" "this" { source_image_id = var.image.custom_id os_disk { caching = "ReadWrite" - disk_encryption_set_id = var.virtual_machine_scale_set.disk_encryption_set_id # The Disk Encryption Set must have the Reader Role Assignment scoped on the Key Vault - in addition to an Access Policy to the Key Vault. + disk_encryption_set_id = var.virtual_machine_scale_set.disk_encryption_set_id # the Disk Encryption Set must have the Reader Role Assignment scoped on the Key Vault, in addition to an Access Policy to the Key Vault storage_account_type = var.virtual_machine_scale_set.disk_type } instances = var.autoscaling_configuration.default_count - upgrade_mode = "Manual" # See README for more details no this setting. + upgrade_mode = "Manual" # see README for more details no this setting - custom_data = var.virtual_machine_scale_set.bootstrap_options == null ? null : base64encode(var.virtual_machine_scale_set.bootstrap_options) + custom_data = var.virtual_machine_scale_set.bootstrap_options == null ? ( + null + ) : base64encode(var.virtual_machine_scale_set.bootstrap_options) scale_in { rule = var.autoscaling_configuration.scale_in_policy @@ -230,23 +232,33 @@ resource "azurerm_monitor_autoscale_setting" "this" { for_each = profile.value.scale_rules content { metric_trigger { - metric_name = rule.value.name - metric_resource_id = contains(local.panos_metrics, rule.value.name) ? var.autoscaling_configuration.application_insights_id : azurerm_linux_virtual_machine_scale_set.this.id - metric_namespace = contains(local.panos_metrics, rule.value.name) ? "Azure.ApplicationInsights" : "microsoft.compute/virtualmachinescalesets" - operator = local.operator[rule.value.scale_out_config.operator] + metric_name = rule.value.name + metric_resource_id = contains(local.panos_metrics, rule.value.name) ? ( + var.autoscaling_configuration.application_insights_id + ) : azurerm_linux_virtual_machine_scale_set.this.id + metric_namespace = contains(local.panos_metrics, rule.value.name) ? ( + "Azure.ApplicationInsights" + ) : "microsoft.compute/virtualmachinescalesets" + operator = local.operator[rule.value.scale_out_config.operator] threshold = rule.value.scale_out_config.threshold statistic = rule.value.scale_out_config.grain_aggregation_type time_aggregation = rule.value.scale_out_config.aggregation_window_type - time_grain = module.ptd_time["${profile.value.name}-${replace(lower(rule.value.name), " ", "_")}-scale_out-grain_window_minutes"].dt_string - time_window = module.ptd_time["${profile.value.name}-${replace(lower(rule.value.name), " ", "_")}-scale_out-aggregation_window_minutes"].dt_string + time_grain = module.ptd_time[ + "${profile.value.name}-${replace(lower(rule.value.name), " ", "_")}-scale_out-grain_window_minutes" + ].dt_string + time_window = module.ptd_time[ + "${profile.value.name}-${replace(lower(rule.value.name), " ", "_")}-scale_out-aggregation_window_minutes" + ].dt_string } scale_action { direction = "Increase" value = rule.value.scale_out_config.change_count_by type = "ChangeCount" - cooldown = module.ptd_time["${profile.value.name}-${replace(lower(rule.value.name), " ", "_")}-scale_out-cooldown_window_minutes"].dt_string + cooldown = module.ptd_time[ + "${profile.value.name}-${replace(lower(rule.value.name), " ", "_")}-scale_out-cooldown_window_minutes" + ].dt_string } } } @@ -256,21 +268,33 @@ resource "azurerm_monitor_autoscale_setting" "this" { for_each = profile.value.scale_rules content { metric_trigger { - metric_name = rule.value.name - metric_resource_id = contains(local.panos_metrics, rule.value.name) ? var.autoscaling_configuration.application_insights_id : azurerm_linux_virtual_machine_scale_set.this.id - metric_namespace = contains(local.panos_metrics, rule.value.name) ? "Azure.ApplicationInsights" : "microsoft.compute/virtualmachinescalesets" - operator = local.operator[rule.value.scale_in_config.operator] + metric_name = rule.value.name + metric_resource_id = contains(local.panos_metrics, rule.value.name) ? ( + var.autoscaling_configuration.application_insights_id + ) : azurerm_linux_virtual_machine_scale_set.this.id + metric_namespace = contains(local.panos_metrics, rule.value.name) ? ( + "Azure.ApplicationInsights" + ) : "microsoft.compute/virtualmachinescalesets" + operator = local.operator[rule.value.scale_in_config.operator] threshold = rule.value.scale_in_config.threshold statistic = rule.value.scale_in_config.grain_aggregation_type time_aggregation = rule.value.scale_in_config.aggregation_window_type time_grain = try( - module.ptd_time["${profile.value.name}-${replace(lower(rule.value.name), " ", "_")}-scale_in-grain_window_minutes"].dt_string, - module.ptd_time["${profile.value.name}-${replace(lower(rule.value.name), " ", "_")}-scale_out-grain_window_minutes"].dt_string + module.ptd_time[ + "${profile.value.name}-${replace(lower(rule.value.name), " ", "_")}-scale_in-grain_window_minutes" + ].dt_string, + module.ptd_time[ + "${profile.value.name}-${replace(lower(rule.value.name), " ", "_")}-scale_out-grain_window_minutes" + ].dt_string ) time_window = try( - module.ptd_time["${profile.value.name}-${replace(lower(rule.value.name), " ", "_")}-scale_in-aggregation_window_minutes"].dt_string, - module.ptd_time["${profile.value.name}-${replace(lower(rule.value.name), " ", "_")}-scale_out-aggregation_window_minutes"].dt_string + module.ptd_time[ + "${profile.value.name}-${replace(lower(rule.value.name), " ", "_")}-scale_in-aggregation_window_minutes" + ].dt_string, + module.ptd_time[ + "${profile.value.name}-${replace(lower(rule.value.name), " ", "_")}-scale_out-aggregation_window_minutes" + ].dt_string ) } @@ -278,7 +302,9 @@ resource "azurerm_monitor_autoscale_setting" "this" { direction = "Decrease" value = rule.value.scale_in_config.change_count_by type = "ChangeCount" - cooldown = module.ptd_time["${profile.value.name}-${replace(lower(rule.value.name), " ", "_")}-scale_in-cooldown_window_minutes"].dt_string + cooldown = module.ptd_time[ + "${profile.value.name}-${replace(lower(rule.value.name), " ", "_")}-scale_in-cooldown_window_minutes" + ].dt_string } } } @@ -313,23 +339,36 @@ resource "azurerm_monitor_autoscale_setting" "this" { for_each = var.autoscaling_profiles[0].scale_rules content { metric_trigger { - metric_name = rule.value.name - metric_resource_id = contains(local.panos_metrics, rule.value.name) ? var.autoscaling_configuration.application_insights_id : azurerm_linux_virtual_machine_scale_set.this.id - metric_namespace = contains(local.panos_metrics, rule.value.name) ? "Azure.ApplicationInsights" : "microsoft.compute/virtualmachinescalesets" - operator = local.operator[rule.value.scale_out_config.operator] + metric_name = rule.value.name + metric_resource_id = contains(local.panos_metrics, rule.value.name) ? ( + var.autoscaling_configuration.application_insights_id + ) : azurerm_linux_virtual_machine_scale_set.this.id + metric_namespace = contains(local.panos_metrics, rule.value.name) ? ( + "Azure.ApplicationInsights" + ) : "microsoft.compute/virtualmachinescalesets" + operator = local.operator[rule.value.scale_out_config.operator] threshold = rule.value.scale_out_config.threshold statistic = rule.value.scale_out_config.grain_aggregation_type time_aggregation = rule.value.scale_out_config.aggregation_window_type - time_grain = module.ptd_time["${var.autoscaling_profiles[0].name}-${replace(lower(rule.value.name), " ", "_")}-scale_out-grain_window_minutes"].dt_string - time_window = module.ptd_time["${var.autoscaling_profiles[0].name}-${replace(lower(rule.value.name), " ", "_")}-scale_out-aggregation_window_minutes"].dt_string + time_grain = module.ptd_time[ + "${var.autoscaling_profiles[0].name}-${replace( + lower(rule.value.name), " ", "_")}-scale_out-grain_window_minutes" + ].dt_string + time_window = module.ptd_time[ + "${var.autoscaling_profiles[0].name}-${replace( + lower(rule.value.name), " ", "_")}-scale_out-aggregation_window_minutes" + ].dt_string } scale_action { direction = "Increase" value = rule.value.scale_out_config.change_count_by type = "ChangeCount" - cooldown = module.ptd_time["${var.autoscaling_profiles[0].name}-${replace(lower(rule.value.name), " ", "_")}-scale_out-cooldown_window_minutes"].dt_string + cooldown = module.ptd_time[ + "${var.autoscaling_profiles[0].name}-${replace( + lower(rule.value.name), " ", "_")}-scale_out-cooldown_window_minutes" + ].dt_string } } } @@ -339,21 +378,35 @@ resource "azurerm_monitor_autoscale_setting" "this" { for_each = var.autoscaling_profiles[0].scale_rules content { metric_trigger { - metric_name = rule.value.name - metric_resource_id = contains(local.panos_metrics, rule.value.name) ? var.autoscaling_configuration.application_insights_id : azurerm_linux_virtual_machine_scale_set.this.id - metric_namespace = contains(local.panos_metrics, rule.value.name) ? "Azure.ApplicationInsights" : "microsoft.compute/virtualmachinescalesets" - operator = local.operator[rule.value.scale_in_config.operator] + metric_name = rule.value.name + metric_resource_id = contains(local.panos_metrics, rule.value.name) ? ( + var.autoscaling_configuration.application_insights_id + ) : azurerm_linux_virtual_machine_scale_set.this.id + metric_namespace = contains(local.panos_metrics, rule.value.name) ? ( + "Azure.ApplicationInsights" + ) : "microsoft.compute/virtualmachinescalesets" + operator = local.operator[rule.value.scale_in_config.operator] threshold = rule.value.scale_in_config.threshold statistic = rule.value.scale_in_config.grain_aggregation_type time_aggregation = rule.value.scale_in_config.aggregation_window_type time_grain = try( - module.ptd_time["${var.autoscaling_profiles[0].name}-${replace(lower(rule.value.name), " ", "_")}-scale_in-grain_window_minutes"].dt_string, - module.ptd_time["${var.autoscaling_profiles[0].name}-${replace(lower(rule.value.name), " ", "_")}-scale_out-grain_window_minutes"].dt_string + module.ptd_time[ + "${var.autoscaling_profiles[0].name}-${replace(lower(rule.value.name), " ", "_")}-scale_in-grain_window_minutes" + ].dt_string, + module.ptd_time[ + "${var.autoscaling_profiles[0].name}-${replace(lower(rule.value.name), " ", "_")}-scale_out-grain_window_minutes" + ].dt_string ) time_window = try( - module.ptd_time["${var.autoscaling_profiles[0].name}-${replace(lower(rule.value.name), " ", "_")}-scale_in-aggregation_window_minutes"].dt_string, - module.ptd_time["${var.autoscaling_profiles[0].name}-${replace(lower(rule.value.name), " ", "_")}-scale_out-aggregation_window_minutes"].dt_string + module.ptd_time[ + "${var.autoscaling_profiles[0].name}-${replace( + lower(rule.value.name), " ", "_")}-scale_in-aggregation_window_minutes" + ].dt_string, + module.ptd_time[ + "${var.autoscaling_profiles[0].name}-${replace( + lower(rule.value.name), " ", "_")}-scale_out-aggregation_window_minutes" + ].dt_string ) } @@ -361,7 +414,9 @@ resource "azurerm_monitor_autoscale_setting" "this" { direction = "Decrease" value = rule.value.scale_in_config.change_count_by type = "ChangeCount" - cooldown = module.ptd_time["${var.autoscaling_profiles[0].name}-${replace(lower(rule.value.name), " ", "_")}-scale_in-cooldown_window_minutes"].dt_string + cooldown = module.ptd_time[ + "${var.autoscaling_profiles[0].name}-${replace(lower(rule.value.name), " ", "_")}-scale_in-cooldown_window_minutes" + ].dt_string } } } diff --git a/modules/vmss/outputs.tf b/modules/vmss/outputs.tf index c49ff837..6c5ee30c 100644 --- a/modules/vmss/outputs.tf +++ b/modules/vmss/outputs.tf @@ -12,4 +12,4 @@ output "password" { description = "Firewall admin password" value = local.password sensitive = true -} \ No newline at end of file +} diff --git a/modules/vnet_peering/README.md b/modules/vnet_peering/README.md index 23a16161..a74b57bc 100644 --- a/modules/vnet_peering/README.md +++ b/modules/vnet_peering/README.md @@ -137,5 +137,4 @@ object({ [back to list](#modules-required-inputs) - \ No newline at end of file diff --git a/modules/vnet_peering/main.tf b/modules/vnet_peering/main.tf index d96db6a1..5019560e 100644 --- a/modules/vnet_peering/main.tf +++ b/modules/vnet_peering/main.tf @@ -32,4 +32,4 @@ resource "azurerm_virtual_network_peering" "remote" { allow_forwarded_traffic = var.remote_peer_config.allow_forwarded_traffic allow_gateway_transit = var.remote_peer_config.allow_gateway_transit use_remote_gateways = var.remote_peer_config.use_remote_gateways -} \ No newline at end of file +} diff --git a/modules/vnet_peering/outputs.tf b/modules/vnet_peering/outputs.tf index c43dbab8..4c489d3f 100644 --- a/modules/vnet_peering/outputs.tf +++ b/modules/vnet_peering/outputs.tf @@ -16,4 +16,4 @@ output "local_peering_id" { output "remote_peering_id" { description = "The ID of the remote VNET peering." value = azurerm_virtual_network_peering.remote.id -} \ No newline at end of file +} diff --git a/modules/vnet_peering/variables.tf b/modules/vnet_peering/variables.tf index e0e071a8..80427776 100644 --- a/modules/vnet_peering/variables.tf +++ b/modules/vnet_peering/variables.tf @@ -50,4 +50,4 @@ variable "remote_peer_config" { allow_gateway_transit = optional(bool, false) use_remote_gateways = optional(bool, false) }) -} \ No newline at end of file +} diff --git a/modules/vnet_peering/versions.tf b/modules/vnet_peering/versions.tf index 48646533..8dc5c1eb 100644 --- a/modules/vnet_peering/versions.tf +++ b/modules/vnet_peering/versions.tf @@ -6,4 +6,4 @@ terraform { version = "~> 3.25" } } -} \ No newline at end of file +} From c37c0cc118d9327c8f1c8ed6411961da3b4d9469 Mon Sep 17 00:00:00 2001 From: Adrian Celebanski Date: Tue, 5 Mar 2024 23:22:46 +0100 Subject: [PATCH 4/5] Fix examples README links --- examples/common_vmseries/.header.md | 4 ++-- examples/common_vmseries_and_autoscale/.header.md | 4 ++-- examples/dedicated_vmseries/.header.md | 4 ++-- examples/dedicated_vmseries_and_autoscale/.header.md | 4 ++-- examples/standalone_panorama/.header.md | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/common_vmseries/.header.md b/examples/common_vmseries/.header.md index 4caf7cbe..4de89653 100644 --- a/examples/common_vmseries/.header.md +++ b/examples/common_vmseries/.header.md @@ -16,7 +16,7 @@ common VM-Series for all traffic; for a discussion of other options, please see ## Reference Architecture Design -![simple](https://github.com/PaloAltoNetworks/terraform-azurerm-vmseries-modules/assets/6574404/a7c2452d-f926-49da-bf21-9d840282a0a2) +![simple](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/assets/2110772/aa2ae33a-fb46-4a1c-9811-98ea3b132297) This code implements: @@ -39,7 +39,7 @@ and may present scale limitations with all traffic flowing through a single set that occurs when traffic crosses virtual routers. This option is suitable for proof-of-concepts and smaller scale deployments because the number of firewalls low. However, the technical integration complexity is high. -![Detailed Topology Diagram](https://user-images.githubusercontent.com/2110772/234920647-c7dc77c1-d86c-42ac-ba5a-59a95439ef23.png) +![Detailed Topology Diagram](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/assets/2110772/8e8da6e0-afba-4bb5-b2c7-a95c7250dab3) This reference architecture consists of: diff --git a/examples/common_vmseries_and_autoscale/.header.md b/examples/common_vmseries_and_autoscale/.header.md index ec76e4d7..c001fc82 100644 --- a/examples/common_vmseries_and_autoscale/.header.md +++ b/examples/common_vmseries_and_autoscale/.header.md @@ -22,7 +22,7 @@ but a [dedicated one exists](../standalone\_panorama/README.md). ## Reference Architecture Design -![simple](https://github.com/PaloAltoNetworks/terraform-azurerm-vmseries-modules/assets/6574404/a7c2452d-f926-49da-bf21-9d840282a0a2) +![simple](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/assets/2110772/aa2ae33a-fb46-4a1c-9811-98ea3b132297) This code implements: @@ -47,7 +47,7 @@ and may present scale limitations with all traffic flowing through a single set that occurs when traffic crosses virtual routers. This option is suitable for smaller scale deployments because inbound and outbound traffic flows occur on the same set of firewalls. However, the technical integration complexity is high. -![Common-VMSeries-with-autoscaling](https://github.com/PaloAltoNetworks/terraform-azurerm-vmseries-modules/assets/6500664/b10403f9-795a-4501-a189-3c21d44fc9e7) +![Common-VMSeries-with-autoscaling](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/assets/2110772/7d363d6a-b394-4851-99b9-03ce8abf379a) This reference architecture consists of: diff --git a/examples/dedicated_vmseries/.header.md b/examples/dedicated_vmseries/.header.md index 0b6f6397..0c812dab 100644 --- a/examples/dedicated_vmseries/.header.md +++ b/examples/dedicated_vmseries/.header.md @@ -16,7 +16,7 @@ dedicated-inbound VM-Series; for a discussion of other options, please see the d ## Reference Architecture Design -![simple](https://github.com/PaloAltoNetworks/terraform-azurerm-vmseries-modules/assets/6574404/a7c2452d-f926-49da-bf21-9d840282a0a2) +![simple](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/assets/2110772/aa2ae33a-fb46-4a1c-9811-98ea3b132297) This code implements: @@ -40,7 +40,7 @@ The second set of VM-Series firewalls services all outbound, east-west, and ente choice offers increased scale and operational resiliency and reduces the chances of high bandwidth use from the inbound traffic flows affecting other traffic flows within the deployment. -![Detailed Topology Diagram](https://user-images.githubusercontent.com/2110772/234920818-44e4082d-b445-4ffc-b0cb-174ef1e3c2ae.png) +![Detailed Topology Diagram](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/assets/2110772/3644469f-5f0f-44f9-8990-010c8bcf1cec) This reference architecture consists of: diff --git a/examples/dedicated_vmseries_and_autoscale/.header.md b/examples/dedicated_vmseries_and_autoscale/.header.md index 57d88b65..cb288864 100644 --- a/examples/dedicated_vmseries_and_autoscale/.header.md +++ b/examples/dedicated_vmseries_and_autoscale/.header.md @@ -22,7 +22,7 @@ Panorama instance is not covered in this example, but a [dedicated one exists](. ## Reference Architecture Design -![simple](https://github.com/PaloAltoNetworks/terraform-azurerm-vmseries-modules/assets/6574404/a7c2452d-f926-49da-bf21-9d840282a0a2) +![simple](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/assets/2110772/aa2ae33a-fb46-4a1c-9811-98ea3b132297) This code implements: @@ -48,7 +48,7 @@ set of VM-Series firewalls services all outbound, east-west, and enterprise netw increased scale and operational resiliency and reduces the chances of high bandwidth use from the inbound traffic flows affecting other traffic flows within the deployment. -![Dedicated-VMSeries-with-autoscaling](https://github.com/PaloAltoNetworks/terraform-azurerm-vmseries-modules/assets/2110772/be84d4cb-c4c0-4e62-8bd7-8f5050215876) +![Dedicated-VMSeries-with-autoscaling](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/assets/2110772/757005dc-3e24-4b39-8a69-7b3fbf9819cb) This reference architecture consists of: diff --git a/examples/standalone_panorama/.header.md b/examples/standalone_panorama/.header.md index 39b84dd9..534dd550 100644 --- a/examples/standalone_panorama/.header.md +++ b/examples/standalone_panorama/.header.md @@ -23,7 +23,7 @@ This is a non zonal deployment. The deployed infrastructure consists of: - a Network Security Group to give access to Panorama's public interface - a Panorama appliance with a public IP assigned to the management interface -![standalone-panorama](https://github.com/PaloAltoNetworks/terraform-azurerm-vmseries-modules/assets/2110772/a2394f73-c0a8-4878-8693-825356abbd23) +![standalone-panorama](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/assets/2110772/b2dadd69-f5b5-4ac4-b356-467ef79cbb0b) ## Prerequisites From 1b4fb1a72423136db3e6bd2bfa245ec2fc642364 Mon Sep 17 00:00:00 2001 From: Adrian Celebanski Date: Tue, 5 Mar 2024 23:25:37 +0100 Subject: [PATCH 5/5] Fix examples README links (applied) --- examples/common_vmseries/README.md | 4 ++-- examples/common_vmseries_and_autoscale/README.md | 4 ++-- examples/dedicated_vmseries/README.md | 4 ++-- examples/dedicated_vmseries_and_autoscale/README.md | 4 ++-- examples/standalone_panorama/README.md | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/common_vmseries/README.md b/examples/common_vmseries/README.md index c7128938..3cd21cbe 100644 --- a/examples/common_vmseries/README.md +++ b/examples/common_vmseries/README.md @@ -17,7 +17,7 @@ common VM-Series for all traffic; for a discussion of other options, please see ## Reference Architecture Design -![simple](https://github.com/PaloAltoNetworks/terraform-azurerm-vmseries-modules/assets/6574404/a7c2452d-f926-49da-bf21-9d840282a0a2) +![simple](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/assets/2110772/aa2ae33a-fb46-4a1c-9811-98ea3b132297) This code implements: @@ -40,7 +40,7 @@ and may present scale limitations with all traffic flowing through a single set that occurs when traffic crosses virtual routers. This option is suitable for proof-of-concepts and smaller scale deployments because the number of firewalls low. However, the technical integration complexity is high. -![Detailed Topology Diagram](https://user-images.githubusercontent.com/2110772/234920647-c7dc77c1-d86c-42ac-ba5a-59a95439ef23.png) +![Detailed Topology Diagram](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/assets/2110772/8e8da6e0-afba-4bb5-b2c7-a95c7250dab3) This reference architecture consists of: diff --git a/examples/common_vmseries_and_autoscale/README.md b/examples/common_vmseries_and_autoscale/README.md index 3760e04e..b84228f3 100644 --- a/examples/common_vmseries_and_autoscale/README.md +++ b/examples/common_vmseries_and_autoscale/README.md @@ -23,7 +23,7 @@ but a [dedicated one exists](../standalone\\_panorama/README.md). ## Reference Architecture Design -![simple](https://github.com/PaloAltoNetworks/terraform-azurerm-vmseries-modules/assets/6574404/a7c2452d-f926-49da-bf21-9d840282a0a2) +![simple](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/assets/2110772/aa2ae33a-fb46-4a1c-9811-98ea3b132297) This code implements: @@ -48,7 +48,7 @@ and may present scale limitations with all traffic flowing through a single set that occurs when traffic crosses virtual routers. This option is suitable for smaller scale deployments because inbound and outbound traffic flows occur on the same set of firewalls. However, the technical integration complexity is high. -![Common-VMSeries-with-autoscaling](https://github.com/PaloAltoNetworks/terraform-azurerm-vmseries-modules/assets/6500664/b10403f9-795a-4501-a189-3c21d44fc9e7) +![Common-VMSeries-with-autoscaling](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/assets/2110772/7d363d6a-b394-4851-99b9-03ce8abf379a) This reference architecture consists of: diff --git a/examples/dedicated_vmseries/README.md b/examples/dedicated_vmseries/README.md index 33755031..d7225420 100644 --- a/examples/dedicated_vmseries/README.md +++ b/examples/dedicated_vmseries/README.md @@ -17,7 +17,7 @@ dedicated-inbound VM-Series; for a discussion of other options, please see the d ## Reference Architecture Design -![simple](https://github.com/PaloAltoNetworks/terraform-azurerm-vmseries-modules/assets/6574404/a7c2452d-f926-49da-bf21-9d840282a0a2) +![simple](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/assets/2110772/aa2ae33a-fb46-4a1c-9811-98ea3b132297) This code implements: @@ -41,7 +41,7 @@ The second set of VM-Series firewalls services all outbound, east-west, and ente choice offers increased scale and operational resiliency and reduces the chances of high bandwidth use from the inbound traffic flows affecting other traffic flows within the deployment. -![Detailed Topology Diagram](https://user-images.githubusercontent.com/2110772/234920818-44e4082d-b445-4ffc-b0cb-174ef1e3c2ae.png) +![Detailed Topology Diagram](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/assets/2110772/3644469f-5f0f-44f9-8990-010c8bcf1cec) This reference architecture consists of: diff --git a/examples/dedicated_vmseries_and_autoscale/README.md b/examples/dedicated_vmseries_and_autoscale/README.md index 5b2e2557..a8b36c05 100644 --- a/examples/dedicated_vmseries_and_autoscale/README.md +++ b/examples/dedicated_vmseries_and_autoscale/README.md @@ -23,7 +23,7 @@ Panorama instance is not covered in this example, but a [dedicated one exists](. ## Reference Architecture Design -![simple](https://github.com/PaloAltoNetworks/terraform-azurerm-vmseries-modules/assets/6574404/a7c2452d-f926-49da-bf21-9d840282a0a2) +![simple](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/assets/2110772/aa2ae33a-fb46-4a1c-9811-98ea3b132297) This code implements: @@ -49,7 +49,7 @@ set of VM-Series firewalls services all outbound, east-west, and enterprise netw increased scale and operational resiliency and reduces the chances of high bandwidth use from the inbound traffic flows affecting other traffic flows within the deployment. -![Dedicated-VMSeries-with-autoscaling](https://github.com/PaloAltoNetworks/terraform-azurerm-vmseries-modules/assets/2110772/be84d4cb-c4c0-4e62-8bd7-8f5050215876) +![Dedicated-VMSeries-with-autoscaling](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/assets/2110772/757005dc-3e24-4b39-8a69-7b3fbf9819cb) This reference architecture consists of: diff --git a/examples/standalone_panorama/README.md b/examples/standalone_panorama/README.md index 7b965bb6..09b594c0 100644 --- a/examples/standalone_panorama/README.md +++ b/examples/standalone_panorama/README.md @@ -24,7 +24,7 @@ This is a non zonal deployment. The deployed infrastructure consists of: - a Network Security Group to give access to Panorama's public interface - a Panorama appliance with a public IP assigned to the management interface -![standalone-panorama](https://github.com/PaloAltoNetworks/terraform-azurerm-vmseries-modules/assets/2110772/a2394f73-c0a8-4878-8693-825356abbd23) +![standalone-panorama](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/assets/2110772/b2dadd69-f5b5-4ac4-b356-467ef79cbb0b) ## Prerequisites