palo-alto-ha tf examples #5
13 changed files with 481 additions and 0 deletions
23
examples/iaas-paloalto-ha/00-provider.tf
Normal file
23
examples/iaas-paloalto-ha/00-provider.tf
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
|
||||
terraform {
|
||||
required_providers {
|
||||
stackit = {
|
||||
source = "stackitcloud/stackit"
|
||||
version = ">=0.50.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Authentication
|
||||
# Key flow (using path)
|
||||
|
||||
|
||||
provider "stackit" {
|
||||
default_region = var.default_region
|
||||
service_account_key_path = var.service_account_key_path
|
||||
enable_beta_resources = true
|
||||
}
|
||||
|
||||
module "project" {
|
||||
source = "./project" # Der Pfad zum Modul-Verzeichnis
|
||||
}
|
||||
158
examples/iaas-paloalto-ha/01-network.tf
Normal file
158
examples/iaas-paloalto-ha/01-network.tf
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
resource "stackit_network" "mgmt_network" {
|
||||
project_id = module.project.project_info["project_id"]
|
||||
name = "mgmt_network"
|
||||
ipv4_nameservers = ["1.1.1.1", "8.8.8.8"]
|
||||
ipv4_prefix = "10.220.129.0/24"
|
||||
routed = true
|
||||
}
|
||||
|
||||
resource "stackit_network" "ha_network" {
|
||||
project_id = module.project.project_info["project_id"]
|
||||
name = "ha_network"
|
||||
ipv4_prefix = "10.220.254.0/24"
|
||||
routed = false
|
||||
}
|
||||
|
||||
resource "stackit_network" "wan_network" {
|
||||
project_id = module.project.project_info["project_id"]
|
||||
name = "wan_network"
|
||||
ipv4_nameservers = ["1.1.1.1", "8.8.8.8"]
|
||||
ipv4_prefix = "10.220.131.0/24"
|
||||
routed = true
|
||||
}
|
||||
|
||||
|
||||
resource "stackit_network" "lan_network1" {
|
||||
project_id = module.project.project_info["project_id"]
|
||||
name = "lan_network1"
|
||||
ipv4_prefix = "10.220.1.0/24"
|
||||
routed = false
|
||||
}
|
||||
|
||||
resource "stackit_network" "lan_network2" {
|
||||
project_id = module.project.project_info["project_id"]
|
||||
name = "lan_network2"
|
||||
ipv4_prefix = "10.220.2.0/24"
|
||||
routed = false
|
||||
}
|
||||
|
||||
resource "stackit_network_interface" "mgmt" {
|
||||
project_id = module.project.project_info["project_id"]
|
||||
network_id = stackit_network.mgmt_network.network_id
|
||||
security = false
|
||||
name = "MGMT"
|
||||
ipv4 = "10.220.129.17"
|
||||
}
|
||||
|
||||
resource "stackit_network_interface" "ha" {
|
||||
project_id = module.project.project_info["project_id"]
|
||||
network_id = stackit_network.ha_network.network_id
|
||||
security = false
|
||||
name = "HA"
|
||||
ipv4 = "10.220.254.100"
|
||||
}
|
||||
resource "stackit_network_interface" "wan" {
|
||||
project_id = module.project.project_info["project_id"]
|
||||
network_id = stackit_network.wan_network.network_id
|
||||
security = true
|
||||
name = "MGMT"
|
||||
ipv4 = "10.220.131.10"
|
||||
allowed_addresses = ["10.220.131.30/32", "0.0.0.0/0"]
|
||||
security_group_ids = [stackit_security_group.paloalto.security_group_id]
|
||||
|
||||
}
|
||||
|
||||
resource "stackit_network_interface" "mgmt2" {
|
||||
project_id = module.project.project_info["project_id"]
|
||||
network_id = stackit_network.mgmt_network.network_id
|
||||
security = false
|
||||
name = "MGMT2"
|
||||
ipv4 = "10.220.129.18"
|
||||
}
|
||||
|
||||
resource "stackit_network_interface" "ha2" {
|
||||
project_id = module.project.project_info["project_id"]
|
||||
network_id = stackit_network.ha_network.network_id
|
||||
security = false
|
||||
name = "HA2"
|
||||
ipv4 = "10.220.254.200"
|
||||
}
|
||||
resource "stackit_network_interface" "wan2" {
|
||||
project_id = module.project.project_info["project_id"]
|
||||
network_id = stackit_network.wan_network.network_id
|
||||
security = true
|
||||
name = "WAN2"
|
||||
allowed_addresses = ["10.220.131.30/32", "0.0.0.0/0"]
|
||||
security_group_ids = [stackit_security_group.paloalto.security_group_id]
|
||||
}
|
||||
|
||||
resource "stackit_network_interface" "vip" {
|
||||
project_id = module.project.project_info["project_id"]
|
||||
network_id = stackit_network.wan_network.network_id
|
||||
security = false
|
||||
name = "VIP"
|
||||
ipv4 = "10.220.131.30"
|
||||
}
|
||||
|
||||
resource "stackit_network_interface" "lan1" {
|
||||
project_id = module.project.project_info["project_id"]
|
||||
network_id = stackit_network.lan_network1.network_id
|
||||
security = false
|
||||
name = "LAN1"
|
||||
}
|
||||
resource "stackit_network_interface" "lan1_2" {
|
||||
project_id = module.project.project_info["project_id"]
|
||||
network_id = stackit_network.lan_network1.network_id
|
||||
security = false
|
||||
name = "LAN1"
|
||||
}
|
||||
|
||||
resource "stackit_network_interface" "lan2" {
|
||||
project_id = module.project.project_info["project_id"]
|
||||
network_id = stackit_network.lan_network2.network_id
|
||||
security = false
|
||||
name = "LAN2"
|
||||
}
|
||||
resource "stackit_network_interface" "lan2_2" {
|
||||
project_id = module.project.project_info["project_id"]
|
||||
network_id = stackit_network.lan_network2.network_id
|
||||
security = false
|
||||
name = "LAN2"
|
||||
}
|
||||
|
||||
resource "stackit_public_ip" "mgmt_ip" {
|
||||
project_id = module.project.project_info["project_id"]
|
||||
network_interface_id = stackit_network_interface.mgmt.network_interface_id
|
||||
}
|
||||
|
||||
resource "stackit_public_ip" "wan_ip" {
|
||||
project_id = module.project.project_info["project_id"]
|
||||
network_interface_id = stackit_network_interface.wan.network_interface_id
|
||||
}
|
||||
|
||||
|
||||
resource "stackit_public_ip" "mgmt2_ip" {
|
||||
project_id = module.project.project_info["project_id"]
|
||||
network_interface_id = stackit_network_interface.mgmt2.network_interface_id
|
||||
}
|
||||
|
||||
resource "stackit_public_ip" "wan2_ip" {
|
||||
project_id = module.project.project_info["project_id"]
|
||||
network_interface_id = stackit_network_interface.wan2.network_interface_id
|
||||
}
|
||||
|
||||
resource "stackit_public_ip" "vip_ip" {
|
||||
project_id = module.project.project_info["project_id"]
|
||||
network_interface_id = stackit_network_interface.vip.network_interface_id
|
||||
}
|
||||
|
||||
output "public_ips" {
|
||||
value = {
|
||||
"mgmt_ip" = stackit_public_ip.mgmt_ip.ip
|
||||
"wan_ip" = stackit_public_ip.wan_ip.ip
|
||||
"mgmt2_ip" = stackit_public_ip.mgmt2_ip.ip
|
||||
"wan2_ip" = stackit_public_ip.wan2_ip.ip
|
||||
"VIP" = stackit_public_ip.vip_ip.ip
|
||||
}
|
||||
}
|
||||
|
||||
13
examples/iaas-paloalto-ha/02-paloalto-image.tf
Normal file
13
examples/iaas-paloalto-ha/02-paloalto-image.tf
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
// Upload VPN Appliance Image to STACKIT
|
||||
resource "stackit_image" "paloalto" {
|
||||
project_id = module.project.project_info["project_id"]
|
||||
name = "PA-VM-KVM-11.2.5-root"
|
||||
local_file_path = "./PA-VM-KVM-11.2.5.qcow2"
|
||||
disk_format = "qcow2"
|
||||
min_disk_size = 80
|
||||
min_ram = 8
|
||||
config = {
|
||||
uefi = false
|
||||
}
|
||||
}
|
||||
|
||||
48
examples/iaas-paloalto-ha/03-paloalto_appliance.tf
Normal file
48
examples/iaas-paloalto-ha/03-paloalto_appliance.tf
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
resource "stackit_volume" "paloalto_vol" {
|
||||
project_id = module.project.project_info["project_id"]
|
||||
name = "PA-VM-KVM-11.2.5-root"
|
||||
availability_zone = var.region_az1
|
||||
size = 100
|
||||
performance_class = "storage_premium_perf2"
|
||||
source = {
|
||||
id = stackit_image.paloalto.image_id
|
||||
type = "image"
|
||||
}
|
||||
}
|
||||
|
||||
resource "stackit_server" "paloalto_server" {
|
||||
project_id = module.project.project_info["project_id"]
|
||||
name = "paloAlto"
|
||||
boot_volume = {
|
||||
source_type = "volume"
|
||||
source_id = stackit_volume.paloalto_vol.volume_id
|
||||
}
|
||||
availability_zone = var.region_az1
|
||||
machine_type = var.flavor
|
||||
network_interfaces = [stackit_network_interface.mgmt.network_interface_id, stackit_network_interface.ha.network_interface_id, stackit_network_interface.wan.network_interface_id]
|
||||
}
|
||||
|
||||
resource "stackit_volume" "paloalto_vol_2" {
|
||||
project_id = module.project.project_info["project_id"]
|
||||
name = "PA-VM-KVM-11.2.5-root2"
|
||||
availability_zone = var.region_az2
|
||||
size = 100
|
||||
performance_class = "storage_premium_perf2"
|
||||
source = {
|
||||
id = stackit_image.paloalto.image_id
|
||||
type = "image"
|
||||
}
|
||||
}
|
||||
|
||||
resource "stackit_server" "paloalto_server_2" {
|
||||
project_id = module.project.project_info["project_id"]
|
||||
name = "paloAlto2"
|
||||
boot_volume = {
|
||||
source_type = "volume"
|
||||
source_id = stackit_volume.paloalto_vol_2.volume_id
|
||||
}
|
||||
availability_zone = var.region_az2
|
||||
machine_type = var.flavor
|
||||
network_interfaces = [stackit_network_interface.mgmt2.network_interface_id, stackit_network_interface.ha2.network_interface_id, stackit_network_interface.wan2.network_interface_id]
|
||||
}
|
||||
|
||||
25
examples/iaas-paloalto-ha/04-attachment.tf
Normal file
25
examples/iaas-paloalto-ha/04-attachment.tf
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
resource "stackit_server_network_interface_attach" "nic-attachment-lan1" {
|
||||
project_id = module.project.project_info.project_id
|
||||
server_id = stackit_server.paloalto_server.server_id
|
||||
network_interface_id = stackit_network_interface.lan1.network_interface_id
|
||||
depends_on = [ stackit_server_network_interface_attach.nic-attachment-lan1 ]
|
||||
}
|
||||
resource "stackit_server_network_interface_attach" "nic-attachment-lan2" {
|
||||
project_id = module.project.project_info.project_id
|
||||
server_id = stackit_server.paloalto_server.server_id
|
||||
network_interface_id = stackit_network_interface.lan2.network_interface_id
|
||||
depends_on = [ stackit_server_network_interface_attach.nic-attachment-lan1 ]
|
||||
}
|
||||
|
||||
resource "stackit_server_network_interface_attach" "nic-attachment-lan1_2" {
|
||||
project_id = module.project.project_info.project_id
|
||||
server_id = stackit_server.paloalto_server_2.server_id
|
||||
network_interface_id = stackit_network_interface.lan1_2.network_interface_id
|
||||
depends_on = [ stackit_server_network_interface_attach.nic-attachment-lan2 ]
|
||||
}
|
||||
resource "stackit_server_network_interface_attach" "nic-attachment-lan2_2" {
|
||||
project_id = module.project.project_info.project_id
|
||||
server_id = stackit_server.paloalto_server_2.server_id
|
||||
network_interface_id = stackit_network_interface.lan2_2.network_interface_id
|
||||
depends_on = [ stackit_server_network_interface_attach.nic-attachment-lan1_2 ]
|
||||
}
|
||||
33
examples/iaas-paloalto-ha/05-security-group.tf
Normal file
33
examples/iaas-paloalto-ha/05-security-group.tf
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
resource "stackit_security_group" "paloalto" {
|
||||
project_id = module.project.project_info["project_id"]
|
||||
name = "test"
|
||||
labels = {
|
||||
|
|
||||
"key" = "example"
|
||||
}
|
||||
}
|
||||
|
||||
resource "stackit_security_group_rule" "icmp_ingress" {
|
||||
project_id = module.project.project_info["project_id"]
|
||||
security_group_id = stackit_security_group.paloalto.security_group_id
|
||||
direction = "ingress"
|
||||
icmp_parameters = {
|
||||
code = 0
|
||||
type = 8
|
||||
}
|
||||
protocol = {
|
||||
name = "icmp"
|
||||
}
|
||||
}
|
||||
resource "stackit_security_group_rule" "icmp_egress" {
|
||||
project_id = module.project.project_info["project_id"]
|
||||
security_group_id = stackit_security_group.paloalto.security_group_id
|
||||
direction = "egress"
|
||||
icmp_parameters = {
|
||||
code = 0
|
||||
type = 8
|
||||
}
|
||||
protocol = {
|
||||
name = "icmp"
|
||||
}
|
||||
}
|
||||
|
||||
35
examples/iaas-paloalto-ha/99-variables.tf
Normal file
35
examples/iaas-paloalto-ha/99-variables.tf
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
# -- network variables
|
||||
variable "organization_id" {
|
||||
default = "03a34540-3c1a-4794-b2c6-7111ecf824ef"
|
||||
}
|
||||
|
||||
variable "service_account_key_path" {
|
||||
default = "/Users/sodan/.stackit/credentials.json"
|
||||
}
|
||||
|
||||
variable "default_region" {
|
||||
default ="eu01"
|
||||
}
|
||||
|
||||
variable "region_az1" {
|
||||
default = "eu01-1"
|
||||
}
|
||||
|
||||
variable "region_az2" {
|
||||
default = "eu01-2"
|
||||
}
|
||||
|
||||
variable "region_az3" {
|
||||
default = "eu01-3"
|
||||
}
|
||||
|
||||
variable "region_metro" {
|
||||
default = "eu01-m"
|
||||
}
|
||||
|
||||
variable "flavor" {
|
||||
type = string
|
||||
description = ""
|
||||
default = "m1.2"
|
||||
|
mauritz.uphoff
commented
flavor ist deprecated flavor ist deprecated
|
||||
}
|
||||
|
||||
56
examples/iaas-paloalto-ha/README.md
Normal file
56
examples/iaas-paloalto-ha/README.md
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
# Palo Alto HA Setup with Terraform (STACKIT Cloud)
|
||||
|
||||
This Terraform configuration sets up a new project inside your organisation with an SNA as described in the .tf file.
|
||||
Then two **Palo Alto Firewalls** in a **High Availability (HA)** setup on the **STACKIT Cloud IaaS** layer will be deployed.
|
||||
It includes proper configuration for floating IPs (VIPs), port security, and network interface rules.
|
||||
This is only example code, so please change for your needs !
|
||||
|
mauritz.uphoff
commented
"his is only example code, so please change for your needs !" his is only example code, so please change for your needs! "his is only example code, so please change for your needs !"
-> kein Leerzeichen zwischen Wort und Ausrufezeichen
his is only example code, so please change for your needs!
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Key Concepts
|
||||
|
||||
### 🔁 High Availability (HA)
|
||||
Two firewalls are deployed with identical network interfaces. A virtual IP (VIP) is configured for failover between the two units.
|
||||
|
||||
### 🧷 Port Security & VIPs
|
||||
- `port_security` **must be enabled** on interfaces where the **VIP** is active.
|
||||
- **Do not attach** the VIP interface to any server or instance!
|
||||
- VIP must be added as an `allowed_address_pair` on **both firewalls'** relevant interfaces.
|
||||
|
||||
---
|
||||
|
||||
## ✅ Requirements
|
||||
|
||||
- Terraform ≥ 1.3.x
|
||||
- [STACKIT Terraform Provider](https://registry.terraform.io/providers/stackitcloud/stackit/latest)
|
||||
- Palo Alto VM-Series Images (pre-imported into the STACKIT project)
|
||||
|
||||
---
|
||||
|
||||
## 🚧 Limitations & Notes
|
||||
|
||||
- **VIP must not be attached to any instance**
|
||||
The floating IP (VIP) is managed entirely by the Palo Alto HA configuration. Do **not** associate this IP statically with any compute instance via Terraform.
|
||||
|
||||
- **Setting CIDRs in `allowed_addresses`**
|
||||
You **must** specify the VIP as a `/32` IP (e.g., `10.220.131.30/32`) — CIDR blocks (e.g., `/24`) are not supported and will be rejected or silently ignored.
|
||||
You **must** specify the CIDR `0.0.0.0/0` as a second string, this is necessary for a working failover scenario.
|
||||
|
||||
- **Routing issues if `allowed_addresses` are missing**
|
||||
If the VIP is not explicitly added to `allowed_addresses` on each port where it might be active, network traffic will fail silently due to missing neighbor/ARP entries.
|
||||
|
||||
- **Security groups must explicitly allow VIP traffic**
|
||||
When using `port_security = true`, ensure that the correct **security group rules** allow inbound/outbound traffic for the VIP address. If omitted, traffic will be blocked.
|
||||
|
||||
- **Interface networks must match on both firewalls**
|
||||
For a successful HA sync and failover, interfaces on both firewalls must be connected to the **same virtual networks** with matching roles (e.g., both `wan`, both `lan1`, etc.).
|
||||
|
||||
- **No dynamic interface switching in Terraform**
|
||||
VIP failover happens on the firewall level. Terraform is **not** responsible for enabling/disabling interfaces — make sure the Palo Alto HA config is correctly set up within the OS.
|
||||
|
||||
- **HA Sync and Preemption is not handled by Terraform**
|
||||
The logic for state sync, failover, and preemption priorities must be configured manually in the firewall GUI or CLI. This project only provisions the infrastructure.
|
||||
|
||||
- **floating IP switch only possible with GARP**
|
||||
Important: The Floating IP will only work correctly after the move if a Gratuitous ARP (GARP) is sent out — this ensures that the IP-to-MAC binding is updated on neighboring network devices.
|
||||
|
||||
18
examples/iaas-paloalto-ha/project/00-provider.tf
Normal file
18
examples/iaas-paloalto-ha/project/00-provider.tf
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
|
||||
terraform {
|
||||
required_providers {
|
||||
stackit = {
|
||||
source = "stackitcloud/stackit"
|
||||
version = ">=0.50.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Authentication
|
||||
# Key flow (using path)
|
||||
|
||||
provider "stackit" {
|
||||
default_region = var.default_region
|
||||
service_account_key_path = var.service_account_key_path
|
||||
enable_beta_resources = true
|
||||
}
|
||||
15
examples/iaas-paloalto-ha/project/01-sna.tf
Normal file
15
examples/iaas-paloalto-ha/project/01-sna.tf
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
resource "time_sleep" "wait_before_destroy" {
|
||||
destroy_duration = "60s"
|
||||
}
|
||||
|
||||
resource "stackit_network_area" "sna" {
|
||||
organization_id = var.organization_id
|
||||
name = "connectivity"
|
||||
network_ranges = [
|
||||
{
|
||||
prefix = "10.0.0.0/8"
|
||||
}
|
||||
]
|
||||
transfer_network = "192.168.254.0/24"
|
||||
depends_on = [time_sleep.wait_before_destroy]
|
||||
}
|
||||
21
examples/iaas-paloalto-ha/project/02-project.tf
Normal file
21
examples/iaas-paloalto-ha/project/02-project.tf
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
resource "stackit_resourcemanager_project" "paloalto" {
|
||||
parent_container_id = var.organization_id
|
||||
name = "paloalto_ha"
|
||||
owner_email = "michael.sodan@stackit.cloud"
|
||||
labels = {
|
||||
"networkArea" = stackit_network_area.sna.network_area_id
|
||||
}
|
||||
}
|
||||
|
||||
data "stackit_resourcemanager_project" "paloalto" {
|
||||
|
mauritz.uphoff
commented
Wozu die Datasource? Wozu die Datasource?
|
||||
project_id = stackit_resourcemanager_project.paloalto.project_id
|
||||
container_id = stackit_resourcemanager_project.paloalto.container_id
|
||||
}
|
||||
|
||||
output "project_info" {
|
||||
value = {
|
||||
project_id = data.stackit_resourcemanager_project.paloalto.project_id
|
||||
|
mauritz.uphoff
commented
Das geht doch auch direkt: stackit_resourcemanager_project.paloalto.project_id Das geht doch auch direkt: stackit_resourcemanager_project.paloalto.project_id
|
||||
container_id = data.stackit_resourcemanager_project.paloalto.container_id
|
||||
}
|
||||
}
|
||||
|
||||
35
examples/iaas-paloalto-ha/project/99-variables.tf
Normal file
35
examples/iaas-paloalto-ha/project/99-variables.tf
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
# -- network variables
|
||||
variable "organization_id" {
|
||||
default = "03a34540-3c1a-4794-b2c6-7111ecf824ef"
|
||||
}
|
||||
|
||||
variable "service_account_key_path" {
|
||||
default = "/Users/sodan/.stackit/credentials.json"
|
||||
}
|
||||
|
||||
variable "default_region" {
|
||||
default ="eu01"
|
||||
}
|
||||
|
||||
variable "region_az1" {
|
||||
default = "eu01-1"
|
||||
}
|
||||
|
||||
variable "region_az2" {
|
||||
default = "eu01-2"
|
||||
}
|
||||
|
||||
variable "region_az3" {
|
||||
default = "eu01-3"
|
||||
}
|
||||
|
||||
variable "region_metro" {
|
||||
default = "eu01-m"
|
||||
}
|
||||
|
||||
variable "flavor" {
|
||||
type = string
|
||||
description = ""
|
||||
default = "c1.2"
|
||||
|
mauritz.uphoff
commented
outdated flavor outdated flavor
|
||||
}
|
||||
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
General maintainers:
|
||||
|
||||
- Mauritz Uphoff (mauritz.uphoff@digits.schwarz)
|
||||
- Michael Sodan (michael.sodan@digits.schwarz)
|
||||
|
||||
This example is actively maintained. The owner is responsible for reviewing and updating dependencies and functionalities on a monthly basis.
|
||||
For questions, issues, or feature requests, please email general maintainers.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue
Label kann entfernt werden