terraform
This commit is contained in:
commit
33a12b643f
15 changed files with 1021 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
secrets/*
|
||||||
50
terraform/.gitignore
vendored
Normal file
50
terraform/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
# Terraform state files
|
||||||
|
*.tfstate
|
||||||
|
*.tfstate.*
|
||||||
|
*.tfstate.backup
|
||||||
|
|
||||||
|
# Terraform plan files
|
||||||
|
tfplan
|
||||||
|
*.tfplan
|
||||||
|
plan.txt
|
||||||
|
|
||||||
|
# Terraform variable files with secrets
|
||||||
|
terraform.tfvars
|
||||||
|
*.auto.tfvars
|
||||||
|
|
||||||
|
# Terraform CLI configuration
|
||||||
|
.terraformrc
|
||||||
|
terraform.rc
|
||||||
|
|
||||||
|
# Terraform directories
|
||||||
|
.terraform/
|
||||||
|
.terraform.lock.hcl
|
||||||
|
|
||||||
|
# Crash log files
|
||||||
|
crash.log
|
||||||
|
crash.*.log
|
||||||
|
|
||||||
|
# Override files
|
||||||
|
override.tf
|
||||||
|
override.tf.json
|
||||||
|
*_override.tf
|
||||||
|
*_override.tf.json
|
||||||
|
|
||||||
|
# SSH keys
|
||||||
|
*.pem
|
||||||
|
*.key
|
||||||
|
*_rsa
|
||||||
|
*_ed25519
|
||||||
|
deploy_key
|
||||||
|
deploy_key.pub
|
||||||
|
|
||||||
|
# IDE and editor files
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# OS files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
133
terraform/README.md
Normal file
133
terraform/README.md
Normal file
|
|
@ -0,0 +1,133 @@
|
||||||
|
# ASXP.IO Infrastructure
|
||||||
|
|
||||||
|
Hetzner Cloud infrastructure managed via Terraform.
|
||||||
|
|
||||||
|
## Servers
|
||||||
|
|
||||||
|
- **asxpio-ops** (CX22: 2 vCPU, 4GB) - Forgejo, Traefik, monitoring, static sites
|
||||||
|
- **asxpio-services** (CX43: 8 vCPU, 16GB) - Immich, game servers, XMPP, CI/CD
|
||||||
|
|
||||||
|
## Storage (S3-compatible)
|
||||||
|
|
||||||
|
**Terraform State:**
|
||||||
|
- asxpio-terraform-main (hel1)
|
||||||
|
- asxpio-terraform-repl (fsn1)
|
||||||
|
|
||||||
|
**Backups:**
|
||||||
|
- asxpio-backups-main (hel1)
|
||||||
|
- asxpio-backups-repl (fsn1)
|
||||||
|
|
||||||
|
**Immich:**
|
||||||
|
- asxpio-immich-main (hel1)
|
||||||
|
- asxpio-immich-repl (fsn1)
|
||||||
|
|
||||||
|
## Network
|
||||||
|
|
||||||
|
- VPC: 10.10.0.0/20
|
||||||
|
- WireGuard VPN: 10.0.0.0/24
|
||||||
|
- IPv4 + IPv6 enabled
|
||||||
|
|
||||||
|
## Cost
|
||||||
|
|
||||||
|
| Item | Monthly |
|
||||||
|
|------|---------|
|
||||||
|
| ops CX22 | €3.71 |
|
||||||
|
| services CX43 | €11.15 |
|
||||||
|
| IPv4 (2x) | €1.24 |
|
||||||
|
| S3 (1TB) | €6.19 |
|
||||||
|
| S3 1TB Traffic | €1.24 |
|
||||||
|
| **Total** | **€22.29** |
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
### 1. Initialize
|
||||||
|
```bash
|
||||||
|
terraform init
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Configure secrets
|
||||||
|
Edit `terraform.tfvars`:
|
||||||
|
```hcl
|
||||||
|
hcloud_token = "your-token"
|
||||||
|
s3_access_key = "your-key"
|
||||||
|
s3_secret_key = "your-secret"
|
||||||
|
s3_endpoint_hel1 = "hel1.your-objectstorage.com"
|
||||||
|
s3_endpoint_fsn1 = "fsn1.your-objectstorage.com"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Deploy
|
||||||
|
```bash
|
||||||
|
terraform plan
|
||||||
|
terraform apply
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Enable S3 backend (optional)
|
||||||
|
After buckets are created:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Set credentials
|
||||||
|
export AWS_ACCESS_KEY_ID="your-key"
|
||||||
|
export AWS_SECRET_ACCESS_KEY="your-secret"
|
||||||
|
|
||||||
|
# Or use ~/.aws/credentials file
|
||||||
|
mkdir -p ~/.aws
|
||||||
|
cat > ~/.aws/credentials <<EOF
|
||||||
|
[default]
|
||||||
|
aws_access_key_id = your-key
|
||||||
|
aws_secret_access_key = your-secret
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Uncomment backend in providers.tf
|
||||||
|
# Then migrate state
|
||||||
|
terraform init -migrate-state
|
||||||
|
```
|
||||||
|
|
||||||
|
## DNS Management
|
||||||
|
|
||||||
|
**Current:** Managed manually via `hcloud` CLI
|
||||||
|
|
||||||
|
Zones: asxp.io (61604), czsk.it (61606), childfr.ee (61605)
|
||||||
|
|
||||||
|
**TODO:** Migrate to Terraform-managed DNS when provider v1.54.0+ is available:
|
||||||
|
```hcl
|
||||||
|
# Upgrade provider in providers.tf
|
||||||
|
hcloud = {
|
||||||
|
source = "hetznercloud/hcloud"
|
||||||
|
version = "~> 1.54"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Import existing zones
|
||||||
|
terraform import hcloud_zone.asxp_io 61604
|
||||||
|
terraform import hcloud_zone.czsk_it 61606
|
||||||
|
terraform import hcloud_zone.childfr_ee 61605
|
||||||
|
|
||||||
|
# Example DNS resource
|
||||||
|
resource "hcloud_zone" "asxp_io" {
|
||||||
|
name = "asxp.io"
|
||||||
|
mode = "primary"
|
||||||
|
labels = {
|
||||||
|
managed_by = "terraform"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "hcloud_zone_rrset" "apex_a" {
|
||||||
|
zone = hcloud_zone.asxp_io.name
|
||||||
|
name = "@"
|
||||||
|
type = "A"
|
||||||
|
records = [
|
||||||
|
{ value = "95.217.19.240", comment = "ops-server" },
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
See: https://github.com/hetznercloud/terraform-provider-hcloud/releases/tag/v1.54.0
|
||||||
|
|
||||||
|
## Files
|
||||||
|
|
||||||
|
- `servers.tf` - Server definitions + cloud-init
|
||||||
|
- `s3.tf` - S3 buckets (6 total)
|
||||||
|
- `vpc.tf` - Private network
|
||||||
|
- `firewall.tf` - Security rules
|
||||||
|
- `dns.tf` - DNS docs (manual management)
|
||||||
|
- `keys.tf` - SSH keys
|
||||||
|
- `cloud-init/*.yaml` - Server provisioning
|
||||||
137
terraform/cloud-init/ops.yaml
Normal file
137
terraform/cloud-init/ops.yaml
Normal file
|
|
@ -0,0 +1,137 @@
|
||||||
|
#cloud-config
|
||||||
|
# Cloud-init configuration for asxpio-ops server
|
||||||
|
# Debian 13 (trixie) - Ops Server
|
||||||
|
|
||||||
|
hostname: asxpio-ops
|
||||||
|
fqdn: asxpio-ops.asxp.io
|
||||||
|
manage_etc_hosts: true
|
||||||
|
|
||||||
|
# Package management
|
||||||
|
package_update: true
|
||||||
|
package_upgrade: true
|
||||||
|
|
||||||
|
packages:
|
||||||
|
- fail2ban
|
||||||
|
- wget
|
||||||
|
- curl
|
||||||
|
- gpg
|
||||||
|
- rsync
|
||||||
|
- unzip
|
||||||
|
- htop
|
||||||
|
- ncdu
|
||||||
|
- tree
|
||||||
|
- git
|
||||||
|
- tmux
|
||||||
|
- apt-transport-https
|
||||||
|
- ca-certificates
|
||||||
|
- gnupg
|
||||||
|
- lsb-release
|
||||||
|
|
||||||
|
# Create users (docker group will be added later in runcmd)
|
||||||
|
users:
|
||||||
|
- name: asxpi
|
||||||
|
groups: sudo
|
||||||
|
shell: /bin/bash
|
||||||
|
sudo: ['ALL=(ALL) NOPASSWD:ALL']
|
||||||
|
lock_passwd: true
|
||||||
|
ssh_authorized_keys:
|
||||||
|
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC//ljrf65xbFyGmy/xeZs5GZvkmufCioqIGYguR3c8c/Ff9HiA4oMRT53Qs16KMuXRg62NusVQvJsvyPRSARpBFsoPiZ/YNBteWlqT1aVqeZwPOfUfFycQ2T8a9qtDnZ0WhamSlJMSAHQPkxXNA6S2ZE9y+dMzMc5qPeRwdsQmuvkxjual/35t9qTgCAG7LvKCKPJkLL5YpwLoqWYWTqSJ6RxNLTYNgIhJBZirzB5rNiFDDupnOuTKSpyRJNxyBSapNge5rCnGQYIeoJ4fi+FTi5wzjlC3hC0BN4Oc/zrm1nS9lyPXQS8KV5/vcQlPrvYZmv0LneeQ/gH/jJsSlwRp2qIatoASSfTlz1y1bOOYtPFojJPikXiXeZMCdlam1II6B94z1ybOIO8TqyKDVs4eHRFfYO72zv0sGsTr7t0C7+N9Wrpmhk38zdlLagZ6HO7KSyoAHm+fQc58fXmOhz4vfYrbmYRPgO0VO03fEb7lSFPPLaSseT0tayli05irJpc= asxpi@laptop
|
||||||
|
- name: deploy
|
||||||
|
groups: sudo
|
||||||
|
shell: /bin/bash
|
||||||
|
sudo: ['ALL=(ALL) NOPASSWD:ALL']
|
||||||
|
lock_passwd: true
|
||||||
|
ssh_authorized_keys:
|
||||||
|
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGTDPg3mV55lO8uBnvpcGRxJ2vMRP0qB3Pxhg+C8rwj9 asxpio-deploy
|
||||||
|
|
||||||
|
# SSH hardening
|
||||||
|
ssh_pwauth: false
|
||||||
|
disable_root: false
|
||||||
|
ssh_deletekeys: false
|
||||||
|
|
||||||
|
# Write files
|
||||||
|
write_files:
|
||||||
|
# Docker daemon configuration
|
||||||
|
- path: /etc/docker/daemon.json
|
||||||
|
content: |
|
||||||
|
{
|
||||||
|
"live-restore": true,
|
||||||
|
"storage-driver": "overlay2",
|
||||||
|
"log-opts": {
|
||||||
|
"max-size": "20m"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
owner: root:root
|
||||||
|
permissions: '0644'
|
||||||
|
|
||||||
|
# Custom bash prompt for asxpi user
|
||||||
|
- path: /home/asxpi/.bashrc_custom
|
||||||
|
content: |
|
||||||
|
# Custom bash prompt styling for asxpio servers
|
||||||
|
export PS1="\[$(tput bold)\]\[\033[38;5;4m\][\[$(tput sgr0)\]\t\[$(tput sgr0)\]\[$(tput bold)\]\[\033[38;5;4m\]]\[$(tput sgr0)\] \[$(tput sgr0)\]\[$(tput bold)\]\[\033[38;5;4m\][\[$(tput sgr0)\]\u@\h \[$(tput sgr0)\]\[$(tput bold)\]\[\033[38;5;4m\]\w]\[$(tput sgr0)\] \[$(tput sgr0)\]\[$(tput bold)\]\[\033[38;5;4m\]\\$\[$(tput sgr0)\] \[$(tput sgr0)\]"
|
||||||
|
owner: root:root
|
||||||
|
permissions: '0644'
|
||||||
|
|
||||||
|
# SSH hardening config
|
||||||
|
- path: /etc/ssh/sshd_config.d/99-hardening.conf
|
||||||
|
content: |
|
||||||
|
PasswordAuthentication no
|
||||||
|
PermitRootLogin prohibit-password
|
||||||
|
PubkeyAuthentication yes
|
||||||
|
owner: root:root
|
||||||
|
permissions: '0644'
|
||||||
|
|
||||||
|
runcmd:
|
||||||
|
# Install Docker
|
||||||
|
- curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
||||||
|
- echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||||
|
- apt-get update
|
||||||
|
- apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
|
||||||
|
|
||||||
|
# Enable and start Docker
|
||||||
|
- systemctl enable docker
|
||||||
|
- systemctl start docker
|
||||||
|
|
||||||
|
# Add users to docker group (after docker is installed)
|
||||||
|
- usermod -aG docker asxpi
|
||||||
|
- usermod -aG docker deploy
|
||||||
|
|
||||||
|
# Enable and start fail2ban
|
||||||
|
- systemctl enable fail2ban
|
||||||
|
- systemctl start fail2ban
|
||||||
|
|
||||||
|
# Fix home directory ownership and setup bashrc for asxpi
|
||||||
|
- chown asxpi:asxpi /home/asxpi
|
||||||
|
- chown asxpi:asxpi /home/asxpi/.bashrc_custom
|
||||||
|
- cp /etc/skel/.bashrc /home/asxpi/.bashrc
|
||||||
|
- cp /etc/skel/.profile /home/asxpi/.profile
|
||||||
|
- chown asxpi:asxpi /home/asxpi/.bashrc /home/asxpi/.profile
|
||||||
|
- echo '[ -f ~/.bashrc_custom ] && source ~/.bashrc_custom' >> /home/asxpi/.bashrc
|
||||||
|
|
||||||
|
# Fix home directory ownership for deploy user
|
||||||
|
- chown deploy:deploy /home/deploy
|
||||||
|
|
||||||
|
# Create directory structure for services
|
||||||
|
- mkdir -p /opt/{traefik,forgejo,grafana,prometheus,loki,promtail,static-sites}
|
||||||
|
- mkdir -p /opt/traefik/config
|
||||||
|
- mkdir -p /opt/static-sites/{asxp.io,czsk.it,childfr.ee,builds,upload}
|
||||||
|
- chown -R asxpi:asxpi /opt/*
|
||||||
|
|
||||||
|
# Set up weekly Docker image pruning
|
||||||
|
- echo '0 3 * * 1 docker image prune -af > /var/log/docker-prune.log 2>&1' | crontab -
|
||||||
|
|
||||||
|
# Restart SSH to apply hardening
|
||||||
|
- systemctl restart sshd
|
||||||
|
|
||||||
|
final_message: |
|
||||||
|
==========================================
|
||||||
|
asxpio-ops server is ready!
|
||||||
|
==========================================
|
||||||
|
Hostname: asxpio-ops
|
||||||
|
OS: Debian 13 (trixie)
|
||||||
|
User: asxpi (sudo + docker access)
|
||||||
|
SSH: Key-only authentication enabled
|
||||||
|
Docker: Installed with compose plugin
|
||||||
|
|
||||||
|
You can now SSH: ssh asxpi@$(hostname -I | awk '{print $1}')
|
||||||
|
==========================================
|
||||||
138
terraform/cloud-init/services.yaml
Normal file
138
terraform/cloud-init/services.yaml
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
#cloud-config
|
||||||
|
# Cloud-init configuration for asxpio-services server
|
||||||
|
# Debian 13 (trixie) - Services Server
|
||||||
|
|
||||||
|
hostname: asxpio-services
|
||||||
|
fqdn: asxpio-services.asxp.io
|
||||||
|
manage_etc_hosts: true
|
||||||
|
|
||||||
|
# Package management
|
||||||
|
package_update: true
|
||||||
|
package_upgrade: true
|
||||||
|
|
||||||
|
packages:
|
||||||
|
- fail2ban
|
||||||
|
- wget
|
||||||
|
- curl
|
||||||
|
- gpg
|
||||||
|
- rsync
|
||||||
|
- unzip
|
||||||
|
- htop
|
||||||
|
- ncdu
|
||||||
|
- tree
|
||||||
|
- git
|
||||||
|
- tmux
|
||||||
|
- apt-transport-https
|
||||||
|
- ca-certificates
|
||||||
|
- gnupg
|
||||||
|
- lsb-release
|
||||||
|
|
||||||
|
# Create users (docker group will be added later in runcmd)
|
||||||
|
users:
|
||||||
|
- name: asxpi
|
||||||
|
groups: sudo
|
||||||
|
shell: /bin/bash
|
||||||
|
sudo: ['ALL=(ALL) NOPASSWD:ALL']
|
||||||
|
lock_passwd: true
|
||||||
|
ssh_authorized_keys:
|
||||||
|
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC//ljrf65xbFyGmy/xeZs5GZvkmufCioqIGYguR3c8c/Ff9HiA4oMRT53Qs16KMuXRg62NusVQvJsvyPRSARpBFsoPiZ/YNBteWlqT1aVqeZwPOfUfFycQ2T8a9qtDnZ0WhamSlJMSAHQPkxXNA6S2ZE9y+dMzMc5qPeRwdsQmuvkxjual/35t9qTgCAG7LvKCKPJkLL5YpwLoqWYWTqSJ6RxNLTYNgIhJBZirzB5rNiFDDupnOuTKSpyRJNxyBSapNge5rCnGQYIeoJ4fi+FTi5wzjlC3hC0BN4Oc/zrm1nS9lyPXQS8KV5/vcQlPrvYZmv0LneeQ/gH/jJsSlwRp2qIatoASSfTlz1y1bOOYtPFojJPikXiXeZMCdlam1II6B94z1ybOIO8TqyKDVs4eHRFfYO72zv0sGsTr7t0C7+N9Wrpmhk38zdlLagZ6HO7KSyoAHm+fQc58fXmOhz4vfYrbmYRPgO0VO03fEb7lSFPPLaSseT0tayli05irJpc= asxpi@laptop
|
||||||
|
- name: deploy
|
||||||
|
groups: sudo
|
||||||
|
shell: /bin/bash
|
||||||
|
sudo: ['ALL=(ALL) NOPASSWD:ALL']
|
||||||
|
lock_passwd: true
|
||||||
|
ssh_authorized_keys:
|
||||||
|
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGTDPg3mV55lO8uBnvpcGRxJ2vMRP0qB3Pxhg+C8rwj9 asxpio-deploy
|
||||||
|
|
||||||
|
# SSH hardening
|
||||||
|
ssh_pwauth: false
|
||||||
|
disable_root: false
|
||||||
|
ssh_deletekeys: false
|
||||||
|
|
||||||
|
# Write files
|
||||||
|
write_files:
|
||||||
|
# Docker daemon configuration
|
||||||
|
- path: /etc/docker/daemon.json
|
||||||
|
content: |
|
||||||
|
{
|
||||||
|
"live-restore": true,
|
||||||
|
"storage-driver": "overlay2",
|
||||||
|
"log-opts": {
|
||||||
|
"max-size": "20m"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
owner: root:root
|
||||||
|
permissions: '0644'
|
||||||
|
|
||||||
|
# Custom bash prompt for asxpi user
|
||||||
|
- path: /home/asxpi/.bashrc_custom
|
||||||
|
content: |
|
||||||
|
# Custom bash prompt styling for asxpio servers
|
||||||
|
export PS1="\[$(tput bold)\]\[\033[38;5;4m\][\[$(tput sgr0)\]\t\[$(tput sgr0)\]\[$(tput bold)\]\[\033[38;5;4m\]]\[$(tput sgr0)\] \[$(tput sgr0)\]\[$(tput bold)\]\[\033[38;5;4m\][\[$(tput sgr0)\]\u@\h \[$(tput sgr0)\]\[$(tput bold)\]\[\033[38;5;4m\]\w]\[$(tput sgr0)\] \[$(tput sgr0)\]\[$(tput bold)\]\[\033[38;5;4m\]\\$\[$(tput sgr0)\] \[$(tput sgr0)\]"
|
||||||
|
owner: root:root
|
||||||
|
permissions: '0644'
|
||||||
|
|
||||||
|
# SSH hardening config
|
||||||
|
- path: /etc/ssh/sshd_config.d/99-hardening.conf
|
||||||
|
content: |
|
||||||
|
PasswordAuthentication no
|
||||||
|
PermitRootLogin prohibit-password
|
||||||
|
PubkeyAuthentication yes
|
||||||
|
owner: root:root
|
||||||
|
permissions: '0644'
|
||||||
|
|
||||||
|
runcmd:
|
||||||
|
# Install Docker
|
||||||
|
- curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
||||||
|
- echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||||
|
- apt-get update
|
||||||
|
- apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
|
||||||
|
|
||||||
|
# Enable and start Docker
|
||||||
|
- systemctl enable docker
|
||||||
|
- systemctl start docker
|
||||||
|
|
||||||
|
# Add users to docker group (after docker is installed)
|
||||||
|
- usermod -aG docker asxpi
|
||||||
|
- usermod -aG docker deploy
|
||||||
|
|
||||||
|
# Enable and start fail2ban
|
||||||
|
- systemctl enable fail2ban
|
||||||
|
- systemctl start fail2ban
|
||||||
|
|
||||||
|
# Fix home directory ownership and setup bashrc for asxpi
|
||||||
|
- chown asxpi:asxpi /home/asxpi
|
||||||
|
- chown asxpi:asxpi /home/asxpi/.bashrc_custom
|
||||||
|
- cp /etc/skel/.bashrc /home/asxpi/.bashrc
|
||||||
|
- cp /etc/skel/.profile /home/asxpi/.profile
|
||||||
|
- chown asxpi:asxpi /home/asxpi/.bashrc /home/asxpi/.profile
|
||||||
|
- echo '[ -f ~/.bashrc_custom ] && source ~/.bashrc_custom' >> /home/asxpi/.bashrc
|
||||||
|
|
||||||
|
# Fix home directory ownership for deploy user
|
||||||
|
- chown deploy:deploy /home/deploy
|
||||||
|
|
||||||
|
# Create directory structure for services
|
||||||
|
- mkdir -p /opt/{forgejo-runner,immich,minecraft,valheim,factorio,prosody,coturn}
|
||||||
|
- mkdir -p /opt/minecraft/{data,backups}
|
||||||
|
- mkdir -p /opt/valheim/data
|
||||||
|
- mkdir -p /opt/factorio/data
|
||||||
|
- chown -R asxpi:asxpi /opt/*
|
||||||
|
|
||||||
|
# Set up weekly Docker image pruning
|
||||||
|
- echo '0 3 * * 1 docker image prune -af > /var/log/docker-prune.log 2>&1' | crontab -
|
||||||
|
|
||||||
|
# Restart SSH to apply hardening
|
||||||
|
- systemctl restart sshd
|
||||||
|
|
||||||
|
final_message: |
|
||||||
|
==========================================
|
||||||
|
asxpio-services server is ready!
|
||||||
|
==========================================
|
||||||
|
Hostname: asxpio-services
|
||||||
|
OS: Debian 13 (trixie)
|
||||||
|
User: asxpi (sudo + docker access)
|
||||||
|
SSH: Key-only authentication enabled
|
||||||
|
Docker: Installed with compose plugin
|
||||||
|
|
||||||
|
You can now SSH: ssh asxpi@$(hostname -I | awk '{print $1}')
|
||||||
|
==========================================
|
||||||
34
terraform/dns.tf
Normal file
34
terraform/dns.tf
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
# Hetzner Cloud DNS Management
|
||||||
|
# =================================
|
||||||
|
#
|
||||||
|
# DNS zones and records are now managed by Terraform.
|
||||||
|
#
|
||||||
|
# Existing Zones:
|
||||||
|
# - asxp.io (ID: 61604) - 34 records
|
||||||
|
# - czsk.it (ID: 61606) - 7 records
|
||||||
|
# - childfr.ee (ID: 61605) - 13 records
|
||||||
|
#
|
||||||
|
# To manage DNS records:
|
||||||
|
# Use the 'hcloud_record' resource in Terraform.
|
||||||
|
#
|
||||||
|
# Key records to update during migration:
|
||||||
|
# - asxp.io: @, git, builds, upload, onitama, proxy, xmpp, turn, photos
|
||||||
|
# - czsk.it: @
|
||||||
|
# - childfr.ee: @
|
||||||
|
|
||||||
|
resource "hcloud_zone" "czsk_it" {
|
||||||
|
name = "czsk.it"
|
||||||
|
mode = "primary"
|
||||||
|
labels = {
|
||||||
|
managed_by = "terraform"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "hcloud_zone_rrset" "apex_a" {
|
||||||
|
zone = hcloud_zone.czsk_it.name
|
||||||
|
name = "test"
|
||||||
|
type = "A"
|
||||||
|
records = [
|
||||||
|
{ value = "127.0.0.1", comment = "test" },
|
||||||
|
]
|
||||||
|
}
|
||||||
278
terraform/firewall.tf
Normal file
278
terraform/firewall.tf
Normal file
|
|
@ -0,0 +1,278 @@
|
||||||
|
resource "hcloud_firewall" "ops_fw" {
|
||||||
|
name = "asxpio-ops-fw"
|
||||||
|
|
||||||
|
# VPC
|
||||||
|
rule {
|
||||||
|
direction = "in"
|
||||||
|
protocol = "tcp"
|
||||||
|
port = "any"
|
||||||
|
source_ips = [
|
||||||
|
"10.10.0.0/20"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
rule {
|
||||||
|
direction = "in"
|
||||||
|
protocol = "udp"
|
||||||
|
port = "any"
|
||||||
|
source_ips = [
|
||||||
|
"10.10.0.0/20"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
rule {
|
||||||
|
direction = "in"
|
||||||
|
protocol = "icmp"
|
||||||
|
source_ips = [
|
||||||
|
"10.10.0.0/20"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
# WireGuard
|
||||||
|
rule {
|
||||||
|
direction = "in"
|
||||||
|
protocol = "tcp"
|
||||||
|
port = "any"
|
||||||
|
source_ips = [
|
||||||
|
"10.20.0.0/24"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
rule {
|
||||||
|
direction = "in"
|
||||||
|
protocol = "udp"
|
||||||
|
port = "any"
|
||||||
|
source_ips = [
|
||||||
|
"10.20.0.0/24"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
rule {
|
||||||
|
direction = "in"
|
||||||
|
protocol = "icmp"
|
||||||
|
source_ips = [
|
||||||
|
"10.20.0.0/24"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
# SSH TODO: Remove
|
||||||
|
rule {
|
||||||
|
direction = "in"
|
||||||
|
protocol = "tcp"
|
||||||
|
port = "22"
|
||||||
|
source_ips = [
|
||||||
|
"0.0.0.0/0",
|
||||||
|
"::/0"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
rule {
|
||||||
|
direction = "in"
|
||||||
|
protocol = "tcp"
|
||||||
|
port = "80"
|
||||||
|
source_ips = [
|
||||||
|
"0.0.0.0/0",
|
||||||
|
"::/0"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
rule {
|
||||||
|
direction = "in"
|
||||||
|
protocol = "tcp"
|
||||||
|
port = "443"
|
||||||
|
source_ips = [
|
||||||
|
"0.0.0.0/0",
|
||||||
|
"::/0"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
# WireGuard VPN
|
||||||
|
rule {
|
||||||
|
direction = "in"
|
||||||
|
protocol = "udp"
|
||||||
|
port = "60101"
|
||||||
|
source_ips = [
|
||||||
|
"0.0.0.0/0",
|
||||||
|
"::/0"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "hcloud_firewall" "services_fw" {
|
||||||
|
name = "asxpio-services-fw"
|
||||||
|
|
||||||
|
# VPC
|
||||||
|
rule {
|
||||||
|
direction = "in"
|
||||||
|
protocol = "tcp"
|
||||||
|
port = "any"
|
||||||
|
source_ips = [
|
||||||
|
"10.10.0.0/20"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
rule {
|
||||||
|
direction = "in"
|
||||||
|
protocol = "udp"
|
||||||
|
port = "any"
|
||||||
|
source_ips = [
|
||||||
|
"10.10.0.0/20"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
rule {
|
||||||
|
direction = "in"
|
||||||
|
protocol = "icmp"
|
||||||
|
source_ips = [
|
||||||
|
"10.10.0.0/20"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
# WireGuard
|
||||||
|
rule {
|
||||||
|
direction = "in"
|
||||||
|
protocol = "tcp"
|
||||||
|
port = "any"
|
||||||
|
source_ips = [
|
||||||
|
"10.20.0.0/24"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
rule {
|
||||||
|
direction = "in"
|
||||||
|
protocol = "udp"
|
||||||
|
port = "any"
|
||||||
|
source_ips = [
|
||||||
|
"10.20.0.0/24"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
rule {
|
||||||
|
direction = "in"
|
||||||
|
protocol = "icmp"
|
||||||
|
source_ips = [
|
||||||
|
"10.20.0.0/24"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
# SSH TODO:Remove
|
||||||
|
rule {
|
||||||
|
direction = "in"
|
||||||
|
protocol = "tcp"
|
||||||
|
port = "22"
|
||||||
|
source_ips = [
|
||||||
|
"0.0.0.0/0",
|
||||||
|
"::/0"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Minecraft Server
|
||||||
|
rule {
|
||||||
|
direction = "in"
|
||||||
|
protocol = "tcp"
|
||||||
|
port = "25565"
|
||||||
|
source_ips = [
|
||||||
|
"0.0.0.0/0",
|
||||||
|
"::/0"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Minecraft Geyser
|
||||||
|
rule {
|
||||||
|
direction = "in"
|
||||||
|
protocol = "udp"
|
||||||
|
port = "19132"
|
||||||
|
source_ips = [
|
||||||
|
"0.0.0.0/0",
|
||||||
|
"::/0"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Valheim Server (UDP port range)
|
||||||
|
rule {
|
||||||
|
direction = "in"
|
||||||
|
protocol = "udp"
|
||||||
|
port = "2456-2458"
|
||||||
|
source_ips = [
|
||||||
|
"0.0.0.0/0",
|
||||||
|
"::/0"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Factorio Server
|
||||||
|
rule {
|
||||||
|
direction = "in"
|
||||||
|
protocol = "udp"
|
||||||
|
port = "34197"
|
||||||
|
source_ips = [
|
||||||
|
"0.0.0.0/0",
|
||||||
|
"::/0"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Prosody XMPP - Client connections
|
||||||
|
rule {
|
||||||
|
direction = "in"
|
||||||
|
protocol = "tcp"
|
||||||
|
port = "5222"
|
||||||
|
source_ips = [
|
||||||
|
"0.0.0.0/0",
|
||||||
|
"::/0"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Prosody XMPP - Server-to-server
|
||||||
|
rule {
|
||||||
|
direction = "in"
|
||||||
|
protocol = "tcp"
|
||||||
|
port = "5269"
|
||||||
|
source_ips = [
|
||||||
|
"0.0.0.0/0",
|
||||||
|
"::/0"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Prosody XMPP - HTTP/BOSH
|
||||||
|
rule {
|
||||||
|
direction = "in"
|
||||||
|
protocol = "tcp"
|
||||||
|
port = "5280"
|
||||||
|
source_ips = [
|
||||||
|
"0.0.0.0/0",
|
||||||
|
"::/0"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Prosody XMPP - HTTPS
|
||||||
|
rule {
|
||||||
|
direction = "in"
|
||||||
|
protocol = "tcp"
|
||||||
|
port = "5281"
|
||||||
|
source_ips = [
|
||||||
|
"0.0.0.0/0",
|
||||||
|
"::/0"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
# TURN/STUN Server (UDP)
|
||||||
|
rule {
|
||||||
|
direction = "in"
|
||||||
|
protocol = "udp"
|
||||||
|
port = "3478"
|
||||||
|
source_ips = [
|
||||||
|
"0.0.0.0/0",
|
||||||
|
"::/0"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
# TURN/STUN Server (TCP)
|
||||||
|
rule {
|
||||||
|
direction = "in"
|
||||||
|
protocol = "tcp"
|
||||||
|
port = "3478"
|
||||||
|
source_ips = [
|
||||||
|
"0.0.0.0/0",
|
||||||
|
"::/0"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
9
terraform/keys.tf
Normal file
9
terraform/keys.tf
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
resource "hcloud_ssh_key" "asxpi" {
|
||||||
|
name = "asxpi"
|
||||||
|
public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC//ljrf65xbFyGmy/xeZs5GZvkmufCioqIGYguR3c8c/Ff9HiA4oMRT53Qs16KMuXRg62NusVQvJsvyPRSARpBFsoPiZ/YNBteWlqT1aVqeZwPOfUfFycQ2T8a9qtDnZ0WhamSlJMSAHQPkxXNA6S2ZE9y+dMzMc5qPeRwdsQmuvkxjual/35t9qTgCAG7LvKCKPJkLL5YpwLoqWYWTqSJ6RxNLTYNgIhJBZirzB5rNiFDDupnOuTKSpyRJNxyBSapNge5rCnGQYIeoJ4fi+FTi5wzjlC3hC0BN4Oc/zrm1nS9lyPXQS8KV5/vcQlPrvYZmv0LneeQ/gH/jJsSlwRp2qIatoASSfTlz1y1bOOYtPFojJPikXiXeZMCdlam1II6B94z1ybOIO8TqyKDVs4eHRFfYO72zv0sGsTr7t0C7+N9Wrpmhk38zdlLagZ6HO7KSyoAHm+fQc58fXmOhz4vfYrbmYRPgO0VO03fEb7lSFPPLaSseT0tayli05irJpc= asxpi@meow"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "hcloud_ssh_key" "deploy" {
|
||||||
|
name = "asxpio-deploy"
|
||||||
|
public_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGTDPg3mV55lO8uBnvpcGRxJ2vMRP0qB3Pxhg+C8rwj9 asxpio-deploy"
|
||||||
|
}
|
||||||
29
terraform/outputs.tf
Normal file
29
terraform/outputs.tf
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
# Server IPs
|
||||||
|
output "ops_ipv4" {
|
||||||
|
value = hcloud_server.ops.ipv4_address
|
||||||
|
description = "Ops server IPv4"
|
||||||
|
}
|
||||||
|
|
||||||
|
output "ops_ipv6" {
|
||||||
|
value = hcloud_server.ops.ipv6_address
|
||||||
|
description = "Ops server IPv6"
|
||||||
|
}
|
||||||
|
|
||||||
|
output "services_ipv4" {
|
||||||
|
value = hcloud_server.services.ipv4_address
|
||||||
|
description = "Services server IPv4"
|
||||||
|
}
|
||||||
|
|
||||||
|
output "services_ipv6" {
|
||||||
|
value = hcloud_server.services.ipv6_address
|
||||||
|
description = "Services server IPv6"
|
||||||
|
}
|
||||||
|
|
||||||
|
# VPC Network
|
||||||
|
output "vpc_network" {
|
||||||
|
value = {
|
||||||
|
id = hcloud_network.main.id
|
||||||
|
ip_range = hcloud_network.main.ip_range
|
||||||
|
}
|
||||||
|
description = "VPC network info"
|
||||||
|
}
|
||||||
51
terraform/providers.tf
Normal file
51
terraform/providers.tf
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
terraform {
|
||||||
|
required_version = ">= 1.0.0"
|
||||||
|
|
||||||
|
# S3 backend - comment this section if bucket not yet created
|
||||||
|
backend "s3" {
|
||||||
|
bucket = "asxpio-terraform-main"
|
||||||
|
key = "terraform/state/terraform.tfstate"
|
||||||
|
region = "hel1"
|
||||||
|
endpoint = "https://hel1.your-objectstorage.com"
|
||||||
|
skip_credentials_validation = true
|
||||||
|
skip_metadata_api_check = true
|
||||||
|
skip_region_validation = true
|
||||||
|
skip_requesting_account_id = true
|
||||||
|
force_path_style = true
|
||||||
|
}
|
||||||
|
|
||||||
|
required_providers {
|
||||||
|
hcloud = {
|
||||||
|
source = "hetznercloud/hcloud"
|
||||||
|
version = "~> 1.54"
|
||||||
|
}
|
||||||
|
minio = {
|
||||||
|
source = "aminueza/minio"
|
||||||
|
version = "~> 3.11"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
provider "hcloud" {
|
||||||
|
token = var.hcloud_token
|
||||||
|
}
|
||||||
|
|
||||||
|
# MinIO provider for Helsinki (hel1) region
|
||||||
|
provider "minio" {
|
||||||
|
alias = "hel1"
|
||||||
|
minio_server = var.s3_endpoint_hel1
|
||||||
|
minio_user = var.s3_access_key
|
||||||
|
minio_password = var.s3_secret_key
|
||||||
|
minio_region = "hel1"
|
||||||
|
minio_ssl = true
|
||||||
|
}
|
||||||
|
|
||||||
|
# MinIO provider for Falkenstein (fsn1) region
|
||||||
|
provider "minio" {
|
||||||
|
alias = "fsn1"
|
||||||
|
minio_server = var.s3_endpoint_fsn1
|
||||||
|
minio_user = var.s3_access_key
|
||||||
|
minio_password = var.s3_secret_key
|
||||||
|
minio_region = "fsn1"
|
||||||
|
minio_ssl = true
|
||||||
|
}
|
||||||
35
terraform/s3.tf
Normal file
35
terraform/s3.tf
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
resource "minio_s3_bucket" "terraform_main" {
|
||||||
|
provider = minio.hel1
|
||||||
|
bucket = "asxpio-terraform-main"
|
||||||
|
acl = "private"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "minio_s3_bucket" "terraform_repl" {
|
||||||
|
provider = minio.fsn1
|
||||||
|
bucket = "asxpio-terraform-repl"
|
||||||
|
acl = "private"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "minio_s3_bucket" "backups_main" {
|
||||||
|
provider = minio.hel1
|
||||||
|
bucket = "asxpio-backups-main"
|
||||||
|
acl = "private"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "minio_s3_bucket" "backups_repl" {
|
||||||
|
provider = minio.fsn1
|
||||||
|
bucket = "asxpio-backups-repl"
|
||||||
|
acl = "private"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "minio_s3_bucket" "immich_main" {
|
||||||
|
provider = minio.hel1
|
||||||
|
bucket = "asxpio-immich-main"
|
||||||
|
acl = "private"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "minio_s3_bucket" "immich_repl" {
|
||||||
|
provider = minio.fsn1
|
||||||
|
bucket = "asxpio-immich-repl"
|
||||||
|
acl = "private"
|
||||||
|
}
|
||||||
73
terraform/servers.tf
Normal file
73
terraform/servers.tf
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
# Ops Server - CX22 (2 vCPU, 4GB RAM)
|
||||||
|
resource "hcloud_server" "ops" {
|
||||||
|
name = "asxpio-ops"
|
||||||
|
image = "debian-13"
|
||||||
|
location = "hel1"
|
||||||
|
server_type = "cx23"
|
||||||
|
|
||||||
|
ssh_keys = [
|
||||||
|
hcloud_ssh_key.asxpi.id,
|
||||||
|
hcloud_ssh_key.deploy.id
|
||||||
|
]
|
||||||
|
|
||||||
|
backups = false
|
||||||
|
|
||||||
|
public_net {
|
||||||
|
ipv4_enabled = true
|
||||||
|
ipv6_enabled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
network {
|
||||||
|
network_id = hcloud_network.main.id
|
||||||
|
ip = "10.10.0.10"
|
||||||
|
}
|
||||||
|
|
||||||
|
firewall_ids = [hcloud_firewall.ops_fw.id]
|
||||||
|
|
||||||
|
labels = {
|
||||||
|
role = "ops"
|
||||||
|
env = "production"
|
||||||
|
managed_by = "terraform"
|
||||||
|
project = "asxpio"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Cloud-init for automated server setup
|
||||||
|
user_data = file("${path.module}/cloud-init/ops.yaml")
|
||||||
|
}
|
||||||
|
|
||||||
|
# Services Server - CX43 (8 vCPU, 16GB RAM)
|
||||||
|
resource "hcloud_server" "services" {
|
||||||
|
name = "asxpio-services"
|
||||||
|
image = "debian-13"
|
||||||
|
location = "hel1"
|
||||||
|
server_type = "cx43"
|
||||||
|
|
||||||
|
ssh_keys = [
|
||||||
|
hcloud_ssh_key.asxpi.id,
|
||||||
|
hcloud_ssh_key.deploy.id
|
||||||
|
]
|
||||||
|
|
||||||
|
backups = false
|
||||||
|
|
||||||
|
public_net {
|
||||||
|
ipv4_enabled = true
|
||||||
|
ipv6_enabled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
network {
|
||||||
|
network_id = hcloud_network.main.id
|
||||||
|
ip = "10.10.0.20"
|
||||||
|
}
|
||||||
|
|
||||||
|
firewall_ids = [hcloud_firewall.services_fw.id]
|
||||||
|
|
||||||
|
labels = {
|
||||||
|
role = "services"
|
||||||
|
env = "production"
|
||||||
|
managed_by = "terraform"
|
||||||
|
project = "asxpio"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Cloud-init for automated server setup
|
||||||
|
user_data = file("${path.module}/cloud-init/services.yaml")
|
||||||
|
}
|
||||||
13
terraform/terraform.tfvars.example
Normal file
13
terraform/terraform.tfvars.example
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
# Hetzner Cloud API Token
|
||||||
|
# Get from: https://console.hetzner.cloud/ → Project → Security → API Tokens
|
||||||
|
hcloud_token = "your-hetzner-cloud-api-token-here"
|
||||||
|
|
||||||
|
# S3 Access Credentials
|
||||||
|
# Create buckets first in Hetzner Cloud Console, then get credentials
|
||||||
|
s3_access_key = "your-s3-access-key-here"
|
||||||
|
s3_secret_key = "your-s3-secret-key-here"
|
||||||
|
|
||||||
|
# S3 Endpoint (update after creating buckets)
|
||||||
|
# Format: https://<bucket-name>.fsn1.your-objectstorage.com
|
||||||
|
s3_endpoint_hel1 = "hel1.your-objectstorage.com"
|
||||||
|
s3_endpoint_fsn1 = "fsn1.your-objectstorage.com"
|
||||||
29
terraform/variables.tf
Normal file
29
terraform/variables.tf
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
variable "hcloud_token" {
|
||||||
|
description = "Hetzner Cloud API Token"
|
||||||
|
type = string
|
||||||
|
sensitive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "s3_access_key" {
|
||||||
|
description = "S3 Access Key"
|
||||||
|
type = string
|
||||||
|
sensitive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "s3_secret_key" {
|
||||||
|
description = "S3 Secret Key"
|
||||||
|
type = string
|
||||||
|
sensitive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "s3_endpoint_hel1" {
|
||||||
|
description = "S3 Endpoint URL for Helsinki region"
|
||||||
|
type = string
|
||||||
|
default = "hel1.your-objectstorage.com"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "s3_endpoint_fsn1" {
|
||||||
|
description = "S3 Endpoint URL for Falkenstein region"
|
||||||
|
type = string
|
||||||
|
default = "fsn1.your-objectstorage.com"
|
||||||
|
}
|
||||||
11
terraform/vpc.tf
Normal file
11
terraform/vpc.tf
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
resource "hcloud_network" "main" {
|
||||||
|
name = "asxpio-vpc"
|
||||||
|
ip_range = "10.10.0.0/20"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "hcloud_network_subnet" "eu-central" {
|
||||||
|
network_id = hcloud_network.main.id
|
||||||
|
type = "cloud"
|
||||||
|
network_zone = "eu-central"
|
||||||
|
ip_range = "10.10.0.0/23"
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue