Luigit
repositories / bugabinga.net

bugabinga.net

personal infrastructure for bugabinga!

owned by admin

modules/klops/main.tf

Raw
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
}