diff --git a/terraform/common/bastion.tf b/terraform/common/bastion.tf index e2971b1..da8e31b 100644 --- a/terraform/common/bastion.tf +++ b/terraform/common/bastion.tf @@ -34,6 +34,13 @@ resource "proxmox_virtual_environment_container" "bastion" { enabled = true } + network_interface { + bridge = var.production_network_bridge_name + name = "eth-prod" + firewall = true + enabled = true + } + initialization { hostname = "bastion" ip_config { @@ -47,6 +54,12 @@ resource "proxmox_virtual_environment_container" "bastion" { # gateway = "192.168.0.1" } } + ip_config { + ipv4 { + address = "192.168.1.254/24" + # gateway = "192.168.1.1" + } + } user_account { keys = [var.ssh_public_key] } diff --git a/terraform/common/firewall_ipsets.tf b/terraform/common/firewall_ipsets.tf index 5458c1d..6a0233f 100644 --- a/terraform/common/firewall_ipsets.tf +++ b/terraform/common/firewall_ipsets.tf @@ -1,3 +1,19 @@ +resource "proxmox_virtual_environment_firewall_ipset" "promeheus_server" { + + name = "prometheus-server" + comment = "Different environment Prometheus Server addresses." + + cidr { + name = "192.168.0.252" + comment = "dev" + } + + cidr { + name = "192.168.1.252" + comment = "prod" + } +} + resource "proxmox_virtual_environment_firewall_ipset" "dev_loggers" { name = "dev-loggers" @@ -44,6 +60,52 @@ resource "proxmox_virtual_environment_firewall_ipset" "dev_loggers" { } } +resource "proxmox_virtual_environment_firewall_ipset" "prod_loggers" { + + name = "prod-loggers" + comment = "Nodes that send logs to Monitoring Node." + + cidr { + name = "192.168.1.254" + comment = "bastion" + } + + cidr { + name = "192.168.1.253" + comment = "load-balancer" + } + + cidr { + name = "192.168.1.252" + comment = "monitoring" + } + + cidr { + name = "192.168.1.3" + comment = "postgresql" + } + + cidr { + name = "192.168.1.10" + comment = "main-page" + } + + cidr { + name = "192.168.1.15" + comment = "searxng" + } + + cidr { + name = "192.168.1.20" + comment = "forgejo" + } + + cidr { + name = "192.168.1.21" + comment = "forgejo-runner" + } +} + resource "proxmox_virtual_environment_firewall_ipset" "dev_postgres_clients" { name = "dev-postgres-clients" @@ -60,6 +122,22 @@ output "dev_postgres_clients_ipset" { sensitive = true } +resource "proxmox_virtual_environment_firewall_ipset" "prod_postgres_clients" { + + name = "prod-postgres-clients" + comment = "Nodes that can connect to postgres Node." + + cidr { + name = "192.168.1.20" + comment = "forgejo" + } +} + +output "prod_postgres_clients_ipset" { + value = proxmox_virtual_environment_firewall_ipset.prod_postgres_clients + sensitive = true +} + resource "proxmox_virtual_environment_firewall_ipset" "dev_valkey_clients" { name = "dev-valkey-clients" @@ -75,3 +153,19 @@ output "dev_valkey_clients_ipset" { value = proxmox_virtual_environment_firewall_ipset.dev_valkey_clients sensitive = true } + +resource "proxmox_virtual_environment_firewall_ipset" "prod_valkey_clients" { + + name = "prod-valkey-clients" + comment = "Nodes that can connect to valkey Node." + + cidr { + name = "192.168.1.15" + comment = "searxng" + } +} + +output "prod_valkey_clients_ipset" { + value = proxmox_virtual_environment_firewall_ipset.prod_valkey_clients + sensitive = true +} diff --git a/terraform/common/firewall_security_groups.tf b/terraform/common/firewall_security_groups.tf index 2ccc812..a717341 100644 --- a/terraform/common/firewall_security_groups.tf +++ b/terraform/common/firewall_security_groups.tf @@ -4,7 +4,7 @@ resource "proxmox_virtual_environment_cluster_firewall_security_group" "promethe rule { type = "in" - source = split("/", proxmox_virtual_environment_container.monitoring.initialization[0].ip_config[0].ipv4[0].address)[0] + source = "+${proxmox_virtual_environment_firewall_ipset.promeheus_server.name}" proto = "tcp" dport = "9100" action = "ACCEPT" @@ -22,7 +22,7 @@ resource "proxmox_virtual_environment_cluster_firewall_security_group" "promethe rule { type = "in" - source = split("/", proxmox_virtual_environment_container.monitoring.initialization[0].ip_config[0].ipv4[0].address)[0] + source = "+${proxmox_virtual_environment_firewall_ipset.promeheus_server.name}" proto = "tcp" dport = "9113" action = "ACCEPT" @@ -40,7 +40,7 @@ resource "proxmox_virtual_environment_cluster_firewall_security_group" "promethe rule { type = "in" - source = split("/", proxmox_virtual_environment_container.monitoring.initialization[0].ip_config[0].ipv4[0].address)[0] + source = "+${proxmox_virtual_environment_firewall_ipset.promeheus_server.name}" proto = "tcp" dport = "9090" action = "ACCEPT" @@ -58,7 +58,7 @@ resource "proxmox_virtual_environment_cluster_firewall_security_group" "promethe rule { type = "in" - source = split("/", proxmox_virtual_environment_container.monitoring.initialization[0].ip_config[0].ipv4[0].address)[0] + source = "+${proxmox_virtual_environment_firewall_ipset.promeheus_server.name}" proto = "tcp" dport = "9093" action = "ACCEPT" diff --git a/terraform/common/load-balancer.tf b/terraform/common/load-balancer.tf index e796183..9464dfe 100644 --- a/terraform/common/load-balancer.tf +++ b/terraform/common/load-balancer.tf @@ -34,6 +34,13 @@ resource "proxmox_virtual_environment_container" "load_balancer" { enabled = true } + network_interface { + bridge = var.production_network_bridge_name + name = "eth-prod" + firewall = true + enabled = true + } + initialization { hostname = "load-balancer" ip_config { @@ -47,6 +54,12 @@ resource "proxmox_virtual_environment_container" "load_balancer" { # gateway = "192.168.0.1" } } + ip_config { + ipv4 { + address = "192.168.1.253/24" + # gateway = "192.168.1.1" + } + } user_account { keys = [var.ssh_public_key] } diff --git a/terraform/common/monitoring.tf b/terraform/common/monitoring.tf index 5e1e437..cbdecaf 100644 --- a/terraform/common/monitoring.tf +++ b/terraform/common/monitoring.tf @@ -27,6 +27,13 @@ resource "proxmox_virtual_environment_container" "monitoring" { enabled = true } + network_interface { + bridge = var.production_network_bridge_name + name = "eth-prod" + firewall = true + enabled = true + } + initialization { hostname = "monitoring" ip_config { @@ -35,6 +42,12 @@ resource "proxmox_virtual_environment_container" "monitoring" { gateway = "192.168.0.1" } } + ip_config { + ipv4 { + address = "192.168.1.252/24" + # gateway = "192.168.1.1" + } + } user_account { keys = [var.ssh_public_key] } diff --git a/terraform/prod/forgejo-runner.tf b/terraform/prod/forgejo-runner.tf new file mode 100644 index 0000000..86eb042 --- /dev/null +++ b/terraform/prod/forgejo-runner.tf @@ -0,0 +1,100 @@ +resource "proxmox_virtual_environment_container" "forgejo-runner" { + node_name = "pve" + + vm_id = 5051 + + tags = ["prod"] + + unprivileged = true + + cpu { + cores = 1 + } + + memory { + dedicated = 1024 + } + + disk { + datastore_id = var.datastore_id + size = 16 + } + + network_interface { + bridge = var.internal_network_bridge_name + name = "eth-prod" + firewall = true + enabled = true + } + + initialization { + hostname = "forgejo-runner" + ip_config { + ipv4 { + address = "192.168.1.21/24" + gateway = "192.168.1.1" + } + } + user_account { + keys = [var.ssh_public_key] + } + } + + operating_system { + template_file_id = "local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst" + type = "debian" + } + + started = true + + startup { + order = 500 + up_delay = 0 + down_delay = 0 + } + + features { + nesting = true + } +} + +resource "proxmox_virtual_environment_firewall_options" "forgejo-runner" { + depends_on = [proxmox_virtual_environment_container.forgejo-runner] + + node_name = proxmox_virtual_environment_container.forgejo-runner.node_name + vm_id = proxmox_virtual_environment_container.forgejo-runner.vm_id + + enabled = true + dhcp = true + input_policy = "DROP" + output_policy = "ACCEPT" +} + +resource "proxmox_virtual_environment_firewall_rules" "forgejo-runner" { + depends_on = [proxmox_virtual_environment_container.forgejo-runner] + + node_name = proxmox_virtual_environment_container.forgejo-runner.node_name + vm_id = proxmox_virtual_environment_container.forgejo-runner.vm_id + + rule { + type = "in" + source = split("/", data.terraform_remote_state.common.outputs.bastion_ct.initialization[0].ip_config[2].ipv4[0].address)[0] + proto = "tcp" + dport = "22" + action = "ACCEPT" + comment = "SSH from Bastion." + } + + rule { + type = "in" + proto = "icmp" + dport = "8" + action = "ACCEPT" + comment = "Ping." + } + + rule { + security_group = data.terraform_remote_state.common.outputs.prometheus_node_exporter_sg.name + comment = "Allow Prometheus server to pull Prometheus node exporter from Monitoring Node." + } +} diff --git a/terraform/prod/forgejo.tf b/terraform/prod/forgejo.tf new file mode 100644 index 0000000..8043622 --- /dev/null +++ b/terraform/prod/forgejo.tf @@ -0,0 +1,109 @@ +resource "proxmox_virtual_environment_container" "forgejo" { + node_name = "pve" + + vm_id = 5050 + + tags = ["prod"] + + unprivileged = true + + cpu { + cores = 1 + } + + memory { + dedicated = 1024 + } + + disk { + datastore_id = var.datastore_id + size = 16 + } + + network_interface { + bridge = var.internal_network_bridge_name + name = "eth-prod" + firewall = true + enabled = true + } + + initialization { + hostname = "forgejo" + ip_config { + ipv4 { + address = "192.168.1.20/24" + gateway = "192.168.1.1" + } + } + user_account { + keys = [var.ssh_public_key] + } + } + + operating_system { + template_file_id = "local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst" + type = "debian" + } + + started = true + + startup { + order = 500 + up_delay = 0 + down_delay = 0 + } + + features { + nesting = true + } +} + +resource "proxmox_virtual_environment_firewall_options" "forgejo" { + depends_on = [proxmox_virtual_environment_container.forgejo] + + node_name = proxmox_virtual_environment_container.forgejo.node_name + vm_id = proxmox_virtual_environment_container.forgejo.vm_id + + enabled = true + dhcp = true + input_policy = "DROP" + output_policy = "ACCEPT" +} + +resource "proxmox_virtual_environment_firewall_rules" "forgejo" { + depends_on = [proxmox_virtual_environment_container.forgejo] + + node_name = proxmox_virtual_environment_container.forgejo.node_name + vm_id = proxmox_virtual_environment_container.forgejo.vm_id + + rule { + type = "in" + source = split("/", data.terraform_remote_state.common.outputs.bastion_ct.initialization[0].ip_config[2].ipv4[0].address)[0] + proto = "tcp" + dport = "22" + action = "ACCEPT" + comment = "SSH from Bastion." + } + + rule { + type = "in" + proto = "icmp" + dport = "8" + action = "ACCEPT" + comment = "Ping." + } + + rule { + type = "in" + source = split("/", data.terraform_remote_state.common.outputs.load_balancer_ct.initialization[0].ip_config[1].ipv4[0].address)[0] + proto = "tcp" + dport = "3000" + action = "ACCEPT" + comment = "Forgejo Web." + } + + rule { + security_group = data.terraform_remote_state.common.outputs.prometheus_node_exporter_sg.name + comment = "Allow Prometheus server to pull Prometheus node exporter from Monitoring Node." + } +} diff --git a/terraform/prod/main-page.tf b/terraform/prod/main-page.tf new file mode 100644 index 0000000..89faf83 --- /dev/null +++ b/terraform/prod/main-page.tf @@ -0,0 +1,109 @@ +resource "proxmox_virtual_environment_container" "main_page" { + node_name = "pve" + + vm_id = 5010 + + tags = ["prod"] + + unprivileged = true + + cpu { + cores = 1 + } + + memory { + dedicated = 512 + } + + disk { + datastore_id = var.datastore_id + size = 4 + } + + network_interface { + bridge = var.internal_network_bridge_name + name = "eth-prod" + firewall = true + enabled = true + } + + initialization { + hostname = "main-page" + ip_config { + ipv4 { + address = "192.168.1.10/24" + gateway = "192.168.1.1" + } + } + user_account { + keys = [var.ssh_public_key] + } + } + + operating_system { + template_file_id = "local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst" + type = "debian" + } + + started = true + + startup { + order = 500 + up_delay = 0 + down_delay = 0 + } + + features { + nesting = true + } +} + +resource "proxmox_virtual_environment_firewall_options" "main_page" { + depends_on = [proxmox_virtual_environment_container.main_page] + + node_name = proxmox_virtual_environment_container.main_page.node_name + vm_id = proxmox_virtual_environment_container.main_page.vm_id + + enabled = true + dhcp = true + input_policy = "DROP" + output_policy = "ACCEPT" +} + +resource "proxmox_virtual_environment_firewall_rules" "main_page" { + depends_on = [proxmox_virtual_environment_container.main_page] + + node_name = proxmox_virtual_environment_container.main_page.node_name + vm_id = proxmox_virtual_environment_container.main_page.vm_id + + rule { + type = "in" + source = split("/", data.terraform_remote_state.common.outputs.bastion_ct.initialization[0].ip_config[2].ipv4[0].address)[0] + proto = "tcp" + dport = "22" + action = "ACCEPT" + comment = "SSH from Bastion." + } + + rule { + type = "in" + proto = "icmp" + dport = "8" + action = "ACCEPT" + comment = "Ping." + } + + rule { + type = "in" + source = split("/", data.terraform_remote_state.common.outputs.load_balancer_ct.initialization[0].ip_config[1].ipv4[0].address)[0] + proto = "tcp" + dport = "80" + action = "ACCEPT" + comment = "Nginx Static Serving." + } + + rule { + security_group = data.terraform_remote_state.common.outputs.prometheus_node_exporter_sg.name + comment = "Allow Prometheus server to pull Prometheus node exporter from Monitoring Node." + } +} diff --git a/terraform/prod/postgresql.tf b/terraform/prod/postgresql.tf new file mode 100644 index 0000000..ff3805b --- /dev/null +++ b/terraform/prod/postgresql.tf @@ -0,0 +1,109 @@ +resource "proxmox_virtual_environment_container" "postgresql" { + node_name = "pve" + + vm_id = 5030 + + tags = ["prod", "database"] + + unprivileged = true + + cpu { + cores = 1 + } + + memory { + dedicated = 512 + } + + disk { + datastore_id = var.datastore_id + size = 8 + } + + network_interface { + bridge = var.internal_network_bridge_name + name = "eth-prod" + firewall = true + enabled = true + } + + initialization { + hostname = "postgresql" + ip_config { + ipv4 { + address = "192.168.1.3/24" + gateway = "192.168.1.1" + } + } + user_account { + keys = [var.ssh_public_key] + } + } + + operating_system { + template_file_id = "local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst" + type = "debian" + } + + started = true + + startup { + order = 100 + up_delay = 0 + down_delay = 0 + } + + features { + nesting = true + } +} + +resource "proxmox_virtual_environment_firewall_options" "postgresql" { + depends_on = [proxmox_virtual_environment_container.postgresql] + + node_name = proxmox_virtual_environment_container.postgresql.node_name + vm_id = proxmox_virtual_environment_container.postgresql.vm_id + + enabled = true + dhcp = true + input_policy = "DROP" + output_policy = "ACCEPT" +} + +resource "proxmox_virtual_environment_firewall_rules" "postgresql" { + depends_on = [proxmox_virtual_environment_container.postgresql] + + node_name = proxmox_virtual_environment_container.postgresql.node_name + vm_id = proxmox_virtual_environment_container.postgresql.vm_id + + rule { + type = "in" + source = split("/", data.terraform_remote_state.common.outputs.bastion_ct.initialization[0].ip_config[2].ipv4[0].address)[0] + proto = "tcp" + dport = "22" + action = "ACCEPT" + comment = "SSH from Bastion." + } + + rule { + type = "in" + proto = "icmp" + dport = "8" + action = "ACCEPT" + comment = "Ping." + } + + rule { + security_group = data.terraform_remote_state.common.outputs.prometheus_node_exporter_sg.name + comment = "Allow Prometheus server to pull Prometheus node exporter from Monitoring Node." + } + + rule { + type = "in" + source = "+${data.terraform_remote_state.common.outputs.prod_postgres_clients_ipset.name}" + proto = "tcp" + dport = "5432" + action = "ACCEPT" + comment = "Access postgres from client nodes." + } +} diff --git a/terraform/prod/searxng.tf b/terraform/prod/searxng.tf new file mode 100644 index 0000000..94e46c3 --- /dev/null +++ b/terraform/prod/searxng.tf @@ -0,0 +1,109 @@ +resource "proxmox_virtual_environment_container" "searxng" { + node_name = "pve" + + vm_id = 5020 + + tags = ["prod"] + + unprivileged = true + + cpu { + cores = 1 + } + + memory { + dedicated = 512 + } + + disk { + datastore_id = var.datastore_id + size = 4 + } + + network_interface { + bridge = var.internal_network_bridge_name + name = "eth-prod" + firewall = true + enabled = true + } + + initialization { + hostname = "searxng" + ip_config { + ipv4 { + address = "192.168.1.15/24" + gateway = "192.168.1.1" + } + } + user_account { + keys = [var.ssh_public_key] + } + } + + operating_system { + template_file_id = "local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst" + type = "debian" + } + + started = true + + startup { + order = 500 + up_delay = 0 + down_delay = 0 + } + + features { + nesting = true + } +} + +resource "proxmox_virtual_environment_firewall_options" "searxng" { + depends_on = [proxmox_virtual_environment_container.searxng] + + node_name = proxmox_virtual_environment_container.searxng.node_name + vm_id = proxmox_virtual_environment_container.searxng.vm_id + + enabled = true + dhcp = true + input_policy = "DROP" + output_policy = "ACCEPT" +} + +resource "proxmox_virtual_environment_firewall_rules" "searxng" { + depends_on = [proxmox_virtual_environment_container.searxng] + + node_name = proxmox_virtual_environment_container.searxng.node_name + vm_id = proxmox_virtual_environment_container.searxng.vm_id + + rule { + type = "in" + source = split("/", data.terraform_remote_state.common.outputs.bastion_ct.initialization[0].ip_config[2].ipv4[0].address)[0] + proto = "tcp" + dport = "22" + action = "ACCEPT" + comment = "SSH from Bastion." + } + + rule { + type = "in" + proto = "icmp" + dport = "8" + action = "ACCEPT" + comment = "Ping." + } + + rule { + type = "in" + source = split("/", data.terraform_remote_state.common.outputs.load_balancer_ct.initialization[0].ip_config[1].ipv4[0].address)[0] + proto = "tcp" + dport = "8888" + action = "ACCEPT" + comment = "SearxNG." + } + + rule { + security_group = data.terraform_remote_state.common.outputs.prometheus_node_exporter_sg.name + comment = "Allow Prometheus server to pull Prometheus node exporter from Monitoring Node." + } +} diff --git a/terraform/prod/valkey.tf b/terraform/prod/valkey.tf new file mode 100644 index 0000000..172448d --- /dev/null +++ b/terraform/prod/valkey.tf @@ -0,0 +1,109 @@ +resource "proxmox_virtual_environment_container" "valkey" { + node_name = "pve" + + vm_id = 5040 + + tags = ["prod", "database", "cache"] + + unprivileged = true + + cpu { + cores = 1 + } + + memory { + dedicated = 512 + } + + disk { + datastore_id = var.datastore_id + size = 4 + } + + network_interface { + bridge = var.internal_network_bridge_name + name = "eth-prod" + firewall = true + enabled = true + } + + initialization { + hostname = "valkey" + ip_config { + ipv4 { + address = "192.168.1.4/24" + gateway = "192.168.1.1" + } + } + user_account { + keys = [var.ssh_public_key] + } + } + + operating_system { + template_file_id = "local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst" + type = "debian" + } + + started = true + + startup { + order = 100 + up_delay = 0 + down_delay = 0 + } + + features { + nesting = true + } +} + +resource "proxmox_virtual_environment_firewall_options" "valkey" { + depends_on = [proxmox_virtual_environment_container.valkey] + + node_name = proxmox_virtual_environment_container.valkey.node_name + vm_id = proxmox_virtual_environment_container.valkey.vm_id + + enabled = true + dhcp = true + input_policy = "DROP" + output_policy = "ACCEPT" +} + +resource "proxmox_virtual_environment_firewall_rules" "valkey" { + depends_on = [proxmox_virtual_environment_container.valkey] + + node_name = proxmox_virtual_environment_container.valkey.node_name + vm_id = proxmox_virtual_environment_container.valkey.vm_id + + rule { + type = "in" + source = split("/", data.terraform_remote_state.common.outputs.bastion_ct.initialization[0].ip_config[2].ipv4[0].address)[0] + proto = "tcp" + dport = "22" + action = "ACCEPT" + comment = "SSH from Bastion." + } + + rule { + type = "in" + proto = "icmp" + dport = "8" + action = "ACCEPT" + comment = "Ping." + } + + rule { + security_group = data.terraform_remote_state.common.outputs.prometheus_node_exporter_sg.name + comment = "Allow Prometheus server to pull Prometheus node exporter from Monitoring Node." + } + + rule { + type = "in" + source = "+${data.terraform_remote_state.common.outputs.prod_valkey_clients_ipset.name}" + proto = "tcp" + dport = "6379" + action = "ACCEPT" + comment = "Access valkey from client nodes." + } +}