From 0182edd24535e0157a5a804ddc21b7cdf513d8e1 Mon Sep 17 00:00:00 2001 From: Oscar Pocock Date: Thu, 7 Apr 2022 21:02:23 +0100 Subject: [PATCH] Added MailCow and Pterodactyl projects --- .../Development/mailcow/.terraform.lock.hcl | 24 ++++ .../Development/mailcow/cloud-config.tpl | 31 +++++ .../Projects/Development/mailcow/firewall.tf | 67 ++++++++++ hetzner/Projects/Development/mailcow/main.tf | 8 ++ .../Projects/Development/mailcow/network.tf | 4 + .../Projects/Development/mailcow/outputs.tf | 11 ++ .../Projects/Development/mailcow/provider.tf | 8 ++ hetzner/Projects/Development/mailcow/rdns.tf | 11 ++ .../Projects/Development/mailcow/server.tf | 15 +++ .../Development/mailcow/server_network.tf | 5 + .../Projects/Development/mailcow/subnet.tf | 6 + .../Projects/Development/mailcow/variables.tf | 42 +++++++ .../Pterodactyl/node-01/.terraform.lock.hcl | 39 ++++++ .../Pterodactyl/node-01/cloud-config.tpl | 32 +++++ .../node-01/docker-compose.yml.bak | 78 ++++++++++++ .../Projects/Pterodactyl/node-01/firewall.tf | 3 + hetzner/Projects/Pterodactyl/node-01/main.tf | 8 ++ .../Projects/Pterodactyl/node-01/network.tf | 3 + .../Projects/Pterodactyl/node-01/outputs.tf | 7 ++ .../Projects/Pterodactyl/node-01/provider.tf | 8 ++ .../Projects/Pterodactyl/node-01/server.tf | 10 ++ .../Pterodactyl/node-01/server_network.tf | 5 + .../Projects/Pterodactyl/node-01/variables.tf | 36 ++++++ .../Pterodactyl/panel/.terraform.lock.hcl | 39 ++++++ .../Pterodactyl/panel/cloud-config.tpl | 64 ++++++++++ .../Pterodactyl/panel/docker-compose.yml.bak | 78 ++++++++++++ .../Projects/Pterodactyl/panel/firewall.tf | 118 ++++++++++++++++++ .../Projects/Pterodactyl/panel/floating_ip.tf | 8 ++ hetzner/Projects/Pterodactyl/panel/main.tf | 8 ++ hetzner/Projects/Pterodactyl/panel/network.tf | 4 + hetzner/Projects/Pterodactyl/panel/outputs.tf | 11 ++ .../Projects/Pterodactyl/panel/provider.tf | 8 ++ hetzner/Projects/Pterodactyl/panel/server.tf | 14 +++ .../Pterodactyl/panel/server_network.tf | 5 + hetzner/Projects/Pterodactyl/panel/subnet.tf | 6 + .../Projects/Pterodactyl/panel/variables.tf | 40 ++++++ .../pterodactyl/.terraform.lock.hcl | 39 ++++++ .../Pterodactyl/pterodactyl/cloud-config.tpl | 60 +++++++++ .../pterodactyl/docker-compose.yml.bak | 78 ++++++++++++ .../Pterodactyl/pterodactyl/firewall.tf | 96 ++++++++++++++ .../Projects/Pterodactyl/pterodactyl/main.tf | 8 ++ .../Pterodactyl/pterodactyl/network.tf | 4 + .../Pterodactyl/pterodactyl/outputs.tf | 7 ++ .../Pterodactyl/pterodactyl/provider.tf | 8 ++ .../Pterodactyl/pterodactyl/server.tf | 14 +++ .../Pterodactyl/pterodactyl/server_network.tf | 5 + .../Pterodactyl/pterodactyl/subnet.tf | 6 + .../Pterodactyl/pterodactyl/variables.tf | 36 ++++++ hetzner/template/.terraform.lock.hcl | 22 ++++ hetzner/template/firewall.tf | 41 ++++++ hetzner/template/main.tf | 8 ++ hetzner/template/network.tf | 4 + hetzner/template/outputs.tf | 7 ++ hetzner/template/provider.tf | 8 ++ hetzner/template/server.tf | 13 ++ hetzner/template/server_network.tf | 5 + hetzner/template/subnet.tf | 6 + hetzner/template/variables.tf | 32 +++++ 58 files changed, 1371 insertions(+) create mode 100644 hetzner/Projects/Development/mailcow/.terraform.lock.hcl create mode 100644 hetzner/Projects/Development/mailcow/cloud-config.tpl create mode 100644 hetzner/Projects/Development/mailcow/firewall.tf create mode 100644 hetzner/Projects/Development/mailcow/main.tf create mode 100644 hetzner/Projects/Development/mailcow/network.tf create mode 100644 hetzner/Projects/Development/mailcow/outputs.tf create mode 100644 hetzner/Projects/Development/mailcow/provider.tf create mode 100644 hetzner/Projects/Development/mailcow/rdns.tf create mode 100644 hetzner/Projects/Development/mailcow/server.tf create mode 100644 hetzner/Projects/Development/mailcow/server_network.tf create mode 100644 hetzner/Projects/Development/mailcow/subnet.tf create mode 100644 hetzner/Projects/Development/mailcow/variables.tf create mode 100644 hetzner/Projects/Pterodactyl/node-01/.terraform.lock.hcl create mode 100644 hetzner/Projects/Pterodactyl/node-01/cloud-config.tpl create mode 100644 hetzner/Projects/Pterodactyl/node-01/docker-compose.yml.bak create mode 100644 hetzner/Projects/Pterodactyl/node-01/firewall.tf create mode 100644 hetzner/Projects/Pterodactyl/node-01/main.tf create mode 100644 hetzner/Projects/Pterodactyl/node-01/network.tf create mode 100644 hetzner/Projects/Pterodactyl/node-01/outputs.tf create mode 100644 hetzner/Projects/Pterodactyl/node-01/provider.tf create mode 100644 hetzner/Projects/Pterodactyl/node-01/server.tf create mode 100644 hetzner/Projects/Pterodactyl/node-01/server_network.tf create mode 100644 hetzner/Projects/Pterodactyl/node-01/variables.tf create mode 100644 hetzner/Projects/Pterodactyl/panel/.terraform.lock.hcl create mode 100644 hetzner/Projects/Pterodactyl/panel/cloud-config.tpl create mode 100644 hetzner/Projects/Pterodactyl/panel/docker-compose.yml.bak create mode 100644 hetzner/Projects/Pterodactyl/panel/firewall.tf create mode 100644 hetzner/Projects/Pterodactyl/panel/floating_ip.tf create mode 100644 hetzner/Projects/Pterodactyl/panel/main.tf create mode 100644 hetzner/Projects/Pterodactyl/panel/network.tf create mode 100644 hetzner/Projects/Pterodactyl/panel/outputs.tf create mode 100644 hetzner/Projects/Pterodactyl/panel/provider.tf create mode 100644 hetzner/Projects/Pterodactyl/panel/server.tf create mode 100644 hetzner/Projects/Pterodactyl/panel/server_network.tf create mode 100644 hetzner/Projects/Pterodactyl/panel/subnet.tf create mode 100644 hetzner/Projects/Pterodactyl/panel/variables.tf create mode 100644 hetzner/Projects/Pterodactyl/pterodactyl/.terraform.lock.hcl create mode 100644 hetzner/Projects/Pterodactyl/pterodactyl/cloud-config.tpl create mode 100644 hetzner/Projects/Pterodactyl/pterodactyl/docker-compose.yml.bak create mode 100644 hetzner/Projects/Pterodactyl/pterodactyl/firewall.tf create mode 100644 hetzner/Projects/Pterodactyl/pterodactyl/main.tf create mode 100644 hetzner/Projects/Pterodactyl/pterodactyl/network.tf create mode 100644 hetzner/Projects/Pterodactyl/pterodactyl/outputs.tf create mode 100644 hetzner/Projects/Pterodactyl/pterodactyl/provider.tf create mode 100644 hetzner/Projects/Pterodactyl/pterodactyl/server.tf create mode 100644 hetzner/Projects/Pterodactyl/pterodactyl/server_network.tf create mode 100644 hetzner/Projects/Pterodactyl/pterodactyl/subnet.tf create mode 100644 hetzner/Projects/Pterodactyl/pterodactyl/variables.tf create mode 100644 hetzner/template/.terraform.lock.hcl create mode 100644 hetzner/template/firewall.tf create mode 100644 hetzner/template/main.tf create mode 100644 hetzner/template/network.tf create mode 100644 hetzner/template/outputs.tf create mode 100644 hetzner/template/provider.tf create mode 100644 hetzner/template/server.tf create mode 100644 hetzner/template/server_network.tf create mode 100644 hetzner/template/subnet.tf create mode 100644 hetzner/template/variables.tf diff --git a/hetzner/Projects/Development/mailcow/.terraform.lock.hcl b/hetzner/Projects/Development/mailcow/.terraform.lock.hcl new file mode 100644 index 0000000..12a50de --- /dev/null +++ b/hetzner/Projects/Development/mailcow/.terraform.lock.hcl @@ -0,0 +1,24 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hetznercloud/hcloud" { + version = "1.33.1" + constraints = "~> 1.33.1" + hashes = [ + "h1:qvQGDcw11niyogj5fNPmGUlkXc/QTJh+UgfwUwZfDeM=", + "zh:0e30919099010a0f6f83631c634512ad27cd02bb119d434a62d0f25061fcffd0", + "zh:121ae06c2d313616f1c4dffd54b0586b48a9a0996117ca45cfc43b6077be0c34", + "zh:18ab43acedcebece7ba2f839d8147371200f9c62c616b2bd8ee730352663cb7d", + "zh:24ffe93b2d9bcf0c7944c178497456f43c6096c80032ca15a7b7fe13021bac5c", + "zh:2f5eb2dba69bff9386ecc675ceb725c4d23f20c8359492666b4469afc8b25930", + "zh:57597aee1fb118c794b67aec4d676447596343959b5de03bc3403ebd2d9ecfd6", + "zh:70c910987bd61e6129d87071766524967fd9336d3b67a5af3e2aee93b896fbd0", + "zh:7250145e6ac09fe5d915c2c09b785062d0d2695557b2f856197b952955781bdc", + "zh:7903ec07eba0db779aec46eaed0605aa9d5be360cd44fc6ed9267bed593ec02f", + "zh:85a101fa71bbec512a7f015aaa18837f2e1218c9279429a110bd01b69dac3acf", + "zh:9470dbb7adfaec8c4996844ac1aa1701341c56de37b570bf811b55529b43697a", + "zh:ad5ffed22254eeafa59bac49fac52bd30bb559d3958b443884affecd5f631dcd", + "zh:d1e6c2d1c07f496cdbde1eac4a6fb96a41edd6f8dbfbacabe33646eb78dbe15e", + "zh:ee0ddda6131b80a2308b2c76addbede27f7739f03e59a4665aff4f83e1e2ef4e", + ] +} diff --git a/hetzner/Projects/Development/mailcow/cloud-config.tpl b/hetzner/Projects/Development/mailcow/cloud-config.tpl new file mode 100644 index 0000000..ac18e80 --- /dev/null +++ b/hetzner/Projects/Development/mailcow/cloud-config.tpl @@ -0,0 +1,31 @@ +#cloud-config + +users: + - default + - name: noble + gecos: Oscar Pocock + groups: users, docker, admin + # primary_group: noble + sudo: ALL=(ALL) NOPASSWD:ALL + shell: /bin/bash + ssh-authorized-keys: + - ${SSH_PUB} + +package_update: true + +package_upgrade: true + +packages: + - vim + - htop + - ranger + - fail2ban + - git + +runcmd: + - curl -fsSL https://get.docker.com | sh + - curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose + - git clone https://github.com/mailcow/mailcow-dockerized /opt/mailcow-dockerized + - systemctl enable --now fail2ban + +final_message: "The system is finally up, after $UPTIME seconds" diff --git a/hetzner/Projects/Development/mailcow/firewall.tf b/hetzner/Projects/Development/mailcow/firewall.tf new file mode 100644 index 0000000..0a18e4b --- /dev/null +++ b/hetzner/Projects/Development/mailcow/firewall.tf @@ -0,0 +1,67 @@ +resource "hcloud_firewall" "firewall" { + name = "${var.project_name}-fw" + rule { + direction = "in" + protocol = "icmp" + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } + # SSH + rule { + direction = "in" + protocol = "tcp" + port = 22 + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } + # HTTP + rule { + direction = "in" + protocol = "tcp" + port = 80 + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } + # HTTPS + rule { + direction = "in" + protocol = "tcp" + port = 443 + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } + + # HTTPS + rule { + direction = "in" + protocol = "tcp" + port = 1025 + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } + +dynamic "rule"{ + for_each = local.mailcow_ports + content { + direction = "in" + protocol = "tcp" + port = rule.value + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + + } +} + +} diff --git a/hetzner/Projects/Development/mailcow/main.tf b/hetzner/Projects/Development/mailcow/main.tf new file mode 100644 index 0000000..2218bc4 --- /dev/null +++ b/hetzner/Projects/Development/mailcow/main.tf @@ -0,0 +1,8 @@ +terraform { + required_providers { + hcloud = { + source = "hetznercloud/hcloud" + version = "~> 1.33.1" + } + } +} diff --git a/hetzner/Projects/Development/mailcow/network.tf b/hetzner/Projects/Development/mailcow/network.tf new file mode 100644 index 0000000..400fd41 --- /dev/null +++ b/hetzner/Projects/Development/mailcow/network.tf @@ -0,0 +1,4 @@ +resource "hcloud_network" "network" { + name = "${var.project_name}-vnet" + ip_range = "10.0.0.0/16" +} diff --git a/hetzner/Projects/Development/mailcow/outputs.tf b/hetzner/Projects/Development/mailcow/outputs.tf new file mode 100644 index 0000000..a2c2974 --- /dev/null +++ b/hetzner/Projects/Development/mailcow/outputs.tf @@ -0,0 +1,11 @@ +output "public_ipv4" { + value = hcloud_server.server.ipv4_address +} + +output "public_ipv6" { + value = hcloud_server.server.ipv6_address +} + +output "private_ip" { + value = hcloud_server_network.server_network.ip +} diff --git a/hetzner/Projects/Development/mailcow/provider.tf b/hetzner/Projects/Development/mailcow/provider.tf new file mode 100644 index 0000000..a42c014 --- /dev/null +++ b/hetzner/Projects/Development/mailcow/provider.tf @@ -0,0 +1,8 @@ +# Set the variable value in *.tfvars file +# or using the -var="hcloud_token=..." CLI option +variable "hcloud_token" {} + +# Configure the Hetzner Cloud Provider +provider "hcloud" { + token = var.hcloud_token +} diff --git a/hetzner/Projects/Development/mailcow/rdns.tf b/hetzner/Projects/Development/mailcow/rdns.tf new file mode 100644 index 0000000..79db4dc --- /dev/null +++ b/hetzner/Projects/Development/mailcow/rdns.tf @@ -0,0 +1,11 @@ +resource "hcloud_rdns" "ipv4" { + server_id = hcloud_server.server.id + ip_address = hcloud_server.server.ipv4_address + dns_ptr = var.rdns +} + +resource "hcloud_rdns" "ipv6" { + server_id = hcloud_server.server.id + ip_address = hcloud_server.server.ipv6_address + dns_ptr = var.rdns +} diff --git a/hetzner/Projects/Development/mailcow/server.tf b/hetzner/Projects/Development/mailcow/server.tf new file mode 100644 index 0000000..7be43e6 --- /dev/null +++ b/hetzner/Projects/Development/mailcow/server.tf @@ -0,0 +1,15 @@ +resource "hcloud_server" "server" { + name = "${var.project_name}-vm" + server_type = var.server_type + image = var.image + location = var.location + backups = var.backups + firewall_ids = [hcloud_firewall.firewall.id] + labels = local.labels + # user_data = file("${path.module}/cloud-config.tpl") + user_data = templatefile("${path.module}/cloud-config.tpl", var.cloud_config) + + depends_on = [ + hcloud_network_subnet.network-subnet + ] +} diff --git a/hetzner/Projects/Development/mailcow/server_network.tf b/hetzner/Projects/Development/mailcow/server_network.tf new file mode 100644 index 0000000..efd5a8d --- /dev/null +++ b/hetzner/Projects/Development/mailcow/server_network.tf @@ -0,0 +1,5 @@ +resource "hcloud_server_network" "server_network" { + server_id = hcloud_server.server.id + network_id = hcloud_network.network.id + ip = "10.0.1.5" +} diff --git a/hetzner/Projects/Development/mailcow/subnet.tf b/hetzner/Projects/Development/mailcow/subnet.tf new file mode 100644 index 0000000..49dbc21 --- /dev/null +++ b/hetzner/Projects/Development/mailcow/subnet.tf @@ -0,0 +1,6 @@ +resource "hcloud_network_subnet" "network-subnet" { + type = "cloud" + network_id = hcloud_network.network.id + network_zone = "eu-central" + ip_range = "10.0.1.0/24" +} diff --git a/hetzner/Projects/Development/mailcow/variables.tf b/hetzner/Projects/Development/mailcow/variables.tf new file mode 100644 index 0000000..7a82005 --- /dev/null +++ b/hetzner/Projects/Development/mailcow/variables.tf @@ -0,0 +1,42 @@ +variable "project_name" { + type = string + default = "project" +} + +variable "server_type" { + type = string + default = "cx11" +} + +variable "image" { + type = string + default = "debian-11" +} + +variable "location" { + type = string + default = "nbg1" +} + +variable "backups" { + type = bool + default = true +} + +variable "rdns" { + type = string + default = "example.com" +} + +variable "cloud_config" { + type = map +} + +locals { + labels = { + "Project" = "${var.project_name}" + "Owner" = "Oscar" + "Environment" = "Development" + } + mailcow_ports = [25, 80, 110, 143, 443, 465, 587, 993, 995, 4190] +} diff --git a/hetzner/Projects/Pterodactyl/node-01/.terraform.lock.hcl b/hetzner/Projects/Pterodactyl/node-01/.terraform.lock.hcl new file mode 100644 index 0000000..ad30c58 --- /dev/null +++ b/hetzner/Projects/Pterodactyl/node-01/.terraform.lock.hcl @@ -0,0 +1,39 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/template" { + version = "2.2.0" + hashes = [ + "h1:94qn780bi1qjrbC3uQtjJh3Wkfwd5+tTtJHOb7KTg9w=", + "zh:01702196f0a0492ec07917db7aaa595843d8f171dc195f4c988d2ffca2a06386", + "zh:09aae3da826ba3d7df69efeb25d146a1de0d03e951d35019a0f80e4f58c89b53", + "zh:09ba83c0625b6fe0a954da6fbd0c355ac0b7f07f86c91a2a97849140fea49603", + "zh:0e3a6c8e16f17f19010accd0844187d524580d9fdb0731f675ffcf4afba03d16", + "zh:45f2c594b6f2f34ea663704cc72048b212fe7d16fb4cfd959365fa997228a776", + "zh:77ea3e5a0446784d77114b5e851c970a3dde1e08fa6de38210b8385d7605d451", + "zh:8a154388f3708e3df5a69122a23bdfaf760a523788a5081976b3d5616f7d30ae", + "zh:992843002f2db5a11e626b3fc23dc0c87ad3729b3b3cff08e32ffb3df97edbde", + "zh:ad906f4cebd3ec5e43d5cd6dc8f4c5c9cc3b33d2243c89c5fc18f97f7277b51d", + "zh:c979425ddb256511137ecd093e23283234da0154b7fa8b21c2687182d9aea8b2", + ] +} + +provider "registry.terraform.io/hetznercloud/hcloud" { + version = "1.26.0" + constraints = "~> 1.26.0" + hashes = [ + "h1:2LLe4UKLS7R+t+tQL1oOFLA8c8/rs3iCfT26LyiQcsk=", + "zh:03d7eb722a4ee25774949baace0125392060d0369d4cb9257d7d298ab6ece3ff", + "zh:0fed2e63ac4cb6fe6b2a5b6891abf973cb7c1716e487fbabc09216e0ec05e866", + "zh:1a84c8c1c8e2d6607de5aa09aa3f9254183cde75a5acc666cca5f4b02a1d290e", + "zh:23ac426aa3a0001fb20045dc35569978864f139732f45ab671c64e80123c91a1", + "zh:23b78348b24ae3e4679bd90989c999346efd71ee228d17368d5f556f63e5fd06", + "zh:2503fe28ac87661af96e7755a7404307000822104ac1abc571271eee46c95ab5", + "zh:3fe859b2611d20ed5cd65cc2ec812acf73c7dfb39f2fee45ef99a3896c2662a8", + "zh:51ef869ed35d0d8aada35f587c4a64802f1140dc93c40a4e7c9800560143bb1a", + "zh:69b93cf4adca465b89da08e4e3b4aaf831821f1fbae68e526c0a292b3cfa463d", + "zh:6a4e23c6aa86e3d30240e6e4c97daef3af9ad217be2c6f35300fe1839fdbf8b2", + "zh:97a513459692a981a62b4a566c1d736c4a67622d2fbbee3771ec3ea8d576d484", + "zh:fec6c07731e23d1dd45015b44747b89c4fee58b5b2560f96d24c7da5a8ecb2ad", + ] +} diff --git a/hetzner/Projects/Pterodactyl/node-01/cloud-config.tpl b/hetzner/Projects/Pterodactyl/node-01/cloud-config.tpl new file mode 100644 index 0000000..9de324f --- /dev/null +++ b/hetzner/Projects/Pterodactyl/node-01/cloud-config.tpl @@ -0,0 +1,32 @@ +#cloud-config + +users: + - default + - name: noble + gecos: Oscar Pocock + groups: users, docker, admin + # primary_group: noble + sudo: ALL=(ALL) NOPASSWD:ALL + shell: /bin/bash + ssh-authorized-keys: + - ${SSH_PUB} + +package_update: true + +package_upgrade: true + +packages: + - vim + - htop + - ranger + - fail2ban + +runcmd: + - curl -fsSL https://get.docker.com | sh + - curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose + - mkdir -p /srv/pterodactyl/wings + - curl "https://raw.githubusercontent.com/pterodactyl/wings/develop/docker-compose.example.yml" -o /srv/pterodactyl/wings/docker-compose.yml + - chown -R noble:noble /srv/pterodactyl + - systemctl enable --now fail2ban + +final_message: "The system is finally up, after $UPTIME seconds" diff --git a/hetzner/Projects/Pterodactyl/node-01/docker-compose.yml.bak b/hetzner/Projects/Pterodactyl/node-01/docker-compose.yml.bak new file mode 100644 index 0000000..ee2f875 --- /dev/null +++ b/hetzner/Projects/Pterodactyl/node-01/docker-compose.yml.bak @@ -0,0 +1,78 @@ +version: '3.8' +x-common: + database: + &db-environment + # Do not remove the "&db-password" from the end of the line below, it is important + # for Panel functionality. + MYSQL_PASSWORD: &db-password "CHANGE_ME" + MYSQL_ROOT_PASSWORD: "CHANGE_ME_TOO" + panel: + &panel-environment + APP_URL: "https://example.com" + # A list of valid timezones can be found here: http://php.net/manual/en/timezones.php + APP_TIMEZONE: "UTC" + APP_SERVICE_AUTHOR: "noreply@example.com" + # Uncomment the line below and set to a non-empty value if you want to use Let's Encrypt + # to generate an SSL certificate for the Panel. + # LE_EMAIL: "" + mail: + &mail-environment + MAIL_FROM: "noreply@example.com" + MAIL_DRIVER: "smtp" + MAIL_HOST: "mail" + MAIL_PORT: "1025" + MAIL_USERNAME: "" + MAIL_PASSWORD: "" + MAIL_ENCRYPTION: "true" + +# +# ------------------------------------------------------------------------------------------ +# DANGER ZONE BELOW +# +# The remainder of this file likely does not need to be changed. Please only make modifications +# below if you understand what you are doing. +# +services: + database: + image: library/mysql:8.0 + restart: always + command: --default-authentication-plugin=mysql_native_password + volumes: + - "/srv/pterodactyl/database:/var/lib/mysql" + environment: + <<: *db-environment + MYSQL_DATABASE: "panel" + MYSQL_USER: "pterodactyl" + cache: + image: redis:alpine + restart: always + panel: + image: ghcr.io/pterodactyl/panel:latest + restart: always + ports: + - "80:80" + - "443:443" + links: + - database + - cache + volumes: + - "/srv/pterodactyl/var/:/app/var/" + - "/srv/pterodactyl/nginx/:/etc/nginx/conf.d/" + - "/srv/pterodactyl/certs/:/etc/letsencrypt/" + - "/srv/pterodactyl/logs/:/app/storage/logs" + environment: + <<: *panel-environment + <<: *mail-environment + DB_PASSWORD: *db-password + APP_ENV: "production" + APP_ENVIRONMENT_ONLY: "false" + CACHE_DRIVER: "redis" + SESSION_DRIVER: "redis" + QUEUE_DRIVER: "redis" + REDIS_HOST: "cache" + DB_HOST: "database" +networks: + default: + ipam: + config: + - subnet: 172.20.0.0/16 diff --git a/hetzner/Projects/Pterodactyl/node-01/firewall.tf b/hetzner/Projects/Pterodactyl/node-01/firewall.tf new file mode 100644 index 0000000..f07caf6 --- /dev/null +++ b/hetzner/Projects/Pterodactyl/node-01/firewall.tf @@ -0,0 +1,3 @@ +data "hcloud_firewall" "firewall" { + id = "37965" +} diff --git a/hetzner/Projects/Pterodactyl/node-01/main.tf b/hetzner/Projects/Pterodactyl/node-01/main.tf new file mode 100644 index 0000000..739ee8c --- /dev/null +++ b/hetzner/Projects/Pterodactyl/node-01/main.tf @@ -0,0 +1,8 @@ +terraform { + required_providers { + hcloud = { + source = "hetznercloud/hcloud" + version = "~> 1.26.0" + } + } +} diff --git a/hetzner/Projects/Pterodactyl/node-01/network.tf b/hetzner/Projects/Pterodactyl/node-01/network.tf new file mode 100644 index 0000000..828ceb1 --- /dev/null +++ b/hetzner/Projects/Pterodactyl/node-01/network.tf @@ -0,0 +1,3 @@ +data "hcloud_network" "network" { + id = "1117192" +} diff --git a/hetzner/Projects/Pterodactyl/node-01/outputs.tf b/hetzner/Projects/Pterodactyl/node-01/outputs.tf new file mode 100644 index 0000000..a471efc --- /dev/null +++ b/hetzner/Projects/Pterodactyl/node-01/outputs.tf @@ -0,0 +1,7 @@ +output "public_ip" { + value = hcloud_server.server.ipv4_address +} + +output "private_ip" { + value = hcloud_server_network.server_network.ip +} diff --git a/hetzner/Projects/Pterodactyl/node-01/provider.tf b/hetzner/Projects/Pterodactyl/node-01/provider.tf new file mode 100644 index 0000000..a42c014 --- /dev/null +++ b/hetzner/Projects/Pterodactyl/node-01/provider.tf @@ -0,0 +1,8 @@ +# Set the variable value in *.tfvars file +# or using the -var="hcloud_token=..." CLI option +variable "hcloud_token" {} + +# Configure the Hetzner Cloud Provider +provider "hcloud" { + token = var.hcloud_token +} diff --git a/hetzner/Projects/Pterodactyl/node-01/server.tf b/hetzner/Projects/Pterodactyl/node-01/server.tf new file mode 100644 index 0000000..363c620 --- /dev/null +++ b/hetzner/Projects/Pterodactyl/node-01/server.tf @@ -0,0 +1,10 @@ +resource "hcloud_server" "server" { + name = "${var.project_name}-node-01-vm" + server_type = var.server_type + image = var.image + location = var.location + backups = var.backups + firewall_ids = [data.hcloud_firewall.firewall.id] + labels = local.labels + user_data = templatefile("${path.module}/cloud-config.tpl", var.panel_vars) +} diff --git a/hetzner/Projects/Pterodactyl/node-01/server_network.tf b/hetzner/Projects/Pterodactyl/node-01/server_network.tf new file mode 100644 index 0000000..d63b342 --- /dev/null +++ b/hetzner/Projects/Pterodactyl/node-01/server_network.tf @@ -0,0 +1,5 @@ +resource "hcloud_server_network" "server_network" { + server_id = hcloud_server.server.id + network_id = data.hcloud_network.network.id + ip = "10.0.1.6" +} diff --git a/hetzner/Projects/Pterodactyl/node-01/variables.tf b/hetzner/Projects/Pterodactyl/node-01/variables.tf new file mode 100644 index 0000000..8e5c64e --- /dev/null +++ b/hetzner/Projects/Pterodactyl/node-01/variables.tf @@ -0,0 +1,36 @@ +variable "project_name" { + type = string + default = "project" +} + +variable "server_type" { + type = string + default = "cx11" +} + +variable "image" { + type = string + default = "debian-10" +} + +variable "location" { + type = string + default = "nbg1" +} + +variable "backups" { + type = bool + default = true +} + +variable "panel_vars" { + type = map +} + +locals { + labels = { + "Project" = "${var.project_name}" + "Owner" = "Oscar" + "Environment" = "Production" + } +} diff --git a/hetzner/Projects/Pterodactyl/panel/.terraform.lock.hcl b/hetzner/Projects/Pterodactyl/panel/.terraform.lock.hcl new file mode 100644 index 0000000..ad30c58 --- /dev/null +++ b/hetzner/Projects/Pterodactyl/panel/.terraform.lock.hcl @@ -0,0 +1,39 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/template" { + version = "2.2.0" + hashes = [ + "h1:94qn780bi1qjrbC3uQtjJh3Wkfwd5+tTtJHOb7KTg9w=", + "zh:01702196f0a0492ec07917db7aaa595843d8f171dc195f4c988d2ffca2a06386", + "zh:09aae3da826ba3d7df69efeb25d146a1de0d03e951d35019a0f80e4f58c89b53", + "zh:09ba83c0625b6fe0a954da6fbd0c355ac0b7f07f86c91a2a97849140fea49603", + "zh:0e3a6c8e16f17f19010accd0844187d524580d9fdb0731f675ffcf4afba03d16", + "zh:45f2c594b6f2f34ea663704cc72048b212fe7d16fb4cfd959365fa997228a776", + "zh:77ea3e5a0446784d77114b5e851c970a3dde1e08fa6de38210b8385d7605d451", + "zh:8a154388f3708e3df5a69122a23bdfaf760a523788a5081976b3d5616f7d30ae", + "zh:992843002f2db5a11e626b3fc23dc0c87ad3729b3b3cff08e32ffb3df97edbde", + "zh:ad906f4cebd3ec5e43d5cd6dc8f4c5c9cc3b33d2243c89c5fc18f97f7277b51d", + "zh:c979425ddb256511137ecd093e23283234da0154b7fa8b21c2687182d9aea8b2", + ] +} + +provider "registry.terraform.io/hetznercloud/hcloud" { + version = "1.26.0" + constraints = "~> 1.26.0" + hashes = [ + "h1:2LLe4UKLS7R+t+tQL1oOFLA8c8/rs3iCfT26LyiQcsk=", + "zh:03d7eb722a4ee25774949baace0125392060d0369d4cb9257d7d298ab6ece3ff", + "zh:0fed2e63ac4cb6fe6b2a5b6891abf973cb7c1716e487fbabc09216e0ec05e866", + "zh:1a84c8c1c8e2d6607de5aa09aa3f9254183cde75a5acc666cca5f4b02a1d290e", + "zh:23ac426aa3a0001fb20045dc35569978864f139732f45ab671c64e80123c91a1", + "zh:23b78348b24ae3e4679bd90989c999346efd71ee228d17368d5f556f63e5fd06", + "zh:2503fe28ac87661af96e7755a7404307000822104ac1abc571271eee46c95ab5", + "zh:3fe859b2611d20ed5cd65cc2ec812acf73c7dfb39f2fee45ef99a3896c2662a8", + "zh:51ef869ed35d0d8aada35f587c4a64802f1140dc93c40a4e7c9800560143bb1a", + "zh:69b93cf4adca465b89da08e4e3b4aaf831821f1fbae68e526c0a292b3cfa463d", + "zh:6a4e23c6aa86e3d30240e6e4c97daef3af9ad217be2c6f35300fe1839fdbf8b2", + "zh:97a513459692a981a62b4a566c1d736c4a67622d2fbbee3771ec3ea8d576d484", + "zh:fec6c07731e23d1dd45015b44747b89c4fee58b5b2560f96d24c7da5a8ecb2ad", + ] +} diff --git a/hetzner/Projects/Pterodactyl/panel/cloud-config.tpl b/hetzner/Projects/Pterodactyl/panel/cloud-config.tpl new file mode 100644 index 0000000..fe03a31 --- /dev/null +++ b/hetzner/Projects/Pterodactyl/panel/cloud-config.tpl @@ -0,0 +1,64 @@ +#cloud-config + +users: + - default + - name: noble + gecos: Oscar Pocock + groups: users, docker, admin + # primary_group: noble + sudo: ALL=(ALL) NOPASSWD:ALL + shell: /bin/bash + ssh-authorized-keys: + - ${SSH_PUB} + +package_update: true + +package_upgrade: true + +packages: + - vim + - htop + - ranger + - fail2ban + - unattended-upgrades + +# Set up floating IP +write_files: + - content: | + auto eth0:1 + iface eth0:1 inet static + address ${IP_ADDRESS} + netmask 32 + path: /etc/network/interfaces.d/60-my-floating-ip.cfg +# Panel env variables + - content: | + MYSQL_PASSWORD=${MYSQL_PASSWORD} + MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} + APP_URL=${APP_URL} + APP_TIMEZONE=${APP_TIMEZONE} + APP_SERVICE_AUTHOR=${APP_SERVICE_AUTHOR} + LE_EMAIL=${EMAIL} + path: /srv/pterodactyl/panel/.env + permissions: '0600' + +# Install docker & docker-compose +runcmd: + - sudo ip addr add ${IP_ADDRESS} dev eth0 + - curl -fsSL https://get.docker.com | sh + - curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose + - mkdir -p /srv/pterodactyl/wings /srv/pterodactyl/panel + - curl "https://raw.githubusercontent.com/pterodactyl/panel/develop/docker-compose.example.yml" -o /srv/pterodactyl/panel/docker-compose.yml + - curl "https://raw.githubusercontent.com/pterodactyl/wings/develop/docker-compose.example.yml" -o /srv/pterodactyl/wings/docker-compose.yml + - [sed, -i, 's/"CHANGE_ME"/"$${MYSQL_PASSWORD}"/g', /srv/pterodactyl/panel/docker-compose.yml] + - [sed, -i, 's/"CHANGE_ME_TOO"/"$${MYSQL_ROOT_PASSWORD}"/g', /srv/pterodactyl/panel/docker-compose.yml] + - [sed, -i, 's/"https:\/\/example.com"/"$${APP_URL}"/g', /srv/pterodactyl/panel/docker-compose.yml] + - [sed, -i, 's/"UTC"/"$${APP_TIMEZONE}"/g', /srv/pterodactyl/panel/docker-compose.yml] + - [sed, -i, 's/"noreply@example.com"/"$${APP_SERVICE_AUTHOR}"/g', /srv/pterodactyl/panel/docker-compose.yml] + - [sed, -i, 's/# LE_EMAIL: ""/LE_EMAIL: "$${LE_EMAIL}"/g', /srv/pterodactyl/panel/docker-compose.yml] + - docker-compose up -d -f /srv/pterodactyl/panel/docker-compose.yml + - chown -R noble:noble /srv/pterodactyl + - systemctl enable --now fail2ban +# - docker-compose -f /srv/pterodactyl/panel/docker-compose.yml --env-file /srv/pterodactyl/panel/.env up -d +# - docker-compose -f /srv/pterodactyl/wings/docker-compose.yml up -d + +final_message: "The system is finally up, after $UPTIME seconds" diff --git a/hetzner/Projects/Pterodactyl/panel/docker-compose.yml.bak b/hetzner/Projects/Pterodactyl/panel/docker-compose.yml.bak new file mode 100644 index 0000000..ee2f875 --- /dev/null +++ b/hetzner/Projects/Pterodactyl/panel/docker-compose.yml.bak @@ -0,0 +1,78 @@ +version: '3.8' +x-common: + database: + &db-environment + # Do not remove the "&db-password" from the end of the line below, it is important + # for Panel functionality. + MYSQL_PASSWORD: &db-password "CHANGE_ME" + MYSQL_ROOT_PASSWORD: "CHANGE_ME_TOO" + panel: + &panel-environment + APP_URL: "https://example.com" + # A list of valid timezones can be found here: http://php.net/manual/en/timezones.php + APP_TIMEZONE: "UTC" + APP_SERVICE_AUTHOR: "noreply@example.com" + # Uncomment the line below and set to a non-empty value if you want to use Let's Encrypt + # to generate an SSL certificate for the Panel. + # LE_EMAIL: "" + mail: + &mail-environment + MAIL_FROM: "noreply@example.com" + MAIL_DRIVER: "smtp" + MAIL_HOST: "mail" + MAIL_PORT: "1025" + MAIL_USERNAME: "" + MAIL_PASSWORD: "" + MAIL_ENCRYPTION: "true" + +# +# ------------------------------------------------------------------------------------------ +# DANGER ZONE BELOW +# +# The remainder of this file likely does not need to be changed. Please only make modifications +# below if you understand what you are doing. +# +services: + database: + image: library/mysql:8.0 + restart: always + command: --default-authentication-plugin=mysql_native_password + volumes: + - "/srv/pterodactyl/database:/var/lib/mysql" + environment: + <<: *db-environment + MYSQL_DATABASE: "panel" + MYSQL_USER: "pterodactyl" + cache: + image: redis:alpine + restart: always + panel: + image: ghcr.io/pterodactyl/panel:latest + restart: always + ports: + - "80:80" + - "443:443" + links: + - database + - cache + volumes: + - "/srv/pterodactyl/var/:/app/var/" + - "/srv/pterodactyl/nginx/:/etc/nginx/conf.d/" + - "/srv/pterodactyl/certs/:/etc/letsencrypt/" + - "/srv/pterodactyl/logs/:/app/storage/logs" + environment: + <<: *panel-environment + <<: *mail-environment + DB_PASSWORD: *db-password + APP_ENV: "production" + APP_ENVIRONMENT_ONLY: "false" + CACHE_DRIVER: "redis" + SESSION_DRIVER: "redis" + QUEUE_DRIVER: "redis" + REDIS_HOST: "cache" + DB_HOST: "database" +networks: + default: + ipam: + config: + - subnet: 172.20.0.0/16 diff --git a/hetzner/Projects/Pterodactyl/panel/firewall.tf b/hetzner/Projects/Pterodactyl/panel/firewall.tf new file mode 100644 index 0000000..5055047 --- /dev/null +++ b/hetzner/Projects/Pterodactyl/panel/firewall.tf @@ -0,0 +1,118 @@ +resource "hcloud_firewall" "firewall" { + name = "${var.project_name}-fw" + rule { + direction = "in" + protocol = "icmp" + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } + # SSH + rule { + direction = "in" + protocol = "tcp" + port = 22 + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } + # HTTP + rule { + direction = "in" + protocol = "tcp" + port = 80 + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } + # HTTPS + rule { + direction = "in" + protocol = "tcp" + port = 443 + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } +# Panel + rule { + direction = "in" + protocol = "tcp" + port = 8080 + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } +# SFTP + rule { + direction = "in" + protocol = "tcp" + port = 2022 + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } + +# Minecraft + rule { + direction = "in" + protocol = "tcp" + port = 25565 + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } + +# Dynamap + rule { + direction = "in" + protocol = "tcp" + port = 8123 + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } + +# Bluemap + rule { + direction = "in" + protocol = "tcp" + port = 8100 + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } + +# Xonotic + rule { + direction = "in" + protocol = "tcp" + port = 26000 + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } + + rule { + direction = "in" + protocol = "udp" + port = 26000 + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } + + + +} diff --git a/hetzner/Projects/Pterodactyl/panel/floating_ip.tf b/hetzner/Projects/Pterodactyl/panel/floating_ip.tf new file mode 100644 index 0000000..7806db0 --- /dev/null +++ b/hetzner/Projects/Pterodactyl/panel/floating_ip.tf @@ -0,0 +1,8 @@ + data "hcloud_floating_ip" "main" { + ip_address = var.floating_ip +} + +resource "hcloud_floating_ip_assignment" "main" { + floating_ip_id = data.hcloud_floating_ip.main.id + server_id = hcloud_server.server.id +} diff --git a/hetzner/Projects/Pterodactyl/panel/main.tf b/hetzner/Projects/Pterodactyl/panel/main.tf new file mode 100644 index 0000000..739ee8c --- /dev/null +++ b/hetzner/Projects/Pterodactyl/panel/main.tf @@ -0,0 +1,8 @@ +terraform { + required_providers { + hcloud = { + source = "hetznercloud/hcloud" + version = "~> 1.26.0" + } + } +} diff --git a/hetzner/Projects/Pterodactyl/panel/network.tf b/hetzner/Projects/Pterodactyl/panel/network.tf new file mode 100644 index 0000000..400fd41 --- /dev/null +++ b/hetzner/Projects/Pterodactyl/panel/network.tf @@ -0,0 +1,4 @@ +resource "hcloud_network" "network" { + name = "${var.project_name}-vnet" + ip_range = "10.0.0.0/16" +} diff --git a/hetzner/Projects/Pterodactyl/panel/outputs.tf b/hetzner/Projects/Pterodactyl/panel/outputs.tf new file mode 100644 index 0000000..f56d78f --- /dev/null +++ b/hetzner/Projects/Pterodactyl/panel/outputs.tf @@ -0,0 +1,11 @@ +output "public_ip" { + value = hcloud_server.server.ipv4_address +} + +output "private_ip" { + value = hcloud_server_network.server_network.ip +} + +output "floating_ip" { + value = data.hcloud_floating_ip.main.ip_address +} diff --git a/hetzner/Projects/Pterodactyl/panel/provider.tf b/hetzner/Projects/Pterodactyl/panel/provider.tf new file mode 100644 index 0000000..a42c014 --- /dev/null +++ b/hetzner/Projects/Pterodactyl/panel/provider.tf @@ -0,0 +1,8 @@ +# Set the variable value in *.tfvars file +# or using the -var="hcloud_token=..." CLI option +variable "hcloud_token" {} + +# Configure the Hetzner Cloud Provider +provider "hcloud" { + token = var.hcloud_token +} diff --git a/hetzner/Projects/Pterodactyl/panel/server.tf b/hetzner/Projects/Pterodactyl/panel/server.tf new file mode 100644 index 0000000..95d5b81 --- /dev/null +++ b/hetzner/Projects/Pterodactyl/panel/server.tf @@ -0,0 +1,14 @@ +resource "hcloud_server" "server" { + name = "${var.project_name}-panel-vm" + server_type = var.server_type + image = var.image + location = var.location + backups = var.backups + firewall_ids = [hcloud_firewall.firewall.id] + labels = local.labels + user_data = templatefile("${path.module}/cloud-config.tpl", var.panel_vars) + + depends_on = [ + hcloud_network_subnet.network-subnet + ] +} diff --git a/hetzner/Projects/Pterodactyl/panel/server_network.tf b/hetzner/Projects/Pterodactyl/panel/server_network.tf new file mode 100644 index 0000000..efd5a8d --- /dev/null +++ b/hetzner/Projects/Pterodactyl/panel/server_network.tf @@ -0,0 +1,5 @@ +resource "hcloud_server_network" "server_network" { + server_id = hcloud_server.server.id + network_id = hcloud_network.network.id + ip = "10.0.1.5" +} diff --git a/hetzner/Projects/Pterodactyl/panel/subnet.tf b/hetzner/Projects/Pterodactyl/panel/subnet.tf new file mode 100644 index 0000000..49dbc21 --- /dev/null +++ b/hetzner/Projects/Pterodactyl/panel/subnet.tf @@ -0,0 +1,6 @@ +resource "hcloud_network_subnet" "network-subnet" { + type = "cloud" + network_id = hcloud_network.network.id + network_zone = "eu-central" + ip_range = "10.0.1.0/24" +} diff --git a/hetzner/Projects/Pterodactyl/panel/variables.tf b/hetzner/Projects/Pterodactyl/panel/variables.tf new file mode 100644 index 0000000..21eb405 --- /dev/null +++ b/hetzner/Projects/Pterodactyl/panel/variables.tf @@ -0,0 +1,40 @@ +variable "project_name" { + type = string + default = "project" +} + +variable "server_type" { + type = string + default = "cx11" +} + +variable "image" { + type = string + default = "debian-10" +} + +variable "location" { + type = string + default = "nbg1" +} + +variable "backups" { + type = bool + default = true +} + +variable "panel_vars" { + type = map +} + +variable "floating_ip" { + type = string +} + +locals { + labels = { + "Project" = "${var.project_name}" + "Owner" = "Oscar" + "Environment" = "Production" + } +} diff --git a/hetzner/Projects/Pterodactyl/pterodactyl/.terraform.lock.hcl b/hetzner/Projects/Pterodactyl/pterodactyl/.terraform.lock.hcl new file mode 100644 index 0000000..ad30c58 --- /dev/null +++ b/hetzner/Projects/Pterodactyl/pterodactyl/.terraform.lock.hcl @@ -0,0 +1,39 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/template" { + version = "2.2.0" + hashes = [ + "h1:94qn780bi1qjrbC3uQtjJh3Wkfwd5+tTtJHOb7KTg9w=", + "zh:01702196f0a0492ec07917db7aaa595843d8f171dc195f4c988d2ffca2a06386", + "zh:09aae3da826ba3d7df69efeb25d146a1de0d03e951d35019a0f80e4f58c89b53", + "zh:09ba83c0625b6fe0a954da6fbd0c355ac0b7f07f86c91a2a97849140fea49603", + "zh:0e3a6c8e16f17f19010accd0844187d524580d9fdb0731f675ffcf4afba03d16", + "zh:45f2c594b6f2f34ea663704cc72048b212fe7d16fb4cfd959365fa997228a776", + "zh:77ea3e5a0446784d77114b5e851c970a3dde1e08fa6de38210b8385d7605d451", + "zh:8a154388f3708e3df5a69122a23bdfaf760a523788a5081976b3d5616f7d30ae", + "zh:992843002f2db5a11e626b3fc23dc0c87ad3729b3b3cff08e32ffb3df97edbde", + "zh:ad906f4cebd3ec5e43d5cd6dc8f4c5c9cc3b33d2243c89c5fc18f97f7277b51d", + "zh:c979425ddb256511137ecd093e23283234da0154b7fa8b21c2687182d9aea8b2", + ] +} + +provider "registry.terraform.io/hetznercloud/hcloud" { + version = "1.26.0" + constraints = "~> 1.26.0" + hashes = [ + "h1:2LLe4UKLS7R+t+tQL1oOFLA8c8/rs3iCfT26LyiQcsk=", + "zh:03d7eb722a4ee25774949baace0125392060d0369d4cb9257d7d298ab6ece3ff", + "zh:0fed2e63ac4cb6fe6b2a5b6891abf973cb7c1716e487fbabc09216e0ec05e866", + "zh:1a84c8c1c8e2d6607de5aa09aa3f9254183cde75a5acc666cca5f4b02a1d290e", + "zh:23ac426aa3a0001fb20045dc35569978864f139732f45ab671c64e80123c91a1", + "zh:23b78348b24ae3e4679bd90989c999346efd71ee228d17368d5f556f63e5fd06", + "zh:2503fe28ac87661af96e7755a7404307000822104ac1abc571271eee46c95ab5", + "zh:3fe859b2611d20ed5cd65cc2ec812acf73c7dfb39f2fee45ef99a3896c2662a8", + "zh:51ef869ed35d0d8aada35f587c4a64802f1140dc93c40a4e7c9800560143bb1a", + "zh:69b93cf4adca465b89da08e4e3b4aaf831821f1fbae68e526c0a292b3cfa463d", + "zh:6a4e23c6aa86e3d30240e6e4c97daef3af9ad217be2c6f35300fe1839fdbf8b2", + "zh:97a513459692a981a62b4a566c1d736c4a67622d2fbbee3771ec3ea8d576d484", + "zh:fec6c07731e23d1dd45015b44747b89c4fee58b5b2560f96d24c7da5a8ecb2ad", + ] +} diff --git a/hetzner/Projects/Pterodactyl/pterodactyl/cloud-config.tpl b/hetzner/Projects/Pterodactyl/pterodactyl/cloud-config.tpl new file mode 100644 index 0000000..d1625bf --- /dev/null +++ b/hetzner/Projects/Pterodactyl/pterodactyl/cloud-config.tpl @@ -0,0 +1,60 @@ +#cloud-config + +users: + - default + - name: noble + gecos: Oscar Pocock + groups: users, docker, admin + # primary_group: noble + sudo: ALL=(ALL) NOPASSWD:ALL + shell: /bin/bash + ssh-authorized-keys: + - ${SSH_PUB} + +package_update: true + +package_upgrade: true + +packages: + - vim + - htop + - ranger + - fail2ban + +write_files: + - content: | + auto eth0:1 + iface eth0:1 inet static + address ${IP_ADDRESS} + netmask 32 + path: /etc/network/interfaces.d/60-my-floating-ip.cfg + - content: | + MYSQL_PASSWORD=${MYSQL_PASSWORD} + MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} + APP_URL=${APP_URL} + APP_TIMEZONE=${APP_TIMEZONE} + APP_SERVICE_AUTHOR=${APP_SERVICE_AUTHOR} + LE_EMAIL=${EMAIL} + path: /srv/pterodactyl/panel/.env + permissions: '0600' + +runcmd: + - sudo ip addr add ${IP_ADDRESS} dev eth0 + - curl -fsSL https://get.docker.com | sh + - curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose + - mkdir -p /srv/pterodactyl/wings /srv/pterodactyl/panel + - curl "https://raw.githubusercontent.com/pterodactyl/panel/develop/docker-compose.example.yml" -o /srv/pterodactyl/panel/docker-compose.yml + - curl "https://raw.githubusercontent.com/pterodactyl/wings/develop/docker-compose.example.yml" -o /srv/pterodactyl/wings/docker-compose.yml + - [sed, -i, 's/"CHANGE_ME"/"$${MYSQL_PASSWORD}"/g', /srv/pterodactyl/panel/docker-compose.yml] + - [sed, -i, 's/"CHANGE_ME_TOO"/"$${MYSQL_ROOT_PASSWORD}"/g', /srv/pterodactyl/panel/docker-compose.yml] + - [sed, -i, 's/"https:\/\/example.com"/"$${APP_URL}"/g', /srv/pterodactyl/panel/docker-compose.yml] + - [sed, -i, 's/"UTC"/"$${APP_TIMEZONE}"/g', /srv/pterodactyl/panel/docker-compose.yml] + - [sed, -i, 's/"noreply@example.com"/"$${APP_SERVICE_AUTHOR}"/g', /srv/pterodactyl/panel/docker-compose.yml] + - [sed, -i, 's/# LE_EMAIL: ""/LE_EMAIL: "$${LE_EMAIL}"/g', /srv/pterodactyl/panel/docker-compose.yml] + - docker-compose up -d -f /srv/pterodactyl/panel/docker-compose.yml + - chown -R noble:noble /srv/pterodactyl + - systemctl enable --now fail2ban + - docker-compose -f /srv/pterodactyl/panel/docker-compose.yml --env-file /srv/pterodactyl/panel/.env up -d + - docker-compose -f /srv/pterodactyl/wings/docker-compose.yml up -d + +final_message: "The system is finally up, after $UPTIME seconds" diff --git a/hetzner/Projects/Pterodactyl/pterodactyl/docker-compose.yml.bak b/hetzner/Projects/Pterodactyl/pterodactyl/docker-compose.yml.bak new file mode 100644 index 0000000..ee2f875 --- /dev/null +++ b/hetzner/Projects/Pterodactyl/pterodactyl/docker-compose.yml.bak @@ -0,0 +1,78 @@ +version: '3.8' +x-common: + database: + &db-environment + # Do not remove the "&db-password" from the end of the line below, it is important + # for Panel functionality. + MYSQL_PASSWORD: &db-password "CHANGE_ME" + MYSQL_ROOT_PASSWORD: "CHANGE_ME_TOO" + panel: + &panel-environment + APP_URL: "https://example.com" + # A list of valid timezones can be found here: http://php.net/manual/en/timezones.php + APP_TIMEZONE: "UTC" + APP_SERVICE_AUTHOR: "noreply@example.com" + # Uncomment the line below and set to a non-empty value if you want to use Let's Encrypt + # to generate an SSL certificate for the Panel. + # LE_EMAIL: "" + mail: + &mail-environment + MAIL_FROM: "noreply@example.com" + MAIL_DRIVER: "smtp" + MAIL_HOST: "mail" + MAIL_PORT: "1025" + MAIL_USERNAME: "" + MAIL_PASSWORD: "" + MAIL_ENCRYPTION: "true" + +# +# ------------------------------------------------------------------------------------------ +# DANGER ZONE BELOW +# +# The remainder of this file likely does not need to be changed. Please only make modifications +# below if you understand what you are doing. +# +services: + database: + image: library/mysql:8.0 + restart: always + command: --default-authentication-plugin=mysql_native_password + volumes: + - "/srv/pterodactyl/database:/var/lib/mysql" + environment: + <<: *db-environment + MYSQL_DATABASE: "panel" + MYSQL_USER: "pterodactyl" + cache: + image: redis:alpine + restart: always + panel: + image: ghcr.io/pterodactyl/panel:latest + restart: always + ports: + - "80:80" + - "443:443" + links: + - database + - cache + volumes: + - "/srv/pterodactyl/var/:/app/var/" + - "/srv/pterodactyl/nginx/:/etc/nginx/conf.d/" + - "/srv/pterodactyl/certs/:/etc/letsencrypt/" + - "/srv/pterodactyl/logs/:/app/storage/logs" + environment: + <<: *panel-environment + <<: *mail-environment + DB_PASSWORD: *db-password + APP_ENV: "production" + APP_ENVIRONMENT_ONLY: "false" + CACHE_DRIVER: "redis" + SESSION_DRIVER: "redis" + QUEUE_DRIVER: "redis" + REDIS_HOST: "cache" + DB_HOST: "database" +networks: + default: + ipam: + config: + - subnet: 172.20.0.0/16 diff --git a/hetzner/Projects/Pterodactyl/pterodactyl/firewall.tf b/hetzner/Projects/Pterodactyl/pterodactyl/firewall.tf new file mode 100644 index 0000000..160fa75 --- /dev/null +++ b/hetzner/Projects/Pterodactyl/pterodactyl/firewall.tf @@ -0,0 +1,96 @@ +resource "hcloud_firewall" "firewall" { + name = "${var.project_name}-fw" + rule { + direction = "in" + protocol = "icmp" + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } + # SSH + rule { + direction = "in" + protocol = "tcp" + port = 22 + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } + # HTTP + rule { + direction = "in" + protocol = "tcp" + port = 80 + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } + # HTTPS + rule { + direction = "in" + protocol = "tcp" + port = 443 + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } +# Panel + rule { + direction = "in" + protocol = "tcp" + port = 8080 + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } +# SFTP + rule { + direction = "in" + protocol = "tcp" + port = 2022 + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } + +# Minecraft + rule { + direction = "in" + protocol = "tcp" + port = 25565 + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } + +# Dynamap + rule { + direction = "in" + protocol = "tcp" + port = 8123 + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } + +# Xonotic + rule { + direction = "in" + protocol = "tcp" + port = 26000 + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } + + +} diff --git a/hetzner/Projects/Pterodactyl/pterodactyl/main.tf b/hetzner/Projects/Pterodactyl/pterodactyl/main.tf new file mode 100644 index 0000000..739ee8c --- /dev/null +++ b/hetzner/Projects/Pterodactyl/pterodactyl/main.tf @@ -0,0 +1,8 @@ +terraform { + required_providers { + hcloud = { + source = "hetznercloud/hcloud" + version = "~> 1.26.0" + } + } +} diff --git a/hetzner/Projects/Pterodactyl/pterodactyl/network.tf b/hetzner/Projects/Pterodactyl/pterodactyl/network.tf new file mode 100644 index 0000000..400fd41 --- /dev/null +++ b/hetzner/Projects/Pterodactyl/pterodactyl/network.tf @@ -0,0 +1,4 @@ +resource "hcloud_network" "network" { + name = "${var.project_name}-vnet" + ip_range = "10.0.0.0/16" +} diff --git a/hetzner/Projects/Pterodactyl/pterodactyl/outputs.tf b/hetzner/Projects/Pterodactyl/pterodactyl/outputs.tf new file mode 100644 index 0000000..a471efc --- /dev/null +++ b/hetzner/Projects/Pterodactyl/pterodactyl/outputs.tf @@ -0,0 +1,7 @@ +output "public_ip" { + value = hcloud_server.server.ipv4_address +} + +output "private_ip" { + value = hcloud_server_network.server_network.ip +} diff --git a/hetzner/Projects/Pterodactyl/pterodactyl/provider.tf b/hetzner/Projects/Pterodactyl/pterodactyl/provider.tf new file mode 100644 index 0000000..a42c014 --- /dev/null +++ b/hetzner/Projects/Pterodactyl/pterodactyl/provider.tf @@ -0,0 +1,8 @@ +# Set the variable value in *.tfvars file +# or using the -var="hcloud_token=..." CLI option +variable "hcloud_token" {} + +# Configure the Hetzner Cloud Provider +provider "hcloud" { + token = var.hcloud_token +} diff --git a/hetzner/Projects/Pterodactyl/pterodactyl/server.tf b/hetzner/Projects/Pterodactyl/pterodactyl/server.tf new file mode 100644 index 0000000..22def90 --- /dev/null +++ b/hetzner/Projects/Pterodactyl/pterodactyl/server.tf @@ -0,0 +1,14 @@ +resource "hcloud_server" "server" { + name = "${var.project_name}-vm" + server_type = var.server_type + image = var.image + location = var.location + backups = var.backups + firewall_ids = [hcloud_firewall.firewall.id] + labels = local.labels + user_data = templatefile("${path.module}/cloud-config.tpl", var.panel_vars) + + depends_on = [ + hcloud_network_subnet.network-subnet + ] +} diff --git a/hetzner/Projects/Pterodactyl/pterodactyl/server_network.tf b/hetzner/Projects/Pterodactyl/pterodactyl/server_network.tf new file mode 100644 index 0000000..1384234 --- /dev/null +++ b/hetzner/Projects/Pterodactyl/pterodactyl/server_network.tf @@ -0,0 +1,5 @@ +resource "hcloud_server_network" "server_network" { + server_id = hcloud_server.server.id + network_id = hcloud_network.network.id + ip = "10.0.1.7" +} diff --git a/hetzner/Projects/Pterodactyl/pterodactyl/subnet.tf b/hetzner/Projects/Pterodactyl/pterodactyl/subnet.tf new file mode 100644 index 0000000..49dbc21 --- /dev/null +++ b/hetzner/Projects/Pterodactyl/pterodactyl/subnet.tf @@ -0,0 +1,6 @@ +resource "hcloud_network_subnet" "network-subnet" { + type = "cloud" + network_id = hcloud_network.network.id + network_zone = "eu-central" + ip_range = "10.0.1.0/24" +} diff --git a/hetzner/Projects/Pterodactyl/pterodactyl/variables.tf b/hetzner/Projects/Pterodactyl/pterodactyl/variables.tf new file mode 100644 index 0000000..8e5c64e --- /dev/null +++ b/hetzner/Projects/Pterodactyl/pterodactyl/variables.tf @@ -0,0 +1,36 @@ +variable "project_name" { + type = string + default = "project" +} + +variable "server_type" { + type = string + default = "cx11" +} + +variable "image" { + type = string + default = "debian-10" +} + +variable "location" { + type = string + default = "nbg1" +} + +variable "backups" { + type = bool + default = true +} + +variable "panel_vars" { + type = map +} + +locals { + labels = { + "Project" = "${var.project_name}" + "Owner" = "Oscar" + "Environment" = "Production" + } +} diff --git a/hetzner/template/.terraform.lock.hcl b/hetzner/template/.terraform.lock.hcl new file mode 100644 index 0000000..8162aac --- /dev/null +++ b/hetzner/template/.terraform.lock.hcl @@ -0,0 +1,22 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hetznercloud/hcloud" { + version = "1.26.0" + constraints = "~> 1.26.0" + hashes = [ + "h1:2LLe4UKLS7R+t+tQL1oOFLA8c8/rs3iCfT26LyiQcsk=", + "zh:03d7eb722a4ee25774949baace0125392060d0369d4cb9257d7d298ab6ece3ff", + "zh:0fed2e63ac4cb6fe6b2a5b6891abf973cb7c1716e487fbabc09216e0ec05e866", + "zh:1a84c8c1c8e2d6607de5aa09aa3f9254183cde75a5acc666cca5f4b02a1d290e", + "zh:23ac426aa3a0001fb20045dc35569978864f139732f45ab671c64e80123c91a1", + "zh:23b78348b24ae3e4679bd90989c999346efd71ee228d17368d5f556f63e5fd06", + "zh:2503fe28ac87661af96e7755a7404307000822104ac1abc571271eee46c95ab5", + "zh:3fe859b2611d20ed5cd65cc2ec812acf73c7dfb39f2fee45ef99a3896c2662a8", + "zh:51ef869ed35d0d8aada35f587c4a64802f1140dc93c40a4e7c9800560143bb1a", + "zh:69b93cf4adca465b89da08e4e3b4aaf831821f1fbae68e526c0a292b3cfa463d", + "zh:6a4e23c6aa86e3d30240e6e4c97daef3af9ad217be2c6f35300fe1839fdbf8b2", + "zh:97a513459692a981a62b4a566c1d736c4a67622d2fbbee3771ec3ea8d576d484", + "zh:fec6c07731e23d1dd45015b44747b89c4fee58b5b2560f96d24c7da5a8ecb2ad", + ] +} diff --git a/hetzner/template/firewall.tf b/hetzner/template/firewall.tf new file mode 100644 index 0000000..e9dddbd --- /dev/null +++ b/hetzner/template/firewall.tf @@ -0,0 +1,41 @@ +resource "hcloud_firewall" "firewall" { + name = "${var.project_name}-fw" + rule { + direction = "in" + protocol = "icmp" + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } + # SSH + rule { + direction = "in" + protocol = "tcp" + port = 22 + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } + # HTTP + rule { + direction = "in" + protocol = "tcp" + port = 80 + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } + # HTTPS + rule { + direction = "in" + protocol = "tcp" + port = 443 + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } +} diff --git a/hetzner/template/main.tf b/hetzner/template/main.tf new file mode 100644 index 0000000..739ee8c --- /dev/null +++ b/hetzner/template/main.tf @@ -0,0 +1,8 @@ +terraform { + required_providers { + hcloud = { + source = "hetznercloud/hcloud" + version = "~> 1.26.0" + } + } +} diff --git a/hetzner/template/network.tf b/hetzner/template/network.tf new file mode 100644 index 0000000..400fd41 --- /dev/null +++ b/hetzner/template/network.tf @@ -0,0 +1,4 @@ +resource "hcloud_network" "network" { + name = "${var.project_name}-vnet" + ip_range = "10.0.0.0/16" +} diff --git a/hetzner/template/outputs.tf b/hetzner/template/outputs.tf new file mode 100644 index 0000000..a471efc --- /dev/null +++ b/hetzner/template/outputs.tf @@ -0,0 +1,7 @@ +output "public_ip" { + value = hcloud_server.server.ipv4_address +} + +output "private_ip" { + value = hcloud_server_network.server_network.ip +} diff --git a/hetzner/template/provider.tf b/hetzner/template/provider.tf new file mode 100644 index 0000000..a42c014 --- /dev/null +++ b/hetzner/template/provider.tf @@ -0,0 +1,8 @@ +# Set the variable value in *.tfvars file +# or using the -var="hcloud_token=..." CLI option +variable "hcloud_token" {} + +# Configure the Hetzner Cloud Provider +provider "hcloud" { + token = var.hcloud_token +} diff --git a/hetzner/template/server.tf b/hetzner/template/server.tf new file mode 100644 index 0000000..2bdb04a --- /dev/null +++ b/hetzner/template/server.tf @@ -0,0 +1,13 @@ +resource "hcloud_server" "server" { + name = "${var.project_name}-vm" + server_type = var.server_type + image = var.image + location = var.location + backups = var.backups + firewall_ids = [hcloud_firewall.firewall.id] + labels = local.labels + + depends_on = [ + hcloud_network_subnet.network-subnet + ] +} diff --git a/hetzner/template/server_network.tf b/hetzner/template/server_network.tf new file mode 100644 index 0000000..efd5a8d --- /dev/null +++ b/hetzner/template/server_network.tf @@ -0,0 +1,5 @@ +resource "hcloud_server_network" "server_network" { + server_id = hcloud_server.server.id + network_id = hcloud_network.network.id + ip = "10.0.1.5" +} diff --git a/hetzner/template/subnet.tf b/hetzner/template/subnet.tf new file mode 100644 index 0000000..49dbc21 --- /dev/null +++ b/hetzner/template/subnet.tf @@ -0,0 +1,6 @@ +resource "hcloud_network_subnet" "network-subnet" { + type = "cloud" + network_id = hcloud_network.network.id + network_zone = "eu-central" + ip_range = "10.0.1.0/24" +} diff --git a/hetzner/template/variables.tf b/hetzner/template/variables.tf new file mode 100644 index 0000000..586c3b4 --- /dev/null +++ b/hetzner/template/variables.tf @@ -0,0 +1,32 @@ +variable "project_name" { + type = string + default = "project" +} + +variable "server_type" { + type = string + default = "cx11" +} + +variable "image" { + type = string + default = "debian-10" +} + +variable "location" { + type = string + default = "nbg1" +} + +variable "backups" { + type = bool + default = true +} + +locals { + labels = { + "Project" = "${var.project_name}" + "Owner" = "Oscar" + "Environment" = "Development" + } +}