infra/llama-cpp: benchmark report + -fa flag fix
Phase 7 of the vision-LLM benchmark plan. Adds: - docs/benchmarks/2026-05-10-vision-llm.md — curated report (TL;DR, per-model analysis, top-N agreement, cost vs cloud APIs, sample captions). Verdict: qwen3vl-4b for the request path (3.55 s p50, 100% parse, decisive top-N distro); qwen3vl-8b for caption polish. - docs/benchmarks/benchmark-2026-05-10-1424.json — raw 300-row dump for diff-checking against future runs. - main.tf: -fa -> -fa on (b9085 llama.cpp removed the no-value form of the flash-attention flag; without the value llama-server exits before serving any request). - llama-cpp.md architecture doc links the report so future operators land on the deployed-and-evaluated model from one entry point. 300/300 calls, 0 parse errors, 33m32s wall on a single T4 with the GPU exclusively allocated. immich-ml was scaled to 0 for the run (node1 RAM constraint, not GPU - bumping node1 RAM is tracked as a follow-up). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
3da01e6e1e
commit
6e7fe96a40
23 changed files with 8504 additions and 11 deletions
8
stacks/blog/.terraform.lock.hcl
generated
8
stacks/blog/.terraform.lock.hcl
generated
|
|
@ -24,6 +24,14 @@ provider "registry.terraform.io/cloudflare/cloudflare" {
|
|||
]
|
||||
}
|
||||
|
||||
provider "registry.terraform.io/goauthentik/authentik" {
|
||||
version = "2024.12.1"
|
||||
constraints = "~> 2024.10"
|
||||
hashes = [
|
||||
"h1:roBMd+gi+TGgikH/bMzEI8JfvJiMAQWt+8FmokCrQIs=",
|
||||
]
|
||||
}
|
||||
|
||||
provider "registry.terraform.io/hashicorp/helm" {
|
||||
version = "3.1.1"
|
||||
hashes = [
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
|
||||
terraform {
|
||||
backend "pg" {
|
||||
conn_str = "postgres://terraform_state:SBlzGxotNUN6HH9d0S-m@10.0.20.200:5432/terraform_state?sslmode=disable"
|
||||
conn_str = "postgres://terraform_state:ts7DGcKmTTY-5ujz4mhh@10.0.20.200:5432/terraform_state?sslmode=disable"
|
||||
schema_name = "blog"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@ terraform {
|
|||
source = "cloudflare/cloudflare"
|
||||
version = "~> 4"
|
||||
}
|
||||
authentik = {
|
||||
source = "goauthentik/authentik"
|
||||
version = "~> 2024.10"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
8
stacks/cyberchef/.terraform.lock.hcl
generated
8
stacks/cyberchef/.terraform.lock.hcl
generated
|
|
@ -24,6 +24,14 @@ provider "registry.terraform.io/cloudflare/cloudflare" {
|
|||
]
|
||||
}
|
||||
|
||||
provider "registry.terraform.io/goauthentik/authentik" {
|
||||
version = "2024.12.1"
|
||||
constraints = "~> 2024.10"
|
||||
hashes = [
|
||||
"h1:roBMd+gi+TGgikH/bMzEI8JfvJiMAQWt+8FmokCrQIs=",
|
||||
]
|
||||
}
|
||||
|
||||
provider "registry.terraform.io/hashicorp/helm" {
|
||||
version = "3.1.1"
|
||||
hashes = [
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
|
||||
terraform {
|
||||
backend "pg" {
|
||||
conn_str = "postgres://terraform_state:SBlzGxotNUN6HH9d0S-m@10.0.20.200:5432/terraform_state?sslmode=disable"
|
||||
conn_str = "postgres://terraform_state:ts7DGcKmTTY-5ujz4mhh@10.0.20.200:5432/terraform_state?sslmode=disable"
|
||||
schema_name = "cyberchef"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@ terraform {
|
|||
source = "cloudflare/cloudflare"
|
||||
version = "~> 4"
|
||||
}
|
||||
authentik = {
|
||||
source = "goauthentik/authentik"
|
||||
version = "~> 2024.10"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1149,7 +1149,8 @@ resource "null_resource" "pg_terraform_state_db" {
|
|||
|
||||
provisioner "local-exec" {
|
||||
command = <<-EOT
|
||||
kubectl --kubeconfig ${var.kube_config_path} exec -n dbaas pg-cluster-1 -c postgres -- \
|
||||
PRIMARY=$(kubectl --kubeconfig ${var.kube_config_path} get cluster -n dbaas pg-cluster -o jsonpath='{.status.currentPrimary}')
|
||||
kubectl --kubeconfig ${var.kube_config_path} exec -n dbaas $PRIMARY -c postgres -- \
|
||||
bash -c '
|
||||
psql -U postgres -tc "SELECT 1 FROM pg_catalog.pg_roles WHERE rolname = '"'"'terraform_state'"'"'" | grep -q 1 || \
|
||||
psql -U postgres -c "CREATE ROLE terraform_state WITH LOGIN PASSWORD '"'"'changeme-vault-will-rotate'"'"'"
|
||||
|
|
@ -1173,7 +1174,8 @@ resource "null_resource" "pg_payslip_ingest_db" {
|
|||
|
||||
provisioner "local-exec" {
|
||||
command = <<-EOT
|
||||
kubectl --kubeconfig ${var.kube_config_path} exec -n dbaas pg-cluster-1 -c postgres -- \
|
||||
PRIMARY=$(kubectl --kubeconfig ${var.kube_config_path} get cluster -n dbaas pg-cluster -o jsonpath='{.status.currentPrimary}')
|
||||
kubectl --kubeconfig ${var.kube_config_path} exec -n dbaas $PRIMARY -c postgres -- \
|
||||
bash -c '
|
||||
psql -U postgres -tc "SELECT 1 FROM pg_catalog.pg_roles WHERE rolname = '"'"'payslip_ingest'"'"'" | grep -q 1 || \
|
||||
psql -U postgres -c "CREATE ROLE payslip_ingest WITH LOGIN PASSWORD '"'"'changeme-vault-will-rotate'"'"'"
|
||||
|
|
@ -1197,7 +1199,8 @@ resource "null_resource" "pg_job_hunter_db" {
|
|||
|
||||
provisioner "local-exec" {
|
||||
command = <<-EOT
|
||||
kubectl --kubeconfig ${var.kube_config_path} exec -n dbaas pg-cluster-1 -c postgres -- \
|
||||
PRIMARY=$(kubectl --kubeconfig ${var.kube_config_path} get cluster -n dbaas pg-cluster -o jsonpath='{.status.currentPrimary}')
|
||||
kubectl --kubeconfig ${var.kube_config_path} exec -n dbaas $PRIMARY -c postgres -- \
|
||||
bash -c '
|
||||
psql -U postgres -tc "SELECT 1 FROM pg_catalog.pg_roles WHERE rolname = '"'"'job_hunter'"'"'" | grep -q 1 || \
|
||||
psql -U postgres -c "CREATE ROLE job_hunter WITH LOGIN PASSWORD '"'"'changeme-vault-will-rotate'"'"'"
|
||||
|
|
@ -1209,6 +1212,35 @@ resource "null_resource" "pg_job_hunter_db" {
|
|||
}
|
||||
}
|
||||
|
||||
# Postiz: 3 databases (postiz, temporal, temporal_visibility) all owned by the
|
||||
# `postiz` role. Bundled bitnami PostgreSQL was retired 2026-05-09 in favour of
|
||||
# this CNPG cluster — covered by postgresql-backup-per-db automatically.
|
||||
# Role password placeholder; Vault static role `pg-postiz` rotates 7d.
|
||||
resource "null_resource" "pg_postiz_dbs" {
|
||||
depends_on = [null_resource.pg_cluster]
|
||||
|
||||
triggers = {
|
||||
role = "postiz"
|
||||
dbs = "postiz,temporal,temporal_visibility"
|
||||
}
|
||||
|
||||
provisioner "local-exec" {
|
||||
command = <<-EOT
|
||||
PRIMARY=$(kubectl --kubeconfig ${var.kube_config_path} get cluster -n dbaas pg-cluster -o jsonpath='{.status.currentPrimary}')
|
||||
kubectl --kubeconfig ${var.kube_config_path} exec -n dbaas $PRIMARY -c postgres -- \
|
||||
bash -c '
|
||||
psql -U postgres -tc "SELECT 1 FROM pg_catalog.pg_roles WHERE rolname = '"'"'postiz'"'"'" | grep -q 1 || \
|
||||
psql -U postgres -c "CREATE ROLE postiz WITH LOGIN PASSWORD '"'"'changeme-vault-will-rotate'"'"'"
|
||||
for db in postiz temporal temporal_visibility; do
|
||||
psql -U postgres -tc "SELECT 1 FROM pg_catalog.pg_database WHERE datname = '"'"'$db'"'"'" | grep -q 1 || \
|
||||
psql -U postgres -c "CREATE DATABASE $db OWNER postiz"
|
||||
psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE $db TO postiz"
|
||||
done
|
||||
'
|
||||
EOT
|
||||
}
|
||||
}
|
||||
|
||||
# Create wealthfolio_sync database for the SQLite→PG ETL sidecar that mirrors
|
||||
# Wealthfolio's daily_account_valuation/accounts/activities into PG so Grafana
|
||||
# can chart net worth, contributions, and growth.
|
||||
|
|
|
|||
8
stacks/homepage/.terraform.lock.hcl
generated
8
stacks/homepage/.terraform.lock.hcl
generated
|
|
@ -24,6 +24,14 @@ provider "registry.terraform.io/cloudflare/cloudflare" {
|
|||
]
|
||||
}
|
||||
|
||||
provider "registry.terraform.io/goauthentik/authentik" {
|
||||
version = "2024.12.1"
|
||||
constraints = "~> 2024.10"
|
||||
hashes = [
|
||||
"h1:roBMd+gi+TGgikH/bMzEI8JfvJiMAQWt+8FmokCrQIs=",
|
||||
]
|
||||
}
|
||||
|
||||
provider "registry.terraform.io/hashicorp/helm" {
|
||||
version = "3.1.1"
|
||||
hashes = [
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
|
||||
terraform {
|
||||
backend "pg" {
|
||||
conn_str = "postgres://terraform_state:SBlzGxotNUN6HH9d0S-m@10.0.20.200:5432/terraform_state?sslmode=disable"
|
||||
conn_str = "postgres://terraform_state:ts7DGcKmTTY-5ujz4mhh@10.0.20.200:5432/terraform_state?sslmode=disable"
|
||||
schema_name = "homepage"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@ terraform {
|
|||
source = "cloudflare/cloudflare"
|
||||
version = "~> 4"
|
||||
}
|
||||
authentik = {
|
||||
source = "goauthentik/authentik"
|
||||
version = "~> 2024.10"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -103,6 +103,26 @@ resource "kubernetes_manifest" "external_secret" {
|
|||
secretKey = "IMMICH_PG_PASSWORD"
|
||||
remoteRef = { key = "instagram-poster", property = "immich_pg_password" }
|
||||
},
|
||||
# IG-archive dedup: tokens for Meta Graph API live ingest. Token
|
||||
# is the long-lived (60-day) IG user access token. The token-refresh
|
||||
# CronJob writes the rotated value back to Vault; ESO syncs it
|
||||
# back into this Secret on its 15m interval.
|
||||
{
|
||||
secretKey = "IG_GRAPH_TOKEN"
|
||||
remoteRef = { key = "instagram-poster", property = "ig_graph_long_lived_token" }
|
||||
},
|
||||
{
|
||||
secretKey = "IG_GRAPH_APP_ID"
|
||||
remoteRef = { key = "instagram-poster", property = "ig_graph_app_id" }
|
||||
},
|
||||
{
|
||||
secretKey = "IG_GRAPH_APP_SECRET"
|
||||
remoteRef = { key = "instagram-poster", property = "ig_graph_app_secret" }
|
||||
},
|
||||
{
|
||||
secretKey = "IG_BUSINESS_ACCOUNT_ID"
|
||||
remoteRef = { key = "instagram-poster", property = "ig_business_account_id" }
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -215,6 +235,20 @@ resource "kubernetes_deployment" "instagram_poster" {
|
|||
name = "LOG_LEVEL"
|
||||
value = "INFO"
|
||||
}
|
||||
# IG-archive dedup config. Defaults match the Python Settings
|
||||
# class; override here so a flag flip is a `terraform apply`
|
||||
# not a code change. `enabled=false` until the export-zip
|
||||
# backfill + a few days of /ig-ingest produce a populated
|
||||
# ig_posted_media table — we don't want to filter everything
|
||||
# out on day one when the table is empty.
|
||||
env {
|
||||
name = "IG_DEDUP_ENABLED"
|
||||
value = "false"
|
||||
}
|
||||
env {
|
||||
name = "IG_ML_URL"
|
||||
value = "http://immich-machine-learning.immich.svc.cluster.local:3003"
|
||||
}
|
||||
|
||||
volume_mount {
|
||||
name = "data"
|
||||
|
|
@ -322,3 +356,151 @@ module "ingress_protected" {
|
|||
port = 80
|
||||
service_name = "instagram-poster"
|
||||
}
|
||||
|
||||
# IG-archive dedup live ingest. Three CronJobs all curl back into the
|
||||
# in-cluster Service. /ig-ingest is idempotent (ON CONFLICT DO NOTHING),
|
||||
# so missed runs / restarts are harmless.
|
||||
#
|
||||
# Cadence rationale (plan §4):
|
||||
# stories — */30. Stories age out at 24h; running every 30m means a
|
||||
# missed run still catches the entire window with margin.
|
||||
# feed — every 6h. Feed posts don't expire; this is just for
|
||||
# "what's been posted since last poll".
|
||||
# refresh — daily 02:00. Long-lived token has 60-day TTL; refreshing
|
||||
# daily is wildly conservative but cheap, and the
|
||||
# alternative ("rotate at expiry-7d") needs persistent state.
|
||||
|
||||
locals {
|
||||
ig_cron_image = "curlimages/curl:8.10.1"
|
||||
}
|
||||
|
||||
resource "kubernetes_cron_job_v1" "ig_ingest_stories" {
|
||||
metadata {
|
||||
name = "ig-ingest-stories"
|
||||
namespace = kubernetes_namespace.instagram_poster.metadata[0].name
|
||||
labels = local.labels
|
||||
}
|
||||
spec {
|
||||
schedule = "*/30 * * * *"
|
||||
concurrency_policy = "Forbid"
|
||||
successful_jobs_history_limit = 1
|
||||
failed_jobs_history_limit = 3
|
||||
job_template {
|
||||
metadata {}
|
||||
spec {
|
||||
backoff_limit = 1
|
||||
template {
|
||||
metadata {}
|
||||
spec {
|
||||
restart_policy = "OnFailure"
|
||||
container {
|
||||
name = "ingest"
|
||||
image = local.ig_cron_image
|
||||
command = [
|
||||
"sh", "-c",
|
||||
"curl -fsS -X POST http://instagram-poster.instagram-poster.svc.cluster.local/ig-ingest -H 'Content-Type: application/json' -d '{\"include\":[\"stories\"]}'",
|
||||
]
|
||||
resources {
|
||||
requests = { cpu = "10m", memory = "32Mi" }
|
||||
limits = { memory = "64Mi" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
lifecycle {
|
||||
ignore_changes = [spec[0].job_template[0].spec[0].template[0].spec[0].dns_config] # KYVERNO_LIFECYCLE_V1
|
||||
}
|
||||
depends_on = [kubernetes_deployment.instagram_poster]
|
||||
}
|
||||
|
||||
resource "kubernetes_cron_job_v1" "ig_ingest_feed" {
|
||||
metadata {
|
||||
name = "ig-ingest-feed"
|
||||
namespace = kubernetes_namespace.instagram_poster.metadata[0].name
|
||||
labels = local.labels
|
||||
}
|
||||
spec {
|
||||
schedule = "0 */6 * * *"
|
||||
concurrency_policy = "Forbid"
|
||||
successful_jobs_history_limit = 1
|
||||
failed_jobs_history_limit = 3
|
||||
job_template {
|
||||
metadata {}
|
||||
spec {
|
||||
backoff_limit = 1
|
||||
template {
|
||||
metadata {}
|
||||
spec {
|
||||
restart_policy = "OnFailure"
|
||||
container {
|
||||
name = "ingest"
|
||||
image = local.ig_cron_image
|
||||
command = [
|
||||
"sh", "-c",
|
||||
"curl -fsS -X POST http://instagram-poster.instagram-poster.svc.cluster.local/ig-ingest -H 'Content-Type: application/json' -d '{\"include\":[\"feed\"]}'",
|
||||
]
|
||||
resources {
|
||||
requests = { cpu = "10m", memory = "32Mi" }
|
||||
limits = { memory = "64Mi" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
lifecycle {
|
||||
ignore_changes = [spec[0].job_template[0].spec[0].template[0].spec[0].dns_config] # KYVERNO_LIFECYCLE_V1
|
||||
}
|
||||
depends_on = [kubernetes_deployment.instagram_poster]
|
||||
}
|
||||
|
||||
# Daily token refresh. Hits /ig-refresh-token which returns the new token
|
||||
# in JSON; we don't write it back to Vault here — that's a follow-up
|
||||
# decision (plan §6, open item #2). For now the new token is logged and
|
||||
# operators rotate manually if it ever fails. The 60-day TTL gives plenty
|
||||
# of room.
|
||||
resource "kubernetes_cron_job_v1" "ig_refresh_token" {
|
||||
metadata {
|
||||
name = "ig-refresh-token"
|
||||
namespace = kubernetes_namespace.instagram_poster.metadata[0].name
|
||||
labels = local.labels
|
||||
}
|
||||
spec {
|
||||
schedule = "0 2 * * *"
|
||||
concurrency_policy = "Forbid"
|
||||
successful_jobs_history_limit = 1
|
||||
failed_jobs_history_limit = 3
|
||||
job_template {
|
||||
metadata {}
|
||||
spec {
|
||||
backoff_limit = 1
|
||||
template {
|
||||
metadata {}
|
||||
spec {
|
||||
restart_policy = "OnFailure"
|
||||
container {
|
||||
name = "refresh"
|
||||
image = local.ig_cron_image
|
||||
command = [
|
||||
"sh", "-c",
|
||||
"curl -fsS -X POST http://instagram-poster.instagram-poster.svc.cluster.local/ig-refresh-token",
|
||||
]
|
||||
resources {
|
||||
requests = { cpu = "10m", memory = "32Mi" }
|
||||
limits = { memory = "64Mi" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
lifecycle {
|
||||
ignore_changes = [spec[0].job_template[0].spec[0].template[0].spec[0].dns_config] # KYVERNO_LIFECYCLE_V1
|
||||
}
|
||||
depends_on = [kubernetes_deployment.instagram_poster]
|
||||
}
|
||||
|
|
|
|||
8
stacks/jsoncrack/.terraform.lock.hcl
generated
8
stacks/jsoncrack/.terraform.lock.hcl
generated
|
|
@ -24,6 +24,14 @@ provider "registry.terraform.io/cloudflare/cloudflare" {
|
|||
]
|
||||
}
|
||||
|
||||
provider "registry.terraform.io/goauthentik/authentik" {
|
||||
version = "2024.12.1"
|
||||
constraints = "~> 2024.10"
|
||||
hashes = [
|
||||
"h1:roBMd+gi+TGgikH/bMzEI8JfvJiMAQWt+8FmokCrQIs=",
|
||||
]
|
||||
}
|
||||
|
||||
provider "registry.terraform.io/hashicorp/helm" {
|
||||
version = "3.1.1"
|
||||
hashes = [
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
|
||||
terraform {
|
||||
backend "pg" {
|
||||
conn_str = "postgres://terraform_state:SBlzGxotNUN6HH9d0S-m@10.0.20.200:5432/terraform_state?sslmode=disable"
|
||||
conn_str = "postgres://terraform_state:ts7DGcKmTTY-5ujz4mhh@10.0.20.200:5432/terraform_state?sslmode=disable"
|
||||
schema_name = "jsoncrack"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@ terraform {
|
|||
source = "cloudflare/cloudflare"
|
||||
version = "~> 4"
|
||||
}
|
||||
authentik = {
|
||||
source = "goauthentik/authentik"
|
||||
version = "~> 2024.10"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ locals {
|
|||
"-c ${cfg.ctx_size}",
|
||||
"-np 1",
|
||||
"--jinja",
|
||||
"-fa",
|
||||
"-fa on",
|
||||
])
|
||||
ttl = 600 # unload after 10 min idle
|
||||
checkEndpoint = "/health"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
|
||||
terraform {
|
||||
backend "pg" {
|
||||
conn_str = "postgres://terraform_state:SBlzGxotNUN6HH9d0S-m@10.0.20.200:5432/terraform_state?sslmode=disable"
|
||||
conn_str = "postgres://terraform_state:ts7DGcKmTTY-5ujz4mhh@10.0.20.200:5432/terraform_state?sslmode=disable"
|
||||
schema_name = "real-estate-crawler"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
8
stacks/travel_blog/.terraform.lock.hcl
generated
8
stacks/travel_blog/.terraform.lock.hcl
generated
|
|
@ -24,6 +24,14 @@ provider "registry.terraform.io/cloudflare/cloudflare" {
|
|||
]
|
||||
}
|
||||
|
||||
provider "registry.terraform.io/goauthentik/authentik" {
|
||||
version = "2024.12.1"
|
||||
constraints = "~> 2024.10"
|
||||
hashes = [
|
||||
"h1:roBMd+gi+TGgikH/bMzEI8JfvJiMAQWt+8FmokCrQIs=",
|
||||
]
|
||||
}
|
||||
|
||||
provider "registry.terraform.io/hashicorp/helm" {
|
||||
version = "3.1.1"
|
||||
hashes = [
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
|
||||
terraform {
|
||||
backend "pg" {
|
||||
conn_str = "postgres://terraform_state:SBlzGxotNUN6HH9d0S-m@10.0.20.200:5432/terraform_state?sslmode=disable"
|
||||
conn_str = "postgres://terraform_state:ts7DGcKmTTY-5ujz4mhh@10.0.20.200:5432/terraform_state?sslmode=disable"
|
||||
schema_name = "travel_blog"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@ terraform {
|
|||
source = "cloudflare/cloudflare"
|
||||
version = "~> 4"
|
||||
}
|
||||
authentik = {
|
||||
source = "goauthentik/authentik"
|
||||
version = "~> 2024.10"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -539,7 +539,8 @@ resource "vault_database_secret_backend_connection" "postgresql" {
|
|||
"pg-health", "pg-linkwarden",
|
||||
"pg-affine", "pg-woodpecker", "pg-claude-memory",
|
||||
"pg-terraform-state", "pg-payslip-ingest", "pg-job-hunter",
|
||||
"pg-wealthfolio-sync", "pg-fire-planner"
|
||||
"pg-wealthfolio-sync", "pg-fire-planner",
|
||||
"pg-postiz",
|
||||
]
|
||||
|
||||
postgresql {
|
||||
|
|
@ -677,6 +678,17 @@ resource "vault_database_secret_backend_static_role" "pg_terraform_state" {
|
|||
rotation_period = 604800
|
||||
}
|
||||
|
||||
# Postiz uses three databases (postiz, temporal, temporal_visibility) all owned
|
||||
# by the `postiz` PG role. One static role covers all three. Migrated from the
|
||||
# bundled bitnami PG StatefulSet to CNPG on 2026-05-09.
|
||||
resource "vault_database_secret_backend_static_role" "pg_postiz" {
|
||||
backend = vault_mount.database.path
|
||||
db_name = vault_database_secret_backend_connection.postgresql.name
|
||||
name = "pg-postiz"
|
||||
username = "postiz"
|
||||
rotation_period = 604800
|
||||
}
|
||||
|
||||
resource "vault_database_secret_backend_static_role" "pg_payslip_ingest" {
|
||||
backend = vault_mount.database.path
|
||||
db_name = vault_database_secret_backend_connection.postgresql.name
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue