resource "hcloud_ssh_key" "default" { name = var.default_ssh_key.name public_key = var.default_ssh_key.public_key } data "template_file" "cloud_init" { template = file("./templates/cloud-init.yaml.tpl") vars = { tailscale_authkey = tailscale_tailnet_key.cloud_init_key.key default_ssh_key = var.default_ssh_key.public_key } } resource "hcloud_placement_group" "default" { name = "serguzim.net" type = "spread" } resource "hcloud_primary_ip" "node_ipv4_addresses" { for_each = local.hetzner_hosts name = "primary_ipv4_${each.value.hostname}" datacenter = each.value.datacenter type = "ipv4" assignee_type = "server" auto_delete = false } resource "hcloud_primary_ip" "node_ipv6_addresses" { for_each = local.hetzner_hosts name = "primary_ipv6_${each.value.hostname}" datacenter = each.value.datacenter type = "ipv6" assignee_type = "server" auto_delete = false } # Create a server resource "hcloud_server" "nodes" { for_each = local.hetzner_hosts name = each.value.hostname datacenter = each.value.datacenter image = each.value.image server_type = each.value.server_type ssh_keys = [hcloud_ssh_key.default.id] user_data = data.template_file.cloud_init.rendered placement_group_id = hcloud_placement_group.default.id public_net { ipv4 = hcloud_primary_ip.node_ipv4_addresses[each.key].id ipv6 = hcloud_primary_ip.node_ipv6_addresses[each.key].id } lifecycle { ignore_changes = [ ssh_keys, user_data ] prevent_destroy = true } } resource "hcloud_rdns" "nodes_rdns_ipv4" { for_each = local.hetzner_hosts server_id = hcloud_server.nodes[each.key].id ip_address = hcloud_server.nodes[each.key].ipv4_address dns_ptr = each.value.rdns } resource "hcloud_rdns" "nodes_rdns_ipv6" { for_each = local.hetzner_hosts server_id = hcloud_server.nodes[each.key].id ip_address = hcloud_server.nodes[each.key].ipv6_address dns_ptr = each.value.rdns } locals { default_firewall_source_ips = [ "0.0.0.0/0", "::/0" ] } # Create firewalls resource "hcloud_firewall" "nodes_services" { for_each = local.hetzner_hosts name = each.key apply_to { server = hcloud_server.nodes[each.key].id } rule { description = "ICMP" direction = "in" protocol = "icmp" source_ips = local.default_firewall_source_ips } dynamic "rule" { for_each = flatten([ for k, v in var.services : v.ports if (v.ports != null && (v.host == each.key || v.host == "*")) ]) content { description = rule.value.description direction = "in" protocol = rule.value.protocol port = rule.value.port source_ips = local.default_firewall_source_ips } } }