locals { # Local variables used to reduce repetition node_username = "root" server_dns = join(".", ["bridge", var.hostname]) } resource "tls_private_key" "global_key" { algorithm = "RSA" rsa_bits = 2048 } resource "local_sensitive_file" "ssh_private_key_pem" { filename = "${path.module}/id_rsa" content = tls_private_key.global_key.private_key_pem file_permission = "0600" } resource "local_file" "ssh_public_key_openssh" { filename = "${path.module}/id_rsa.pub" content = tls_private_key.global_key.public_key_openssh } resource "hcloud_network" "private" { name = "${var.prefix}-private-network" ip_range = var.network_cidr } resource "hcloud_network_route" "egress" { network_id = hcloud_network.private.id destination = "0.0.0.0/0" gateway = "10.0.1.1" } resource "hcloud_network_subnet" "private" { type = "cloud" network_id = hcloud_network.private.id network_zone = var.network_zone ip_range = var.network_ip_range } # Temporary key pair used for SSH access resource "hcloud_ssh_key" "management_ssh_key" { name = "${var.prefix}-management-ssh-key" public_key = tls_private_key.global_key.public_key_openssh } # HCloud Instance for creating a single node RKE cluster and installing the Rancher server resource "hcloud_server" "management_server" { name = "${var.prefix}-management-1" image = "ubuntu-24.04" server_type = var.instance_type location = var.hcloud_location ssh_keys = [hcloud_ssh_key.management_ssh_key.id] network { network_id = hcloud_network.private.id } user_data = file(format("%s/files/userdata.template", path.module)) provisioner "remote-exec" { inline = [ "echo 'Waiting for cloud-init to complete...'", "cloud-init status --wait > /dev/null", "echo 'Completed cloud-init!'", ] connection { type = "ssh" host = self.ipv4_address user = local.node_username private_key = tls_private_key.global_key.private_key_pem } } depends_on = [ hcloud_network_subnet.private ] lifecycle { ignore_changes = [ssh_keys, network, user_data] } } module "k3s" { source = "../../../modules/cluster/init-k3s" node_public_ip = hcloud_server.management_server.ipv4_address node_internal_ip = one(hcloud_server.management_server.network[*]).ip node_username = local.node_username ssh_private_key_pem = tls_private_key.global_key.private_key_pem } # install traefik module "traefik" { source = "../../../modules/traefik" k8s_config_path = module.k3s.kube_config_server_yaml } # install cert-manager module "cert_manager" { source = "../../../modules/cert-manager" wait_on = module.traefik.installed k8s_config_path = module.k3s.kube_config_server_yaml } # install hetzner module "cert_manager_hetzner" { source = "../../../modules/cert-manager/hetzner" wait_on = module.cert_manager.installed k8s_config_yaml = file(module.k3s.kube_config_server_yaml) tld = "fourlights.dev" hetzner_api_token = var.hdns_token } # install letsencrypt module "letsencrypt" { source = "../../../modules/letsencrypt" wait_on = module.cert_manager_hetzner.installed k8s_config_path = module.k3s.kube_config_server_yaml extraSolvers = [module.cert_manager_hetzner.solver] } module "bridge-tls" { source = "../../../modules/cluster/tls" wait_on = module.letsencrypt.installed name = "bridge" namespace = "cert-manager" # TODO: Get from cert-manager module hosts = ["bridge.fourlights.dev", "*.bridge.fourlights.dev"] k8s_config_yaml = file(module.k3s.kube_config_server_yaml) } # install rancher module "rancher" { source = "../../../modules/rancher" wait_on = module.bridge-tls.installed k8s_config_path = module.k3s.kube_config_server_yaml server_dns = local.server_dns } # install minio module "minio" { source = "../../../modules/minio" wait_on = module.rancher.installed k8s_config_yaml = file(module.k3s.kube_config_server_yaml) server_dns = local.server_dns service_name = "storage" namespace = "minio" admin = true tls = true ingressClass = "traefik" } # install vault module "vault" { source = "../../../modules/vault" wait_on = module.rancher.installed k8s_config_path = module.k3s.kube_config_server_yaml server_dns = local.server_dns service_name = "vault" namespace = "vault" aws = { access_key_id = var.aws_access_key_id secret_access_key = var.aws_secret_access_key kms_key_id = var.aws_kms_key_id region = var.aws_region } ingress = { enabled = true tls = true className = "traefik" annotations = { "kubernetes.io/ingress.class" : "traefik" "cert-manager.io/cluster-issuer" = "letsencrypt" "traefik.ingress.kubernetes.io/router.entrypoints" = "web,websecure" "traefik.ingress.kubernetes.io/router.middlewares" = "default-redirect-to-https@kubernetescrd,default-preserve-host-headers@kubernetescrd" } } } # bootstrap module "cluster-bootstrap" { source = "../../../modules/cluster/bootstrap" cluster = "management" wait_on = module.vault.installed vault_server = module.vault.vault_uri vault_root_token = module.vault.vault_root_token minio_server = module.minio.minio_server minio_access_key = module.minio.minio_access_key minio_secret_key = module.minio.minio_secret_key } # management module "cluster-management" { source = "../../../modules/cluster/management" cluster = "management" minio_server = module.minio.minio_server minio_access_key = module.cluster-bootstrap.minio_access_key minio_secret_key = module.cluster-bootstrap.minio_secret_key vault_server = module.vault.vault_uri vault_token = module.cluster-bootstrap.vault_token k8s_config_yaml = file(module.k3s.kube_config_server_yaml) ssh_private_key = local_sensitive_file.ssh_private_key_pem.content ssh_public_key = local_file.ssh_public_key_openssh.content hcloud_token = var.hcloud_token hcloud_network_id = hcloud_network.private.id vault_secret_path = module.vault.vault_local_file } resource "vault_kv_secret_v2" "rancher" { mount = "management" name = "rancher" delete_all_versions = true data_json = jsonencode({ token = module.rancher.rancher_server_admin_token }) depends_on = [module.vault.installed] } # install mijn 365zon module "mijn_365zon" { source = "../../../modules/mijn-365zon-nl" wait_on = module.rancher.installed k8s_config_path = module.k3s.kube_config_server_yaml }