Refine Hetzner firewall rules and update server types
Overhaul and expand firewall definitions for both `prod` and `test` environments to enable comprehensive inter-subnet communication. This includes implementing explicit rules supporting: - Docker Swarm overlay networks between application and database subnets. - High-availability database clusters (PostgreSQL replication, MongoDB replica sets, Patroni, etcd). - Internal access for various infrastructure services (Vault, Redis, RabbitMQ, APISIX, Prometheus, Grafana). All firewall rule descriptions are standardized in English for improved clarity and consistency. Additionally, update default `server_type_swarm` and `server_type_db` variables to the recommended `CPX` series for both environments. An initial generated Ansible inventory for the test environment is also added.
This commit is contained in:
parent
b115a4cbdf
commit
03ad812512
14
ansible/inventory/generated/test.yml
Normal file
14
ansible/inventory/generated/test.yml
Normal file
@ -0,0 +1,14 @@
|
||||
"all":
|
||||
"children":
|
||||
"db":
|
||||
"hosts":
|
||||
"iklim-db-01":
|
||||
"ansible_host": "167.235.194.61"
|
||||
"ansible_user": "root"
|
||||
"private_ip": "10.10.20.11"
|
||||
"swarm":
|
||||
"hosts":
|
||||
"iklim-app-01":
|
||||
"ansible_host": "167.235.205.93"
|
||||
"ansible_user": "root"
|
||||
"private_ip": "10.10.10.11"
|
||||
@ -1,141 +1,172 @@
|
||||
# Swarm node firewall — public HTTP/HTTPS + private infra services
|
||||
resource "hcloud_firewall" "swarm" {
|
||||
name = "${local.name_prefix}-firewall-app"
|
||||
|
||||
# SSH — admin CIDRs only
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "22"
|
||||
source_ips = var.admin_allowed_cidrs
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "22"
|
||||
source_ips = var.admin_allowed_cidrs
|
||||
description = "SSH — admin CIDRs only"
|
||||
}
|
||||
|
||||
# HTTP public
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "80"
|
||||
source_ips = ["0.0.0.0/0", "::/0"]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "80"
|
||||
source_ips = ["0.0.0.0/0", "::/0"]
|
||||
description = "HTTP public"
|
||||
}
|
||||
|
||||
# HTTPS public
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "443"
|
||||
source_ips = ["0.0.0.0/0", "::/0"]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "443"
|
||||
source_ips = ["0.0.0.0/0", "::/0"]
|
||||
description = "HTTPS public"
|
||||
}
|
||||
|
||||
# Docker Swarm control plane
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "2377"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "2377"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "Docker Swarm control plane"
|
||||
}
|
||||
|
||||
# Docker Swarm node discovery (TCP)
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "7946"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "7946"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "Docker Swarm node discovery (TCP)"
|
||||
}
|
||||
|
||||
# Docker Swarm node discovery (UDP)
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "udp"
|
||||
port = "7946"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "udp"
|
||||
port = "7946"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "Docker Swarm node discovery (UDP)"
|
||||
}
|
||||
|
||||
# Docker Swarm VXLAN overlay
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "udp"
|
||||
port = "4789"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "udp"
|
||||
port = "4789"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "Docker Swarm VXLAN overlay"
|
||||
}
|
||||
|
||||
# Vault API — private only, never public
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "8200"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "2377"
|
||||
source_ips = [local.db_subnet_cidr]
|
||||
description = "Docker Swarm control plane from DB subnet"
|
||||
}
|
||||
|
||||
# Redis
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "6379"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "7946"
|
||||
source_ips = [local.db_subnet_cidr]
|
||||
description = "Docker Swarm node discovery (TCP) from DB subnet"
|
||||
}
|
||||
|
||||
# RabbitMQ AMQP
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "5672"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "udp"
|
||||
port = "7946"
|
||||
source_ips = [local.db_subnet_cidr]
|
||||
description = "Docker Swarm node discovery (UDP) from DB subnet"
|
||||
}
|
||||
|
||||
# RabbitMQ STOMP
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "61613"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "udp"
|
||||
port = "4789"
|
||||
source_ips = [local.db_subnet_cidr]
|
||||
description = "Docker Swarm VXLAN overlay from DB subnet"
|
||||
}
|
||||
|
||||
# RabbitMQ Web STOMP
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "15674"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "8200"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "Vault API — private only, never public"
|
||||
}
|
||||
|
||||
# RabbitMQ Management — private only, SWAG arkasindan 443 uzerinden
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "15672"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "6379"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "Redis"
|
||||
}
|
||||
|
||||
# APISIX Dashboard — private only, SWAG arkasindan 443 uzerinden (IP kisitli)
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "9000"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "5672"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "RabbitMQ AMQP"
|
||||
}
|
||||
|
||||
# APISIX Admin API — sadece Docker overlay icinden Dashboard erisir
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "9180"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "61613"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "RabbitMQ STOMP"
|
||||
}
|
||||
|
||||
# Prometheus — private only, Grafana Docker overlay uzerinden erisir
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "9090"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "15674"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "RabbitMQ Web STOMP"
|
||||
}
|
||||
|
||||
# Grafana — private only, SWAG arkasindan 443 uzerinden (IP kisitli)
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "3000"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "15672"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "RabbitMQ Management — private, via SWAG on 443"
|
||||
}
|
||||
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "9000"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "APISIX Dashboard — private, via SWAG on 443 (IP restricted)"
|
||||
}
|
||||
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "9180"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "APISIX Admin API — internal only, accessed by Dashboard via Docker overlay"
|
||||
}
|
||||
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "9090"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "Prometheus — private, accessed by Grafana via Docker overlay"
|
||||
}
|
||||
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "3000"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "Grafana — private, via SWAG on 443 (IP restricted)"
|
||||
}
|
||||
|
||||
labels = {
|
||||
@ -144,48 +175,103 @@ resource "hcloud_firewall" "swarm" {
|
||||
}
|
||||
}
|
||||
|
||||
# DB node firewall — SSH + DB ports from app/swarm subnet only
|
||||
resource "hcloud_firewall" "db" {
|
||||
name = "${local.name_prefix}-firewall-db"
|
||||
|
||||
# SSH — admin CIDRs only
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "22"
|
||||
source_ips = var.admin_allowed_cidrs
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "22"
|
||||
source_ips = var.admin_allowed_cidrs
|
||||
description = "SSH — admin CIDRs only"
|
||||
}
|
||||
|
||||
# PostgreSQL from app/swarm subnet
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "5432"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "5432"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "PostgreSQL from app subnet"
|
||||
}
|
||||
|
||||
# PostgreSQL replication within DB subnet
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "5432"
|
||||
source_ips = [local.db_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "5432"
|
||||
source_ips = [local.db_subnet_cidr]
|
||||
description = "PostgreSQL replication within DB subnet"
|
||||
}
|
||||
|
||||
# MongoDB from app/swarm subnet
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "27017"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "27017"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "MongoDB from app subnet"
|
||||
}
|
||||
|
||||
# MongoDB replica set internal traffic
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "27017"
|
||||
source_ips = [local.db_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "27017"
|
||||
source_ips = [local.db_subnet_cidr]
|
||||
description = "MongoDB replica set internal traffic"
|
||||
}
|
||||
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "2377"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "Docker Swarm control plane from app subnet"
|
||||
}
|
||||
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "7946"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "Docker Swarm node discovery (TCP) from app subnet"
|
||||
}
|
||||
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "udp"
|
||||
port = "7946"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "Docker Swarm node discovery (UDP) from app subnet"
|
||||
}
|
||||
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "udp"
|
||||
port = "4789"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "Docker Swarm VXLAN overlay from app subnet"
|
||||
}
|
||||
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "2379"
|
||||
source_ips = [local.db_subnet_cidr]
|
||||
description = "etcd client port within DB subnet"
|
||||
}
|
||||
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "2380"
|
||||
source_ips = [local.db_subnet_cidr]
|
||||
description = "etcd peer port within DB subnet"
|
||||
}
|
||||
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "8008"
|
||||
source_ips = [local.db_subnet_cidr]
|
||||
description = "Patroni REST API within DB subnet"
|
||||
}
|
||||
|
||||
labels = {
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
hcloud_token = "YOUR_HETZNER_PROD_PROJECT_API_TOKEN"
|
||||
location = "fsn1"
|
||||
image = "rocky-10"
|
||||
server_type_swarm = "cx42"
|
||||
server_type_db = "cx52"
|
||||
server_type_swarm = "cpx42"
|
||||
server_type_db = "cpx32"
|
||||
admin_ssh_public_key_path = "~/.ssh/id_ed25519.pub"
|
||||
admin_allowed_cidrs = ["1.2.3.4/32", "5.6.7.8/32"]
|
||||
|
||||
@ -18,13 +18,13 @@ variable "image" {
|
||||
|
||||
variable "server_type_swarm" {
|
||||
type = string
|
||||
default = "cx42"
|
||||
default = "cpx42"
|
||||
description = "Hetzner server type for Swarm nodes"
|
||||
}
|
||||
|
||||
variable "server_type_db" {
|
||||
type = string
|
||||
default = "cx52"
|
||||
default = "cpx32"
|
||||
description = "Hetzner server type for DB nodes"
|
||||
}
|
||||
|
||||
|
||||
23
terraform/hetzner/test/.terraform.lock.hcl
generated
Normal file
23
terraform/hetzner/test/.terraform.lock.hcl
generated
Normal file
@ -0,0 +1,23 @@
|
||||
# This file is maintained automatically by "terraform init".
|
||||
# Manual edits may be lost in future updates.
|
||||
|
||||
provider "registry.terraform.io/hetznercloud/hcloud" {
|
||||
version = "1.62.0"
|
||||
constraints = "~> 1.49"
|
||||
hashes = [
|
||||
"h1:Y9/c7aSVFnOvkvx+E33cNqHsFOu7S4vijxorU9FXmxs=",
|
||||
"zh:2077f1655b6a7e26ae6d8ce3b5f35a6a65728416deb16dbd5165115da7534f37",
|
||||
"zh:2234db7b84efa489b8e5f29f756cfed4a5bab760985f62d38c4b9ed2b3d6b4b6",
|
||||
"zh:4abee7212fd15bcbf22b156ff18933f3975f2b1153fd3e93a1cacf31b9d35137",
|
||||
"zh:5d7a63a8d4c73babea715c0c7a5dc04a08b5076e2f1f59855bf61f2393017bf0",
|
||||
"zh:5ef15b4367c139b18167b2169421cb1f760d485db42f05ef292bd63eadcfa802",
|
||||
"zh:62b432d918815812ea35ceca252d0ea833a8e1dbbc72c6b2d410369d7b8b0d85",
|
||||
"zh:63fd3d3803a86447f9a1c0c49bffe704168fbc907ea3688cfd847e1dd012e9ff",
|
||||
"zh:6a84f7125dad475f939afb58a1f0ec089e835d1b30ca64f467d85565a89f7508",
|
||||
"zh:834c2ddcaa986323ecb7aa2baa3fd7b1888c2aec249f296822e53a4bc46be66e",
|
||||
"zh:887e503de3720894eb756bcfc67b3d8ceb68564f9f8bb2a115d7398f0b5990b7",
|
||||
"zh:976216f9aa89a466a1d97ae776c4df2edbac4a9ab29ff9850884060d15024570",
|
||||
"zh:c3d7fc02e0fdf1bbee3a07c9171281a59d79ad9df2ec04342a81f3875709171c",
|
||||
"zh:e0165f404357f2c1f89524165f38c88f643fb518483adfbf7817a6033a83f4d8",
|
||||
]
|
||||
}
|
||||
@ -1,141 +1,172 @@
|
||||
# Swarm node firewall — public HTTP/HTTPS + private infra services
|
||||
resource "hcloud_firewall" "swarm" {
|
||||
name = "${local.name_prefix}-firewall-app"
|
||||
|
||||
# SSH — admin CIDRs only
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "22"
|
||||
source_ips = var.admin_allowed_cidrs
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "22"
|
||||
source_ips = var.admin_allowed_cidrs
|
||||
description = "SSH — admin CIDRs only"
|
||||
}
|
||||
|
||||
# HTTP public
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "80"
|
||||
source_ips = ["0.0.0.0/0", "::/0"]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "80"
|
||||
source_ips = ["0.0.0.0/0", "::/0"]
|
||||
description = "HTTP public"
|
||||
}
|
||||
|
||||
# HTTPS public
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "443"
|
||||
source_ips = ["0.0.0.0/0", "::/0"]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "443"
|
||||
source_ips = ["0.0.0.0/0", "::/0"]
|
||||
description = "HTTPS public"
|
||||
}
|
||||
|
||||
# Docker Swarm control plane
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "2377"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "2377"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "Docker Swarm control plane"
|
||||
}
|
||||
|
||||
# Docker Swarm node discovery (TCP)
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "7946"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "7946"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "Docker Swarm node discovery (TCP)"
|
||||
}
|
||||
|
||||
# Docker Swarm node discovery (UDP)
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "udp"
|
||||
port = "7946"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "udp"
|
||||
port = "7946"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "Docker Swarm node discovery (UDP)"
|
||||
}
|
||||
|
||||
# Docker Swarm VXLAN overlay
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "udp"
|
||||
port = "4789"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "udp"
|
||||
port = "4789"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "Docker Swarm VXLAN overlay"
|
||||
}
|
||||
|
||||
# Vault API — private only, never public
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "8200"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "2377"
|
||||
source_ips = [local.db_subnet_cidr]
|
||||
description = "Docker Swarm control plane from DB subnet"
|
||||
}
|
||||
|
||||
# Redis
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "6379"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "7946"
|
||||
source_ips = [local.db_subnet_cidr]
|
||||
description = "Docker Swarm node discovery (TCP) from DB subnet"
|
||||
}
|
||||
|
||||
# RabbitMQ AMQP
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "5672"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "udp"
|
||||
port = "7946"
|
||||
source_ips = [local.db_subnet_cidr]
|
||||
description = "Docker Swarm node discovery (UDP) from DB subnet"
|
||||
}
|
||||
|
||||
# RabbitMQ STOMP
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "61613"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "udp"
|
||||
port = "4789"
|
||||
source_ips = [local.db_subnet_cidr]
|
||||
description = "Docker Swarm VXLAN overlay from DB subnet"
|
||||
}
|
||||
|
||||
# RabbitMQ Web STOMP
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "15674"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "8200"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "Vault API — private only, never public"
|
||||
}
|
||||
|
||||
# RabbitMQ Management — private only, SWAG arkasindan 443 uzerinden erisim
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "15672"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "6379"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "Redis"
|
||||
}
|
||||
|
||||
# APISIX Dashboard — private only, SWAG arkasindan 443 uzerinden (IP kisitli)
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "9000"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "5672"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "RabbitMQ AMQP"
|
||||
}
|
||||
|
||||
# APISIX Admin API — sadece Docker overlay icinden Dashboard erisir, insan erisimi gerekmez
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "9180"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "61613"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "RabbitMQ STOMP"
|
||||
}
|
||||
|
||||
# Prometheus — private only, SWAG arkasindan 443 uzerinden erisim
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "9090"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "15674"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "RabbitMQ Web STOMP"
|
||||
}
|
||||
|
||||
# Grafana — private only, SWAG arkasindan 443 uzerinden erisim
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "3000"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "15672"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "RabbitMQ Management — private, via SWAG on 443"
|
||||
}
|
||||
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "9000"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "APISIX Dashboard — private, via SWAG on 443 (IP restricted)"
|
||||
}
|
||||
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "9180"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "APISIX Admin API — internal only, accessed by Dashboard via Docker overlay"
|
||||
}
|
||||
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "9090"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "Prometheus — private, via SWAG on 443"
|
||||
}
|
||||
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "3000"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "Grafana — private, via SWAG on 443"
|
||||
}
|
||||
|
||||
labels = {
|
||||
@ -144,32 +175,63 @@ resource "hcloud_firewall" "swarm" {
|
||||
}
|
||||
}
|
||||
|
||||
# DB node firewall — SSH + DB ports from app/swarm subnet only
|
||||
resource "hcloud_firewall" "db" {
|
||||
name = "${local.name_prefix}-firewall-db"
|
||||
|
||||
# SSH — admin CIDRs only
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "22"
|
||||
source_ips = var.admin_allowed_cidrs
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "22"
|
||||
source_ips = var.admin_allowed_cidrs
|
||||
description = "SSH — admin CIDRs only"
|
||||
}
|
||||
|
||||
# PostgreSQL from app/swarm subnet
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "5432"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "5432"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "PostgreSQL from app subnet"
|
||||
}
|
||||
|
||||
# MongoDB from app/swarm subnet
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "27017"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "27017"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "MongoDB from app subnet"
|
||||
}
|
||||
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "2377"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "Docker Swarm control plane from app subnet"
|
||||
}
|
||||
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "tcp"
|
||||
port = "7946"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "Docker Swarm node discovery (TCP) from app subnet"
|
||||
}
|
||||
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "udp"
|
||||
port = "7946"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "Docker Swarm node discovery (UDP) from app subnet"
|
||||
}
|
||||
|
||||
rule {
|
||||
direction = "in"
|
||||
protocol = "udp"
|
||||
port = "4789"
|
||||
source_ips = [local.app_subnet_cidr]
|
||||
description = "Docker Swarm VXLAN overlay from app subnet"
|
||||
}
|
||||
|
||||
labels = {
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
hcloud_token = "YOUR_HETZNER_TEST_PROJECT_API_TOKEN"
|
||||
location = "fsn1"
|
||||
image = "rocky-10"
|
||||
server_type_swarm = "cx32"
|
||||
server_type_db = "cx42"
|
||||
server_type_swarm = "cpx42"
|
||||
server_type_db = "cpx42"
|
||||
admin_ssh_public_key_path = "~/.ssh/id_ed25519.pub"
|
||||
admin_allowed_cidrs = ["1.2.3.4/32", "5.6.7.8/32"]
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
variable "hcloud_token" {
|
||||
type = string
|
||||
sensitive = true
|
||||
type = string
|
||||
sensitive = true
|
||||
description = "Hetzner Cloud API token for the test project"
|
||||
}
|
||||
|
||||
@ -18,13 +18,13 @@ variable "image" {
|
||||
|
||||
variable "server_type_swarm" {
|
||||
type = string
|
||||
default = "cx32"
|
||||
default = "cpx42"
|
||||
description = "Hetzner server type for the Swarm node"
|
||||
}
|
||||
|
||||
variable "server_type_db" {
|
||||
type = string
|
||||
default = "cx42"
|
||||
default = "cpx42"
|
||||
description = "Hetzner server type for the DB node"
|
||||
}
|
||||
|
||||
|
||||
BIN
test-app-graphs.png
Normal file
BIN
test-app-graphs.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 114 KiB |
BIN
test-db-graphs.png
Normal file
BIN
test-db-graphs.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 109 KiB |
Loading…
x
Reference in New Issue
Block a user