# Root module: wires together the shared network and the three host modules # (one per server in docs/architecture.md). Each host module owns its own # firewall (and volume, where applicable) - see modules//main.tf. locals { # SSH to dev/prod is only permitted from the vpn server's public IP: admins must # tunnel through the VPN first, whose egress traffic is then sourced from this IP. # vpn itself can't require tunneling through itself, so it keeps # var.allowed_ssh_source_ips for direct SSH access. vpn_ssh_source_ips = ["${module.vpn.ipv4}/32"] # Rendered once and uploaded+run by every host module immediately after its # server is created - see scripts/bootstrap.sh.tftpl. bootstrap_script = templatefile("${path.module}/scripts/bootstrap.sh.tftpl", { deploy_user = var.deploy_user }) # IDs for every named key in var.ssh_key_names - installed on every server. ssh_key_ids = [for k in data.hcloud_ssh_key.main : k.id] # Every A record currently referenced by a Traefik Host() rule anywhere under # services/ - kept in sync with the actual compose files, not aspirational. # "dev.luke-else.co.uk" is a *website* served from prod (a dev-tagged build of # luke-else.co.uk), not the dev server - don't confuse the two. dns_records = [ { zone = "luke-else.co.uk", name = "@", value = module.prod.ipv4 }, { zone = "luke-else.co.uk", name = "dev", value = module.prod.ipv4 }, { zone = "luke-else.co.uk", name = "metarius", value = module.prod.ipv4 }, { zone = "luke-else.co.uk", name = "traefik", value = module.prod.ipv4 }, { zone = "luke-else.co.uk", name = "status", value = module.prod.ipv4 }, { zone = "luke-else.co.uk", name = "bitwarden", value = module.prod.ipv4 }, { zone = "luke-else.co.uk", name = "rd", value = module.prod.ipv4 }, { zone = "luke-else.co.uk", name = "git", value = module.dev.ipv4 }, { zone = "luke-else.co.uk", name = "traefik.cicd", value = module.dev.ipv4 }, { zone = "luke-else.co.uk", name = "vpn", value = module.vpn.ipv4 }, { zone = "luke-else.co.uk", name = "traefik.vpn", value = module.vpn.ipv4 }, { zone = "divine-couture.co.uk", name = "www", value = module.prod.ipv4 }, { zone = "snexo.co.uk", name = "@", value = module.prod.ipv4 }, ] } module "network" { source = "./modules/network" ip_range = var.network_ip_range network_zone = var.network_zone subnet_ip_range = var.subnet_ip_range } module "dev" { source = "./modules/dev" server_type = var.dev_server_type image = var.server_image location = var.location ssh_key_ids = local.ssh_key_ids network_id = module.network.id private_ip = var.dev_private_ip volume_size = var.dev_volume_size allowed_ssh_source_ips = local.vpn_ssh_source_ips network_ip_range = var.network_ip_range bootstrap_script = local.bootstrap_script ssh_private_key_path = var.ssh_private_key_path deploy_user = var.deploy_user runner_count = var.dev_runner_count # module.network.id alone doesn't guarantee the subnet exists yet, and a server # can't join a network before it has a subnet. depends_on = [module.network] } module "prod" { source = "./modules/prod" server_type = var.prod_server_type image = var.server_image location = var.location ssh_key_ids = local.ssh_key_ids network_id = module.network.id private_ip = var.prod_private_ip volume_size = var.prod_volume_size allowed_ssh_source_ips = local.vpn_ssh_source_ips network_ip_range = var.network_ip_range bootstrap_script = local.bootstrap_script ssh_private_key_path = var.ssh_private_key_path deploy_user = var.deploy_user depends_on = [module.network] } module "vpn" { source = "./modules/vpn" server_type = var.vpn_server_type image = var.server_image location = var.location ssh_key_ids = local.ssh_key_ids allowed_ssh_source_ips = var.allowed_ssh_source_ips bootstrap_script = local.bootstrap_script ssh_private_key_path = var.ssh_private_key_path deploy_user = var.deploy_user } module "dns" { source = "./modules/dns" zone_names = var.dns_zones records = local.dns_records }