- This commit introduces the Terraform configuration to provision a production environment on Hetzner Cloud, building on the existing test setup. - Key improvements and new features include: * **Multi-node clusters:** Scaling to 3-node Swarm application and database clusters for improved resilience. * **High availability:** Utilizing a Hetzner Floating IP for the application entry point and `spread` placement groups for fault tolerance across physical hosts. * **Enhanced network security:** Internal management services (RabbitMQ, APISIX, Prometheus, Grafana) are restricted to the application subnet, expected to be accessed via an internal reverse proxy (SWAG). * **Internal database replication:** New firewall rules enable PostgreSQL replication and MongoDB replica set traffic within the database subnet. * **Refined test environment:** Updates to align `test` configuration with the new `prod` structure, including a dedicated floating IP and adjusted firewall rules. * **Configuration standardization:** Environment-specific details moved to `locals.tf` for clarity, with upgraded server types and migration to Rocky Linux as the base image. - Updates were also made to the latest version of Terraform to ensure consistency in the documentation
196 lines
4.0 KiB
HCL
196 lines
4.0 KiB
HCL
# 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
|
|
}
|
|
|
|
# HTTP public
|
|
rule {
|
|
direction = "in"
|
|
protocol = "tcp"
|
|
port = "80"
|
|
source_ips = ["0.0.0.0/0", "::/0"]
|
|
}
|
|
|
|
# HTTPS public
|
|
rule {
|
|
direction = "in"
|
|
protocol = "tcp"
|
|
port = "443"
|
|
source_ips = ["0.0.0.0/0", "::/0"]
|
|
}
|
|
|
|
# Docker Swarm control plane
|
|
rule {
|
|
direction = "in"
|
|
protocol = "tcp"
|
|
port = "2377"
|
|
source_ips = [local.app_subnet_cidr]
|
|
}
|
|
|
|
# Docker Swarm node discovery (TCP)
|
|
rule {
|
|
direction = "in"
|
|
protocol = "tcp"
|
|
port = "7946"
|
|
source_ips = [local.app_subnet_cidr]
|
|
}
|
|
|
|
# Docker Swarm node discovery (UDP)
|
|
rule {
|
|
direction = "in"
|
|
protocol = "udp"
|
|
port = "7946"
|
|
source_ips = [local.app_subnet_cidr]
|
|
}
|
|
|
|
# Docker Swarm VXLAN overlay
|
|
rule {
|
|
direction = "in"
|
|
protocol = "udp"
|
|
port = "4789"
|
|
source_ips = [local.app_subnet_cidr]
|
|
}
|
|
|
|
# Vault API — private only, never public
|
|
rule {
|
|
direction = "in"
|
|
protocol = "tcp"
|
|
port = "8200"
|
|
source_ips = [local.app_subnet_cidr]
|
|
}
|
|
|
|
# Redis
|
|
rule {
|
|
direction = "in"
|
|
protocol = "tcp"
|
|
port = "6379"
|
|
source_ips = [local.app_subnet_cidr]
|
|
}
|
|
|
|
# RabbitMQ AMQP
|
|
rule {
|
|
direction = "in"
|
|
protocol = "tcp"
|
|
port = "5672"
|
|
source_ips = [local.app_subnet_cidr]
|
|
}
|
|
|
|
# RabbitMQ STOMP
|
|
rule {
|
|
direction = "in"
|
|
protocol = "tcp"
|
|
port = "61613"
|
|
source_ips = [local.app_subnet_cidr]
|
|
}
|
|
|
|
# RabbitMQ Web STOMP
|
|
rule {
|
|
direction = "in"
|
|
protocol = "tcp"
|
|
port = "15674"
|
|
source_ips = [local.app_subnet_cidr]
|
|
}
|
|
|
|
# RabbitMQ Management — private only, SWAG arkasindan 443 uzerinden
|
|
rule {
|
|
direction = "in"
|
|
protocol = "tcp"
|
|
port = "15672"
|
|
source_ips = [local.app_subnet_cidr]
|
|
}
|
|
|
|
# APISIX Dashboard — private only, SWAG arkasindan 443 uzerinden (IP kisitli)
|
|
rule {
|
|
direction = "in"
|
|
protocol = "tcp"
|
|
port = "9000"
|
|
source_ips = [local.app_subnet_cidr]
|
|
}
|
|
|
|
# APISIX Admin API — sadece Docker overlay icinden Dashboard erisir
|
|
rule {
|
|
direction = "in"
|
|
protocol = "tcp"
|
|
port = "9180"
|
|
source_ips = [local.app_subnet_cidr]
|
|
}
|
|
|
|
# Prometheus — private only, Grafana Docker overlay uzerinden erisir
|
|
rule {
|
|
direction = "in"
|
|
protocol = "tcp"
|
|
port = "9090"
|
|
source_ips = [local.app_subnet_cidr]
|
|
}
|
|
|
|
# Grafana — private only, SWAG arkasindan 443 uzerinden (IP kisitli)
|
|
rule {
|
|
direction = "in"
|
|
protocol = "tcp"
|
|
port = "3000"
|
|
source_ips = [local.app_subnet_cidr]
|
|
}
|
|
|
|
labels = {
|
|
environment = local.environment
|
|
role = "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
|
|
}
|
|
|
|
# PostgreSQL from app/swarm subnet
|
|
rule {
|
|
direction = "in"
|
|
protocol = "tcp"
|
|
port = "5432"
|
|
source_ips = [local.app_subnet_cidr]
|
|
}
|
|
|
|
# PostgreSQL replication within DB subnet
|
|
rule {
|
|
direction = "in"
|
|
protocol = "tcp"
|
|
port = "5432"
|
|
source_ips = [local.db_subnet_cidr]
|
|
}
|
|
|
|
# MongoDB from app/swarm subnet
|
|
rule {
|
|
direction = "in"
|
|
protocol = "tcp"
|
|
port = "27017"
|
|
source_ips = [local.app_subnet_cidr]
|
|
}
|
|
|
|
# MongoDB replica set internal traffic
|
|
rule {
|
|
direction = "in"
|
|
protocol = "tcp"
|
|
port = "27017"
|
|
source_ips = [local.db_subnet_cidr]
|
|
}
|
|
|
|
labels = {
|
|
environment = local.environment
|
|
role = "db"
|
|
}
|
|
}
|