diff --git a/products/terraform/docs/swfw/azure/cloudngfw/modules/loadbalancer.md b/products/terraform/docs/swfw/azure/cloudngfw/modules/loadbalancer.md index a7a723d0a..d09d47ef1 100644 --- a/products/terraform/docs/swfw/azure/cloudngfw/modules/loadbalancer.md +++ b/products/terraform/docs/swfw/azure/cloudngfw/modules/loadbalancer.md @@ -111,11 +111,11 @@ module "lbe" { ### Requirements - `terraform`, version: >= 1.5, < 2.0 -- `azurerm`, version: ~> 4.0 +- `azurerm`, version: ~> 4.42 ### Providers -- `azurerm`, version: ~> 4.0 +- `azurerm`, version: ~> 4.42 @@ -344,14 +344,15 @@ map(object({ private_ip_address = optional(string) gwlb_fip_id = optional(string) in_rules = optional(map(object({ - name = string - protocol = string - port = number - backend_port = optional(number) - health_probe_key = optional(string, "default") - floating_ip = optional(bool, true) - session_persistence = optional(string, "Default") - nsg_priority = optional(number) + name = string + protocol = string + port = number + backend_port = optional(number) + health_probe_key = optional(string, "default") + floating_ip = optional(bool, true) + session_persistence = optional(string, "Default") + nsg_priority = optional(number) + idle_timeout_in_minutes = optional(number) })), {}) out_rules = optional(map(object({ name = string diff --git a/products/terraform/docs/swfw/azure/cloudngfw/modules/name_templater.md b/products/terraform/docs/swfw/azure/cloudngfw/modules/name_templater.md index 03829ea7a..c035885eb 100644 --- a/products/terraform/docs/swfw/azure/cloudngfw/modules/name_templater.md +++ b/products/terraform/docs/swfw/azure/cloudngfw/modules/name_templater.md @@ -61,7 +61,7 @@ As you can see: * the `prefix` key is just a placeholder that eventually is replaced with the value of `name_prefix` * the `__random__` string is replaced with a name of a [random pet](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) (in case you need to randomize some name, for testing purposes for example) * the `__default__` string is replaced with a resource abbreviation. - This abbreviations are defined with `var.abbreviations` variable. The module contains basic abbreviations following Microsoft suggestions, but they can be overridden with custom definitions. + This abbreviations are defined with `var.abbreviations` variable. The module contains basic abbreviations following Microsoft suggestions, but they can be overriden with custom definitions. The important part is that the `resource_type` has to match an entry in `abbreviations` variable, otherwise the abbreviation will be replaced with an empty string. To create the actual resource name the following code can be used: @@ -199,4 +199,4 @@ Type: map(string) Default value: `map[application_gw:agw application_insights:appi availability_set:avail bastion:bas data_disk:disk file_share:share load_balancer:lb log_analytics_workspace:log managed_identity:id nat_gw:ng network_interface:nic nsg:nsg nsg_rule:nsgsr os_disk:osdisk public_ip:pip public_ip_prefix:ippre resource_group:rg route_table:rt service_endpoint:se storage_account:st subnet:snet udr:udr virtual_machine:vm virtual_machine_scale_set:vmss virtual_network_gateway:vgw vnet:vnet vnet_peering:peer]` -[back to list](#modules-optional-inputs) +[back to list](#modules-optional-inputs) \ No newline at end of file diff --git a/products/terraform/docs/swfw/azure/cloudngfw/modules/vmseries.md b/products/terraform/docs/swfw/azure/cloudngfw/modules/vmseries.md index ddcd4ff32..dc9d3f1a1 100644 --- a/products/terraform/docs/swfw/azure/cloudngfw/modules/vmseries.md +++ b/products/terraform/docs/swfw/azure/cloudngfw/modules/vmseries.md @@ -212,7 +212,7 @@ Firewall parameters configuration. This map contains basic, as well as some optional Firewall parameters. Both types contain sane defaults. Nevertheless they should be at least reviewed to meet deployment requirements. -List of either required or important properties: +List of either required or important properties: - `size` - (`string`, optional, defaults to `Standard_D3_v2`) Azure VM size (type). Consult the *VM-Series Deployment Guide* as only a few selected sizes are supported. @@ -231,7 +231,7 @@ List of either required or important properties: 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: +List of other, optional properties: - `avset_id` - (`string`, optional, default to `null`) identifier of the Availability Set to use. - `capacity_reservation_group_id` - (`string`, optional, defaults to `null`) specifies the ID of the Capacity Reservation Group @@ -250,7 +250,7 @@ List of other, optional properties: - `identity_type` - (`string`, optional, defaults to `SystemAssigned`) type of Managed Service Identity that should be configured on this VM. Can be one of "SystemAssigned", "UserAssigned" or "SystemAssigned, UserAssigned". -- `identity_ids` - (`list`, optional, defaults to `[]`) a list of User Assigned Managed Identity IDs to be +- `identity_ids` - (`list`, optional, defaults to `[]`) a list of User Assigned Managed Identity IDs to be assigned to this VM. Required only if `identity_type` is not "SystemAssigned". @@ -290,26 +290,30 @@ Interfaces will be attached to VM in the order you define here, therefore: - The first should be the management interface, which does not participate in data filtering. - The remaining ones are the dataplane interfaces. - + Following configuration options are available: - `name` - (`string`, required) the interface name. - `subnet_id` - (`string`, required) ID of an existing subnet to create the interface in. -- `ip_configuration_name` - (`string`, optional, defaults to `primary`) the name of the interface IP configuration. -- `private_ip_address` - (`string`, optional, defaults to `null`) static private IP to assign to the interface. When - skipped Azure will assign one dynamically. Keep in mind that a dynamic IP is guarantied not - to change as long as the VM is running. Any stop/deallocate/restart operation might cause - the IP to change. -- `create_public_ip` - (`bool`, optional, defaults to `false`) if `true`, creates a public IP for the interface. -- `public_ip_name` - (`string`, optional, defaults to `null`) name of the public IP to associate with the - interface. When `create_public_ip` is set to `true` this will become a name of a newly - created Public IP interface. Otherwise this is a name of an existing interfaces that will - be sourced and attached to the interface. Not used when using `public_ip` module. -- `public_ip_resource_group_name` - (`string`, optional, defaults to `var.resource_group_name`) name of a Resource Group that - contains public IP that that will be associated with the interface. Used only when - `create_public_ip` is `false`. -- `public_ip_id` - (`string`, optional, defaults to `null`) ID of the public IP to associate with the - interface. Property is used when public IP is not created or sourced within this module. +- ip_configurations - (`map`, required) A map that contains the IP configurations for the interface. + - `name` - (`string`, optional, defaults to `primary`) the name of the interface IP configuration. + - `primary` - (`bool`, optional, defaults to `true`) sets the current IP configuration as the primary + one. + - `private_ip_address` - (`string`, optional, defaults to `null`) static private IP to assign to the interface. + When skipped Azure will assign one dynamically. Keep in mind that a dynamic IP is + guaranteed not to change as long as the VM is running. Any stop/deallocate/restart + operation might cause the IP to change. + - `create_public_ip` - (`bool`, optional, defaults to `false`) if `true`, creates a public IP for the interface. + **Note!** When you define multiple IP configurations, exactly one must be the primary. + - `public_ip_name` - (`string`, optional, defaults to `null`) name of the public IP to associate with the + interface. When `create_public_ip` is set to `true` this will become a name of a newly + created Public IP interface. Otherwise this is a name of an existing interfaces that will + be sourced and attached to the interface. Not used when using `public_ip` module. + - `public_ip_resource_group_name` - (`string`, optional, defaults to `var.resource_group_name`) name of a Resource Group that + contains public IP that that will be associated with the interface. Used only when + `create_public_ip` is `false`. + - `public_ip_id` - (`string`, optional, defaults to `null`) ID of the public IP to associate with the + interface. Property is used when public IP is not created or sourced within this module. - `attach_to_lb_backend_pool` - (`bool`, optional, defaults to `false`) set to `true` if you would like to associate this interface with a Load Balancer backend pool. - `lb_backend_pool_id` - (`string`, optional, defaults to `null`) ID of an existing backend pool to associate the @@ -327,8 +331,13 @@ Example: { name = "fw-mgmt" subnet_id = azurerm_subnet.my_mgmt_subnet.id - public_ip_name = "fw-mgmt-pip" - create_public_ip = true + ip_configurations = { + primary-ip = { + name = "primary-ip" + primary = true + create_public_ip = true + public_ip_name = "fw-mgmt-pip" + } }, # public interface reusing an existing public IP resource { @@ -336,8 +345,35 @@ Example: subnet_id = azurerm_subnet.my_pub_subnet.id attach_to_lb_backend_pool = true lb_backend_pool_id = module.inbound_lb.backend_pool_id - create_public_ip = false - public_ip_name = "fw-public-pip" + ip_configurations = { + primary-ip = { + name = "primary-ip" + primary = true + create_public_ip = false + public_ip_name = "fw-public-pip" + } + }, + # interface with 2 IP addresses + { + name = "fw-two-ips" + subnet_id = azurerm_subnet.my_pub_subnet.id + attach_to_lb_backend_pool = true + lb_backend_pool_id = module.inbound_lb.backend_pool_id + ip_configurations = { + primary-ip = { + name = "primary-ip" + primary = true + create_public_ip = false + private_ip_address = "10.0.0.5" + public_ip_name = "fw-public-pip" + }, + secondary-ip = { + name = "secondary-ip" + primary = false + create_public_ip = false + private_ip_address = "10.0.0.6" + public_ip_name = "fw-public-pip" + } }, ] ``` @@ -347,18 +383,21 @@ Type: ```hcl list(object({ - name = string - subnet_id = string - ip_configuration_name = optional(string, "primary") - create_public_ip = optional(bool, false) - public_ip_name = optional(string) - public_ip_resource_group_name = optional(string) - public_ip_id = optional(string) - private_ip_address = optional(string) - lb_backend_pool_id = optional(string) - attach_to_lb_backend_pool = optional(bool, false) - appgw_backend_pool_id = optional(string) - attach_to_appgw_backend_pool = optional(bool, false) + name = string + subnet_id = string + ip_configurations = map(object({ + name = optional(string, "primary") + primary = optional(bool, true) + create_public_ip = optional(bool, false) + public_ip_name = optional(string) + public_ip_resource_group_name = optional(string) + public_ip_id = optional(string) + private_ip_address = optional(string) + })) + lb_backend_pool_id = optional(string) + attach_to_lb_backend_pool = optional(bool, false) + appgw_backend_pool_id = optional(string) + attach_to_appgw_backend_pool = optional(bool, false) })) ``` diff --git a/products/terraform/docs/swfw/azure/cloudngfw/modules/vmss.md b/products/terraform/docs/swfw/azure/cloudngfw/modules/vmss.md index 57ee7e8d3..5598afc27 100644 --- a/products/terraform/docs/swfw/azure/cloudngfw/modules/vmss.md +++ b/products/terraform/docs/swfw/azure/cloudngfw/modules/vmss.md @@ -54,6 +54,19 @@ probe would target the management interface which could lead to false-positives. probes, while the data plane remains unconfigured. An easy solution would to bo configure an interface swap, unfortunately this is not available in the Azure VM-Series image yet. +## Orchestration modes + +This module allows you to deploy a Virtual Machine Scale Set (VMSS) with a configurable orchestration mode. The choice of mode is +determined by the `orchestration_type` variable, which provides a single point of control over the VMSS deployment. + +Uniform Orchestration: if `orchestration_type` is set to `Uniform`, traditional uniform orchestration mode is used, where all +VMs are managed as a single entity. + +Flexible Orchestration: if `orchestration_type` is set to `Flexible`, new flexible orchestration mode is used. For this mode to +function correctly, the VMSS's identity type must be set to `UserAssigned` in order to manage individual VMs in the set. + +By default, the Uniform Orchestration is used by the module. + ## Custom Metrics and Autoscaling Firewalls can publish custom metrics (for example `panSessionUtilization`) to Azure Application Insights to improve the @@ -144,6 +157,8 @@ Name | Version | Source | Description - `linux_virtual_machine_scale_set` (managed) - `monitor_autoscale_setting` (managed) +- `orchestrated_virtual_machine_scale_set` (managed) +- `user_assigned_identity` (managed) - `public_ip_prefix` (data) ### Required Inputs @@ -292,22 +307,26 @@ Following configuration options are available: - `name` - (`string`, required) the interface name. - `subnet_id` - (`string`, required) ID of an existing subnet to create the interface in. -- `create_public_ip` - (`bool`, optional, defaults to `false`) if `true`, create a public IP for the interface. -- `pip_domain_name_label` - (`string`, optional, defaults to `null`) the Prefix which should be used for the Domain - Name Label for each Virtual Machine Instance. -- `pip_idle_timeout_in_minutes` - (`number`, optional, defaults to Azure default) the Idle Timeout in minutes for the Public - IP Address, possible values are in the range from 4 to 32. -- `pip_prefix_name` - (`string`, optional) the name of an existing Public IP Address Prefix from where Public IP - Addresses should be allocated. -- `pip_prefix_resource_group_name` - (`string`, optional, defaults to the VMSS's RG) name of a Resource Group hosting an - existing Public IP Prefix resource. -- `pip_prefix_id` - (`string`, optional) you can specify Public IP Prefix ID as an alternative to the - properties above (name and resource group), in case you want to avoid using a data source - block. +- `ip_configurations` - (`map`, required) A map that contains the IP configurations for the interface. + - `name` - (`string`, optional, defaults to `primary`) the name of the interface IP configuration. + - `primary` - (`bool`, optional, defaults to `true`) sets the current IP configuration as the primary + one. + - `create_public_ip` - (`bool`, optional, defaults to `false`) if `true`, create a public IP for the interface. + - `pip_domain_name_label` - (`string`, optional, defaults to `null`) the Prefix which should be used for the Domain + Name Label for each Virtual Machine Instance. + - `pip_idle_timeout_in_minutes` - (`number`, optional, defaults to Azure default) the Idle Timeout in minutes for the + Public IP Address, possible values are in the range from 4 to 32. + - `pip_prefix_name` - (`string`, optional) the name of an existing Public IP Address Prefix from where Public + IP Addresses should be allocated. + - `pip_prefix_resource_group_name` - (`string`, optional, defaults to the VMSS's RG) name of a Resource Group hosting an + existing Public IP Prefix resource. + - `pip_prefix_id` - (`string`, optional) you can specify Public IP Prefix ID as an alternative to the + properties above (name and resource group), in case you want to avoid using a data + source block. - `lb_backend_pool_ids` - (`list`, optional, defaults to `[]`) a list of identifiers of existing Load Balancer - backend pools to associate the interface with. + backend pools to associate the interface with. Only applied to primary IP configuration. - `appgw_backend_pool_ids` - (`list`, optional, defaults to `[]`) a list of identifier of Application Gateway's backend - pools to associate the interface with. + pools to associate the interface with. Only applied to primary IP configuration. Example: @@ -316,16 +335,33 @@ Example: { name = "management" subnet_id = azurerm_subnet.my_mgmt_subnet.id - create_pip = true + ip_configurations = { + primary-ip = { + name = "primary-ip" + primary = true + create_public_ip = true + } }, { name = "private" subnet_id = azurerm_subnet.my_priv_subnet.id + ip_configurations = { + primary-ip = { + name = "primary-ip" + primary = true + create_public_ip = false + } }, { name = "public" subnet_id = azurerm_subnet.my_pub_subnet.id lb_backend_pool_ids = [azurerm_lb_backend_address_pool.lb_backend.id] + ip_configurations = { + primary-ip = { + name = "primary-ip" + primary = true + create_public_ip = true + } } ] ``` @@ -335,16 +371,20 @@ Type: ```hcl list(object({ - name = string - subnet_id = string - create_public_ip = optional(bool, false) - pip_domain_name_label = optional(string) - pip_idle_timeout_in_minutes = optional(number) - pip_prefix_name = optional(string) - pip_prefix_resource_group_name = optional(string) - pip_prefix_id = optional(string) - lb_backend_pool_ids = optional(list(string), []) - appgw_backend_pool_ids = optional(list(string), []) + name = string + subnet_id = string + ip_configurations = map(object({ + name = optional(string, "primary") + primary = optional(bool, true) + create_public_ip = optional(bool, false) + pip_domain_name_label = optional(string) + pip_idle_timeout_in_minutes = optional(number) + pip_prefix_name = optional(string) + pip_prefix_resource_group_name = optional(string) + pip_prefix_id = optional(string) + })) + lb_backend_pool_ids = optional(list(string), []) + appgw_backend_pool_ids = optional(list(string), []) })) ``` @@ -372,14 +412,16 @@ Nevertheless they should be at least reviewed to meet deployment requirements. List of either required or important properties: -- `size` - (`string`, optional, defaults to `Standard_D3_v2`) Azure VM size (type). Consult the *VM-Series - Deployment Guide* as only few selected sizes are supported. The default one is a VM-300 equivalent. -- `zones` - (`list`, optional, defaults to `null`) a list of Availability Zones in which VMs from this Scale Set - will be created. -- `disk_type` - (`string`, optional, defaults to `StandardSSD_LRS`) type of 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) bootstrap options to pass to VM-Series instance. +- `orchestration_type` - (`string`, optional, defaults to `Uniform`) this variable is used to select between the Uniform or + Flexible Scale Set orchestration modes. Possible values are `Uniform` and `Flexible`. +- `size` - (`string`, optional, defaults to `Standard_D3_v2`) Azure VM size (type). Consult the *VM-Series + Deployment Guide* as only few selected sizes are supported. The default one is a VM-300 equivalent. +- `zones` - (`list`, optional, defaults to `null`) a list of Availability Zones in which VMs from this Scale Set + will be created. Zone balance is available from at least 2 zones. +- `disk_type` - (`string`, optional, defaults to `StandardSSD_LRS`) type of 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) bootstrap options to pass to VM-Series instance. Proper syntax is a string of semicolon separated properties, for example: @@ -399,9 +441,11 @@ List of other, optional properties: used to encrypt this VM's disk. - `encryption_at_host_enabled` - (`bool`, optional, defaults to Azure defaults) should all of disks be encrypted by enabling Encryption at Host. -- `overprovision` - (`bool`, optional, defaults to `true`) See the [provider documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/linux_virtual_machine_scale_set). -- `platform_fault_domain_count` - (`number`, optional, defaults to Azure defaults) specifies the number of fault domains that - are used by this Virtual Machine Scale Set. +- `overprovision` - (`bool`, optional, defaults to `true`) controls whether Azure should over-provision Virtual + Machines in the Scale Set for improved deployment time and provisioning success rate. +- `platform_fault_domain_count` - (`number`, optional, defaults to `5`) specifies the number of fault domains that are used + by this Virtual Machine Scale Set. The Flexible orchestration mode requires this parameter + to be set. - `single_placement_group` - (`bool`, optional, defaults to Azure defaults) when `true` this Virtual Machine Scale Set will be limited to a Single Placement Group, which means the number of instances will be capped at 100 Virtual Machines. @@ -412,7 +456,8 @@ List of other, optional properties: files, when skipped a managed Storage Account will be used (preferred). - `identity_type` - (`string`, optional, defaults to `SystemAssigned`) type of Managed Service Identity that should be configured on this VM. Can be one of "SystemAssigned", "UserAssigned" or - "SystemAssigned, UserAssigned". + "SystemAssigned, UserAssigned". For the Flexible orchestration mode this parameter must be + configured to "UserAssigned". - `identity_ids` - (`list`, optional, defaults to `[]`) a list of User Assigned Managed Identity IDs to be assigned to this VM. Required only if `identity_type` is not "SystemAssigned". @@ -421,6 +466,7 @@ Type: ```hcl object({ + orchestration_type = optional(string, "Uniform") size = optional(string, "Standard_D3_v2") bootstrap_options = optional(string) zones = optional(list(string)) @@ -429,7 +475,7 @@ object({ allow_extension_operations = optional(bool, false) encryption_at_host_enabled = optional(bool) overprovision = optional(bool, true) - platform_fault_domain_count = optional(number) + platform_fault_domain_count = optional(number, 5) single_placement_group = optional(bool) capacity_reservation_group_id = optional(string) disk_encryption_set_id = optional(string) diff --git a/products/terraform/docs/swfw/azure/cloudngfw/modules/vwan.md b/products/terraform/docs/swfw/azure/cloudngfw/modules/vwan.md index f709b5e3c..3c9a36248 100644 --- a/products/terraform/docs/swfw/azure/cloudngfw/modules/vwan.md +++ b/products/terraform/docs/swfw/azure/cloudngfw/modules/vwan.md @@ -377,6 +377,8 @@ Each object represents one Connection and supports the following properties: - `name` - (`string`, required) the name of the Connection, must be unique within the Virtual Hub. - `connection_type` - (`string`, required) the type of Connection, use `Vnet` for Virtual Network connections. - `remote_virtual_network_id` - (`string`, optional) the resource ID of a remote Virtual Network. +- `internet_security_enabled` - (`bool`, optional) the parameter that enables internet-bound traffic from the connected VNet + to be routed through the Virtual Hub for inspection by a Network Virtual Appliance (NVA). - `hub_key` - (`string`, required) the key referencing the Virtual Hub. - `vpn_site_key` - (`string`, optional) the key referencing the VPN Site used in this Connection. - `vpn_link` - (`list`, optional, defaults to `[]`) list of VPN link configurations, each object supports the @@ -428,6 +430,7 @@ map(object({ connection_type = string hub_key = string remote_virtual_network_id = optional(string) + internet_security_enabled = optional(bool) vpn_site_key = optional(string) vpn_link = optional(list(object({ vpn_link_name = string diff --git a/products/terraform/docs/swfw/azure/cloudngfw/reference-architectures/cloudngfw_centralized_single_vwan.md b/products/terraform/docs/swfw/azure/cloudngfw/reference-architectures/cloudngfw_centralized_single_vwan.md index 8d445bb08..1d7e08c5e 100644 --- a/products/terraform/docs/swfw/azure/cloudngfw/reference-architectures/cloudngfw_centralized_single_vwan.md +++ b/products/terraform/docs/swfw/azure/cloudngfw/reference-architectures/cloudngfw_centralized_single_vwan.md @@ -816,14 +816,15 @@ map(object({ private_ip_address = optional(string) gwlb_key = optional(string) in_rules = optional(map(object({ - name = string - protocol = string - port = number - backend_port = optional(number) - health_probe_key = optional(string) - floating_ip = optional(bool) - session_persistence = optional(string) - nsg_priority = optional(number) + name = string + protocol = string + port = number + backend_port = optional(number) + health_probe_key = optional(string) + floating_ip = optional(bool) + session_persistence = optional(string) + nsg_priority = optional(number) + idle_timeout_in_minutes = optional(number) })), {}) out_rules = optional(map(object({ name = string diff --git a/products/terraform/docs/swfw/azure/cloudngfw/reference-architectures/cloudngfw_centralized_vnet.md b/products/terraform/docs/swfw/azure/cloudngfw/reference-architectures/cloudngfw_centralized_vnet.md index ee67bfe86..7d0ecadf3 100644 --- a/products/terraform/docs/swfw/azure/cloudngfw/reference-architectures/cloudngfw_centralized_vnet.md +++ b/products/terraform/docs/swfw/azure/cloudngfw/reference-architectures/cloudngfw_centralized_vnet.md @@ -816,14 +816,15 @@ map(object({ private_ip_address = optional(string) gwlb_key = optional(string) in_rules = optional(map(object({ - name = string - protocol = string - port = number - backend_port = optional(number) - health_probe_key = optional(string) - floating_ip = optional(bool) - session_persistence = optional(string) - nsg_priority = optional(number) + name = string + protocol = string + port = number + backend_port = optional(number) + health_probe_key = optional(string) + floating_ip = optional(bool) + session_persistence = optional(string) + nsg_priority = optional(number) + idle_timeout_in_minutes = optional(number) })), {}) out_rules = optional(map(object({ name = string diff --git a/products/terraform/docs/swfw/azure/cloudngfw/reference-architectures/cloudngfw_distributed.md b/products/terraform/docs/swfw/azure/cloudngfw/reference-architectures/cloudngfw_distributed.md index 0c0f04378..1f06881f3 100644 --- a/products/terraform/docs/swfw/azure/cloudngfw/reference-architectures/cloudngfw_distributed.md +++ b/products/terraform/docs/swfw/azure/cloudngfw/reference-architectures/cloudngfw_distributed.md @@ -807,14 +807,15 @@ map(object({ private_ip_address = optional(string) gwlb_key = optional(string) in_rules = optional(map(object({ - name = string - protocol = string - port = number - backend_port = optional(number) - health_probe_key = optional(string) - floating_ip = optional(bool) - session_persistence = optional(string) - nsg_priority = optional(number) + name = string + protocol = string + port = number + backend_port = optional(number) + health_probe_key = optional(string) + floating_ip = optional(bool) + session_persistence = optional(string) + nsg_priority = optional(number) + idle_timeout_in_minutes = optional(number) })), {}) out_rules = optional(map(object({ name = string diff --git a/products/terraform/docs/swfw/azure/vmseries/modules/loadbalancer.md b/products/terraform/docs/swfw/azure/vmseries/modules/loadbalancer.md index a7a723d0a..d09d47ef1 100644 --- a/products/terraform/docs/swfw/azure/vmseries/modules/loadbalancer.md +++ b/products/terraform/docs/swfw/azure/vmseries/modules/loadbalancer.md @@ -111,11 +111,11 @@ module "lbe" { ### Requirements - `terraform`, version: >= 1.5, < 2.0 -- `azurerm`, version: ~> 4.0 +- `azurerm`, version: ~> 4.42 ### Providers -- `azurerm`, version: ~> 4.0 +- `azurerm`, version: ~> 4.42 @@ -344,14 +344,15 @@ map(object({ private_ip_address = optional(string) gwlb_fip_id = optional(string) in_rules = optional(map(object({ - name = string - protocol = string - port = number - backend_port = optional(number) - health_probe_key = optional(string, "default") - floating_ip = optional(bool, true) - session_persistence = optional(string, "Default") - nsg_priority = optional(number) + name = string + protocol = string + port = number + backend_port = optional(number) + health_probe_key = optional(string, "default") + floating_ip = optional(bool, true) + session_persistence = optional(string, "Default") + nsg_priority = optional(number) + idle_timeout_in_minutes = optional(number) })), {}) out_rules = optional(map(object({ name = string diff --git a/products/terraform/docs/swfw/azure/vmseries/modules/vmseries.md b/products/terraform/docs/swfw/azure/vmseries/modules/vmseries.md index ddcd4ff32..dc9d3f1a1 100644 --- a/products/terraform/docs/swfw/azure/vmseries/modules/vmseries.md +++ b/products/terraform/docs/swfw/azure/vmseries/modules/vmseries.md @@ -212,7 +212,7 @@ Firewall parameters configuration. This map contains basic, as well as some optional Firewall parameters. Both types contain sane defaults. Nevertheless they should be at least reviewed to meet deployment requirements. -List of either required or important properties: +List of either required or important properties: - `size` - (`string`, optional, defaults to `Standard_D3_v2`) Azure VM size (type). Consult the *VM-Series Deployment Guide* as only a few selected sizes are supported. @@ -231,7 +231,7 @@ List of either required or important properties: 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: +List of other, optional properties: - `avset_id` - (`string`, optional, default to `null`) identifier of the Availability Set to use. - `capacity_reservation_group_id` - (`string`, optional, defaults to `null`) specifies the ID of the Capacity Reservation Group @@ -250,7 +250,7 @@ List of other, optional properties: - `identity_type` - (`string`, optional, defaults to `SystemAssigned`) type of Managed Service Identity that should be configured on this VM. Can be one of "SystemAssigned", "UserAssigned" or "SystemAssigned, UserAssigned". -- `identity_ids` - (`list`, optional, defaults to `[]`) a list of User Assigned Managed Identity IDs to be +- `identity_ids` - (`list`, optional, defaults to `[]`) a list of User Assigned Managed Identity IDs to be assigned to this VM. Required only if `identity_type` is not "SystemAssigned". @@ -290,26 +290,30 @@ Interfaces will be attached to VM in the order you define here, therefore: - The first should be the management interface, which does not participate in data filtering. - The remaining ones are the dataplane interfaces. - + Following configuration options are available: - `name` - (`string`, required) the interface name. - `subnet_id` - (`string`, required) ID of an existing subnet to create the interface in. -- `ip_configuration_name` - (`string`, optional, defaults to `primary`) the name of the interface IP configuration. -- `private_ip_address` - (`string`, optional, defaults to `null`) static private IP to assign to the interface. When - skipped Azure will assign one dynamically. Keep in mind that a dynamic IP is guarantied not - to change as long as the VM is running. Any stop/deallocate/restart operation might cause - the IP to change. -- `create_public_ip` - (`bool`, optional, defaults to `false`) if `true`, creates a public IP for the interface. -- `public_ip_name` - (`string`, optional, defaults to `null`) name of the public IP to associate with the - interface. When `create_public_ip` is set to `true` this will become a name of a newly - created Public IP interface. Otherwise this is a name of an existing interfaces that will - be sourced and attached to the interface. Not used when using `public_ip` module. -- `public_ip_resource_group_name` - (`string`, optional, defaults to `var.resource_group_name`) name of a Resource Group that - contains public IP that that will be associated with the interface. Used only when - `create_public_ip` is `false`. -- `public_ip_id` - (`string`, optional, defaults to `null`) ID of the public IP to associate with the - interface. Property is used when public IP is not created or sourced within this module. +- ip_configurations - (`map`, required) A map that contains the IP configurations for the interface. + - `name` - (`string`, optional, defaults to `primary`) the name of the interface IP configuration. + - `primary` - (`bool`, optional, defaults to `true`) sets the current IP configuration as the primary + one. + - `private_ip_address` - (`string`, optional, defaults to `null`) static private IP to assign to the interface. + When skipped Azure will assign one dynamically. Keep in mind that a dynamic IP is + guaranteed not to change as long as the VM is running. Any stop/deallocate/restart + operation might cause the IP to change. + - `create_public_ip` - (`bool`, optional, defaults to `false`) if `true`, creates a public IP for the interface. + **Note!** When you define multiple IP configurations, exactly one must be the primary. + - `public_ip_name` - (`string`, optional, defaults to `null`) name of the public IP to associate with the + interface. When `create_public_ip` is set to `true` this will become a name of a newly + created Public IP interface. Otherwise this is a name of an existing interfaces that will + be sourced and attached to the interface. Not used when using `public_ip` module. + - `public_ip_resource_group_name` - (`string`, optional, defaults to `var.resource_group_name`) name of a Resource Group that + contains public IP that that will be associated with the interface. Used only when + `create_public_ip` is `false`. + - `public_ip_id` - (`string`, optional, defaults to `null`) ID of the public IP to associate with the + interface. Property is used when public IP is not created or sourced within this module. - `attach_to_lb_backend_pool` - (`bool`, optional, defaults to `false`) set to `true` if you would like to associate this interface with a Load Balancer backend pool. - `lb_backend_pool_id` - (`string`, optional, defaults to `null`) ID of an existing backend pool to associate the @@ -327,8 +331,13 @@ Example: { name = "fw-mgmt" subnet_id = azurerm_subnet.my_mgmt_subnet.id - public_ip_name = "fw-mgmt-pip" - create_public_ip = true + ip_configurations = { + primary-ip = { + name = "primary-ip" + primary = true + create_public_ip = true + public_ip_name = "fw-mgmt-pip" + } }, # public interface reusing an existing public IP resource { @@ -336,8 +345,35 @@ Example: subnet_id = azurerm_subnet.my_pub_subnet.id attach_to_lb_backend_pool = true lb_backend_pool_id = module.inbound_lb.backend_pool_id - create_public_ip = false - public_ip_name = "fw-public-pip" + ip_configurations = { + primary-ip = { + name = "primary-ip" + primary = true + create_public_ip = false + public_ip_name = "fw-public-pip" + } + }, + # interface with 2 IP addresses + { + name = "fw-two-ips" + subnet_id = azurerm_subnet.my_pub_subnet.id + attach_to_lb_backend_pool = true + lb_backend_pool_id = module.inbound_lb.backend_pool_id + ip_configurations = { + primary-ip = { + name = "primary-ip" + primary = true + create_public_ip = false + private_ip_address = "10.0.0.5" + public_ip_name = "fw-public-pip" + }, + secondary-ip = { + name = "secondary-ip" + primary = false + create_public_ip = false + private_ip_address = "10.0.0.6" + public_ip_name = "fw-public-pip" + } }, ] ``` @@ -347,18 +383,21 @@ Type: ```hcl list(object({ - name = string - subnet_id = string - ip_configuration_name = optional(string, "primary") - create_public_ip = optional(bool, false) - public_ip_name = optional(string) - public_ip_resource_group_name = optional(string) - public_ip_id = optional(string) - private_ip_address = optional(string) - lb_backend_pool_id = optional(string) - attach_to_lb_backend_pool = optional(bool, false) - appgw_backend_pool_id = optional(string) - attach_to_appgw_backend_pool = optional(bool, false) + name = string + subnet_id = string + ip_configurations = map(object({ + name = optional(string, "primary") + primary = optional(bool, true) + create_public_ip = optional(bool, false) + public_ip_name = optional(string) + public_ip_resource_group_name = optional(string) + public_ip_id = optional(string) + private_ip_address = optional(string) + })) + lb_backend_pool_id = optional(string) + attach_to_lb_backend_pool = optional(bool, false) + appgw_backend_pool_id = optional(string) + attach_to_appgw_backend_pool = optional(bool, false) })) ``` diff --git a/products/terraform/docs/swfw/azure/vmseries/modules/vmss.md b/products/terraform/docs/swfw/azure/vmseries/modules/vmss.md index 57ee7e8d3..5598afc27 100644 --- a/products/terraform/docs/swfw/azure/vmseries/modules/vmss.md +++ b/products/terraform/docs/swfw/azure/vmseries/modules/vmss.md @@ -54,6 +54,19 @@ probe would target the management interface which could lead to false-positives. probes, while the data plane remains unconfigured. An easy solution would to bo configure an interface swap, unfortunately this is not available in the Azure VM-Series image yet. +## Orchestration modes + +This module allows you to deploy a Virtual Machine Scale Set (VMSS) with a configurable orchestration mode. The choice of mode is +determined by the `orchestration_type` variable, which provides a single point of control over the VMSS deployment. + +Uniform Orchestration: if `orchestration_type` is set to `Uniform`, traditional uniform orchestration mode is used, where all +VMs are managed as a single entity. + +Flexible Orchestration: if `orchestration_type` is set to `Flexible`, new flexible orchestration mode is used. For this mode to +function correctly, the VMSS's identity type must be set to `UserAssigned` in order to manage individual VMs in the set. + +By default, the Uniform Orchestration is used by the module. + ## Custom Metrics and Autoscaling Firewalls can publish custom metrics (for example `panSessionUtilization`) to Azure Application Insights to improve the @@ -144,6 +157,8 @@ Name | Version | Source | Description - `linux_virtual_machine_scale_set` (managed) - `monitor_autoscale_setting` (managed) +- `orchestrated_virtual_machine_scale_set` (managed) +- `user_assigned_identity` (managed) - `public_ip_prefix` (data) ### Required Inputs @@ -292,22 +307,26 @@ Following configuration options are available: - `name` - (`string`, required) the interface name. - `subnet_id` - (`string`, required) ID of an existing subnet to create the interface in. -- `create_public_ip` - (`bool`, optional, defaults to `false`) if `true`, create a public IP for the interface. -- `pip_domain_name_label` - (`string`, optional, defaults to `null`) the Prefix which should be used for the Domain - Name Label for each Virtual Machine Instance. -- `pip_idle_timeout_in_minutes` - (`number`, optional, defaults to Azure default) the Idle Timeout in minutes for the Public - IP Address, possible values are in the range from 4 to 32. -- `pip_prefix_name` - (`string`, optional) the name of an existing Public IP Address Prefix from where Public IP - Addresses should be allocated. -- `pip_prefix_resource_group_name` - (`string`, optional, defaults to the VMSS's RG) name of a Resource Group hosting an - existing Public IP Prefix resource. -- `pip_prefix_id` - (`string`, optional) you can specify Public IP Prefix ID as an alternative to the - properties above (name and resource group), in case you want to avoid using a data source - block. +- `ip_configurations` - (`map`, required) A map that contains the IP configurations for the interface. + - `name` - (`string`, optional, defaults to `primary`) the name of the interface IP configuration. + - `primary` - (`bool`, optional, defaults to `true`) sets the current IP configuration as the primary + one. + - `create_public_ip` - (`bool`, optional, defaults to `false`) if `true`, create a public IP for the interface. + - `pip_domain_name_label` - (`string`, optional, defaults to `null`) the Prefix which should be used for the Domain + Name Label for each Virtual Machine Instance. + - `pip_idle_timeout_in_minutes` - (`number`, optional, defaults to Azure default) the Idle Timeout in minutes for the + Public IP Address, possible values are in the range from 4 to 32. + - `pip_prefix_name` - (`string`, optional) the name of an existing Public IP Address Prefix from where Public + IP Addresses should be allocated. + - `pip_prefix_resource_group_name` - (`string`, optional, defaults to the VMSS's RG) name of a Resource Group hosting an + existing Public IP Prefix resource. + - `pip_prefix_id` - (`string`, optional) you can specify Public IP Prefix ID as an alternative to the + properties above (name and resource group), in case you want to avoid using a data + source block. - `lb_backend_pool_ids` - (`list`, optional, defaults to `[]`) a list of identifiers of existing Load Balancer - backend pools to associate the interface with. + backend pools to associate the interface with. Only applied to primary IP configuration. - `appgw_backend_pool_ids` - (`list`, optional, defaults to `[]`) a list of identifier of Application Gateway's backend - pools to associate the interface with. + pools to associate the interface with. Only applied to primary IP configuration. Example: @@ -316,16 +335,33 @@ Example: { name = "management" subnet_id = azurerm_subnet.my_mgmt_subnet.id - create_pip = true + ip_configurations = { + primary-ip = { + name = "primary-ip" + primary = true + create_public_ip = true + } }, { name = "private" subnet_id = azurerm_subnet.my_priv_subnet.id + ip_configurations = { + primary-ip = { + name = "primary-ip" + primary = true + create_public_ip = false + } }, { name = "public" subnet_id = azurerm_subnet.my_pub_subnet.id lb_backend_pool_ids = [azurerm_lb_backend_address_pool.lb_backend.id] + ip_configurations = { + primary-ip = { + name = "primary-ip" + primary = true + create_public_ip = true + } } ] ``` @@ -335,16 +371,20 @@ Type: ```hcl list(object({ - name = string - subnet_id = string - create_public_ip = optional(bool, false) - pip_domain_name_label = optional(string) - pip_idle_timeout_in_minutes = optional(number) - pip_prefix_name = optional(string) - pip_prefix_resource_group_name = optional(string) - pip_prefix_id = optional(string) - lb_backend_pool_ids = optional(list(string), []) - appgw_backend_pool_ids = optional(list(string), []) + name = string + subnet_id = string + ip_configurations = map(object({ + name = optional(string, "primary") + primary = optional(bool, true) + create_public_ip = optional(bool, false) + pip_domain_name_label = optional(string) + pip_idle_timeout_in_minutes = optional(number) + pip_prefix_name = optional(string) + pip_prefix_resource_group_name = optional(string) + pip_prefix_id = optional(string) + })) + lb_backend_pool_ids = optional(list(string), []) + appgw_backend_pool_ids = optional(list(string), []) })) ``` @@ -372,14 +412,16 @@ Nevertheless they should be at least reviewed to meet deployment requirements. List of either required or important properties: -- `size` - (`string`, optional, defaults to `Standard_D3_v2`) Azure VM size (type). Consult the *VM-Series - Deployment Guide* as only few selected sizes are supported. The default one is a VM-300 equivalent. -- `zones` - (`list`, optional, defaults to `null`) a list of Availability Zones in which VMs from this Scale Set - will be created. -- `disk_type` - (`string`, optional, defaults to `StandardSSD_LRS`) type of 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) bootstrap options to pass to VM-Series instance. +- `orchestration_type` - (`string`, optional, defaults to `Uniform`) this variable is used to select between the Uniform or + Flexible Scale Set orchestration modes. Possible values are `Uniform` and `Flexible`. +- `size` - (`string`, optional, defaults to `Standard_D3_v2`) Azure VM size (type). Consult the *VM-Series + Deployment Guide* as only few selected sizes are supported. The default one is a VM-300 equivalent. +- `zones` - (`list`, optional, defaults to `null`) a list of Availability Zones in which VMs from this Scale Set + will be created. Zone balance is available from at least 2 zones. +- `disk_type` - (`string`, optional, defaults to `StandardSSD_LRS`) type of 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) bootstrap options to pass to VM-Series instance. Proper syntax is a string of semicolon separated properties, for example: @@ -399,9 +441,11 @@ List of other, optional properties: used to encrypt this VM's disk. - `encryption_at_host_enabled` - (`bool`, optional, defaults to Azure defaults) should all of disks be encrypted by enabling Encryption at Host. -- `overprovision` - (`bool`, optional, defaults to `true`) See the [provider documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/linux_virtual_machine_scale_set). -- `platform_fault_domain_count` - (`number`, optional, defaults to Azure defaults) specifies the number of fault domains that - are used by this Virtual Machine Scale Set. +- `overprovision` - (`bool`, optional, defaults to `true`) controls whether Azure should over-provision Virtual + Machines in the Scale Set for improved deployment time and provisioning success rate. +- `platform_fault_domain_count` - (`number`, optional, defaults to `5`) specifies the number of fault domains that are used + by this Virtual Machine Scale Set. The Flexible orchestration mode requires this parameter + to be set. - `single_placement_group` - (`bool`, optional, defaults to Azure defaults) when `true` this Virtual Machine Scale Set will be limited to a Single Placement Group, which means the number of instances will be capped at 100 Virtual Machines. @@ -412,7 +456,8 @@ List of other, optional properties: files, when skipped a managed Storage Account will be used (preferred). - `identity_type` - (`string`, optional, defaults to `SystemAssigned`) type of Managed Service Identity that should be configured on this VM. Can be one of "SystemAssigned", "UserAssigned" or - "SystemAssigned, UserAssigned". + "SystemAssigned, UserAssigned". For the Flexible orchestration mode this parameter must be + configured to "UserAssigned". - `identity_ids` - (`list`, optional, defaults to `[]`) a list of User Assigned Managed Identity IDs to be assigned to this VM. Required only if `identity_type` is not "SystemAssigned". @@ -421,6 +466,7 @@ Type: ```hcl object({ + orchestration_type = optional(string, "Uniform") size = optional(string, "Standard_D3_v2") bootstrap_options = optional(string) zones = optional(list(string)) @@ -429,7 +475,7 @@ object({ allow_extension_operations = optional(bool, false) encryption_at_host_enabled = optional(bool) overprovision = optional(bool, true) - platform_fault_domain_count = optional(number) + platform_fault_domain_count = optional(number, 5) single_placement_group = optional(bool) capacity_reservation_group_id = optional(string) disk_encryption_set_id = optional(string) diff --git a/products/terraform/docs/swfw/azure/vmseries/modules/vwan.md b/products/terraform/docs/swfw/azure/vmseries/modules/vwan.md index f709b5e3c..3c9a36248 100644 --- a/products/terraform/docs/swfw/azure/vmseries/modules/vwan.md +++ b/products/terraform/docs/swfw/azure/vmseries/modules/vwan.md @@ -377,6 +377,8 @@ Each object represents one Connection and supports the following properties: - `name` - (`string`, required) the name of the Connection, must be unique within the Virtual Hub. - `connection_type` - (`string`, required) the type of Connection, use `Vnet` for Virtual Network connections. - `remote_virtual_network_id` - (`string`, optional) the resource ID of a remote Virtual Network. +- `internet_security_enabled` - (`bool`, optional) the parameter that enables internet-bound traffic from the connected VNet + to be routed through the Virtual Hub for inspection by a Network Virtual Appliance (NVA). - `hub_key` - (`string`, required) the key referencing the Virtual Hub. - `vpn_site_key` - (`string`, optional) the key referencing the VPN Site used in this Connection. - `vpn_link` - (`list`, optional, defaults to `[]`) list of VPN link configurations, each object supports the @@ -428,6 +430,7 @@ map(object({ connection_type = string hub_key = string remote_virtual_network_id = optional(string) + internet_security_enabled = optional(bool) vpn_site_key = optional(string) vpn_link = optional(list(object({ vpn_link_name = string diff --git a/products/terraform/docs/swfw/azure/vmseries/reference-architectures/2ef99143-3dcf-4113-814d-aedca8fcccf3.png b/products/terraform/docs/swfw/azure/vmseries/reference-architectures/2ef99143-3dcf-4113-814d-aedca8fcccf3.png new file mode 100644 index 000000000..2edea159e Binary files /dev/null and b/products/terraform/docs/swfw/azure/vmseries/reference-architectures/2ef99143-3dcf-4113-814d-aedca8fcccf3.png differ diff --git a/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_common.md b/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_common.md index 6f0c7a98d..61d0e9d20 100644 --- a/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_common.md +++ b/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_common.md @@ -657,14 +657,15 @@ map(object({ private_ip_address = optional(string) gwlb_key = optional(string) in_rules = optional(map(object({ - name = string - protocol = string - port = number - backend_port = optional(number) - health_probe_key = optional(string) - floating_ip = optional(bool) - session_persistence = optional(string) - nsg_priority = optional(number) + name = string + protocol = string + port = number + backend_port = optional(number) + health_probe_key = optional(string) + floating_ip = optional(bool) + session_persistence = optional(string) + nsg_priority = optional(number) + idle_timeout_in_minutes = optional(number) })), {}) out_rules = optional(map(object({ name = string @@ -1026,16 +1027,16 @@ Default value: `map[]` #### vmseries_universal -A map defining common settings for all created VM-Series instances. - +A map defining common settings for all created VM-Series instances. + It duplicates popular properties from `vmseries` variable, specifically `vmseries.image` and `vmseries.virtual_machine` maps. However, if values are set in those maps, they still take precedence over the ones set within this variable. As a result, all universal properties can be overriden on a per-VM basis. Following properties are supported: -- `use_airs` - (`bool`, optional, defaults to `false`) when set to `true`, the AI Runtime Security VM image is used - instead of the one passed to the module and version for `airs-flex` offer must be provided. +- `use_airs` - (`bool`, optional, defaults to `false`) when set to `true`, the AI Runtime Security VM image is used + instead of the one passed to the module and version for `airs-flex` offer must be provided. - `version` - (`string`, optional) describes the PAN-OS image version from Azure Marketplace. - `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. @@ -1122,7 +1123,7 @@ The most basic properties are as follows: For all properties and their default values see [module's documentation](../../modules/vmseries#authentication). - `image` - (`map`, optional) properties defining a base image used by the deployed VM. The `image` property is - required (if no common properties were set within `vmseries_universal` variable) but there are only 2 + required (if no common properties were set within `vmseries_universal` variable) 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. @@ -1199,7 +1200,15 @@ The most basic properties are as follows: - `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. + - `ip_configurations` - (`map`, required) A map that contains the IP configurations for the interface. + - `name` - (`string`, optional, defaults to `primary`) the name of the interface IP configuration. + - `primary` - (`bool`, optional, defaults to `true`) sets the current IP configuration as the primary one. + **Note!** When you define multiple IP configurations, exactly one must be the primary. + - `private_ip_address` - (`string`, optional, defaults to `null`) static private IP to assign to the interface. When + skipped Azure will assign one dynamically. Keep in mind that a dynamic IP is guarantied not + to change as long as the VM is running. Any stop/deallocate/restart operation might cause + the IP to change. + - `create_public_ip` - (`bool`, optional, defaults to `false`) if `true`, creates a public IP for the 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. @@ -1288,17 +1297,20 @@ map(object({ identity_ids = optional(list(string)) }) interfaces = list(object({ - name = string - subnet_key = string - ip_configuration_name = optional(string) - create_public_ip = optional(bool, false) - public_ip_name = optional(string) - public_ip_resource_group_name = optional(string) - public_ip_key = optional(string) - private_ip_address = optional(string) - load_balancer_key = optional(string) - application_gateway_key = optional(string) - appgw_backend_pool_id = optional(string) + name = string + subnet_key = string + ip_configurations = map(object({ + name = optional(string) + primary = optional(bool, true) + create_public_ip = optional(bool, false) + public_ip_name = optional(string) + public_ip_resource_group_name = optional(string) + public_ip_key = optional(string) + private_ip_address = optional(string) + })) + load_balancer_key = optional(string) + application_gateway_key = optional(string) + appgw_backend_pool_id = optional(string) })) })) ``` @@ -1335,12 +1347,12 @@ Following properties are supported: [VNET module documentation](../../modules/vnet#route_tables). - `subnets` - (`map`, optional) map of Subnets to create or source, for details see [VNET module documentation](../../modules/vnet#subnets). - - `local_peer_config` - (`map`, optional) a map that contains local peer configuration parameters. This value allows to - set `allow_virtual_network_access`, `allow_forwarded_traffic`, `allow_gateway_transit` and - `use_remote_gateways` parameters on the local VNet peering. + - `local_peer_config` - (`map`, optional) a map that contains local peer configuration parameters. This value allows to + set `allow_virtual_network_access`, `allow_forwarded_traffic`, `allow_gateway_transit` and + `use_remote_gateways` parameters on the local VNet peering. - `remote_peer_config` - (`map`, optional) a map that contains remote peer configuration parameters. This value allows to - set `allow_virtual_network_access`, `allow_forwarded_traffic`, `allow_gateway_transit` and - `use_remote_gateways` parameters on the remote VNet peering. + set `allow_virtual_network_access`, `allow_forwarded_traffic`, `allow_gateway_transit` and + `use_remote_gateways` parameters on the remote VNet peering. For all properties and their default values see [module's documentation](../../modules/test_infrastructure#vnets). @@ -1504,14 +1516,15 @@ map(object({ private_ip_address = optional(string) gwlb_key = optional(string) in_rules = optional(map(object({ - name = string - protocol = string - port = number - backend_port = optional(number) - health_probe_key = optional(string) - floating_ip = optional(bool) - session_persistence = optional(string) - nsg_priority = optional(number) + name = string + protocol = string + port = number + backend_port = optional(number) + health_probe_key = optional(string) + floating_ip = optional(bool) + session_persistence = optional(string) + nsg_priority = optional(number) + idle_timeout_in_minutes = optional(number) })), {}) out_rules = optional(map(object({ name = string diff --git a/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_common_autoscale.md b/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_common_autoscale.md index ce164a1b4..bc7156708 100644 --- a/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_common_autoscale.md +++ b/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_common_autoscale.md @@ -684,14 +684,15 @@ map(object({ private_ip_address = optional(string) gwlb_key = optional(string) in_rules = optional(map(object({ - name = string - protocol = string - port = number - backend_port = optional(number) - health_probe_key = optional(string) - floating_ip = optional(bool) - session_persistence = optional(string) - nsg_priority = optional(number) + name = string + protocol = string + port = number + backend_port = optional(number) + health_probe_key = optional(string) + floating_ip = optional(bool) + session_persistence = optional(string) + nsg_priority = optional(number) + idle_timeout_in_minutes = optional(number) })), {}) out_rules = optional(map(object({ name = string @@ -1209,7 +1210,10 @@ The basic Scale Set configuration properties are as follows: - `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. + - `ip_configurations` - (`map`, required) A map that contains the IP configurations for the interface. + - `name` - (`string`, optional, defaults to `primary`) the name of the interface IP configuration. + - `primary` - (`bool`, optional, defaults to `true`) sets the current IP configuration as the primary one. + - `create_public_ip` - (`bool`, optional, defaults to `false`) if `true`, create a public IP for the 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. @@ -1246,9 +1250,10 @@ map(object({ custom_id = optional(string) })) virtual_machine_scale_set = optional(object({ - size = optional(string) - zones = optional(list(string)) - disk_type = optional(string) + orchestration_type = optional(string) + size = optional(string) + zones = optional(list(string)) + disk_type = optional(string) bootstrap_options = optional(object({ type = optional(string) ip-address = optional(string) @@ -1308,16 +1313,20 @@ map(object({ webhooks_uris = optional(map(string), {}) }), {}) interfaces = list(object({ - name = string - subnet_key = string - create_public_ip = optional(bool) - pip_domain_name_label = optional(string) - pip_idle_timeout_in_minutes = optional(number) - pip_prefix_name = optional(string) - pip_prefix_resource_group_name = optional(string) - pip_prefix_id = optional(string) - load_balancer_key = optional(string) - application_gateway_key = optional(string) + name = string + subnet_key = string + ip_configurations = optional(map(object({ + name = optional(string) + primary = optional(bool, true) + create_public_ip = optional(bool, false) + pip_domain_name_label = optional(string) + pip_idle_timeout_in_minutes = optional(number) + pip_prefix_name = optional(string) + pip_prefix_resource_group_name = optional(string) + pip_prefix_id = optional(string) + }))) + load_balancer_key = optional(string) + application_gateway_key = optional(string) })) autoscaling_profiles = optional(list(object({ name = string @@ -1558,14 +1567,15 @@ map(object({ private_ip_address = optional(string) gwlb_key = optional(string) in_rules = optional(map(object({ - name = string - protocol = string - port = number - backend_port = optional(number) - health_probe_key = optional(string) - floating_ip = optional(bool) - session_persistence = optional(string) - nsg_priority = optional(number) + name = string + protocol = string + port = number + backend_port = optional(number) + health_probe_key = optional(string) + floating_ip = optional(bool) + session_persistence = optional(string) + nsg_priority = optional(number) + idle_timeout_in_minutes = optional(number) })), {}) out_rules = optional(map(object({ name = string diff --git a/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_dedicated.md b/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_dedicated.md index fb7bdafde..560204d31 100644 --- a/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_dedicated.md +++ b/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_dedicated.md @@ -661,14 +661,15 @@ map(object({ private_ip_address = optional(string) gwlb_key = optional(string) in_rules = optional(map(object({ - name = string - protocol = string - port = number - backend_port = optional(number) - health_probe_key = optional(string) - floating_ip = optional(bool) - session_persistence = optional(string) - nsg_priority = optional(number) + name = string + protocol = string + port = number + backend_port = optional(number) + health_probe_key = optional(string) + floating_ip = optional(bool) + session_persistence = optional(string) + nsg_priority = optional(number) + idle_timeout_in_minutes = optional(number) })), {}) out_rules = optional(map(object({ name = string @@ -1030,16 +1031,16 @@ Default value: `map[]` #### vmseries_universal -A map defining common settings for all created VM-Series instances. - +A map defining common settings for all created VM-Series instances. + It duplicates popular properties from `vmseries` variable, specifically `vmseries.image` and `vmseries.virtual_machine` maps. However, if values are set in those maps, they still take precedence over the ones set within this variable. As a result, all universal properties can be overriden on a per-VM basis. Following properties are supported: -- `use_airs` - (`bool`, optional, defaults to `false`) when set to `true`, the AI Runtime Security VM image is used - instead of the one passed to the module and version for `airs-flex` offer must be provided. +- `use_airs` - (`bool`, optional, defaults to `false`) when set to `true`, the AI Runtime Security VM image is used + instead of the one passed to the module and version for `airs-flex` offer must be provided. - `version` - (`string`, optional) describes the PAN-OS image version from Azure Marketplace. - `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. @@ -1126,7 +1127,7 @@ The most basic properties are as follows: For all properties and their default values see [module's documentation](../../modules/vmseries#authentication). - `image` - (`map`, optional) properties defining a base image used by the deployed VM. The `image` property is - required (if no common properties were set within `vmseries_universal` variable) but there are only 2 + required (if no common properties were set within `vmseries_universal` variable) 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. @@ -1203,7 +1204,15 @@ The most basic properties are as follows: - `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. + - `ip_configurations` - (`map`, required) A map that contains the IP configurations for the interface. + - `name` - (`string`, optional, defaults to `primary`) the name of the interface IP configuration. + - `primary` - (`bool`, optional, defaults to `true`) sets the current IP configuration as the primary one. + **Note!** When you define multiple IP configurations, exactly one must be the primary. + - `private_ip_address` - (`string`, optional, defaults to `null`) static private IP to assign to the interface. When + skipped Azure will assign one dynamically. Keep in mind that a dynamic IP is guarantied not + to change as long as the VM is running. Any stop/deallocate/restart operation might cause + the IP to change. + - `create_public_ip` - (`bool`, optional, defaults to `false`) if `true`, creates a public IP for the 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. @@ -1292,17 +1301,20 @@ map(object({ identity_ids = optional(list(string)) }) interfaces = list(object({ - name = string - subnet_key = string - ip_configuration_name = optional(string) - create_public_ip = optional(bool, false) - public_ip_name = optional(string) - public_ip_resource_group_name = optional(string) - public_ip_key = optional(string) - private_ip_address = optional(string) - load_balancer_key = optional(string) - application_gateway_key = optional(string) - appgw_backend_pool_id = optional(string) + name = string + subnet_key = string + ip_configurations = map(object({ + name = optional(string) + primary = optional(bool, true) + create_public_ip = optional(bool, false) + public_ip_name = optional(string) + public_ip_resource_group_name = optional(string) + public_ip_key = optional(string) + private_ip_address = optional(string) + })) + load_balancer_key = optional(string) + application_gateway_key = optional(string) + appgw_backend_pool_id = optional(string) })) })) ``` @@ -1339,12 +1351,12 @@ Following properties are supported: [VNET module documentation](../../modules/vnet#route_tables). - `subnets` - (`map`, optional) map of Subnets to create or source, for details see [VNET module documentation](../../modules/vnet#subnets). - - `local_peer_config` - (`map`, optional) a map that contains local peer configuration parameters. This value allows to - set `allow_virtual_network_access`, `allow_forwarded_traffic`, `allow_gateway_transit` and - `use_remote_gateways` parameters on the local VNet peering. + - `local_peer_config` - (`map`, optional) a map that contains local peer configuration parameters. This value allows to + set `allow_virtual_network_access`, `allow_forwarded_traffic`, `allow_gateway_transit` and + `use_remote_gateways` parameters on the local VNet peering. - `remote_peer_config` - (`map`, optional) a map that contains remote peer configuration parameters. This value allows to - set `allow_virtual_network_access`, `allow_forwarded_traffic`, `allow_gateway_transit` and - `use_remote_gateways` parameters on the remote VNet peering. + set `allow_virtual_network_access`, `allow_forwarded_traffic`, `allow_gateway_transit` and + `use_remote_gateways` parameters on the remote VNet peering. For all properties and their default values see [module's documentation](../../modules/test_infrastructure#vnets). @@ -1508,14 +1520,15 @@ map(object({ private_ip_address = optional(string) gwlb_key = optional(string) in_rules = optional(map(object({ - name = string - protocol = string - port = number - backend_port = optional(number) - health_probe_key = optional(string) - floating_ip = optional(bool) - session_persistence = optional(string) - nsg_priority = optional(number) + name = string + protocol = string + port = number + backend_port = optional(number) + health_probe_key = optional(string) + floating_ip = optional(bool) + session_persistence = optional(string) + nsg_priority = optional(number) + idle_timeout_in_minutes = optional(number) })), {}) out_rules = optional(map(object({ name = string diff --git a/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_dedicated_autoscale.md b/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_dedicated_autoscale.md index 4f4df4031..b3df58307 100644 --- a/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_dedicated_autoscale.md +++ b/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_dedicated_autoscale.md @@ -678,14 +678,15 @@ map(object({ private_ip_address = optional(string) gwlb_key = optional(string) in_rules = optional(map(object({ - name = string - protocol = string - port = number - backend_port = optional(number) - health_probe_key = optional(string) - floating_ip = optional(bool) - session_persistence = optional(string) - nsg_priority = optional(number) + name = string + protocol = string + port = number + backend_port = optional(number) + health_probe_key = optional(string) + floating_ip = optional(bool) + session_persistence = optional(string) + nsg_priority = optional(number) + idle_timeout_in_minutes = optional(number) })), {}) out_rules = optional(map(object({ name = string @@ -1026,7 +1027,7 @@ set within this variable. As a result, all universal properties can be overriden Following properties are supported: - `use_airs` - (`bool`, optional, defaults to `false`) when set to `true`, the AI Runtime Security VM image is used - instead of the one passed to the module and version for `airs-flex` offer must be provided. + instead of the one passed to the module and version for `airs-flex` offer must be provided. - `version` - (`string`, optional) describes the PAN-OS image version from Azure Marketplace. - `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. @@ -1203,7 +1204,10 @@ The basic Scale Set configuration properties are as follows: - `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. + - `ip_configurations` - (`map`, required) A map that contains the IP configurations for the interface. + - `name` - (`string`, optional, defaults to `primary`) the name of the interface IP configuration. + - `primary` - (`bool`, optional, defaults to `true`) sets the current IP configuration as the primary one. + - `create_public_ip` - (`bool`, optional, defaults to `false`) if `true`, create a public IP for the 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. @@ -1240,9 +1244,10 @@ map(object({ custom_id = optional(string) })) virtual_machine_scale_set = optional(object({ - size = optional(string) - zones = optional(list(string)) - disk_type = optional(string) + orchestration_type = optional(string) + size = optional(string) + zones = optional(list(string)) + disk_type = optional(string) bootstrap_options = optional(object({ type = optional(string) ip-address = optional(string) @@ -1302,16 +1307,20 @@ map(object({ webhooks_uris = optional(map(string), {}) }), {}) interfaces = list(object({ - name = string - subnet_key = string - create_public_ip = optional(bool) - pip_domain_name_label = optional(string) - pip_idle_timeout_in_minutes = optional(number) - pip_prefix_name = optional(string) - pip_prefix_resource_group_name = optional(string) - pip_prefix_id = optional(string) - load_balancer_key = optional(string) - application_gateway_key = optional(string) + name = string + subnet_key = string + ip_configurations = optional(map(object({ + name = optional(string) + primary = optional(bool, true) + create_public_ip = optional(bool, false) + pip_domain_name_label = optional(string) + pip_idle_timeout_in_minutes = optional(number) + pip_prefix_name = optional(string) + pip_prefix_resource_group_name = optional(string) + pip_prefix_id = optional(string) + }))) + load_balancer_key = optional(string) + application_gateway_key = optional(string) })) autoscaling_profiles = optional(list(object({ name = string @@ -1552,14 +1561,15 @@ map(object({ private_ip_address = optional(string) gwlb_key = optional(string) in_rules = optional(map(object({ - name = string - protocol = string - port = number - backend_port = optional(number) - health_probe_key = optional(string) - floating_ip = optional(bool) - session_persistence = optional(string) - nsg_priority = optional(number) + name = string + protocol = string + port = number + backend_port = optional(number) + health_probe_key = optional(string) + floating_ip = optional(bool) + session_persistence = optional(string) + nsg_priority = optional(number) + idle_timeout_in_minutes = optional(number) })), {}) out_rules = optional(map(object({ name = string diff --git a/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_dedicated_vwan.md b/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_dedicated_vwan.md new file mode 100644 index 000000000..d80726bec --- /dev/null +++ b/products/terraform/docs/swfw/azure/vmseries/reference-architectures/vmseries_transit_vnet_dedicated_vwan.md @@ -0,0 +1,1703 @@ +--- +hide_title: true +id: vmseries_transit_vnet_dedicated_vwan +keywords: +- pan-os +- panos +- firewall +- configuration +- terraform +- vmseries +- vm-series +- swfw +- software-firewalls +- azure +pagination_next: null +pagination_prev: null +sidebar_label: VM-Series Transit VNet Dedicated Vwan +title: 'Reference Architecture with Terraform: VM-Series in Azure, Centralized Architecture, + Dedicated Inbound NGFW Option' +--- + +# Reference Architecture with Terraform: VM-Series in Azure, Centralized Architecture, Dedicated Inbound NGFW Option + +Palo Alto Networks produces several +[validated reference architecture design and deployment documentation guides](https://www.paloaltonetworks.com/resources/reference-architectures), +which describe well-architected and tested deployments. When deploying VM-Series in a public cloud, the reference architectures +guide users toward the best security outcomes, whilst reducing rollout time and avoiding common integration efforts. + +The Terraform code presented here will deploy Palo Alto Networks VM-Series firewalls in Azure based on a centralized design with +dedicated-inbound VM-Series and integration with Azure Virtual WAN; for a discussion of other options, please see the design guide from +[the reference architecture guides](https://www.paloaltonetworks.com/resources/reference-architectures). + +[![GitHub Logo](/img/view_on_github.png)](https://github.com/PaloAltoNetworks/terraform-azurerm-swfw-modules/tree/main/examples/vmseries_transit_vnet_dedicated_vwan) [![Terraform Logo](/img/view_on_terraform_registry.png)](https://registry.terraform.io/modules/PaloAltoNetworks/swfw-modules/azurerm/latest/examples/vmseries_transit_vnet_dedicated_vwan) + +## Reference Architecture Design + +![simple](aa2ae33a-fb46-4a1c-9811-98ea3b132297.png) + +This code implements: + +- a *centralized design*, a hub-and-spoke topology with a Transit VNet containing VM-Series to inspect all inbound, outbound, + east-west, and enterprise traffic +- the *dedicated inbound option*, which separates inbound traffic flows onto a separate set of VM-Series. + +## Detailed Architecture and Design + +### Centralized Design + +This design uses a Transit VNet. Application functions and resources are deployed across multiple VNets that are connected in +a hub-and-spoke topology. The hub of the topology, or transit VNet, is the central point of connectivity for all inbound, +outbound, east-west, and enterprise traffic. You deploy all VM-Series firewalls within the transit VNet. + +### Dedicated Inbound Option + +The dedicated inbound option separates traffic flows across two separate sets of VM-Series firewalls. One set of VM-Series +firewalls is dedicated to inbound traffic flows, allowing for greater flexibility and scaling of inbound traffic loads. +The second set of VM-Series firewalls services all outbound, east-west, and enterprise network traffic flows. This deployment +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](2ef99143-3dcf-4113-814d-aedca8fcccf3.png) + +This reference architecture consists of: + +- a VNET containing: + - 3 subnets dedicated to the firewalls: management, private and public + - Route Tables and Network Security Groups +- 2 Load Balancers: + - public - with a public IP address assigned, in front of the firewalls public interfaces, for incoming traffic + - private - in front of the firewalls private interfaces, for outgoing and east-west traffic +- a Storage Account used to keep bootstrap packages containing `DAY0` configuration for the firewalls +- 4 firewalls: + - deployed in different zones + - 2 pairs, one for inbound, the other for outbound and east-west traffic + - with 3 network interfaces each: management, public, private + - with public IP addresses assigned to: + - management interface + - public interface +- a Virtual WAN containing: + - one Virtual Hub + - 2 connections to the Virtual Hub (one dedicated for spoke vnet and one dedicated for the transit vnet) +- _(optional)_ test workloads with accompanying infrastructure: + - 3 Spoke VNETs with Route Tables and Network Security Groups + - 3 Spoke VMs serving as WordPress-based web servers + - 3 Azure Bastion managed jump hosts + +**NOTE!** +- In order to deploy the architecture without test workloads described above, empty the `test_infrastructure` map in + `example.tfvars` file. + +## Prerequisites + +A list of requirements might vary depending on the platform used to deploy the infrastructure but a minimum one includes: + +- _(in case of non cloud shell deployment)_ credentials and (optionally) tools required to authenticate against Azure Cloud, see + [AzureRM provider documentation for details](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs#authenticating-to-azure) +- [supported](#requirements) version of [`Terraform`]() +- if you have not run Palo Alto NGFW images in a subscription it might be necessary to accept the license first + ([see this note](../../modules/vmseries#accept-azure-marketplace-terms)) + +**Note!** +- after the deployment the firewalls remain not licensed, they do however contain minimum `DAY0` configuration (required NIC, VR, + routes configuration). +- this example contains some **files** that **can contain sensitive data**. Keep in mind that **this code** is + **only an example**. It's main purpose is to introduce the Terraform modules. + +## Usage + +### Deployment Steps + +- checkout the code locally (if you haven't done so yet) +- copy the [`example.tfvars`](./example.tfvars) file, rename it to `terraform.tfvars` and adjust it to your needs (take a closer + look at the `TODO` markers) +- copy the [`init-cfg.sample.txt`](./files/init-cfg.sample.txt) to `init-cfg.txt` and fill it out with required bootstrap + parameters (see this [documentation](https://docs.paloaltonetworks.com/vm-series/9-1/vm-series-deployment/bootstrap-the-vm-series-firewall/create-the-init-cfgtxt-file/init-cfgtxt-file-components#id07933d91-15be-414d-bc8d-f2a5f3d8df6b) for details) +- _(optional)_ authenticate to AzureRM, switch to the Subscription of your choice +- provide `subscription_id` either by creating an environment variable named `ARM_SUBSCRIPTION_ID` with Subscription ID as value + in your shell (recommended option) or by setting the value of `subscription_id` variable within your `tfvars` file (discouraged + option, we don't recommend putting the Subscription ID in clear text inside the code). +- initialize the Terraform module: + + ```bash + terraform init + ``` + +- _(optional)_ plan you infrastructure to see what will be actually deployed: + + ```bash + terraform plan + ``` + +- deploy the infrastructure (you will have to confirm it with typing in `yes`): + + ```bash + terraform apply + ``` + + The deployment takes couple of minutes. Observe the output. At the end you should see a summary similar to this: + + ```console + bootstrap_storage_urls = + lb_frontend_ips = { + "private" = { + "ha-ports" = "1.2.3.4" + } + "public" = { + "palo-lb-app1-pip" = "1.2.3.4" + } + } + password = + username = "panadmin" + vmseries_mgmt_ips = { + "fw-in-1" = "1.2.3.4" + "fw-in-2" = "1.2.3.4" + "fw-obew-1" = "1.2.3.4" + "fw-obew-2" = "1.2.3.4" + } + ``` + +- at this stage you have to wait couple of minutes for the firewalls to bootstrap. + +### Post deploy + +Firewalls in this example are configured with password authentication. To retrieve the initial credentials run: + +- for username: + + ```bash + terraform output usernames + ``` + +- for password: + + ```bash + terraform output passwords + ``` + +The management public IP addresses are available in the `vmseries_mgmt_ips`: + +```bash +terraform output vmseries_mgmt_ips +``` + +You can now login to the devices using either: + +- cli - ssh client is required +- Web UI (https) - any modern web browser, note that initially the traffic is encrypted with a self-signed certificate. + +As mentioned, the devices already contain `DAY0` configuration, so all network interfaces should be configured and Azure Load +Balancer should already report that the devices are healthy. + +You can now proceed with licensing the devices and configuring your first rules. + +Please also refer to [this repository](https://github.com/PaloAltoNetworks/iron-skillet) for `DAY1` configuration +(security hardening). + +### Cleanup + +To remove the deployed infrastructure run: + +```bash +terraform destroy +``` + +## Reference + +### Requirements + +- `terraform`, version: >= 1.5, < 2.0 + +### Providers + +- `random` +- `local` +- `azurerm` + +### Modules +Name | Version | Source | Description +--- | --- | --- | --- +`vnet` | - | ../../modules/vnet | +`vnet_peering` | - | ../../modules/vnet_peering | +`public_ip` | - | ../../modules/public_ip | +`natgw` | - | ../../modules/natgw | +`load_balancer` | - | ../../modules/loadbalancer | +`appgw` | - | ../../modules/appgw | +`ngfw_metrics` | - | ../../modules/ngfw_metrics | +`bootstrap` | - | ../../modules/bootstrap | +`vmseries` | - | ../../modules/vmseries | +`virtual_wan` | - | ../../modules/vwan | +`test_infrastructure` | - | ../../modules/test_infrastructure | + +### Resources + +- `availability_set` (managed) +- `resource_group` (managed) +- `file` (managed) +- `password` (managed) +- `resource_group` (data) + +### Required Inputs + +Name | Type | Description +--- | --- | --- +[`subscription_id`](#subscription_id) | `string` | Azure Subscription ID is a required argument since AzureRM provider v4. +[`resource_group_name`](#resource_group_name) | `string` | Name of the Resource Group. +[`region`](#region) | `string` | The Azure region to use. +[`vnets`](#vnets) | `map` | A map defining VNETs. + +### Optional Inputs + +Name | Type | Description +--- | --- | --- +[`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. +[`vnet_peerings`](#vnet_peerings) | `map` | A map defining VNET peerings. +[`public_ips`](#public_ips) | `object` | A map defining Public IP Addresses and Prefixes. +[`natgws`](#natgws) | `map` | A map defining NAT Gateways. +[`virtual_wans`](#virtual_wans) | `map` | A map defining Virtual WANs. +[`load_balancers`](#load_balancers) | `map` | A map containing configuration for all (both private and public) Load Balancers. +[`appgws`](#appgws) | `map` | A map defining all Application Gateways in the current deployment. +[`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. +[`vmseries_universal`](#vmseries_universal) | `object` | A map defining common settings for all created VM-Series instances. +[`vmseries`](#vmseries) | `map` | A map defining Azure Virtual Machines based on Palo Alto Networks Next Generation Firewall image. +[`test_infrastructure`](#test_infrastructure) | `map` | A map defining test infrastructure including test VMs and Azure Bastion hosts. + +### Outputs + +Name | Description +--- | --- +`usernames` | Initial administrative username to use for VM-Series. +`passwords` | Initial administrative password to use for VM-Series. +`natgw_public_ips` | Nat Gateways Public IP resources. +`metrics_instrumentation_keys` | The Instrumentation Key of the created instance(s) of Azure Application Insights. +`lb_frontend_ips` | IP Addresses of the load balancers. +`vmseries_mgmt_ips` | IP addresses for the VM-Series management interface. +`bootstrap_storage_urls` | +`test_vms_usernames` | Initial administrative username to use for test VMs. +`test_vms_passwords` | Initial administrative password to use for test VMs. +`test_vms_ips` | IP Addresses of the test VMs. +`test_lb_frontend_ips` | IP Addresses of the test load balancers. + +### Required Inputs details + +#### subscription_id + +Azure Subscription ID is a required argument since AzureRM provider v4. + +**Note!** \ +Instead of putting the Subscription ID directly in the code, it's recommended to use an environment variable. Create an +environment variable named `ARM_SUBSCRIPTION_ID` with your Subscription ID as value and leave this variable set to `null`. + + +Type: string + +[back to list](#modules-required-inputs) + +#### resource_group_name + +Name of the Resource Group. + +Type: string + +[back to list](#modules-required-inputs) + +#### region + +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) + +- `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. +- `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. +- `address_space` - (`list`, required when `create_virtual_network = false`) a list of CIDRs for a newly created VNET. +- `dns_servers` - (`list`, optional, defaults to module defaults) a list of IP addresses of custom DNS servers + (by default Azure DNS is used). +- `vnet_encryption` - (`string`, optional, defaults to module default) enables Azure Virtual Network Encryption when + set, only possible value at the moment is `AllowUnencrypted`. When set to `null`, the feature is + disabled. +- `ddos_protection_plan_id` - (`string`, optional, defaults to `null`) ID of an existing Azure Network DDOS Protection Plan to + be associated with the VNET. +- `network_security_groups` - (`map`, optional) map of Network Security Groups to create, for details see + [VNET module documentation](../../modules/vnet#network_security_groups). +- `route_tables` - (`map`, optional) map of Route Tables to create, for details see + [VNET module documentation](../../modules/vnet#route_tables). +- `subnets` - (`map`, optional) map of Subnets to create or source, for details see + [VNET module documentation](../../modules/vnet#subnets). + + +Type: + +```hcl +map(object({ + create_virtual_network = optional(bool, true) + name = string + resource_group_name = optional(string) + address_space = optional(list(string)) + dns_servers = optional(list(string)) + vnet_encryption = optional(string) + ddos_protection_plan_id = optional(string) + network_security_groups = optional(map(object({ + name = string + rules = optional(map(object({ + name = string + priority = number + direction = string + access = string + protocol = string + source_port_range = optional(string) + source_port_ranges = optional(list(string)) + destination_port_range = optional(string) + destination_port_ranges = optional(list(string)) + source_address_prefix = optional(string) + source_address_prefixes = optional(list(string)) + destination_address_prefix = optional(string) + destination_address_prefixes = optional(list(string)) + })), {}) + })), {}) + route_tables = optional(map(object({ + name = string + bgp_route_propagation_enabled = optional(bool) + routes = map(object({ + name = string + address_prefix = string + next_hop_type = string + next_hop_ip_address = optional(string) + })) + })), {}) + subnets = optional(map(object({ + create = optional(bool, true) + name = string + address_prefixes = optional(list(string), []) + network_security_group_key = optional(string) + route_table_key = optional(string) + default_outbound_access_enabled = optional(bool) + enable_storage_service_endpoint = optional(bool) + enable_appgw_delegation = optional(bool) + enable_cloudngfw_delegation = optional(bool) + })), {}) + })) +``` + + +[back to list](#modules-required-inputs) + +### Optional Inputs details + +#### 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. + +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. + + +Type: string + +Default value: `` + +[back to list](#modules-optional-inputs) + +#### 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 `false` the `resource_group_name` parameter is used to specify a name of an existing Resource Group. + + +Type: bool + +Default value: `true` + +[back to list](#modules-optional-inputs) + +#### tags + +Map of tags to assign to the created resources. + +Type: map(string) + +Default value: `map[]` + +[back to list](#modules-optional-inputs) + +#### vnet_peerings + +A map defining VNET peerings. + +Following properties are supported: +- `local_vnet_name` - (`string`, required) name of the local VNET. +- `local_resource_group_name` - (`string`, optional) name of the resource group, in which local VNET exists. +- `remote_vnet_name` - (`string`, required) name of the remote VNET. +- `remote_resource_group_name` - (`string`, optional) name of the resource group, in which remote VNET exists. + + +Type: + +```hcl +map(object({ + local_vnet_name = string + local_resource_group_name = optional(string) + remote_vnet_name = string + remote_resource_group_name = optional(string) + })) +``` + + +Default value: `map[]` + +[back to list](#modules-optional-inputs) + +#### public_ips + +A map defining Public IP Addresses and Prefixes. + +Following properties are available: + +- `public_ip_addresses` - (`map`, optional) map of objects describing Public IP Addresses, please refer to + [module documentation](../../modules/public_ip#public_ip_addresses) + for available properties. +- `public_ip_prefixes` - (`map`, optional) map of objects describing Public IP Prefixes, please refer to + [module documentation](../../modules/public_ip#public_ip_prefixes) + for available properties. + + +Type: + +```hcl +object({ + public_ip_addresses = optional(map(object({ + create = bool + name = string + resource_group_name = optional(string) + zones = optional(list(string)) + domain_name_label = optional(string) + idle_timeout_in_minutes = optional(number) + prefix_name = optional(string) + prefix_resource_group_name = optional(string) + prefix_id = optional(string) + })), {}) + public_ip_prefixes = optional(map(object({ + create = bool + name = string + resource_group_name = optional(string) + zones = optional(list(string)) + length = optional(number) + })), {}) + }) +``` + + +Default value: `map[]` + +[back to list](#modules-optional-inputs) + +#### natgws + +A map defining NAT Gateways. + +Please note that a NAT Gateway is a zonal resource, this means it's always placed in a zone (even when you do not specify one +explicitly). Please refer to Microsoft documentation for notes on NAT Gateway's zonal resiliency. +For detailed documentation on each property refer to [module documentation](../../modules/natgw). + +Following properties are supported: +- `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: +``` +natgws = { + "natgw" = { + name = "natgw" + vnet_key = "transit-vnet" + subnet_keys = ["management"] + public_ip = { + create = true + name = "natgw-pip" + } + } +} +``` + + +Type: + +```hcl +map(object({ + 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) + public_ip = optional(object({ + create = bool + name = optional(string) + resource_group_name = optional(string) + key = optional(string) + })) + public_ip_prefix = optional(object({ + create = bool + name = optional(string) + resource_group_name = optional(string) + length = optional(number) + key = optional(string) + })) + })) +``` + + +Default value: `map[]` + +[back to list](#modules-optional-inputs) + +#### virtual_wans + +A map defining Virtual WANs. + +For detailed documentation on each property refer to [module documentation](../../modules/vwan) + +- `create` - (`bool`, optional, defaults to `true`) when set to `true` will create a new Virtual WAN, + `false` will source an existing Virtual WAN. +- `name` - (`string`, required) a name of a Virtual WAN. In case `create = false` this should be a + full resource name, including prefixes. +- `resource_group_name` - (`string`, optional, defaults to current RG) a name of an existing Resource Group in which + the Virtual WAN will reside or is sourced from. +- `disable_vpn_encryption` - (`bool`, optional, defaults to `false`) if `true`, VPN encryption is disabled. +- `allow_branch_to_branch_traffic` - (`bool`, optional, defaults to `true`) if `false`, branch-to-branch traffic is not allowed. +- `virtual_hubs` - (`map`, optional) map of Virtual Hubs to create or source, for details see + [Virtual WAN module documentation](../../modules/vwan#virtual_hubs). + + +Type: + +```hcl +map(object({ + name = string + resource_group_name = optional(string) + create = optional(bool, true) + region = optional(string) + disable_vpn_encryption = optional(bool, false) + allow_branch_to_branch_traffic = optional(bool, true) + virtual_hubs = optional(map(object({ + name = string + address_prefix = string + create = optional(bool, true) + resource_group_name = optional(string) + region = optional(string) + hub_routing_preference = optional(string) + virtual_router_auto_scale_min_capacity = optional(number) + connections = optional(map(object({ + name = string + connection_type = string + remote_virtual_network_key = optional(string) + internet_security_enabled = optional(bool) + vpn_site_key = optional(string) + vpn_link = optional(list(object({ + vpn_link_name = string + vpn_site_link_key = string + bandwidth_mbps = optional(number) + bgp_enabled = optional(bool) + connection_mode = optional(string) + protocol = optional(string) + ratelimit_enabled = optional(bool) + shared_key = optional(string) + local_azure_ip_address_enabled = optional(bool) + ipsec_policy = optional(object({ + dh_group = optional(string) + ike_encryption_algorithm = optional(string) + ike_integrity_algorithm = optional(string) + encryption_algorithm = optional(string) + integrity_algorithm = optional(string) + pfs_group = optional(string) + sa_data_size_kb = optional(number) + sa_lifetime_sec = optional(number) + })) + }))) + routing = optional(object({ + associated_route_table_key = optional(string) + propagated_route_table_keys = optional(list(string)) + propagated_route_table_labels = optional(set(string)) + static_vnet_route_name = optional(string) + static_vnet_route_address_prefixes = optional(set(string)) + static_vnet_route_next_hop_ip_address = optional(string) + static_vnet_local_route_override_criteria = optional(string) + })) + })), {}) + route_tables = optional(map(object({ + name = string + labels = optional(set(string)) + routes = optional(map(object({ + name = string + destinations_type = string + destinations = list(string) + next_hop_type = optional(string) + next_hop_key = string + })), {}) + })), {}) + routing_intent = optional(object({ + routing_intent_name = string + routing_policy = list(object({ + routing_policy_name = string + destinations = list(string) + next_hop_key = string + })) + })) + vpn_gateway = optional(object({ + name = string + resource_group_name = optional(string) + scale_unit = optional(number) + routing_preference = optional(string) + }), null) + vpn_sites = optional(map(object({ + name = string + region = optional(string) + resource_group_name = optional(string) + address_cidrs = optional(set(string)) + link = optional(map(object({ + name = string + ip_address = optional(string) + fqdn = optional(string) + provider_name = optional(string) + speed_in_mbps = optional(number, 0) + }))) + })), {}) + })), {}) + })) +``` + + +Default value: `map[]` + +[back to list](#modules-optional-inputs) + +#### 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). + +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 ["1", "2", "3"]) a list of zones for Load Balancer's frontend IP + configurations. +- `backend_name` - (`string`, optional, defaults to "vmseries_backend") 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#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 refer to + [module documentation](../../modules/loadbalancer#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`, please refer to + [module documentation](../../modules/loadbalancer#frontend_ips) for available + properties. + + **Note!** \ + In this example the `subnet_id` is not available directly, another property has been introduced instead: + + - `subnet_key` - (`string`, optional, defaults to `null`) a key pointing to a Subnet definition in the `var.vnets` map. + + +Type: + +```hcl +map(object({ + name = string + vnet_key = optional(string) + zones = optional(list(string), ["1", "2", "3"]) + backend_name = optional(string, "vmseries_backend") + health_probes = optional(map(object({ + name = string + protocol = string + port = optional(number) + probe_threshold = optional(number) + interval_in_seconds = optional(number) + request_path = optional(string) + }))) + nsg_auto_rules_settings = optional(object({ + nsg_name = optional(string) + nsg_vnet_key = optional(string) + nsg_key = optional(string) + nsg_resource_group_name = optional(string) + source_ips = list(string) + base_priority = optional(number) + })) + frontend_ips = optional(map(object({ + name = string + subnet_key = optional(string) + create_public_ip = optional(bool, false) + public_ip_name = optional(string) + public_ip_resource_group_name = optional(string) + public_ip_key = optional(string) + public_ip_prefix_key = optional(string) + private_ip_address = optional(string) + gwlb_key = optional(string) + in_rules = optional(map(object({ + name = string + protocol = string + port = number + backend_port = optional(number) + health_probe_key = optional(string) + floating_ip = optional(bool) + session_persistence = optional(string) + nsg_priority = optional(number) + idle_timeout_in_minutes = optional(number) + })), {}) + out_rules = optional(map(object({ + name = string + protocol = string + allocated_outbound_ports = optional(number) + enable_tcp_reset = optional(bool) + idle_timeout_in_minutes = optional(number) + })), {}) + })), {}) + })) +``` + + +Default value: `map[]` + +[back to list](#modules-optional-inputs) + +#### appgws + +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). + +**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 `["1", "2", "3"]`) 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#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#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#probes) for details. +- `rewrites` - (`map`, optional, defaults to module default) defines rewrite rules, see + [module's documentation](../../modules/appgw#rewrites) for details. +- `redirects` - (`map`, optional, mutually exclusive with `backend_settings` and `url_path_maps`) static redirects + definition, see [module's documentation](../../modules/appgw#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#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#rules) for details. + + +Type: + +```hcl +map(object({ + name = string + vnet_key = string + subnet_key = string + zones = optional(list(string), ["1", "2", "3"]) + public_ip = object({ + create = optional(bool, true) + name = optional(string) + resource_group_name = optional(string) + key = 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, "public_ipconfig") + 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_key = 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) + })) + })) +``` + + +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` - (`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: + +```hcl +map(object({ + name = string + update_domain_count = optional(number) + fault_domain_count = optional(number) + })) +``` + + +Default value: `map[]` + +[back to list](#modules-optional-inputs) + +#### ngfw_metrics + +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. + + +Type: + +```hcl +object({ + name = string + create_workspace = optional(bool, true) + resource_group_name = optional(string) + sku = optional(string) + metrics_retention_in_days = optional(number) + }) +``` + + +Default value: `&{}` + +[back to list](#modules-optional-inputs) + +#### bootstrap_storages + +A map defining Azure Storage Accounts used to host file shares for bootstrapping NGFWs. + +You can create or re-use an existing Storage Account and/or File Share. For details on all available properties please refer to +[module's documentation](../../modules/bootstrap). Following is just an extract of the most important ones: + +- `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. + +- `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. + + 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#storage_account). + +- `storage_network_security` - (`map`, optional, defaults to `{}`) a map defining network security settings for a **new** + 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#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 default) for sourced File Shares, controls if the + bootstrap package folder structure will be created. + + For detailed documentation see [module's documentation](../../modules/bootstrap#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#file_shares). + + +Type: + +```hcl +map(object({ + name = string + resource_group_name = optional(string) + storage_account = optional(object({ + create = optional(bool) + replication_type = optional(string) + kind = optional(string) + tier = optional(string) + blob_retention = optional(number) + }), {}) + storage_network_security = optional(object({ + min_tls_version = optional(string) + allowed_public_ips = optional(list(string)) + vnet_key = optional(string) + allowed_subnet_keys = optional(list(string), []) + }), {}) + file_shares_configuration = optional(object({ + create_file_shares = optional(bool) + disable_package_dirs_creation = optional(bool) + quota = optional(number) + access_tier = optional(string) + }), {}) + file_shares = optional(map(object({ + name = string + bootstrap_package_path = optional(string) + bootstrap_files = optional(map(string)) + bootstrap_files_md5 = optional(map(string)) + quota = optional(number) + access_tier = optional(string) + })), {}) + })) +``` + + +Default value: `map[]` + +[back to list](#modules-optional-inputs) + +#### vmseries_universal + +A map defining common settings for all created VM-Series instances. + +It duplicates popular properties from `vmseries` variable, specifically `vmseries.image` and `vmseries.virtual_machine` maps. +However, if values are set in those maps, they still take precedence over the ones set within this variable. As a result, all +universal properties can be overriden on a per-VM basis. + +Following properties are supported: + +- `use_airs` - (`bool`, optional, defaults to `false`) when set to `true`, the AI Runtime Security VM image is used + instead of the one passed to the module and version for `airs-flex` offer must be provided. +- `version` - (`string`, optional) describes the PAN-OS image version from Azure Marketplace. +- `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. +- `bootstrap_options` - (`map`, 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. For details and available properties refer to `vmseries` variable. + + +Type: + +```hcl +object({ + use_airs = optional(bool) + version = optional(string) + size = optional(string) + bootstrap_options = optional(object({ + type = optional(string) + ip-address = optional(string) + default-gateway = optional(string) + netmask = optional(string) + ipv6-address = optional(string) + ipv6-default-gateway = optional(string) + hostname = optional(string) + panorama-server = optional(string) + panorama-server-2 = optional(string) + tplname = optional(string) + dgname = optional(string) + cgname = optional(string) + dns-primary = optional(string) + dns-secondary = optional(string) + vm-auth-key = optional(string) + op-command-modes = optional(string) + op-cmd-dpdk-pkt-io = optional(string) + plugin-op-commands = optional(string) + dhcp-send-hostname = optional(string) + dhcp-send-client-id = optional(string) + dhcp-accept-server-hostname = optional(string) + dhcp-accept-server-domain = optional(string) + vm-series-auto-registration-pin-id = optional(string) + vm-series-auto-registration-pin-value = optional(string) + auth-key = optional(string) + authcodes = optional(string) + })) + bootstrap_package = optional(object({ + bootstrap_storage_key = string + static_files = optional(map(string), {}) + bootstrap_package_path = optional(string) + bootstrap_xml_template = optional(string) + private_snet_key = optional(string) + public_snet_key = optional(string) + ai_update_interval = optional(number, 5) + intranet_cidr = optional(string) + })) + }) +``` + + +Default value: `map[]` + +[back to list](#modules-optional-inputs) + +#### vmseries + +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) 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). + + **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#authentication). + +- `image` - (`map`, optional) properties defining a base image used by the deployed VM. The `image` property is + required (if no common properties were set within `vmseries_universal` variable) 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 all properties refer to [module's documentation](../../modules/vmseries#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`, required) 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` - (`map`, 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). + + 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#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/vmseries#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. + - `ip_configurations` - (`map`, required) A map that contains the IP configurations for the interface. + - `name` - (`string`, optional, defaults to `primary`) the name of the interface IP configuration. + - `primary` - (`bool`, optional, defaults to `true`) sets the current IP configuration as the primary one. + **Note!** When you define multiple IP configurations, exactly one must be the primary. + - `private_ip_address` - (`string`, optional, defaults to `null`) static private IP to assign to the interface. When + skipped Azure will assign one dynamically. Keep in mind that a dynamic IP is guarantied not + to change as long as the VM is running. Any stop/deallocate/restart operation might cause + the IP to change. + - `create_public_ip` - (`bool`, optional, defaults to `false`) if `true`, creates a public IP for the 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. Mutually exclusive with `appgw_backend_pool_id`. + - `appgw_backend_pool_id` - (`string`, optional, defaults to `null`) ID of the Application Gateway backend pool to which + the network interface will be added. Mutually exclusive with `application_gateway_key`. + + For details on all properties refer to [module's documentation](../../modules/panorama#interfaces). + + +Type: + +```hcl +map(object({ + name = string + vnet_key = string + authentication = optional(object({ + username = optional(string, "panadmin") + password = optional(string) + disable_password_authentication = optional(bool, false) + ssh_keys = optional(list(string), []) + }), {}) + image = optional(object({ + use_airs = optional(bool) + version = optional(string) + publisher = optional(string) + offer = optional(string) + sku = optional(string) + enable_marketplace_plan = optional(bool) + custom_id = optional(string) + })) + virtual_machine = object({ + size = optional(string) + bootstrap_options = optional(object({ + type = optional(string) + ip-address = optional(string) + default-gateway = optional(string) + netmask = optional(string) + ipv6-address = optional(string) + ipv6-default-gateway = optional(string) + hostname = optional(string) + panorama-server = optional(string) + panorama-server-2 = optional(string) + tplname = optional(string) + dgname = optional(string) + cgname = optional(string) + dns-primary = optional(string) + dns-secondary = optional(string) + vm-auth-key = optional(string) + op-command-modes = optional(string) + op-cmd-dpdk-pkt-io = optional(string) + plugin-op-commands = optional(string) + dhcp-send-hostname = optional(string) + dhcp-send-client-id = optional(string) + dhcp-accept-server-hostname = optional(string) + dhcp-accept-server-domain = optional(string) + vm-series-auto-registration-pin-id = optional(string) + vm-series-auto-registration-pin-value = optional(string) + auth-key = optional(string) + authcodes = optional(string) + })) + bootstrap_package = optional(object({ + bootstrap_storage_key = string + static_files = optional(map(string), {}) + bootstrap_package_path = optional(string) + bootstrap_xml_template = 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) + capacity_reservation_group_id = optional(string) + accelerated_networking = optional(bool) + allow_extension_operations = 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)) + }) + interfaces = list(object({ + name = string + subnet_key = string + ip_configurations = map(object({ + name = optional(string) + primary = optional(bool, true) + create_public_ip = optional(bool, false) + public_ip_name = optional(string) + public_ip_resource_group_name = optional(string) + public_ip_key = optional(string) + private_ip_address = optional(string) + })) + load_balancer_key = optional(string) + application_gateway_key = optional(string) + appgw_backend_pool_id = optional(string) + })) + })) +``` + + +Default value: `map[]` + +[back to list](#modules-optional-inputs) + +#### test_infrastructure + +A map defining test infrastructure including test VMs and Azure Bastion hosts. + +For details and defaults for available options please refer to the +[`test_infrastructure`](../../modules/test_infrastructure) module. + +Following properties are supported: + +- `create_resource_group` - (`bool`, optional, defaults to `true`) when set to `true`, a new Resource Group is created. When + set to `false`, an existing Resource Group is sourced. +- `resource_group_name` - (`string`, optional) name of the Resource Group to be created or sourced. +- `vnets` - (`map`, required) a map defining VNETs and peerings for the test environment. The most basic + properties are as follows: + + - `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. + - `network_security_groups` - (`map`, optional) map of Network Security Groups to create, for details see + [VNET module documentation](../../modules/vnet#network_security_groups). + - `route_tables` - (`map`, optional) map of Route Tables to create, for details see + [VNET module documentation](../../modules/vnet#route_tables). + - `subnets` - (`map`, optional) map of Subnets to create or source, for details see + [VNET module documentation](../../modules/vnet#subnets). + - `local_peer_config` - (`map`, optional) a map that contains local peer configuration parameters. This value allows to + set `allow_virtual_network_access`, `allow_forwarded_traffic`, `allow_gateway_transit` and + `use_remote_gateways` parameters on the local VNet peering. + - `remote_peer_config` - (`map`, optional) a map that contains remote peer configuration parameters. This value allows to + set `allow_virtual_network_access`, `allow_forwarded_traffic`, `allow_gateway_transit` and + `use_remote_gateways` parameters on the remote VNet peering. + + For all properties and their default values see [module's documentation](../../modules/test_infrastructure#vnets). + +- `load_balancers` - (`map`, optional) a map containing configuration for all (both private and public) Load Balancers. + The most basic properties are as follows: + + - `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 ["1", "2", "3"]) a list of zones for Load Balancer's frontend IP + configurations. + - `backend_name` - (`string`, optional) 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 + [loadbalancer module documentation](../../modules/loadbalancer#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 refer to + [loadbalancer module documentation](../../modules/loadbalancer#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`, please refer to + [loadbalancer module documentation](../../modules/loadbalancer#frontend_ips) for + available properties. + + **Note!** \ + In this example the `subnet_id` is not available directly, another property has been introduced instead: + + - `subnet_key` - (`string`, optional, defaults to `null`) a key pointing to a Subnet definition in the `var.vnets` map. + + For all properties and their default values see + [module's documentation](../../modules/test_infrastructure#load_balancers). + +- `authentication` - (`map`, optional, defaults to example defaults) authentication settings for the deployed VMs. +- `spoke_vms` - (`map`, required) a map defining test VMs. The most basic properties are as follows: + + - `name` - (`string`, required) a name of the VM. + - `vnet_key` - (`string`, required) a key describing a VNET defined in `vnets` property. + - `subnet_key` - (`string`, required) a key describing a Subnet found in a VNET definition. + - `load_balancer_key` - (`string`, optional) a key describing a Load Balancer defined in `load_balancers` property. + + For all properties and their default values see + [module's documentation](../../modules/test_infrastructure#test_vms). + +- `bastions` - (`map`, required) a map containing Azure Bastion definitions. The most basic properties are as + follows: + + - `name` - (`string`, required) an Azure Bastion name. + - `vnet_key` - (`string`, required) a key describing a VNET defined in `vnets` property. This VNET should already have an + existing subnet called `AzureBastionSubnet` (the name is hardcoded by Microsoft). + - `subnet_key` - (`string`, required) a key pointing to a Subnet dedicated to a Bastion deployment. + + For all properties and their default values see + [module's documentation](../../modules/test_infrastructure#bastions). + + +Type: + +```hcl +map(object({ + create_resource_group = optional(bool, true) + resource_group_name = optional(string) + vnets = map(object({ + create_virtual_network = optional(bool, true) + name = string + address_space = optional(list(string)) + dns_servers = optional(list(string)) + vnet_encryption = optional(string) + ddos_protection_plan_id = optional(string) + hub_vnet_key = optional(string) + network_security_groups = optional(map(object({ + name = string + rules = optional(map(object({ + name = string + priority = number + direction = string + access = string + protocol = string + source_port_range = optional(string) + source_port_ranges = optional(list(string)) + destination_port_range = optional(string) + destination_port_ranges = optional(list(string)) + source_address_prefix = optional(string) + source_address_prefixes = optional(list(string)) + destination_address_prefix = optional(string) + destination_address_prefixes = optional(list(string)) + })), {}) + })), {}) + route_tables = optional(map(object({ + name = string + bgp_route_propagation_enabled = optional(bool) + routes = map(object({ + name = string + address_prefix = string + next_hop_type = string + next_hop_ip_address = optional(string) + })) + })), {}) + subnets = optional(map(object({ + create = optional(bool, true) + name = string + address_prefixes = optional(list(string), []) + network_security_group_key = optional(string) + route_table_key = optional(string) + default_outbound_access_enabled = optional(bool) + enable_storage_service_endpoint = optional(bool) + enable_appgw_delegation = optional(bool) + enable_cloudngfw_delegation = optional(bool) + })), {}) + local_peer_config = optional(object({ + allow_virtual_network_access = optional(bool, true) + allow_forwarded_traffic = optional(bool, true) + allow_gateway_transit = optional(bool, false) + use_remote_gateways = optional(bool, false) + }), {}) + remote_peer_config = optional(object({ + allow_virtual_network_access = optional(bool, true) + allow_forwarded_traffic = optional(bool, true) + allow_gateway_transit = optional(bool, false) + use_remote_gateways = optional(bool, false) + }), {}) + })) + load_balancers = optional(map(object({ + name = string + vnet_key = optional(string) + zones = optional(list(string), ["1", "2", "3"]) + backend_name = optional(string) + health_probes = optional(map(object({ + name = string + protocol = string + port = optional(number) + probe_threshold = optional(number) + interval_in_seconds = optional(number) + request_path = optional(string) + }))) + nsg_auto_rules_settings = optional(object({ + nsg_name = optional(string) + nsg_vnet_key = optional(string) + nsg_key = optional(string) + nsg_resource_group_name = optional(string) + source_ips = list(string) + base_priority = optional(number) + })) + frontend_ips = optional(map(object({ + name = string + subnet_key = optional(string) + create_public_ip = optional(bool, false) + public_ip_name = optional(string) + public_ip_resource_group_name = optional(string) + public_ip_key = optional(string) + public_ip_prefix_key = optional(string) + private_ip_address = optional(string) + gwlb_key = optional(string) + in_rules = optional(map(object({ + name = string + protocol = string + port = number + backend_port = optional(number) + health_probe_key = optional(string) + floating_ip = optional(bool) + session_persistence = optional(string) + nsg_priority = optional(number) + idle_timeout_in_minutes = optional(number) + })), {}) + out_rules = optional(map(object({ + name = string + protocol = string + allocated_outbound_ports = optional(number) + enable_tcp_reset = optional(bool) + idle_timeout_in_minutes = optional(number) + })), {}) + })), {}) + })), {}) + authentication = optional(object({ + username = optional(string, "bitnami") + password = optional(string) + }), {}) + spoke_vms = map(object({ + name = string + interface_name = optional(string) + disk_name = optional(string) + vnet_key = string + subnet_key = string + load_balancer_key = optional(string) + private_ip_address = optional(string) + size = optional(string) + image = optional(object({ + publisher = optional(string) + offer = optional(string) + sku = optional(string) + version = optional(string) + enable_marketplace_plan = optional(bool) + }), {}) + custom_data = optional(string) + })) + bastions = map(object({ + name = string + create_public_ip = optional(bool, true) + public_ip_name = optional(string) + public_ip_resource_group_name = optional(string) + public_ip_key = optional(string) + vnet_key = string + subnet_key = string + })) + })) +``` + + +Default value: `map[]` + +[back to list](#modules-optional-inputs) \ No newline at end of file