diff --git a/examples/pfsense-hub-and-spoke/001-hub-project/000-backend.tf b/examples/opnsense-hub-and-spoke/001-hub-project/000-backend.tf similarity index 100% rename from examples/pfsense-hub-and-spoke/001-hub-project/000-backend.tf rename to examples/opnsense-hub-and-spoke/001-hub-project/000-backend.tf diff --git a/examples/pfsense-hub-and-spoke/001-hub-project/000-variables.tf b/examples/opnsense-hub-and-spoke/001-hub-project/000-variables.tf similarity index 94% rename from examples/pfsense-hub-and-spoke/001-hub-project/000-variables.tf rename to examples/opnsense-hub-and-spoke/001-hub-project/000-variables.tf index 4ce0077..983bac8 100644 --- a/examples/pfsense-hub-and-spoke/001-hub-project/000-variables.tf +++ b/examples/opnsense-hub-and-spoke/001-hub-project/000-variables.tf @@ -57,8 +57,8 @@ variable "mgmt_ip_range" { default = "" } -variable "pfsense_machine_type" { - description = "Machine type for the pfSense firewall (e.g. c2i.2, c2i.4)." +variable "opnsense_machine_type" { + description = "Machine type for the OPNsense firewall (e.g. c2i.2, c2i.4)." type = string default = "c2i.2" } diff --git a/examples/pfsense-hub-and-spoke/001-hub-project/010-provider.tf b/examples/opnsense-hub-and-spoke/001-hub-project/010-provider.tf similarity index 100% rename from examples/pfsense-hub-and-spoke/001-hub-project/010-provider.tf rename to examples/opnsense-hub-and-spoke/001-hub-project/010-provider.tf diff --git a/examples/pfsense-hub-and-spoke/001-hub-project/020-projects.tf b/examples/opnsense-hub-and-spoke/001-hub-project/020-projects.tf similarity index 100% rename from examples/pfsense-hub-and-spoke/001-hub-project/020-projects.tf rename to examples/opnsense-hub-and-spoke/001-hub-project/020-projects.tf diff --git a/examples/pfsense-hub-and-spoke/001-hub-project/030-network.tf b/examples/opnsense-hub-and-spoke/001-hub-project/030-network.tf similarity index 100% rename from examples/pfsense-hub-and-spoke/001-hub-project/030-network.tf rename to examples/opnsense-hub-and-spoke/001-hub-project/030-network.tf diff --git a/examples/pfsense-hub-and-spoke/001-hub-project/040-hub-fw-pfsense.tf b/examples/opnsense-hub-and-spoke/001-hub-project/040-hub-fw-opnsense.tf similarity index 66% rename from examples/pfsense-hub-and-spoke/001-hub-project/040-hub-fw-pfsense.tf rename to examples/opnsense-hub-and-spoke/001-hub-project/040-hub-fw-opnsense.tf index dee5ae7..b6956b3 100644 --- a/examples/pfsense-hub-and-spoke/001-hub-project/040-hub-fw-pfsense.tf +++ b/examples/opnsense-hub-and-spoke/001-hub-project/040-hub-fw-opnsense.tf @@ -12,41 +12,52 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Place pfsense.qcow2 at ./image/pfsense.qcow2 before first apply. -# Download pfSense 2.7.x AMD64 from netgate.com and convert to qcow2 if needed. +resource "null_resource" "opnsense_image_file" { + triggers = { + always_run = timestamp() + } + provisioner "local-exec" { + command = "curl -o opnsense.qcow2 https://opnsense.object.storage.eu01.onstackit.cloud/opnsense-26.1-amd64-21-05-2026.qcow2" + } + lifecycle { + ignore_changes = all + } +} -resource "stackit_image" "pfsense_image" { +# Upload VPN Appliance Image to STACKIT +resource "stackit_image" "opnsense_image" { project_id = local.hub_project_id - name = "pfsense-2.7.x-amd64" - local_file_path = "./image/pfsense.qcow2" + name = "opnsense-26.1-amd64-image" + local_file_path = "opnsense.qcow2" disk_format = "qcow2" - min_disk_size = 10 + depends_on = [null_resource.opnsense_image_file] + min_disk_size = 16 min_ram = 2 config = { uefi = false } } -resource "stackit_volume" "pfsense_volume" { +resource "stackit_volume" "opnsense_volume" { project_id = local.hub_project_id - name = "pfsense-root" + name = "opnsense-root" availability_zone = var.default_zone size = 16 performance_class = "storage_premium_perf4" source = { - id = stackit_image.pfsense_image.image_id + id = stackit_image.opnsense_image.image_id type = "image" } } -resource "stackit_server" "pfsense" { +resource "stackit_server" "opnsense" { project_id = local.hub_project_id - name = "pfsense" + name = "opnsense" availability_zone = var.default_zone - machine_type = var.pfsense_machine_type + machine_type = var.opnsense_machine_type boot_volume = { source_type = "volume" - source_id = stackit_volume.pfsense_volume.volume_id + source_id = stackit_volume.opnsense_volume.volume_id } # WAN boots first (vtnet0); LAN and MGMT are attached in order below → vtnet1–2. network_interfaces = [stackit_network_interface.nic_wan.network_interface_id] @@ -54,14 +65,14 @@ resource "stackit_server" "pfsense" { resource "stackit_server_network_interface_attach" "attach_lan" { project_id = local.hub_project_id - server_id = stackit_server.pfsense.server_id + server_id = stackit_server.opnsense.server_id network_interface_id = stackit_network_interface.nic_lan.network_interface_id - depends_on = [stackit_server.pfsense] + depends_on = [stackit_server.opnsense] } resource "stackit_server_network_interface_attach" "attach_mgmt" { project_id = local.hub_project_id - server_id = stackit_server.pfsense.server_id + server_id = stackit_server.opnsense.server_id network_interface_id = stackit_network_interface.nic_mgmt.network_interface_id depends_on = [stackit_server_network_interface_attach.attach_lan] } diff --git a/examples/pfsense-hub-and-spoke/001-hub-project/050-outputs.tf b/examples/opnsense-hub-and-spoke/001-hub-project/050-outputs.tf similarity index 81% rename from examples/pfsense-hub-and-spoke/001-hub-project/050-outputs.tf rename to examples/opnsense-hub-and-spoke/001-hub-project/050-outputs.tf index 29c09aa..9b3e5a9 100644 --- a/examples/pfsense-hub-and-spoke/001-hub-project/050-outputs.tf +++ b/examples/opnsense-hub-and-spoke/001-hub-project/050-outputs.tf @@ -23,16 +23,16 @@ output "hub_project_id" { } output "firewall_lan_ip" { - description = "pfSense LAN IP — set as hub_firewall_lan_ip in spoke terraform.tfvars." + description = "OPNsense LAN IP — set as hub_firewall_lan_ip in spoke terraform.tfvars." value = stackit_network_interface.nic_lan.ipv4 } output "wan_public_ip" { - description = "WAN public IP of the pfSense firewall." + description = "WAN public IP of the OPNsense firewall." value = stackit_public_ip.wan_public_ip.ip } output "mgmt_public_ip" { - description = "Public IP of the pfSense MGMT interface. Access the web UI at https:///" + description = "Public IP of the OPNsense MGMT interface. Access the web UI at https:///" value = stackit_public_ip.mgmt_public_ip.ip } diff --git a/examples/pfsense-hub-and-spoke/001-hub-project/backend.conf.example b/examples/opnsense-hub-and-spoke/001-hub-project/backend.conf.example similarity index 100% rename from examples/pfsense-hub-and-spoke/001-hub-project/backend.conf.example rename to examples/opnsense-hub-and-spoke/001-hub-project/backend.conf.example diff --git a/examples/pfsense-hub-and-spoke/002-spoke-project/000-backend.tf b/examples/opnsense-hub-and-spoke/002-spoke-project/000-backend.tf similarity index 100% rename from examples/pfsense-hub-and-spoke/002-spoke-project/000-backend.tf rename to examples/opnsense-hub-and-spoke/002-spoke-project/000-backend.tf diff --git a/examples/pfsense-hub-and-spoke/002-spoke-project/000-variables.tf b/examples/opnsense-hub-and-spoke/002-spoke-project/000-variables.tf similarity index 92% rename from examples/pfsense-hub-and-spoke/002-spoke-project/000-variables.tf rename to examples/opnsense-hub-and-spoke/002-spoke-project/000-variables.tf index f359f80..e1315ee 100644 --- a/examples/pfsense-hub-and-spoke/002-spoke-project/000-variables.tf +++ b/examples/opnsense-hub-and-spoke/002-spoke-project/000-variables.tf @@ -63,7 +63,7 @@ variable "spoke_subnet" { } variable "hub_firewall_lan_ip" { - description = "LAN IP of the active pfSense node. Used as the default route next-hop for all spoke traffic. Run `terraform output firewall_lan_ip` in 001-hub-project." + description = "LAN IP of the active OPNsense node. Used as the default route next-hop for all spoke traffic. Run `terraform output firewall_lan_ip` in 001-hub-project." type = string default = "10.28.0.20" } diff --git a/examples/pfsense-hub-and-spoke/002-spoke-project/010-provider.tf b/examples/opnsense-hub-and-spoke/002-spoke-project/010-provider.tf similarity index 100% rename from examples/pfsense-hub-and-spoke/002-spoke-project/010-provider.tf rename to examples/opnsense-hub-and-spoke/002-spoke-project/010-provider.tf diff --git a/examples/pfsense-hub-and-spoke/002-spoke-project/020-projects.tf b/examples/opnsense-hub-and-spoke/002-spoke-project/020-projects.tf similarity index 100% rename from examples/pfsense-hub-and-spoke/002-spoke-project/020-projects.tf rename to examples/opnsense-hub-and-spoke/002-spoke-project/020-projects.tf diff --git a/examples/pfsense-hub-and-spoke/002-spoke-project/030-network.tf b/examples/opnsense-hub-and-spoke/002-spoke-project/030-network.tf similarity index 100% rename from examples/pfsense-hub-and-spoke/002-spoke-project/030-network.tf rename to examples/opnsense-hub-and-spoke/002-spoke-project/030-network.tf diff --git a/examples/pfsense-hub-and-spoke/002-spoke-project/040-servers.tf b/examples/opnsense-hub-and-spoke/002-spoke-project/040-servers.tf similarity index 100% rename from examples/pfsense-hub-and-spoke/002-spoke-project/040-servers.tf rename to examples/opnsense-hub-and-spoke/002-spoke-project/040-servers.tf diff --git a/examples/pfsense-hub-and-spoke/002-spoke-project/050-outputs.tf b/examples/opnsense-hub-and-spoke/002-spoke-project/050-outputs.tf similarity index 100% rename from examples/pfsense-hub-and-spoke/002-spoke-project/050-outputs.tf rename to examples/opnsense-hub-and-spoke/002-spoke-project/050-outputs.tf diff --git a/examples/pfsense-hub-and-spoke/002-spoke-project/backend.conf.example b/examples/opnsense-hub-and-spoke/002-spoke-project/backend.conf.example similarity index 100% rename from examples/pfsense-hub-and-spoke/002-spoke-project/backend.conf.example rename to examples/opnsense-hub-and-spoke/002-spoke-project/backend.conf.example diff --git a/examples/pfsense-hub-and-spoke/003-spoke-project/000-backend.tf b/examples/opnsense-hub-and-spoke/003-spoke-project/000-backend.tf similarity index 100% rename from examples/pfsense-hub-and-spoke/003-spoke-project/000-backend.tf rename to examples/opnsense-hub-and-spoke/003-spoke-project/000-backend.tf diff --git a/examples/pfsense-hub-and-spoke/003-spoke-project/000-variables.tf b/examples/opnsense-hub-and-spoke/003-spoke-project/000-variables.tf similarity index 92% rename from examples/pfsense-hub-and-spoke/003-spoke-project/000-variables.tf rename to examples/opnsense-hub-and-spoke/003-spoke-project/000-variables.tf index ba627ad..0536af9 100644 --- a/examples/pfsense-hub-and-spoke/003-spoke-project/000-variables.tf +++ b/examples/opnsense-hub-and-spoke/003-spoke-project/000-variables.tf @@ -63,7 +63,7 @@ variable "spoke_subnet" { } variable "hub_firewall_lan_ip" { - description = "LAN IP of the active pfSense node. Used as the default route next-hop for all spoke traffic. Run `terraform output firewall_lan_ip` in 001-hub-project." + description = "LAN IP of the active OPNsense node. Used as the default route next-hop for all spoke traffic. Run `terraform output firewall_lan_ip` in 001-hub-project." type = string default = "10.28.0.20" } diff --git a/examples/pfsense-hub-and-spoke/003-spoke-project/010-provider.tf b/examples/opnsense-hub-and-spoke/003-spoke-project/010-provider.tf similarity index 100% rename from examples/pfsense-hub-and-spoke/003-spoke-project/010-provider.tf rename to examples/opnsense-hub-and-spoke/003-spoke-project/010-provider.tf diff --git a/examples/pfsense-hub-and-spoke/003-spoke-project/020-projects.tf b/examples/opnsense-hub-and-spoke/003-spoke-project/020-projects.tf similarity index 100% rename from examples/pfsense-hub-and-spoke/003-spoke-project/020-projects.tf rename to examples/opnsense-hub-and-spoke/003-spoke-project/020-projects.tf diff --git a/examples/pfsense-hub-and-spoke/003-spoke-project/030-network.tf b/examples/opnsense-hub-and-spoke/003-spoke-project/030-network.tf similarity index 100% rename from examples/pfsense-hub-and-spoke/003-spoke-project/030-network.tf rename to examples/opnsense-hub-and-spoke/003-spoke-project/030-network.tf diff --git a/examples/pfsense-hub-and-spoke/003-spoke-project/040-servers.tf b/examples/opnsense-hub-and-spoke/003-spoke-project/040-servers.tf similarity index 100% rename from examples/pfsense-hub-and-spoke/003-spoke-project/040-servers.tf rename to examples/opnsense-hub-and-spoke/003-spoke-project/040-servers.tf diff --git a/examples/pfsense-hub-and-spoke/003-spoke-project/050-outputs.tf b/examples/opnsense-hub-and-spoke/003-spoke-project/050-outputs.tf similarity index 100% rename from examples/pfsense-hub-and-spoke/003-spoke-project/050-outputs.tf rename to examples/opnsense-hub-and-spoke/003-spoke-project/050-outputs.tf diff --git a/examples/pfsense-hub-and-spoke/003-spoke-project/backend.conf.example b/examples/opnsense-hub-and-spoke/003-spoke-project/backend.conf.example similarity index 100% rename from examples/pfsense-hub-and-spoke/003-spoke-project/backend.conf.example rename to examples/opnsense-hub-and-spoke/003-spoke-project/backend.conf.example diff --git a/examples/pfsense-hub-and-spoke/MAINTAINERS.md b/examples/opnsense-hub-and-spoke/MAINTAINERS.md similarity index 100% rename from examples/pfsense-hub-and-spoke/MAINTAINERS.md rename to examples/opnsense-hub-and-spoke/MAINTAINERS.md diff --git a/examples/pfsense-hub-and-spoke/README.md b/examples/opnsense-hub-and-spoke/README.md similarity index 83% rename from examples/pfsense-hub-and-spoke/README.md rename to examples/opnsense-hub-and-spoke/README.md index 46de94b..bb21d0c 100644 --- a/examples/pfsense-hub-and-spoke/README.md +++ b/examples/opnsense-hub-and-spoke/README.md @@ -1,8 +1,8 @@ -# Hub-and-Spoke VPN on STACKIT — pfSense Reference Implementation +# Hub-and-Spoke VPN on STACKIT — OPNsense Reference Implementation A reference implementation of a **hub-and-spoke network topology** on [STACKIT](https://www.stackit.de/), provisioned with Terraform. -The hub deploys a **pfSense firewall** as the central routing and security component. All spoke traffic is forwarded through pfSense for routing, NAT, and policy enforcement. Each project is a self-contained Terraform stack with independent state. +The hub deploys an **OPNsense firewall** as the central routing and security component. All spoke traffic is forwarded through OPNsense for routing, NAT, and policy enforcement. Each project is a self-contained Terraform stack with independent state. --- @@ -17,7 +17,7 @@ The hub deploys a **pfSense firewall** as the central routing and security compo | +-------------------------------------------------------------+ | | | 001-hub-project | | | | | | - | | pfSense Firewall | | + | | OPNsense Firewall | | | | +------------------+------------------+ | | | | | Interface | IP | | | | | +------------------+------------------+ | | @@ -38,7 +38,7 @@ The hub deploys a **pfSense firewall** as the central routing and security compo +-------------------------------------------------------------------+ ``` -**Traffic flow:** All spoke traffic (including internet-bound) is forwarded to the pfSense LAN NIC (`10.28.0.20`) via a routing table route attached to each spoke network. pfSense handles routing, NAT, and firewall policy centrally. +**Traffic flow:** All spoke traffic (including internet-bound) is forwarded to the OPNsense LAN NIC (`10.28.0.20`) via a routing table route attached to each spoke network. OPNsense handles routing, NAT, and firewall policy centrally. --- @@ -46,22 +46,22 @@ The hub deploys a **pfSense firewall** as the central routing and security compo ``` hub-and-spoke-vpn/ -├── 001-hub-project/ # Hub: pfSense firewall, network area, routing tables -│ ├── 000-backend.tf # S3 remote state backend -│ ├── 000-variables.tf # Input variables (pfsense_machine_type, mgmt_ip_range) -│ ├── 010-provider.tf # STACKIT provider -│ ├── 020-projects.tf # STACKIT project + shared network area (SNA) -│ ├── 030-network.tf # Subnets, routing tables, NICs, security groups -│ ├── 040-hub-fw-pfsense.tf # pfSense image, volume, server, public IPs -│ ├── 050-outputs.tf # network_area_id, firewall_lan_ip, public IPs (needed by spokes) -│ └── backend.conf.example # Backend credential template +├── 001-hub-project/ # Hub: OPNsense firewall, network area, routing tables +│ ├── 000-backend.tf # S3 remote state backend +│ ├── 000-variables.tf # Input variables (opnsense_machine_type, mgmt_ip_range) +│ ├── 010-provider.tf # STACKIT provider +│ ├── 020-projects.tf # STACKIT project + shared network area (SNA) +│ ├── 030-network.tf # Subnets, routing tables, NICs, security groups +│ ├── 040-hub-fw-opnsense.tf # OPNsense image, volume, server, public IPs +│ ├── 050-outputs.tf # network_area_id, firewall_lan_ip, public IPs (needed by spokes) +│ └── backend.conf.example # Backend credential template │ ├── 002-spoke-project/ # Spoke A: example Linux servers (RHEL 9) │ ├── 000-backend.tf │ ├── 000-variables.tf │ ├── 010-provider.tf │ ├── 020-projects.tf -│ ├── 030-network.tf # Spoke subnet + routing table (default → pfSense LAN) +│ ├── 030-network.tf # Spoke subnet + routing table (default → OPNsense LAN) │ ├── 040-servers.tf # Two Linux server examples (different machine types) │ ├── 050-outputs.tf │ └── backend.conf.example @@ -161,7 +161,7 @@ The minimum required values are documented in each `000-variables.tf`. Deploy in numbered order. The hub creates the shared network area that spokes depend on. ```sh -# Step 1 — Deploy the hub (creates the network area and the pfSense firewall) +# Step 1 — Deploy the hub (creates the network area and the OPNsense firewall) cd 001-hub-project terraform init -backend-config=backend.conf terraform apply @@ -182,9 +182,9 @@ terraform apply --- -## Hub Firewall (pfSense) +## Hub Firewall (OPNsense) -pfSense is provisioned from a qcow2 image with three network interfaces: +OPNsense is provisioned from a qcow2 image with three network interfaces: | Interface | Subnet | IP | Purpose | | --------- | --------------- | ------------ | -------------------------- | @@ -194,7 +194,7 @@ pfSense is provisioned from a qcow2 image with three network interfaces: The WAN interface boots first (`vtnet0`); LAN and MGMT are attached sequentially and appear as `vtnet1` and `vtnet2`. The MGMT interface is protected by a security group that restricts SSH, HTTP, and HTTPS access to the CIDR set in `mgmt_ip_range`. -**pfSense image:** Place `pfsense.qcow2` at `001-hub-project/image/pfsense.qcow2` before the first apply. Download pfSense 2.7.x AMD64 from netgate.com and convert to qcow2 if needed. +**OPNsense image:** The image is downloaded automatically during `terraform apply` via a `null_resource` provisioner. The qcow2 image is fetched from the STACKIT Object Storage endpoint and uploaded to STACKIT as a custom image. --- @@ -244,7 +244,6 @@ A single generic module used by all spokes. Select the OS by passing the appropr | Backend credentials | `backend.conf` per project | Object Storage bucket + S3 keys | | Service account key | `keys/service-account.json` per project | Downloaded from STACKIT portal | | Cloud-init password | `cloud-init/*.yml` | Replace placeholder hash with a real one | -| pfSense image | `001-hub-project/image/pfsense.qcow2` | Download separately | --- @@ -252,4 +251,4 @@ A single generic module used by all spokes. Select the OS by passing the appropr - [STACKIT Terraform Provider](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs) - [STACKIT Documentation](https://docs.stackit.cloud/) -- [pfSense Documentation](https://docs.netgate.com/pfsense/en/latest/) +- [OPNsense Documentation](https://docs.opnsense.org/) diff --git a/examples/pfsense-hub-and-spoke/cloud-init/user-init-linux.yml b/examples/opnsense-hub-and-spoke/cloud-init/user-init-linux.yml similarity index 100% rename from examples/pfsense-hub-and-spoke/cloud-init/user-init-linux.yml rename to examples/opnsense-hub-and-spoke/cloud-init/user-init-linux.yml diff --git a/examples/pfsense-hub-and-spoke/cloud-init/user-init-windows.yml b/examples/opnsense-hub-and-spoke/cloud-init/user-init-windows.yml similarity index 100% rename from examples/pfsense-hub-and-spoke/cloud-init/user-init-windows.yml rename to examples/opnsense-hub-and-spoke/cloud-init/user-init-windows.yml diff --git a/examples/pfsense-hub-and-spoke/modules/server/main.tf b/examples/opnsense-hub-and-spoke/modules/server/main.tf similarity index 100% rename from examples/pfsense-hub-and-spoke/modules/server/main.tf rename to examples/opnsense-hub-and-spoke/modules/server/main.tf diff --git a/examples/pfsense-hub-and-spoke/modules/server/outputs.tf b/examples/opnsense-hub-and-spoke/modules/server/outputs.tf similarity index 100% rename from examples/pfsense-hub-and-spoke/modules/server/outputs.tf rename to examples/opnsense-hub-and-spoke/modules/server/outputs.tf diff --git a/examples/pfsense-hub-and-spoke/modules/server/variables.tf b/examples/opnsense-hub-and-spoke/modules/server/variables.tf similarity index 100% rename from examples/pfsense-hub-and-spoke/modules/server/variables.tf rename to examples/opnsense-hub-and-spoke/modules/server/variables.tf diff --git a/examples/pfsense-hub-and-spoke/terraform.tfvars.example b/examples/opnsense-hub-and-spoke/terraform.tfvars.example similarity index 92% rename from examples/pfsense-hub-and-spoke/terraform.tfvars.example rename to examples/opnsense-hub-and-spoke/terraform.tfvars.example index 9720e4a..f95ac88 100644 --- a/examples/pfsense-hub-and-spoke/terraform.tfvars.example +++ b/examples/opnsense-hub-and-spoke/terraform.tfvars.example @@ -39,7 +39,7 @@ default_zone = "eu01-1" # --- Hub: network access control (001-hub-project only) ---------------------- -# CIDR allowed to reach the pfSense management interface (SSH, HTTP, HTTPS). +# CIDR allowed to reach the OPNsense management interface (SSH, HTTP, HTTPS). # Example: your office public IP or VPN exit in /32 or /24 notation. # Leave empty (or remove) to create no management access rules. # mgmt_ip_range = "" @@ -51,6 +51,6 @@ default_zone = "eu01-1" # 003-spoke-project default: 10.28.2.0/28 # spoke_subnet = "10.28.1.0/28" -# LAN IP of the pfSense firewall — used as the default route next-hop for spoke traffic. +# LAN IP of the OPNsense firewall — used as the default route next-hop for spoke traffic. # Run `terraform output firewall_lan_ip` in 001-hub-project. # hub_firewall_lan_ip = "10.28.0.20"