- HCL 100%
| .gitignore | ||
| .terraform.lock.hcl | ||
| 00-variables.auto.tfvars.example | ||
| 01-provider.tf | ||
| 02-config.tf | ||
| 03-paloalto-infra.tf | ||
| 04-paloalto-network.tf | ||
| 05-paloalto-appliance1.tf | ||
| 06-paloalto-appliance2.tf | ||
| 07-spoke-vm.tf | ||
| HubSpokePaloAlto.drawio | ||
| HubSpokePaloAlto.png | ||
| README.md | ||
Palo Alto VM-Series HA on STACKIT
Terraform reference deployment for a hub-and-spoke environment on STACKIT. It provisions two Palo Alto Networks VM-Series firewalls as the infrastructure for an active/passive HA pair, a STACKIT Network Area (SNA), separate management, WAN, LAN and HA2 networks, and a Debian VM in a second project for testing the spoke connection.
Important
Terraform creates the cloud infrastructure, but it does not configure PAN-OS. Licensing, HA, interfaces, virtual routers, security policies and NAT must be configured on the appliances after deployment.
The editable architecture diagram is available as
HubSpokePaloAlto.drawio.
Architecture
The deployment separates the firewall hub and test workload into two STACKIT projects connected through one SNA:
- Hub project: two VM-Series appliances, their boot volumes, four firewall networks, HA VIP interfaces, a public IP and security groups.
- Spoke project: one Debian test VM, its network, boot volume, public IP, SSH key pair and security group.
- STACKIT Network Area: connects both projects and provides routing tables for WAN, LAN and spoke traffic.
- High availability: both firewalls use dedicated node addresses. Shared WAN and LAN addresses are represented by separate, unattached network interfaces and permitted on both firewall NICs through allowed addresses.
Traffic paths
| Traffic | Path |
|---|---|
| Internet to firewall | Public IP → WAN VIP → active firewall WAN interface |
| Spoke to Internet | Debian network → LAN VIP → active firewall → WAN → Internet |
| Firewall management | Management network → individual management IP |
| HA synchronization | Dedicated sync network between both HA2 interfaces |
The routing tables point default traffic from the spoke and firewall LAN toward
the LAN VIP. The WAN routing table uses the Internet as its default next hop.
Routes for the workstation's current public IP are generated from
https://ifconfig.schwarz during Terraform evaluation.
Provisioned resources
| Area | Resources |
|---|---|
| Organization | One SNA, one SNA region and three routing tables |
| Hub project | Four networks, two firewalls, two 200 GiB boot volumes, eight node NICs, two VIP NICs, one public VIP and one security group |
| Spoke project | One network, one Debian VM, one 60 GiB boot volume, one NIC, one public IP, one key pair and one security group |
| Image | One private VM-Series image imported from a local QCOW2 file |
Both STACKIT projects are created by this configuration. The SNA ID is applied
to them through the networkArea project label.
Network defaults
The values below are defaults from 02-config.tf. Values in
00-variables.auto.tfvars override them.
| Network / address | Default | Purpose |
|---|---|---|
| WAN | 10.220.1.0/24 |
Internet-facing firewall interfaces |
| Management | 10.220.2.0/24 |
Per-node PAN-OS management and HA1 control |
| HA2 sync | 10.220.3.0/24 |
Session and state synchronization |
| LAN | 10.220.4.0/24 |
Protected side of the firewall pair |
| Spoke | 10.220.0.0/25 |
Debian test workload |
| WAN VIP | 10.220.1.60 |
Shared external address |
| LAN VIP | 10.220.4.80 |
Shared internal gateway |
All five network ranges must be unique. Keep every node address and VIP inside its corresponding subnet when overriding these values.
PAN-OS interface mapping
The management NIC is supplied when each server is created. The remaining NICs are attached sequentially, producing the following expected mapping:
| PAN-OS interface | STACKIT network | Purpose |
|---|---|---|
management |
paloalto_mgmt_net |
Management and HA1 control |
ethernet1/1 |
paloalto_wan_net |
WAN and public VIP traffic |
ethernet1/2 |
paloalto_lan_net |
Protected LAN and LAN gateway VIP |
ethernet1/3 |
paloalto_sync_net |
HA2 session/state synchronization |
VM-Series normally maps the first KVM interface (eth0) to management and the
following interfaces to ethernet1/1, ethernet1/2, and so on. Verify the
mapping after boot using the NIC MAC addresses shown by STACKIT:
debug show vm-series interfaces all
Repository layout
| File | Purpose |
|---|---|
00-variables.auto.tfvars.example |
Example environment-specific values |
01-provider.tf |
Provider requirements and S3-compatible remote state backend |
02-config.tf |
Input variables, defaults and network validation |
03-paloalto-infra.tf |
STACKIT projects and VM-Series image import |
04-paloalto-network.tf |
SNA, routing tables, networks, VIPs and security groups |
05-paloalto-appliance1.tf |
First VM-Series appliance, volume and NICs |
06-paloalto-appliance2.tf |
Second VM-Series appliance, volume and NICs |
07-spoke-vm.tf |
Debian spoke test VM and its network resources |
HubSpokePaloAlto.png |
Rendered architecture diagram |
HubSpokePaloAlto.drawio |
Editable diagrams.net source |
The local 00-variables.auto.tfvars, Terraform state and *.qcow2 images are
intentionally excluded through .gitignore.
Prerequisites
- Terraform CLI compatible with the provider versions in
.terraform.lock.hcl. - STACKIT organization and folder IDs plus a service-account key with permission to create the listed resources.
- An SSH public key for the Debian test VM.
- A licensed Palo Alto VM-Series KVM QCOW2 image. The default local filename is
Palo-Alto-1217.qcow2; the image itself is not included in Git. - Compatible VM-Series licenses for both peers. Both appliances should use the same PAN-OS release, VM model, license capacity and content version.
- A STACKIT machine type that meets the selected VM-Series model requirements. Verify CPU, memory and disk against the official VM-Series system requirements.
- A pre-existing Object Storage bucket and S3 credentials for the remote state
backend configured in
01-provider.tf.
The current configuration imports the QCOW2 image with a minimum disk size of 100 GiB and creates a 200 GiB premium boot volume for each firewall.
Configuration
Create a local variable file from the tracked example:
cp 00-variables.auto.tfvars.example 00-variables.auto.tfvars
At minimum, review and set:
organization_id,folder_idandproject_owner_mailservice_account_key_pathandpublic_key_pathdefault_regionanddefault_az- SNA transfer and network ranges
- firewall subnets, node IPs and shared VIPs
paloalto_image_pathand the VMflavor
Keep service-account keys and other credentials outside this repository. The paths in the variable file may point to files elsewhere on the local machine.
The backend in 01-provider.tf uses STACKIT Object Storage's S3-compatible
endpoint. The bucket must already exist, and S3 credentials must be available
to Terraform before initialization.
Deployment
Review and initialize the configuration:
terraform fmt -check
terraform init
terraform validate
terraform plan
Inspect the plan carefully, then deploy:
terraform apply
After a successful apply, Terraform exposes:
public-vip.public_ip_paloalto— public IP attached to the firewall WAN VIP.public-vm-ip.public_ip_spoke_vm— public IP attached to the Debian test VM.
Cleanup
To remove the resources managed by this configuration:
terraform plan -destroy
terraform destroy
Review the destroy plan first. The remote-state bucket, local QCOW2 image and credentials are not managed by this Terraform configuration.
