From 68290e3e897642919e9c6a3ff70bd31185f45e37 Mon Sep 17 00:00:00 2001 From: alessandrovitali Date: Wed, 2 Sep 2026 20:18:46 +0200 Subject: [PATCH 1/3] add hetzner server module --- modules/hetzner_server/main.tf | 40 +++++++++++++++++++++++++ modules/hetzner_server/outputs.tf | 24 +++++++++++++++ modules/hetzner_server/variables.tf | 46 +++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 modules/hetzner_server/main.tf create mode 100644 modules/hetzner_server/outputs.tf create mode 100644 modules/hetzner_server/variables.tf diff --git a/modules/hetzner_server/main.tf b/modules/hetzner_server/main.tf new file mode 100644 index 0000000..31a519e --- /dev/null +++ b/modules/hetzner_server/main.tf @@ -0,0 +1,40 @@ +terraform { + required_version = ">= 1.0.0" + required_providers { + hcloud = { source = "hetznercloud/hcloud", version = "~> 1.68.0" } + } +} + +locals { + # single naming scheme - propagates everywhere + key_name = "${var.name}-key" + firewall_name = "${var.name}-fw" +} + +resource "hcloud_ssh_key" "this" { + name = local.key_name + public_key = var.ssh_public_key +} + +resource "hcloud_firewall" "this" { + name = local.firewall_name + + dynamic "rule" { + for_each = var.firewall_rules + content { + direction = rule.value.direction + protocol = rule.value.protocol + port = rule.value.port + source_ips = rule.value.source_ips + } + } +} + +resource "hcloud_server" "this" { + name = var.name + image = var.image + server_type = var.server_type + location = var.location + user_data = var.user_data + firewall_ids = [hcloud_firewall.this.id] +} \ No newline at end of file diff --git a/modules/hetzner_server/outputs.tf b/modules/hetzner_server/outputs.tf new file mode 100644 index 0000000..dee5039 --- /dev/null +++ b/modules/hetzner_server/outputs.tf @@ -0,0 +1,24 @@ +output "ipv4_address" { + description = "Primary public IPv4 address of the host" + value = hcloud_server.this.ipv4_address +} + +output "ipv6_address" { + description = "Primary public IPv6 address of the host" + value = hcloud_server.this.ipv6_address +} + +output "server_id" { + description = "Hetzner server ID" + value = hcloud_server.this.id +} + +output "ssh_key_name" { + description = "Name of the registered Hetzner SSH key" + value = hcloud_ssh_key.this.name +} + +output "firewall_name" { + description = "Name of the firewall attached to the host" + value = hcloud_firewall.this.name +} \ No newline at end of file diff --git a/modules/hetzner_server/variables.tf b/modules/hetzner_server/variables.tf new file mode 100644 index 0000000..016e271 --- /dev/null +++ b/modules/hetzner_server/variables.tf @@ -0,0 +1,46 @@ +variable "name" { + type = string + description = "Host name (used as prefix for the SSH key and firewall)" +} + +variable "ssh_public_key" { + type = string + description = "Public SSH key to manage the host" +} + +variable "server_type" { + type = string + description = "Hetzner server type (e.g. cx22)" +} + +variable "image" { + type = string + description = "OS image to boot (e.g. debian-13)" +} + +variable "location" { + type = string + description = "Hetzner location (fsn1, nbg1, hel1, ash1)" + default = "nbg1" + validation { + condition = contains(["fsn1", "nbg1", "hel1", "ash1"], var.location) + error_message = "location must be one of fsn1, nbg1, hel1, ash1." + } +} + +variable "user_data" { + type = string + description = "Pre-rendered cloud-init user data (optional). Caller renders it from a template." + default = null +} + +variable "firewall_rules" { + type = list(object({ + direction = string + protocol = string + port = string + source_ips = list(string) + })) + description = "Firewall rules applied to the host" + default = [] +} \ No newline at end of file -- 2.54.0 From dc1a6a8556ae4f4bfa2a80d9860fb09b7ddee729 Mon Sep 17 00:00:00 2001 From: alessandrovitali Date: Thu, 3 Sep 2026 00:30:08 +0200 Subject: [PATCH 2/3] update variables --- modules/hetzner_server/main.tf | 16 ++++++++-------- modules/hetzner_server/variables.tf | 19 +++++++++---------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/modules/hetzner_server/main.tf b/modules/hetzner_server/main.tf index 31a519e..befaf11 100644 --- a/modules/hetzner_server/main.tf +++ b/modules/hetzner_server/main.tf @@ -7,12 +7,12 @@ terraform { locals { # single naming scheme - propagates everywhere - key_name = "${var.name}-key" - firewall_name = "${var.name}-fw" + ssh_key_name = "${var.project_name}-key" + firewall_name = "${var.project_name}-fw" } resource "hcloud_ssh_key" "this" { - name = local.key_name + name = local.ssh_key_name public_key = var.ssh_public_key } @@ -31,10 +31,10 @@ resource "hcloud_firewall" "this" { } resource "hcloud_server" "this" { - name = var.name - image = var.image - server_type = var.server_type - location = var.location - user_data = var.user_data + name = var.project_name + image = var.hcloud_image + server_type = var.hcloud_server_type + location = var.hcloud_location + user_data = var.init_user_data firewall_ids = [hcloud_firewall.this.id] } \ No newline at end of file diff --git a/modules/hetzner_server/variables.tf b/modules/hetzner_server/variables.tf index 016e271..dd64239 100644 --- a/modules/hetzner_server/variables.tf +++ b/modules/hetzner_server/variables.tf @@ -1,6 +1,6 @@ -variable "name" { +variable "project_name" { type = string - description = "Host name (used as prefix for the SSH key and firewall)" + description = "Project / host name" } variable "ssh_public_key" { @@ -8,29 +8,28 @@ variable "ssh_public_key" { description = "Public SSH key to manage the host" } -variable "server_type" { +variable "hcloud_server_type" { type = string description = "Hetzner server type (e.g. cx22)" } -variable "image" { +variable "hcloud_image" { type = string description = "OS image to boot (e.g. debian-13)" } -variable "location" { +variable "hcloud_location" { type = string description = "Hetzner location (fsn1, nbg1, hel1, ash1)" - default = "nbg1" validation { - condition = contains(["fsn1", "nbg1", "hel1", "ash1"], var.location) - error_message = "location must be one of fsn1, nbg1, hel1, ash1." + condition = contains(["fsn1", "nbg1", "hel1", "ash1"], var.hcloud_location) + error_message = "location must be one of fsn1, nbg1, hel1, ash1" } } -variable "user_data" { +variable "init_user_data" { type = string - description = "Pre-rendered cloud-init user data (optional). Caller renders it from a template." + description = "Pre-rendered cloud-init user data (optional)" default = null } -- 2.54.0 From ea42bea0a2fa14f9e61dc370c587647131c8f655 Mon Sep 17 00:00:00 2001 From: alessandrovitali Date: Thu, 3 Sep 2026 01:15:01 +0200 Subject: [PATCH 3/3] remove unreferenced outputs --- modules/hetzner_server/outputs.tf | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/modules/hetzner_server/outputs.tf b/modules/hetzner_server/outputs.tf index dee5039..87795a9 100644 --- a/modules/hetzner_server/outputs.tf +++ b/modules/hetzner_server/outputs.tf @@ -6,19 +6,4 @@ output "ipv4_address" { output "ipv6_address" { description = "Primary public IPv6 address of the host" value = hcloud_server.this.ipv6_address -} - -output "server_id" { - description = "Hetzner server ID" - value = hcloud_server.this.id -} - -output "ssh_key_name" { - description = "Name of the registered Hetzner SSH key" - value = hcloud_ssh_key.this.name -} - -output "firewall_name" { - description = "Name of the firewall attached to the host" - value = hcloud_firewall.this.name } \ No newline at end of file -- 2.54.0