infra/stacks/servarr/main.tf
Viktor Barzin ebc8b6588f
Some checks failed
ci/woodpecker/push/default Pipeline failed
ESO: add force_conflicts to all ExternalSecret manifests (fleet sweep)
The 2026-06-22 external-secrets v1 migration made the ESO controller the
server-side-apply owner of .spec.refreshInterval on every ExternalSecret, so any
stack defining one via kubernetes_manifest fails `terraform apply` with a
field-manager conflict the next time it's applied (instagram-poster + grafana hit
this on 2026-06-24; it was latent across the whole fleet). Add
field_manager { force_conflicts = true } to all 101 remaining ExternalSecret
manifests across 70 stacks, matching the fix already on grafana / woodpecker /
traefik / k8s-version-upgrade / instagram-poster. TF and ESO set the same value,
so it's stable (no perpetual drift). Defuses the landmine before each stack's
next apply trips it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 21:28:11 +00:00

136 lines
3.5 KiB
HCL

variable "tls_secret_name" {
type = string
sensitive = true
}
variable "nfs_server" { type = string }
resource "kubernetes_manifest" "external_secret" {
field_manager {
force_conflicts = true
}
manifest = {
apiVersion = "external-secrets.io/v1"
kind = "ExternalSecret"
metadata = {
name = "servarr-secrets"
namespace = "servarr"
}
spec = {
refreshInterval = "15m"
secretStoreRef = {
name = "vault-kv"
kind = "ClusterSecretStore"
}
target = {
name = "servarr-secrets"
}
dataFrom = [{
extract = {
key = "servarr"
}
}]
}
}
depends_on = [kubernetes_namespace.servarr]
}
data "kubernetes_secret" "eso_secrets" {
metadata {
name = "servarr-secrets"
namespace = kubernetes_namespace.servarr.metadata[0].name
}
depends_on = [kubernetes_manifest.external_secret]
}
locals {
homepage_credentials = jsondecode(data.kubernetes_secret.eso_secrets.data["homepage_credentials"])
}
resource "kubernetes_namespace" "servarr" {
metadata {
name = "servarr"
labels = {
tier = local.tiers.aux
"keel.sh/enrolled" = "true"
}
}
lifecycle {
# KYVERNO_LIFECYCLE_V1: goldilocks-vpa-auto-mode ClusterPolicy stamps this label on every namespace
ignore_changes = [metadata[0].labels["goldilocks.fairwinds.com/vpa-update-mode"]]
}
}
module "tls_secret" {
source = "../../modules/kubernetes/setup_tls_secret"
namespace = kubernetes_namespace.servarr.metadata[0].name
tls_secret_name = var.tls_secret_name
}
# module "readarr" {
# source = "./readarr"
# tls_secret_name = var.tls_secret_name
# tier = local.tiers.aux
# }
module "prowlarr" {
source = "./prowlarr"
tls_secret_name = var.tls_secret_name
tier = local.tiers.aux
nfs_server = var.nfs_server
homepage_credentials = local.homepage_credentials
}
module "qbittorrent" {
source = "./qbittorrent"
tls_secret_name = var.tls_secret_name
tier = local.tiers.aux
nfs_server = var.nfs_server
homepage_credentials = local.homepage_credentials
}
module "mam_farming" {
source = "./mam-farming"
namespace = kubernetes_namespace.servarr.metadata[0].name
depends_on = [
kubernetes_manifest.external_secret,
module.qbittorrent,
]
}
module "flaresolverr" {
source = "./flaresolverr"
tls_secret_name = var.tls_secret_name
tier = local.tiers.aux
}
# module "lidarr" {
# source = "./lidarr"
# tls_secret_name = var.tls_secret_name
# tier = local.tiers.aux
# }
# module "soulseek" {
# source = "./soulseek"
# tls_secret_name = var.tls_secret_name
# tier = local.tiers.aux
# }
module "listenarr" {
source = "./listenarr"
tls_secret_name = var.tls_secret_name
tier = local.tiers.aux
nfs_server = var.nfs_server
}
module "aiostreams" {
source = "./aiostreams"
tls_secret_name = var.tls_secret_name
aiostreams_database_connection_string = data.kubernetes_secret.eso_secrets.data["aiostreams_database_connection_string"]
tier = local.tiers.aux
nfs_server = var.nfs_server
}
# CI retrigger 2026-05-16T13:42:57+00:00 — bulk enrollment apply (pipeline #689 killed)
# CI retrigger v2 2026-05-16T13:46:35+00:00