diff --git a/modules/cloudflare_dns/main.tf b/modules/cloudflare_dns/main.tf index d4662ce..fc1aa7d 100644 --- a/modules/cloudflare_dns/main.tf +++ b/modules/cloudflare_dns/main.tf @@ -1,7 +1,7 @@ terraform { required_version = ">= 1.0.0" required_providers { - cloudflare = { source = "cloudflare/cloudflare", version = "~> 5.23.0" } + cloudflare = { source = "cloudflare/cloudflare", version = "~> 5.24.0" } } } @@ -16,6 +16,6 @@ resource "cloudflare_dns_record" "this" { name = var.record_name type = var.record_type content = var.record_value - proxied = var.proxied - ttl = var.proxied ? 1 : var.ttl + proxied = var.cloudflare_proxied + ttl = var.cloudflare_proxied ? 1 : var.record_ttl } \ No newline at end of file diff --git a/modules/cloudflare_dns/variables.tf b/modules/cloudflare_dns/variables.tf index 1e1438e..2f358e1 100644 --- a/modules/cloudflare_dns/variables.tf +++ b/modules/cloudflare_dns/variables.tf @@ -18,18 +18,18 @@ variable "record_value" { description = "Record content (IP address, target hostname, text)" } -variable "proxied" { +variable "cloudflare_proxied" { type = bool description = "Route through the Cloudflare proxy (orange cloud)" default = true } -variable "ttl" { +variable "record_ttl" { type = number description = "TTL in seconds (ignored when proxied)" default = 3600 validation { - condition = var.ttl >= 60 && var.ttl <= 86400 + condition = var.record_ttl >= 60 && var.record_ttl <= 86400 error_message = "ttl must be between 60 and 86400 seconds" } } \ No newline at end of file diff --git a/modules/hetzner_server/main.tf b/modules/hetzner_server/main.tf new file mode 100644 index 0000000..befaf11 --- /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 + ssh_key_name = "${var.project_name}-key" + firewall_name = "${var.project_name}-fw" +} + +resource "hcloud_ssh_key" "this" { + name = local.ssh_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.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/outputs.tf b/modules/hetzner_server/outputs.tf new file mode 100644 index 0000000..87795a9 --- /dev/null +++ b/modules/hetzner_server/outputs.tf @@ -0,0 +1,9 @@ +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 +} \ 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..dd64239 --- /dev/null +++ b/modules/hetzner_server/variables.tf @@ -0,0 +1,45 @@ +variable "project_name" { + type = string + description = "Project / host name" +} + +variable "ssh_public_key" { + type = string + description = "Public SSH key to manage the host" +} + +variable "hcloud_server_type" { + type = string + description = "Hetzner server type (e.g. cx22)" +} + +variable "hcloud_image" { + type = string + description = "OS image to boot (e.g. debian-13)" +} + +variable "hcloud_location" { + type = string + description = "Hetzner location (fsn1, nbg1, hel1, ash1)" + validation { + condition = contains(["fsn1", "nbg1", "hel1", "ash1"], var.hcloud_location) + error_message = "location must be one of fsn1, nbg1, hel1, ash1" + } +} + +variable "init_user_data" { + type = string + description = "Pre-rendered cloud-init user data (optional)" + 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 diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..e50104d --- /dev/null +++ b/renovate.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": ["local>renovate-bot/renovate-config", "local>renovate-bot/renovate-config:docker"], + "dependencyDashboard": true, + "dependencyDashboardTitle": "Renovate Dashboard", + "assignees": ["alessandrovitali"], + "labels": ["renovate"] +}