Added MailCow and Pterodactyl projects

This commit is contained in:
Oscar Blue 2022-04-07 21:02:23 +01:00
parent 984900e55a
commit 0182edd245
58 changed files with 1371 additions and 0 deletions

View file

@ -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",
]
}

View file

@ -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"

View file

@ -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"
]
}
}
}

View file

@ -0,0 +1,8 @@
terraform {
required_providers {
hcloud = {
source = "hetznercloud/hcloud"
version = "~> 1.33.1"
}
}
}

View file

@ -0,0 +1,4 @@
resource "hcloud_network" "network" {
name = "${var.project_name}-vnet"
ip_range = "10.0.0.0/16"
}

View file

@ -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
}

View file

@ -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
}

View file

@ -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
}

View file

@ -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
]
}

View file

@ -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"
}

View file

@ -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"
}

View file

@ -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]
}

View file

@ -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",
]
}

View file

@ -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"

View file

@ -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

View file

@ -0,0 +1,3 @@
data "hcloud_firewall" "firewall" {
id = "37965"
}

View file

@ -0,0 +1,8 @@
terraform {
required_providers {
hcloud = {
source = "hetznercloud/hcloud"
version = "~> 1.26.0"
}
}
}

View file

@ -0,0 +1,3 @@
data "hcloud_network" "network" {
id = "1117192"
}

View file

@ -0,0 +1,7 @@
output "public_ip" {
value = hcloud_server.server.ipv4_address
}
output "private_ip" {
value = hcloud_server_network.server_network.ip
}

View file

@ -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
}

View file

@ -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)
}

View file

@ -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"
}

View file

@ -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"
}
}

View file

@ -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",
]
}

View file

@ -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"

View file

@ -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

View file

@ -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"
]
}
}

View file

@ -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
}

View file

@ -0,0 +1,8 @@
terraform {
required_providers {
hcloud = {
source = "hetznercloud/hcloud"
version = "~> 1.26.0"
}
}
}

View file

@ -0,0 +1,4 @@
resource "hcloud_network" "network" {
name = "${var.project_name}-vnet"
ip_range = "10.0.0.0/16"
}

View file

@ -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
}

View file

@ -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
}

View file

@ -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
]
}

View file

@ -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"
}

View file

@ -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"
}

View file

@ -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"
}
}

View file

@ -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",
]
}

View file

@ -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"

View file

@ -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

View file

@ -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"
]
}
}

View file

@ -0,0 +1,8 @@
terraform {
required_providers {
hcloud = {
source = "hetznercloud/hcloud"
version = "~> 1.26.0"
}
}
}

View file

@ -0,0 +1,4 @@
resource "hcloud_network" "network" {
name = "${var.project_name}-vnet"
ip_range = "10.0.0.0/16"
}

View file

@ -0,0 +1,7 @@
output "public_ip" {
value = hcloud_server.server.ipv4_address
}
output "private_ip" {
value = hcloud_server_network.server_network.ip
}

View file

@ -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
}

View file

@ -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
]
}

View file

@ -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"
}

View file

@ -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"
}

View file

@ -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"
}
}

View file

@ -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",
]
}

View file

@ -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"
]
}
}

8
hetzner/template/main.tf Normal file
View file

@ -0,0 +1,8 @@
terraform {
required_providers {
hcloud = {
source = "hetznercloud/hcloud"
version = "~> 1.26.0"
}
}
}

View file

@ -0,0 +1,4 @@
resource "hcloud_network" "network" {
name = "${var.project_name}-vnet"
ip_range = "10.0.0.0/16"
}

View file

@ -0,0 +1,7 @@
output "public_ip" {
value = hcloud_server.server.ipv4_address
}
output "private_ip" {
value = hcloud_server_network.server_network.ip
}

View file

@ -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
}

View file

@ -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
]
}

View file

@ -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"
}

View file

@ -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"
}

View file

@ -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"
}
}