resource "kubernetes_namespace" "gitea" { metadata { annotations = { name = "gitea" } labels = { name = "gitea" } name = "gitea" } } resource "kubernetes_secret" "gitea_mail_credentials" { metadata { name = "gitea-mail-credentials" namespace = kubernetes_namespace.gitea.metadata[0].name } data = { username = var.smtp_username password = var.smtp_password } type = "Opaque" } resource "kubernetes_service_account" "gitea_service_account" { metadata { name = "gitea-app-sa" namespace = kubernetes_namespace.gitea.metadata[0].name } automount_service_account_token = false } resource "kubernetes_service" "gitea_http" { metadata { name = "http" namespace = kubernetes_namespace.gitea.metadata[0].name } spec { port { port = 80 target_port = "http" } selector = { app = "gitea" } cluster_ip = "None" } } resource "kubernetes_ingress_v1" "gitea_ingress" { metadata { name = "gitea-ingress" namespace = kubernetes_namespace.gitea.metadata[0].name annotations = { "kubernetes.io/ingress.class" = "public" "cert-manager.io/cluster-issuer" = "letsencrypt-prod" "nginx.ingress.kubernetes.io/ssl-redirect" = "true" "nginx.ingress.kubernetes.io/proxy-body-size" = "8m" "nginx.ingress.kubernetes.io/proxy-request-buffering" = "on" "nginx.ingress.kubernetes.io/proxy-buffer-size" = "32k" "nginx.ingress.kubernetes.io/proxy-buffers-number" = "16" } } spec { tls { hosts = [var.fqdn] secret_name = "gitea-tls" } rule { host = var.fqdn http { path { backend { service { name = "http" port { number = 80 } } } } } } } } resource "kubernetes_deployment" "gitea" { depends_on = [module.gitea_database] metadata { name = "gitea-app" namespace = kubernetes_namespace.gitea.metadata[0].name } spec { selector { match_labels = { app = "gitea" } } strategy { type = "Recreate" } template { metadata { labels = { app = "gitea" } } spec { service_account_name = kubernetes_service_account.gitea_service_account.metadata[0].name container { name = "gitea" image = "gitea/gitea:${var.tag}" image_pull_policy = "Always" resources { requests = { memory = "100Mi" } limits = { memory = "300Mi" } } liveness_probe { http_get { path = "/api/healthz" port = "http" } initial_delay_seconds = 200 period_seconds = 300 success_threshold = 1 failure_threshold = 5 } readiness_probe { tcp_socket { port = "http" } initial_delay_seconds = 5 period_seconds = 10 success_threshold = 1 failure_threshold = 3 } dynamic "env" { for_each = local.gitea_env_vars content { name = env.key value = env.value } } security_context { allow_privilege_escalation = false } dynamic "env" { for_each = local.gitea_secrets content { name = env.key value_from { secret_key_ref { key = env.value.key name = env.value.name } } } } port { container_port = 3000 name = "http" } port { container_port = 22 name = "ssh" } volume_mount { mount_path = "/data" name = "persistent-storage" } } volume { name = "persistent-storage" host_path { path = local.gitea_path } } } } } } resource "kubernetes_role" "gitea_ssh_access" { metadata { name = "gitea-ssh-access" namespace = kubernetes_namespace.gitea.metadata[0].name } rule { api_groups = [""] resources = ["pods", "pods/log"] verbs = ["get", "list"] } rule { api_groups = [""] resources = ["pods/exec"] verbs = ["create"] } } resource "kubernetes_role_binding" "gitea_ssh_access" { metadata { name = "gitea-ssh-access" namespace = kubernetes_namespace.gitea.metadata[0].name } role_ref { api_group = "rbac.authorization.k8s.io" kind = "Role" name = kubernetes_role.gitea_ssh_access.metadata[0].name } subject { kind = "ServiceAccount" name = kubernetes_service_account.gitea_service_account.metadata[0].name namespace = kubernetes_namespace.gitea.metadata[0].name } } resource "kubernetes_secret" "gitea_access_token" { metadata { annotations = { "kubernetes.io/service-account.name" = kubernetes_service_account.gitea_service_account.metadata[0].name } name = "git-token" namespace = kubernetes_namespace.gitea.metadata[0].name } type = "kubernetes.io/service-account-token" wait_for_service_account_token = true }