glam/infrastructure/terraform/main.tf
2025-11-30 23:30:29 +01:00

165 lines
3.6 KiB
HCL

# GLAM Heritage Custodian Ontology - Hetzner Infrastructure
# Terraform configuration for deploying Oxigraph SPARQL triplestore
terraform {
required_version = ">= 1.0"
required_providers {
hcloud = {
source = "hetznercloud/hcloud"
version = "~> 1.45"
}
}
# Optional: Store state in Terraform Cloud or S3
# backend "s3" {
# bucket = "glam-terraform-state"
# key = "hetzner/terraform.tfstate"
# region = "eu-central-1"
# }
}
# Configure the Hetzner Cloud Provider
provider "hcloud" {
token = var.hcloud_token
}
# SSH Key for server access
resource "hcloud_ssh_key" "default" {
name = "glam-deploy-key"
public_key = file(pathexpand(var.ssh_public_key_path))
}
# Firewall rules
resource "hcloud_firewall" "glam" {
name = "glam-firewall"
# SSH access
rule {
direction = "in"
protocol = "tcp"
port = "22"
source_ips = var.ssh_allowed_ips
}
# HTTP (redirects to HTTPS)
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"]
}
# SPARQL endpoint (optional direct access, usually via reverse proxy)
dynamic "rule" {
for_each = length(var.sparql_allowed_ips) > 0 ? [1] : []
content {
direction = "in"
protocol = "tcp"
port = "7878"
source_ips = var.sparql_allowed_ips
}
}
# Outbound - allow all
rule {
direction = "out"
protocol = "tcp"
port = "1-65535"
destination_ips = ["0.0.0.0/0", "::/0"]
}
rule {
direction = "out"
protocol = "udp"
port = "1-65535"
destination_ips = ["0.0.0.0/0", "::/0"]
}
rule {
direction = "out"
protocol = "icmp"
destination_ips = ["0.0.0.0/0", "::/0"]
}
}
# Persistent storage volume for Oxigraph data
resource "hcloud_volume" "data" {
name = "glam-data"
size = var.volume_size_gb
location = var.location
format = "ext4"
automount = false
labels = {
project = "glam"
purpose = "oxigraph-data"
}
}
# Main server
resource "hcloud_server" "glam" {
name = "glam-sparql"
server_type = var.server_type
location = var.location
image = "ubuntu-24.04"
ssh_keys = [hcloud_ssh_key.default.id]
firewall_ids = [hcloud_firewall.glam.id]
labels = {
project = "glam"
environment = var.environment
service = "oxigraph"
}
user_data = templatefile("${path.module}/cloud-init.yaml", {
domain = var.domain
admin_email = var.admin_email
oxigraph_version = var.oxigraph_version
volume_device = "/dev/disk/by-id/scsi-0HC_Volume_${hcloud_volume.data.id}"
})
# Prevent destroy of server if volume is attached
lifecycle {
create_before_destroy = true
}
}
# Attach volume to server
resource "hcloud_volume_attachment" "data" {
volume_id = hcloud_volume.data.id
server_id = hcloud_server.glam.id
automount = true
}
# Floating IP for stable endpoint (optional)
resource "hcloud_primary_ip" "glam" {
count = var.use_floating_ip ? 1 : 0
name = "glam-ip"
type = "ipv4"
datacenter = "${var.location}-dc14"
assignee_type = "server"
assignee_id = hcloud_server.glam.id
auto_delete = false
labels = {
project = "glam"
}
}
# Reverse DNS for the server IP
resource "hcloud_rdns" "glam" {
server_id = hcloud_server.glam.id
ip_address = hcloud_server.glam.ipv4_address
dns_ptr = var.domain
}