Skip to main content

Palo Alto Networks VMSS Module for Azure

A terraform module for VMSS VM-Series firewalls in Azure.

NOTE \ Due to lack of proper method of running health probes against Pan-OS based VMs running in a Scale Set, the upgrade_mode property is hardcoded to Manual. For this mode to actually work the roll_instances_when_required provider feature has to be also configured and set to false. Unfortunately this cannot be set in the vmss module, it has to be specified in the root module.

Therefore, when using this module please add the following provider block to your code:

provider "azurerm" {
features {
virtual_machine_scale_set {
roll_instances_when_required = false
}
}
}

GitHub Logo Terraform Logo

Usage

module "vmss" {
source = "PaloAltoNetworks/vmseries-modules/azurerm//modules/vmss"

location = "Australia Central"
name_prefix = "pan"
password = "your-password"
subnet_mgmt = azurerm_subnet.subnet_mgmt
subnet_private = azurerm_subnet.subnet_private
subnet_public = module.networks.subnet_public
bootstrap_storage_account = module.panorama.bootstrap_storage_account
bootstrap_share_name = "inboundsharename"
vhd_container = "vhd-storage-container-id"
lb_backend_pool_id = "private-backend-pool-id"
}

Reference

Requirements

NameVersion
terraform>= 1.2, < 2.0
azurerm~> 3.25

Providers

NameVersion
azurerm~> 3.25

Modules

No modules.

Resources

NameType
azurerm_linux_virtual_machine_scale_set.thisresource
azurerm_monitor_autoscale_setting.thisresource

Inputs

NameDescriptionTypeDefaultRequired
nameName of the created scale set.stringn/ayes
locationRegion to install VM-Series and dependencies.stringn/ayes
resource_group_nameName of the existing resource group where to place the resources created.stringn/ayes
vm_sizeAzure VM size (type) to be created. Consult the VM-Series Deployment Guide as only a few selected sizes are supported.string"Standard_D3_v2"no
interfacesList of the network interface specifications.

NOTICE. The ORDER in which you specify the interfaces DOES MATTER.
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.

Options for an interface object:
- name - (required|string) Interface name.
- subnet_id - (required|string) Identifier of an existing subnet to create interface in.
- create_pip - (optional|bool) If true, create a public IP for the interface
- lb_backend_pool_ids - (optional|list(string)) A list of identifiers of an existing Load Balancer backend pools to associate interface with.
- appgw_backend_pool_ids - (optional|list(String)) A list of identifier of the Application Gateway backend pools to associate interface with.
- pip_domain_name_label - (optional|string) The Prefix which should be used for the Domain Name Label for each Virtual Machine Instance.

Example:
[
{
name = "management"
subnet_id = azurerm_subnet.my_mgmt_subnet.id
create_pip = true
},
{
name = "private"
subnet_id = azurerm_subnet.my_priv_subnet.id
},
{
name = "public"
subnet_id = azurerm_subnet.my_pub_subnet.id
lb_backend_pool_ids = [azurerm_lb_backend_address_pool.lb_backend.id]
}
]
list(any)n/ayes
usernameInitial administrative username to use for VM-Series.string"panadmin"no
passwordInitial administrative password to use for VM-Series.stringn/ayes
ssh_keysA list of initial administrative SSH public keys that allow key-pair authentication. If not defined the password variable must be specified.

This is a list of strings, so each item should be the actual public key value. If you would like to load them from files instead, following method is available:
[
file("/path/to/public/keys/key_1.pub"),
file("/path/to/public/keys/key_2.pub")
]
list(string)[]no
disable_password_authenticationIf true, disables password-based authentication on VM-Series instances.booltrueno
encryption_at_host_enabledSee the provider documentation.boolnullno
overprovisionSee the provider documentation.boolfalseno
platform_fault_domain_countSee the provider documentation.numbernullno
proximity_placement_group_idSee the provider documentation.stringnullno
scale_in_policyWhich virtual machines are chosen for removal when a Virtual Machine Scale Set is scaled in. Either:

- Default, which, baring the availability zone usage and fault domain usage, deletes VM with the highest-numbered instance id,
- NewestVM, which, baring the availability zone usage, deletes VM with the newest creation time,
- OldestVM, which, baring the availability zone usage, deletes VM with the oldest creation time.
stringnullno
scale_in_force_deletionWhen set to true will force delete machines selected for removal by the scale_in_policy.boolfalseno
single_placement_groupSee the provider documentation.boolnullno
zone_balanceSee the provider documentation.booltrueno
zonesThe availability zones to use, for example ["1", "2", "3"]. If an empty list, no Availability Zones are used: [].list(string)
[
"1",
"2",
"3"
]
no
storage_account_typeType of Managed Disk which should be created. Possible values are Standard_LRS, StandardSSD_LRS or Premium_LRS. The Premium_LRS works only for selected vm_size values, details in Azure docs.string"StandardSSD_LRS"no
disk_encryption_set_idThe ID of the Disk Encryption Set which should be used to encrypt this Data Disk.stringnullno
use_custom_imageIf true, use custom_image_id and ignore the inputs username, password, img_version, img_publisher, img_offer, img_sku (all these are used only for published images, not custom ones).boolfalseno
custom_image_idAbsolute ID of your own Custom Image to be used for creating new VM-Series. The Custom Image is expected to contain PAN-OS software.stringnullno
enable_planEnable usage of the Offer/Plan on Azure Marketplace. Even plan sku "byol", which means "bring your own license", still requires accepting on the Marketplace (as of 2021). Can be set to false when using a custom image.booltrueno
img_publisherThe Azure Publisher identifier for a image which should be deployed.string"paloaltonetworks"no
img_offerThe Azure Offer identifier corresponding to a published image. For img_version 9.1.1 or above, use "vmseries-flex"; for 9.1.0 or below use "vmseries1".string"vmseries-flex"no
img_skuVM-Series SKU - list available with az vm image list -o table --all --publisher paloaltonetworksstring"byol"no
img_versionVM-Series PAN-OS version - list available for a default img_offer with az vm image list -o table --publisher paloaltonetworks --offer vmseries-flex --allstringn/ayes
accelerated_networkingIf true, enable Azure accelerated networking (SR-IOV) for all dataplane network interfaces. Requires PAN-OS 9.0 or higher. The PAN-OS management interface (nic0) is never accelerated, whether this variable is true or false.booltrueno
application_insights_idAn ID of Application Insights instance that should be used to provide metrics for autoscaling.

Note, to avoid false positives this should be an instance dedicated to this VMSS.
stringnullno
autoscale_count_defaultThe minimum number of instances that should be present in the scale set when the autoscaling engine cannot read the metrics or is otherwise unable to compare the metrics to the thresholds.number2no
autoscale_count_minimumThe minimum number of instances that should be present in the scale set.number2no
autoscale_count_maximumThe maximum number of instances that should be present in the scale set.number5no
autoscale_notification_emailsList of email addresses to notify about autoscaling events.list(string)[]no
autoscale_webhooks_urisMap where each key is an arbitrary identifier and each value is a webhook URI. The URIs receive autoscaling events.map(string){}no
autoscale_metricsMap of objects, where each key is the metric name to be used for autoscaling.
Each value of the map has the attributes scaleout_threshold and scalein_threshold, which cause the instance count to grow by 1 when metrics are greater or equal, or decrease by 1 when lower or equal, respectively.
The thresholds are applied to results of metrics' aggregation over a time window.
Example:
{
"DataPlaneCPUUtilizationPct" = {
scaleout_threshold = 80
scalein_threshold = 20
}
"panSessionUtilization" = {
scaleout_threshold = 80
scalein_threshold = 20
}
}
Other possible metrics include panSessionActive, panSessionThroughputKbps, panSessionThroughputPps, DataPlanePacketBufferUtilization.
map(any){}no
scaleout_statisticAggregation to use within each minute (the time grain) for metrics coming from different virtual machines. Possible values are Average, Min and Max.string"Max"no
scaleout_time_aggregationSpecifies how the metric should be combined over the time scaleout_window_minutes. Possible values are Average, Count, Maximum, Minimum, Last and Total.string"Maximum"no
scaleout_window_minutesThis is amount of time in minutes that autoscale engine will look back for metrics. For example, 10 minutes means that every time autoscale runs,
it will query metrics for the past 10 minutes. This allows metrics to stabilize and avoids reacting to transient spikes.
Must be between 5 and 720 minutes.
number10no
scaleout_cooldown_minutesAzure only considers adding a VM after this number of minutes has passed since the last VM scaling action. It should be much higher than scaleout_window_minutes, to account both for the VM-Series spin-up time and for the subsequent metrics stabilization time. Must be between 1 and 10080 minutes.number25no
scalein_statisticAggregation to use within each minute (the time grain) for metrics coming from different virtual machines. Possible values are Average, Min and Max.string"Max"no
scalein_time_aggregationSpecifies how the metric should be combined over the time scalein_window_minutes. Possible values are Average, Count, Maximum, Minimum, Last and Total.string"Maximum"no
scalein_window_minutesThis is amount of time in minutes that autoscale engine will look back for metrics. For example, 10 minutes means that every time autoscale runs,
it will query metrics for the past 10 minutes. This allows metrics to stabilize and avoids reacting to transient spikes.
Must be between 5 and 720 minutes.
number15no
scalein_cooldown_minutesAzure only considers deleting a VM after this number of minutes has passed since the last VM scaling action. Should be higher or equal to scalein_window_minutes. Must be between 1 and 10080 minutes.number2880no
tagsMap of tags to use for all the created resources.map(string){}no
bootstrap_optionsBootstrap options to pass to VM-Series instance.

Proper syntax is a string of semicolon separated properties.
Example:
bootstrap_options = "type=dhcp-client;panorama-server=1.2.3.4"

For more details on bootstrapping see documentation: https://docs.paloaltonetworks.com/vm-series/10-2/vm-series-deployment/bootstrap-the-vm-series-firewall/create-the-init-cfgtxt-file/init-cfgtxt-file-components
string""no
diagnostics_storage_uriThe storage account's blob endpoint to hold diagnostic files.stringnullno

Outputs

NameDescription
scale_set_nameName of the created scale set.

Custom Metrics

Firewalls can publish custom metrics (for example panSessionUtilization) to Azure Application Insights to improve the autoscaling. This however requires a manual initialization: copy the outputs metrics_instrumentation_key and paste it into your PAN-OS webUI -> Device -> VM-Series -> Azure. This module automatically completes solely the Step 1 of the official procedure.

If you manage the configuration from Panorama, this can be done in the same place, however the PAN-OS VM-Series plugin needs to be installed on both Panorama and VM-Series.

The metrics gathered within a single Azure Application Insights instance provided by the module, cannot be split to obtain back a result for solely a single firewall. Thus for example if three firewalls use the same Instrumentation Key and report their respective session utilizations as 90%, 20%, 10%, it is possible to see in Azure the average of 40%, the sum of 120%, the max of 90%, but it is not possible to know which of the firewalls reported the 90% utilization.