resource "local_file" "klops_wg0_conf" { content = templatefile("${path.module}/templates/wg0.conf.tftpl", { private_key = var.wg_peer_private_key address = "${var.wg_peer_ip}/24" ipv4_host = var.wg_peer_ip ipv6_address = "${var.wg_peer_ipv6}/64" ipv6_host = var.wg_peer_ipv6 listen_port = 51820 mtu = var.wg_mtu server_public_key = var.wg_server_public_key server_endpoint = var.wg_server_endpoint server_endpoint_port = var.wg_server_endpoint_port endpoint_route = var.wg_server_endpoint allowed_ips = var.wg_allowed_ips persistent_keepalive = 25 }) filename = "${path.module}/generated/klops-wg0.conf" } resource "local_file" "klops_caddyfile" { content = file("${path.module}/templates/Caddyfile.tftpl") filename = "${path.module}/generated/Caddyfile" } resource "local_file" "klops_ddns_quadlet" { content = templatefile("${path.module}/templates/ddns.container.tftpl", { relay_ipv4 = var.relay_ipv4 relay_ipv6 = var.relay_ipv6 }) filename = "${path.module}/generated/ddns.container" } resource "local_file" "klops_soft_serve_env" { content = templatefile("${path.module}/templates/soft-serve.env.tftpl", { base_domain = var.base_domain initial_admin_key = var.soft_serve_initial_admin_key }) filename = "${path.module}/generated/soft-serve.env" file_permission = "0600" } resource "local_file" "klops_soft_serve_quadlet" { content = templatefile("${path.module}/templates/soft-serve.container.tftpl", { vcs_ssh_peer_port = var.vcs_ssh_peer_port }) filename = "${path.module}/generated/soft-serve.container" file_permission = "0644" } resource "local_file" "klops_luci_quadlet" { content = templatefile("${path.module}/templates/luci.container.tftpl", { luci_ssh_peer_port = var.luci_ssh_peer_port }) filename = "${path.module}/generated/luci.container" file_permission = "0644" } resource "local_file" "klops_zot_config" { content = templatefile("${path.module}/templates/zot.config.json.tftpl", { base_domain = var.base_domain }) filename = "${path.module}/generated/zot.config.json" file_permission = "0644" } resource "local_file" "klops_zot_htpasswd" { content = var.zot_htpasswd_content filename = "${path.module}/generated/zot.htpasswd" file_permission = "0600" } resource "local_sensitive_file" "klops_hallucygenie_env" { content = "MINIMAX_API_KEY=${var.hallucygenie_minimax_api_key}\n" filename = "${path.module}/generated/hallucygenie.env" file_permission = "0600" } resource "local_sensitive_file" "klops_hallucygenie_basic_auth" { content = "basic_auth {\n${var.hallucygenie_basic_auth_users}\n}\n" filename = "${path.module}/generated/genie-basicauth.caddy" file_permission = "0600" } resource "local_sensitive_file" "klops_toad_basic_auth" { content = "basic_auth {\n${var.toad_basic_auth_users}\n}\n" filename = "${path.module}/generated/toad-basicauth.caddy" file_permission = "0600" } resource "local_sensitive_file" "klops_paperless_env" { content = "PAPERLESS_SECRET_KEY=${var.paperless_secret_key}\n" filename = "${path.module}/generated/paperless.env" file_permission = "0600" } resource "local_sensitive_file" "klops_quest_log_env" { content = "QUEST_LOG_EDITOR_PASSWORD_HASH=${var.quest_log_editor_password_hash}\n" filename = "${path.module}/generated/quest-log.env" file_permission = "0600" } locals { brand_svg_hash = filesha256("${path.root}/assets/bugabinga.min.svg") nugu_css_hash = filesha256("${path.root}/assets/nugu.css") app_theme_hash = filesha256("${path.root}/assets/jellyfin-branding.xml") registry_zui_css_hash = filesha256("${path.root}/assets/registry/index-BAkATJzA.css") dawarich_js_hash = filesha256("${path.root}/assets/dawarich/application-b5a7662b4bd877f1de1fe5769d2b98adfa15a8095b784d392ae1154df6f3b865.js") homepage_config_files = { "bookmarks.yaml" = templatefile("${path.module}/templates/homepage/bookmarks.yaml.tftpl", { base_domain = var.base_domain }) "custom.css" = templatefile("${path.module}/templates/homepage/custom.css.tftpl", {}) "custom.js" = templatefile("${path.module}/templates/homepage/custom.js.tftpl", {}) "docker.yaml" = templatefile("${path.module}/templates/homepage/docker.yaml.tftpl", {}) "services.yaml" = templatefile("${path.module}/templates/homepage/services.yaml.tftpl", { base_domain = var.base_domain enable_jellyfin_widget = nonsensitive(var.homepage_jellyfin_api_key) != "" enable_paperless_widget = nonsensitive(var.homepage_paperless_api_token) != "" }) "settings.yaml" = templatefile("${path.module}/templates/homepage/settings.yaml.tftpl", { base_domain = var.base_domain }) "widgets.yaml" = templatefile("${path.module}/templates/homepage/widgets.yaml.tftpl", { base_domain = var.base_domain }) } homepage_config_hash = md5(join("", [ for filename, content in local.homepage_config_files : sha256("${filename}:${content}") ])) luigit_source_hash = md5(join("", concat([ for f in fileset("${path.root}/services/luigit", "Cargo.*") : filesha256("${path.root}/services/luigit/${f}") ], [ for f in fileset("${path.root}/services/luigit", "src/**") : filesha256("${path.root}/services/luigit/${f}") ], [ for f in fileset("${path.root}/services/luigit", "assets/**") : filesha256("${path.root}/services/luigit/${f}") ], [ filesha256("${path.root}/services/luigit/Containerfile"), filesha256("${path.root}/services/luigit/THIRD_PARTY.md") ]))) quadlets_hash = md5(join("", concat([ for f in fileset("${path.module}/quadlets/", "*") : filesha256("${path.module}/quadlets/${f}") ], [ sha256(local.luigit_source_hash), sha256(local_file.klops_ddns_quadlet.content), nonsensitive(sha256(local_file.klops_soft_serve_env.content)), sha256(local_file.klops_soft_serve_quadlet.content), sha256(local_file.klops_zot_config.content), nonsensitive(sha256(local_file.klops_zot_htpasswd.content)), local_sensitive_file.klops_hallucygenie_env.id, local_sensitive_file.klops_hallucygenie_basic_auth.id, local_sensitive_file.klops_toad_basic_auth.id, local_sensitive_file.klops_paperless_env.id, local_sensitive_file.klops_quest_log_env.id ]))) ci_quadlets_hash = md5(join("", concat([ for f in fileset("${path.module}/ci-quadlets/", "*") : filesha256("${path.module}/ci-quadlets/${f}") ], [ sha256(local_file.klops_luci_quadlet.content) ]))) site_index_hash = md5(join("", [ for f in fileset("${path.root}/sites/index", "**") : filesha256("${path.root}/sites/index/${f}") ])) personal_site_hash = md5(join("", concat([ for f in fileset("${path.root}/sites/personal", "**") : filesha256("${path.root}/sites/personal/${f}") ], [local.brand_svg_hash]))) genie_site_hash = md5(join("", concat([ for f in fileset("${path.root}/sites/genie", "**") : filesha256("${path.root}/sites/genie/${f}") ], [local.brand_svg_hash]))) deployment_script_files = concat( ["local/klops.sh"], [for f in fileset("${path.root}/scripts/remote/", "*.sh") : "remote/${f}"] ) deployment_scripts_hash = md5(join("", [ for f in local.deployment_script_files : filesha256("${path.root}/scripts/${f}") ])) } resource "local_file" "homepage_config" { for_each = local.homepage_config_files content = each.value filename = "${path.module}/generated/homepage/${each.key}" } resource "local_sensitive_file" "homepage_env" { content = templatefile("${path.module}/templates/homepage/homepage.env.tftpl", { jellyfin_api_key = var.homepage_jellyfin_api_key paperless_token = var.homepage_paperless_api_token }) filename = "${path.module}/generated/homepage/homepage.env" file_permission = "0600" } resource "null_resource" "klops_setup" { count = var.klops_ssh_host != "" ? 1 : 0 triggers = { wg_config_hash = md5(local_file.klops_wg0_conf.content) deployment_script_hash = local.deployment_scripts_hash } provisioner "local-exec" { interpreter = ["/bin/bash", "-c"] command = "${abspath(path.root)}/scripts/local/klops.sh wg ${var.klops_ssh_host} ${var.klops_ssh_port} ${local_file.klops_wg0_conf.filename}" } } resource "null_resource" "klops_homepage_config" { count = var.klops_ssh_host != "" ? 1 : 0 depends_on = [ local_file.homepage_config, local_sensitive_file.homepage_env, ] triggers = { homepage_config_hash = local.homepage_config_hash homepage_env_hash = local_sensitive_file.homepage_env.id homepage_icon_hash = local.brand_svg_hash nugu_css_hash = local.nugu_css_hash deployment_script_hash = local.deployment_scripts_hash } provisioner "local-exec" { interpreter = ["/bin/bash", "-c"] command = "${abspath(path.root)}/scripts/local/klops.sh homepage ${var.klops_ssh_host} ${var.klops_ssh_port} ${var.klops_ssh_user} ${abspath(path.module)}/generated/homepage ${abspath(path.root)}/assets/bugabinga.min.svg" } } resource "null_resource" "klops_quadlets" { count = var.klops_ssh_host != "" ? 1 : 0 depends_on = [ null_resource.klops_homepage_config, null_resource.klops_ci, null_resource.klops_toad, ] triggers = { quadlets_hash = local.quadlets_hash brand_svg_hash = local.brand_svg_hash nugu_css_hash = local.nugu_css_hash app_theme_hash = local.app_theme_hash registry_zui_css_hash = local.registry_zui_css_hash dawarich_js_hash = local.dawarich_js_hash deployment_logic_hash = filesha256("${path.module}/main.tf") deployment_script_hash = local.deployment_scripts_hash } provisioner "local-exec" { interpreter = ["/bin/bash", "-c"] command = "${abspath(path.root)}/scripts/local/klops.sh quadlets ${var.klops_ssh_host} ${var.klops_ssh_port} ${var.klops_ssh_user} ${abspath(path.module)}/quadlets ${abspath(path.root)}/services/luigit ${local_file.klops_ddns_quadlet.filename} ${local_file.klops_soft_serve_quadlet.filename} ${local_file.klops_soft_serve_env.filename} ${local_file.klops_zot_config.filename} ${local_file.klops_zot_htpasswd.filename} ${abspath(path.module)}/generated/hallucygenie.env ${abspath(path.module)}/generated/genie-basicauth.caddy ${abspath(path.module)}/generated/toad-basicauth.caddy ${abspath(path.module)}/generated/paperless.env ${abspath(path.module)}/generated/quest-log.env ${abspath(path.root)}/scripts/remote/restart-klops-quadlets.sh" } } resource "null_resource" "klops_site_index" { count = var.klops_ssh_host != "" ? 1 : 0 depends_on = [null_resource.klops_ci] triggers = { site_index_hash = local.site_index_hash nugu_css_hash = local.nugu_css_hash deployment_script_hash = local.deployment_scripts_hash } provisioner "local-exec" { interpreter = ["/bin/bash", "-c"] command = "${abspath(path.root)}/scripts/local/klops.sh site-index ${var.klops_ssh_host} ${var.klops_ssh_port} ${var.klops_ssh_user} ${abspath(path.root)}/sites/index" } } resource "null_resource" "klops_personal_site" { count = var.klops_ssh_host != "" ? 1 : 0 depends_on = [null_resource.klops_ci] triggers = { personal_site_hash = local.personal_site_hash nugu_css_hash = local.nugu_css_hash deployment_script_hash = local.deployment_scripts_hash } provisioner "local-exec" { interpreter = ["/bin/bash", "-c"] command = "${abspath(path.root)}/scripts/local/klops.sh site ${var.klops_ssh_host} ${var.klops_ssh_port} ${var.klops_ssh_user} ${abspath(path.root)}/sites/personal personal" } } resource "null_resource" "klops_genie_site" { count = var.klops_ssh_host != "" ? 1 : 0 depends_on = [null_resource.klops_ci] triggers = { genie_site_hash = local.genie_site_hash nugu_css_hash = local.nugu_css_hash deployment_script_hash = local.deployment_scripts_hash } provisioner "local-exec" { interpreter = ["/bin/bash", "-c"] command = "${abspath(path.root)}/scripts/local/klops.sh site ${var.klops_ssh_host} ${var.klops_ssh_port} ${var.klops_ssh_user} ${abspath(path.root)}/sites/genie genie" } } resource "null_resource" "klops_ci" { count = var.klops_ssh_host != "" ? 1 : 0 depends_on = [null_resource.klops_setup] triggers = { ci_quadlets_hash = local.ci_quadlets_hash nugu_css_hash = local.nugu_css_hash deployment_logic_hash = filesha256("${path.module}/main.tf") deployment_script_hash = local.deployment_scripts_hash } provisioner "local-exec" { interpreter = ["/bin/bash", "-c"] command = "${abspath(path.root)}/scripts/local/klops.sh ci ${var.klops_ssh_host} ${var.klops_ssh_port} ${var.klops_ssh_user} ${abspath(path.module)}/ci-quadlets ${abspath(path.module)}/generated/luci.container" } } resource "null_resource" "klops_gc" { count = var.klops_ssh_host != "" ? 1 : 0 depends_on = [null_resource.klops_ci] triggers = { gc_policy_hash = filesha256("${path.root}/scripts/remote/setup-garbage-collection.sh") gc_check_hash = filesha256("${path.root}/scripts/remote/check-maintenance.sh") service_user = var.klops_ssh_user deployment_logic_hash = filesha256("${path.module}/main.tf") } provisioner "local-exec" { interpreter = ["/bin/bash", "-c"] command = "${abspath(path.root)}/scripts/local/klops.sh gc ${var.klops_ssh_host} ${var.klops_ssh_port} ${var.klops_ssh_user} ci toad" } } resource "null_resource" "klops_caddyfile" { count = var.klops_ssh_host != "" ? 1 : 0 depends_on = [null_resource.klops_quadlets] triggers = { caddyfile_hash = md5(local_file.klops_caddyfile.content) deployment_script_hash = local.deployment_scripts_hash } provisioner "local-exec" { interpreter = ["/bin/bash", "-c"] command = "${abspath(path.root)}/scripts/local/klops.sh caddyfile ${var.klops_ssh_host} ${var.klops_ssh_port} ${var.klops_ssh_user} ${local_file.klops_caddyfile.filename}" } } output "klops_wg_config_path" { description = "Path to generated WireGuard config" value = local_file.klops_wg0_conf.filename } output "klops_wg_config" { description = "WireGuard config content for klops" value = local_file.klops_wg0_conf.content sensitive = true }