example(iaas): add example on how to use alb with waf integrations #14
23 changed files with 505 additions and 4 deletions
|
|
@ -21,7 +21,7 @@ module "test-machine01" {
|
|||
|
||||
name = "machine01"
|
||||
machine_type = var.jumphost_flavor
|
||||
disk_size = 500
|
||||
disk_size = 48
|
||||
|
||||
user_data = templatefile("${path.module}/apache-debug-user.yaml", {})
|
||||
}
|
||||
|
|
@ -21,7 +21,7 @@ module "test-machine02" {
|
|||
|
||||
name = "machine02"
|
||||
machine_type = var.jumphost_flavor
|
||||
disk_size = 500
|
||||
disk_size = 48
|
||||
|
||||
user_data = templatefile("${path.module}/apache-debug-user.yaml", {})
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
# IaaS cross AZ Loadbalancer
|
||||
# IaaS cross AZ Layer4 Loadbalancer
|
||||
|
||||
## Overview
|
||||
|
||||
A classic highly-available architecture: provisioning multiple VMs across different Availability Zones (AZs) and putting them behind a STACKIT Load Balancer.
|
||||
A classic highly-available architecture: provisioning multiple VMs across different Availability Zones (AZs) and putting them behind a STACKIT L4 Load Balancer.
|
||||
|
|
@ -0,0 +1 @@
|
|||
v1.14.0
|
||||
86
examples/iaas-cross-az-layer7-loadbalancer-waf/.terraform.lock.hcl
generated
Normal file
86
examples/iaas-cross-az-layer7-loadbalancer-waf/.terraform.lock.hcl
generated
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
# This file is maintained automatically by "terraform init".
|
||||
# Manual edits may be lost in future updates.
|
||||
|
||||
provider "registry.terraform.io/hashicorp/random" {
|
||||
version = "3.8.1"
|
||||
constraints = ">= 3.6.3"
|
||||
hashes = [
|
||||
"h1:u8AKlWVDTH5r9YLSeswoVEjiY72Rt4/ch7U+61ZDkiQ=",
|
||||
"zh:08dd03b918c7b55713026037c5400c48af5b9f468f483463321bd18e17b907b4",
|
||||
"zh:0eee654a5542dc1d41920bbf2419032d6f0d5625b03bd81339e5b33394a3e0ae",
|
||||
"zh:229665ddf060aa0ed315597908483eee5b818a17d09b6417a0f52fd9405c4f57",
|
||||
"zh:2469d2e48f28076254a2a3fc327f184914566d9e40c5780b8d96ebf7205f8bc0",
|
||||
"zh:37d7eb334d9561f335e748280f5535a384a88675af9a9eac439d4cfd663bcb66",
|
||||
"zh:741101426a2f2c52dee37122f0f4a2f2d6af6d852cb1db634480a86398fa3511",
|
||||
"zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
|
||||
"zh:a902473f08ef8df62cfe6116bd6c157070a93f66622384300de235a533e9d4a9",
|
||||
"zh:b85c511a23e57a2147355932b3b6dce2a11e856b941165793a0c3d7578d94d05",
|
||||
"zh:c5172226d18eaac95b1daac80172287b69d4ce32750c82ad77fa0768be4ea4b8",
|
||||
"zh:dab4434dba34aad569b0bc243c2d3f3ff86dd7740def373f2a49816bd2ff819b",
|
||||
"zh:f49fd62aa8c5525a5c17abd51e27ca5e213881d58882fd42fec4a545b53c9699",
|
||||
]
|
||||
}
|
||||
|
||||
provider "registry.terraform.io/hashicorp/tls" {
|
||||
version = "4.2.1"
|
||||
hashes = [
|
||||
"h1:akFNuHwvrtnYMBofieoeXhPJDhYZzJVu/Q/BgZK2fgg=",
|
||||
"zh:0d1e7d07ac973b97fa228f46596c800de830820506ee145626f079dd6bbf8d8a",
|
||||
"zh:5c7e3d4348cb4861ab812973ef493814a4b224bdd3e9d534a7c8a7c992382b86",
|
||||
"zh:7c6d4a86cd7a4e9c1025c6b3a3a6a45dea202af85d870cddbab455fb1bd568ad",
|
||||
"zh:7d0864755ba093664c4b2c07c045d3f5e3d7c799dda1a3ef33d17ed1ac563191",
|
||||
"zh:83734f57950ab67c0d6a87babdb3f13c908cbe0a48949333f489698532e1391b",
|
||||
"zh:951e3c285218ebca0cf20eaa4265020b4ef042fea9c6ade115ad1558cfe459e5",
|
||||
"zh:b9543955b4297e1d93b85900854891c0e645d936d8285a190030475379c5c635",
|
||||
"zh:bb1bd9e86c003d08c30c1b00d44118ed5bbbf6b1d2d6f7eaac4fa5c6ebea5933",
|
||||
"zh:c9477bfe00653629cd77ddac3968475f7ad93ac3ca8bc45b56d1d9efb25e4a6e",
|
||||
"zh:d4cfda8687f736d0cba664c22ec49dae1188289e214ef57f5afe6a7217854fed",
|
||||
"zh:dc77ee066cf96532a48f0578c35b1eaf6dc4d8ddd0e3ae8e029a3b10676dd5d3",
|
||||
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
|
||||
]
|
||||
}
|
||||
|
||||
provider "registry.terraform.io/mastercard/restapi" {
|
||||
version = "3.0.0"
|
||||
constraints = "3.0.0"
|
||||
hashes = [
|
||||
"h1:y1I3azDHOqRySTyDHsb3Xh1waP/99KfykZRagbRx1qI=",
|
||||
"zh:0b63bd3c25a31f090a41933f90b7dd6e984add1c4261d8f5caa73f4d5aa065a4",
|
||||
"zh:1c3e89cf19118fc07d7b04257251fc9897e722c16e0a0df7b07fcd261f8c12e7",
|
||||
"zh:2d31f322454d271eb328c2d3b3d41f426df98503982788be347799ddf68bf9bf",
|
||||
"zh:47dd97e3f43bb89ae4254bba90ffbc6d521338554a1f94961e21214dd801b81b",
|
||||
"zh:49636b072b9a30d15916468857bce91d39bc87bbba1c99fb3894fafa9409b8b4",
|
||||
"zh:5566605a8e16478bc66c1fec8dea0890586c084221161dc82b73d162d44c08a7",
|
||||
"zh:5859e0ad05aa6b3b108f0b718986e237a18d5176efea62d1ac1ef352561b4713",
|
||||
"zh:76129b89e2b56d8d2af8f6e10cc748bea4ee6ec1105e916f1254cd124f4dcf9c",
|
||||
"zh:bfc20b5fd03cb3243917e8cf360e5208284e757ab82f83c992da471ef16a0eab",
|
||||
"zh:d1d2363009253cdfe5795a48b6412bff11104fe6a52fb0a57e5a95fc765a161e",
|
||||
"zh:d1f0b981089ad709b73c4f989a9cd9118c4e3cb8fc0a2b303aa4d77cc5102a53",
|
||||
"zh:dbfddb2f407481a4e88fdc17739c805d9d9fff2451efcb9226572d59ed2e9128",
|
||||
"zh:df04a8c777d05896684171807b27c41befbf5f217f50b0e9b2b27164d4aacca5",
|
||||
"zh:e68b450c66efe55d1132585477fa71207680806edafb3792ca44d9695d0a1d75",
|
||||
"zh:f894e7e9913347e25e67d5d3bf91659c06877dd5fa11acf75820fa03fa34b8bd",
|
||||
]
|
||||
}
|
||||
|
||||
provider "registry.terraform.io/stackitcloud/stackit" {
|
||||
version = "0.91.0"
|
||||
constraints = ">= 0.87.0"
|
||||
hashes = [
|
||||
"h1:8de9n+Roq6Z2Ltp9poBBBN9a4zSpx73VLpgFS5mTyoI=",
|
||||
"zh:0dde99e7b343fa01f8eefc378171fb8621bedb20f59157d6cc8e3d46c738105f",
|
||||
"zh:0ed12db90276ccd2d6f87135b7dd078657823c3ca33121c6a157d0bdf08f801e",
|
||||
"zh:160b32bcf1d01666784cf8469e10e0a38d4c3d24c80c0c5be470cc63ef27ea62",
|
||||
"zh:32e1909037235c24138b74131c6fb12ac99003f79750f1768ca5468cc05da6b0",
|
||||
"zh:4376f1cdafbb35ad5f220e28153741908390b23161d9eae3828f7830039ce8ef",
|
||||
"zh:458b054781ef6165d9136fc3d667f9bf37319e37d0f19300bbb63b703de2599d",
|
||||
"zh:54a1864cf1315a118c043f834e02f2a1ca0ecbc8c2a246460589a95847da6c80",
|
||||
"zh:83424712926ccef3c60cc011dfa298721bdbaee3598a0c8459da46bc6b7424cc",
|
||||
"zh:a3c38ebffdbca21dd177b06acf891bed1a903907ba252d0219d91ff0ecf9d861",
|
||||
"zh:c6325e583b77aa1e9df94e3b4b12479d7bf12c66a2ace71c1b8f64e46ac5c37e",
|
||||
"zh:de6db8deeee895af5670df2449c8b8c34df051277f8a6e2f19c5c9ec1f0ddb12",
|
||||
"zh:e18b05e7d8356caa6103c5c80b5ea373be3ff255b453cf577c68798ffe1b93ce",
|
||||
"zh:f4d9215f7a2888c882892642539b2edd3ea97cb25904e4fa358db4f001c3ccd0",
|
||||
"zh:f94d0c0c2bf843867122ababc8d8066d52257e68bbcb5c62a603f77c581e9668",
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
# Copyright 2026 Schwarz Digits Cloud GmbH & Co. KG
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Define required providers
|
||||
terraform {
|
||||
required_version = ">= 0.14.0"
|
||||
required_providers {
|
||||
stackit = {
|
||||
source = "stackitcloud/stackit"
|
||||
version = ">= 0.87.0"
|
||||
}
|
||||
random = {
|
||||
source = "hashicorp/random"
|
||||
version = ">= 3.6.3"
|
||||
}
|
||||
restapi = {
|
||||
source = "Mastercard/restapi"
|
||||
version = ">= 3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ephemeral "stackit_access_token" "alb" {}
|
||||
|
||||
provider "restapi" {
|
||||
uri = "https://alb-waf.api.stackit.cloud"
|
||||
bearer_token = ephemeral.stackit_access_token.alb.access_token
|
||||
|
||||
id_attribute = "name"
|
||||
write_returns_object = true
|
||||
}
|
||||
|
||||
provider "stackit" {
|
||||
default_region = var.stackit_region
|
||||
service_account_key_path = var.stackit_service_account_key_path
|
||||
enable_beta_resources = true
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
# Copyright 2026 Schwarz Digits Cloud GmbH & Co. KG
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
variable "stackit_project_id" {
|
||||
type = string
|
||||
default = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||
}
|
||||
|
||||
variable "stackit_region" {
|
||||
type = string
|
||||
default = "eu01"
|
||||
}
|
||||
|
||||
variable "stackit_service_account_key_path" {
|
||||
type = string
|
||||
default = "../../keys/stackit-sa.json"
|
||||
}
|
||||
|
||||
resource "stackit_key_pair" "admin_keypair" {
|
||||
name = "admin-keypair-12345"
|
||||
public_key = chomp(file("~/.ssh/id_rsa.pub"))
|
||||
}
|
||||
|
||||
variable "jumphost_flavor" {
|
||||
default = "c2i.1"
|
||||
}
|
||||
20
examples/iaas-cross-az-layer7-loadbalancer-waf/02-network.tf
Normal file
20
examples/iaas-cross-az-layer7-loadbalancer-waf/02-network.tf
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# Copyright 2026 Schwarz Digits Cloud GmbH & Co. KG
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
resource "stackit_network" "network" {
|
||||
project_id = var.stackit_project_id
|
||||
name = "network01"
|
||||
ipv4_nameservers = ["1.1.1.1", "9.9.9.9"]
|
||||
ipv4_prefix = "172.17.1.0/24"
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
# Copyright 2026 Schwarz Digits Cloud GmbH & Co. KG
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
module "test-machine01" {
|
||||
source = "../../modules/test-machine"
|
||||
|
||||
project_id = var.stackit_project_id
|
||||
network_id = stackit_network.network.network_id
|
||||
availability_zone = "eu01-1"
|
||||
security_enabled = true
|
||||
|
||||
name = "machine01"
|
||||
machine_type = var.jumphost_flavor
|
||||
disk_size = 48
|
||||
|
||||
user_data = templatefile("${path.module}/apache-debug-user.yaml", {})
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
# Copyright 2026 Schwarz Digits Cloud GmbH & Co. KG
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
module "test-machine02" {
|
||||
source = "../../modules/test-machine"
|
||||
|
||||
project_id = var.stackit_project_id
|
||||
network_id = stackit_network.network.network_id
|
||||
availability_zone = "eu01-2"
|
||||
security_enabled = true
|
||||
|
||||
name = "machine02"
|
||||
machine_type = var.jumphost_flavor
|
||||
disk_size = 48
|
||||
|
||||
user_data = templatefile("${path.module}/apache-debug-user.yaml", {})
|
||||
}
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
# Copyright 2026 Schwarz Digits Cloud GmbH & Co. KG
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
resource "tls_private_key" "example" {
|
||||
algorithm = "RSA"
|
||||
rsa_bits = 2048
|
||||
}
|
||||
|
||||
resource "tls_self_signed_cert" "example" {
|
||||
private_key_pem = tls_private_key.example.private_key_pem
|
||||
|
||||
subject {
|
||||
common_name = "localhost"
|
||||
organization = "STACKIT Test"
|
||||
}
|
||||
|
||||
validity_period_hours = 12
|
||||
|
||||
allowed_uses = [
|
||||
"key_encipherment",
|
||||
"digital_signature",
|
||||
"server_auth",
|
||||
]
|
||||
}
|
||||
|
||||
resource "stackit_public_ip" "public_ip" {
|
||||
project_id = var.stackit_project_id
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [network_interface_id]
|
||||
}
|
||||
}
|
||||
|
||||
resource "stackit_alb_certificate" "this" {
|
||||
project_id = var.stackit_project_id
|
||||
name = "example-certificate"
|
||||
private_key = tls_private_key.example.private_key_pem
|
||||
public_key = tls_self_signed_cert.example.cert_pem
|
||||
}
|
||||
|
||||
resource "stackit_application_load_balancer" "this" {
|
||||
project_id = var.stackit_project_id
|
||||
region = var.stackit_region
|
||||
name = "example-load-balancer"
|
||||
plan_id = "p10"
|
||||
external_address = stackit_public_ip.public_ip.ip
|
||||
|
||||
listeners = [
|
||||
{
|
||||
name = "listener01"
|
||||
port = 443
|
||||
http = {
|
||||
hosts = [{
|
||||
host = "*"
|
||||
rules = [{
|
||||
target_pool = "target-pool-01"
|
||||
/*path = {
|
||||
prefix = "/path"
|
||||
}*/
|
||||
}]
|
||||
}]
|
||||
}
|
||||
https = {
|
||||
certificate_config = {
|
||||
certificate_ids = [
|
||||
stackit_alb_certificate.this.cert_id
|
||||
]
|
||||
}
|
||||
}
|
||||
waf_config_name = restapi_object.waf.api_data.name
|
||||
protocol = "PROTOCOL_HTTPS"
|
||||
}
|
||||
]
|
||||
networks = [
|
||||
{
|
||||
network_id = stackit_network.network.network_id
|
||||
role = "ROLE_LISTENERS_AND_TARGETS"
|
||||
}
|
||||
]
|
||||
target_pools = [
|
||||
{
|
||||
name = "target-pool-01"
|
||||
target_port = 80
|
||||
targets = [
|
||||
{
|
||||
display_name = "server01"
|
||||
ip = module.test-machine01.primary_ip
|
||||
},
|
||||
{
|
||||
display_name = "server02"
|
||||
ip = module.test-machine02.primary_ip
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
output "alb_external_address" {
|
||||
value = stackit_application_load_balancer.this.external_address
|
||||
}
|
||||
|
||||
/*output "alb_private_ip_address" {
|
||||
// for private alb loadbalancer usage
|
||||
value = stackit_application_load_balancer.this.private_address
|
||||
}*/
|
||||
46
examples/iaas-cross-az-layer7-loadbalancer-waf/06-waf.tf
Normal file
46
examples/iaas-cross-az-layer7-loadbalancer-waf/06-waf.tf
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
# Copyright 2026 Schwarz Digits Cloud GmbH & Co. KG
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
resource "restapi_object" "waf_crs" {
|
||||
path = "/v1alpha/projects/${var.stackit_project_id}/regions/${var.stackit_region}/core-rule-sets"
|
||||
data = jsonencode({
|
||||
name = "example-crs"
|
||||
active = true
|
||||
})
|
||||
|
||||
ignore_server_additions = true
|
||||
}
|
||||
|
||||
resource "restapi_object" "waf_rules" {
|
||||
path = "/v1alpha/projects/${var.stackit_project_id}/regions/${var.stackit_region}/rules"
|
||||
data = jsonencode({
|
||||
name = "example-rules"
|
||||
rules = file("${path.module}/example-waf.conf")
|
||||
})
|
||||
|
||||
ignore_server_additions = true
|
||||
depends_on = [restapi_object.waf_crs]
|
||||
}
|
||||
|
||||
resource "restapi_object" "waf" {
|
||||
path = "/v1alpha/projects/${var.stackit_project_id}/regions/${var.stackit_region}/wafs"
|
||||
data = jsonencode({
|
||||
name = "example-waf"
|
||||
coreRuleSetName = restapi_object.waf_crs.api_data.name
|
||||
rulesConfigName = restapi_object.waf_rules.api_data.name
|
||||
})
|
||||
|
||||
ignore_server_additions = true
|
||||
depends_on = [restapi_object.waf_rules]
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# Maintainers
|
||||
|
||||
General maintainers:
|
||||
|
||||
- Mauritz Uphoff (Mauritz.Uphoff@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.
|
||||
Please include the BP name and version in your request. We will track your request as an issue.
|
||||
36
examples/iaas-cross-az-layer7-loadbalancer-waf/README.md
Normal file
36
examples/iaas-cross-az-layer7-loadbalancer-waf/README.md
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
# IaaS cross AZ Layer 7 Loadbalancer
|
||||
|
||||
## Overview
|
||||
|
||||
A classic highly-available architecture: provisioning multiple VMs across different Availability Zones (AZs) and putting them behind a STACKIT L7 Load Balancer. This example also includes a Web Application Firewall (WAF) configuration to secure the backend workloads against malicious traffic.
|
||||
|
||||
## ⚠️ Important Note: [WAF Implementation](06-waf.tf)
|
||||
|
||||
Currently, the official STACKIT Terraform provider does not natively support Web Application Firewall (WAF) resources.
|
||||
|
||||
To bridge this gap and fully automate the deployment, this example utilizes a `restapi` provider as a workaround. This allows Terraform to interact directly with the STACKIT WAF REST API (`/v1alpha/projects/...`) to create and attach the Core Rule Sets and custom SecLang rules until native support is released.
|
||||
|
||||
## Testing the WAF
|
||||
|
||||
This deployment includes rules written in SecLang. These rules are specifically designed to safely verify that the WAF is successfully deployed, actively intercepting traffic, and applying your configurations.
|
||||
|
||||
Once `terraform apply` completes successfully, extract the public IP of your Load Balancer from the Terraform outputs:
|
||||
|
||||
```bash
|
||||
# Export the Load Balancer IP to an environment variable
|
||||
export ALB_IP=$(terraform output -raw alb_external_address)
|
||||
```
|
||||
|
||||
Now, use curl to trigger the custom rules. Because the WAF is configured to block these specific signatures, both of the following commands should return an HTTP 403 Forbidden status code.
|
||||
|
||||
Test 1: Trigger via Query Parameter
|
||||
|
||||
```Bash
|
||||
curl -k -I -X GET "https://${ALB_IP}/?waf_test=trigger"
|
||||
```
|
||||
|
||||
Test 2: Trigger via Custom HTTP Header
|
||||
|
||||
```Bash
|
||||
curl -k -I -H "X-WAF-Test: trigger" "https://${ALB_IP}/"
|
||||
```
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
#cloud-config
|
||||
users:
|
||||
- name: debug
|
||||
groups: sudo
|
||||
shell: /bin/bash
|
||||
sudo: ["ALL=(ALL) NOPASSWD:ALL"]
|
||||
lock_passwd: false
|
||||
passwd: "$6$JZBVJ2zsw/o4C1UJ$FskGQWf.nqwj.o9bHbxkSGvSilQcHt03KdPYlgsiE3L77tNqFj0/vnlCXSf.SRb4jR2xsHk/.OlEyT16Txj4J." # hashed version of 'House123!'
|
||||
|
||||
chpasswd:
|
||||
expire: false
|
||||
|
||||
ssh_pwauth: true
|
||||
|
||||
packages:
|
||||
- apache2
|
||||
|
||||
runcmd:
|
||||
- systemctl enable apache2
|
||||
- systemctl start apache2
|
||||
- echo "<h1>Hello from STACKIT Instance</h1><p>Hostname $(hostname)</p>" > /var/www/html/index.html
|
||||
- chown www-data:www-data /var/www/html/index.html
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
# ------------------------------------------------------------------------
|
||||
# WAF TEST RULES
|
||||
# Custom rule IDs should generally start at 1000000 to avoid conflicting
|
||||
# with the OWASP Core Rule Set (which uses the 900000 - 999999 range).
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
# Test Rule 1: Block based on a specific query parameter (?waf_test=trigger)
|
||||
SecRule ARGS:waf_test "@streq trigger" \
|
||||
"id:1000001,\
|
||||
phase:1,\
|
||||
deny,\
|
||||
status:403,\
|
||||
log,\
|
||||
msg:'WAF Test Rule Triggered via Query Parameter'"
|
||||
|
||||
# Test Rule 2: Block based on a specific custom header (X-WAF-Test: trigger)
|
||||
SecRule REQUEST_HEADERS:X-WAF-Test "@streq trigger" \
|
||||
"id:1000002,\
|
||||
phase:1,\
|
||||
deny,\
|
||||
status:403,\
|
||||
log,\
|
||||
msg:'WAF Test Rule Triggered via Custom Header'"
|
||||
Loading…
Add table
Add a link
Reference in a new issue