fix(fire-planner): grafana fire-planner-pg datasource survives pw rotation
Some checks failed
ci/woodpecker/push/default Pipeline failed
Some checks failed
ci/woodpecker/push/default Pipeline failed
The fire-planner-pg Grafana datasource baked the rotating fire_planner DB
password into its provisioning ConfigMap at terraform plan-time, so on every
7-day static-role rotation the password went stale and ALL fire-planner-pg
dashboards (fire-planner, cost-of-living, and the new wealth FIRE Countdown)
silently failed with "password authentication failed for user fire_planner"
until the next stack apply.
Switch to the same live-env pattern wealth-pg / payslips-pg already use:
- new ExternalSecret grafana-fire-planner-pg-creds (monitoring ns, Reloader
match) mirrors the rotating Vault static-creds/pg-fire-planner password
- datasource ConfigMap now references $__env{FIRE_PLANNER_PG_PASSWORD}
- Grafana mounts it via envFromSecrets; reloader (auto) restarts Grafana on
rotation so the provisioned datasource never goes stale
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
35c0057d83
commit
6f042ee239
2 changed files with 52 additions and 10 deletions
|
|
@ -660,16 +660,53 @@ module "ingress_api" {
|
||||||
auth = "none"
|
auth = "none"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Plan-time read of the ESO-created K8s Secret for Grafana datasource
|
# ExternalSecret in the monitoring namespace mirroring the rotating
|
||||||
# password. First-apply gotcha: must
|
# fire_planner DB password. Grafana mounts this via envFromSecrets in
|
||||||
# `terragrunt apply -target=kubernetes_manifest.db_external_secret` so
|
# monitoring/grafana_chart_values.yaml; the datasource ConfigMap below
|
||||||
# the Secret exists before this data source plans.
|
# references it as $__env{FIRE_PLANNER_PG_PASSWORD}. Reloader restarts
|
||||||
data "kubernetes_secret" "fire_planner_db_creds" {
|
# Grafana whenever ESO updates this secret (on the 7d static-role
|
||||||
metadata {
|
# rotation), so the provisioned datasource never goes stale — replaces
|
||||||
name = "fire-planner-db-creds"
|
# the old plan-time `data.kubernetes_secret` bake that broke weekly.
|
||||||
namespace = kubernetes_namespace.fire_planner.metadata[0].name
|
# Mirrors the wealth-pg / payslips-pg pattern.
|
||||||
|
resource "kubernetes_manifest" "grafana_fire_planner_pg_creds" {
|
||||||
|
field_manager {
|
||||||
|
force_conflicts = true
|
||||||
|
}
|
||||||
|
manifest = {
|
||||||
|
apiVersion = "external-secrets.io/v1"
|
||||||
|
kind = "ExternalSecret"
|
||||||
|
metadata = {
|
||||||
|
name = "grafana-fire-planner-pg-creds"
|
||||||
|
namespace = "monitoring"
|
||||||
|
}
|
||||||
|
spec = {
|
||||||
|
refreshInterval = "15m"
|
||||||
|
secretStoreRef = {
|
||||||
|
name = "vault-database"
|
||||||
|
kind = "ClusterSecretStore"
|
||||||
|
}
|
||||||
|
target = {
|
||||||
|
name = "grafana-fire-planner-pg-creds"
|
||||||
|
template = {
|
||||||
|
metadata = {
|
||||||
|
annotations = {
|
||||||
|
"reloader.stakater.com/match" = "true"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data = {
|
||||||
|
FIRE_PLANNER_PG_PASSWORD = "{{ .password }}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data = [{
|
||||||
|
secretKey = "password"
|
||||||
|
remoteRef = {
|
||||||
|
key = "static-creds/pg-fire-planner"
|
||||||
|
property = "password"
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
depends_on = [kubernetes_manifest.db_external_secret]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Grafana datasource for fire_planner PostgreSQL DB.
|
# Grafana datasource for fire_planner PostgreSQL DB.
|
||||||
|
|
@ -706,12 +743,15 @@ resource "kubernetes_config_map" "grafana_fire_planner_datasource" {
|
||||||
timescaledb = false
|
timescaledb = false
|
||||||
}
|
}
|
||||||
secureJsonData = {
|
secureJsonData = {
|
||||||
password = data.kubernetes_secret.fire_planner_db_creds.data["DB_PASSWORD"]
|
# Live env from grafana-fire-planner-pg-creds (above), injected into
|
||||||
|
# Grafana via envFromSecrets; reloader refreshes it on rotation.
|
||||||
|
password = "$__env{FIRE_PLANNER_PG_PASSWORD}"
|
||||||
}
|
}
|
||||||
editable = true
|
editable = true
|
||||||
}]
|
}]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
depends_on = [kubernetes_manifest.grafana_fire_planner_pg_creds]
|
||||||
}
|
}
|
||||||
|
|
||||||
# CI retrigger 2026-05-16T13:42:57+00:00 — bulk enrollment apply (pipeline #689 killed)
|
# CI retrigger 2026-05-16T13:42:57+00:00 — bulk enrollment apply (pipeline #689 killed)
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,8 @@ envFromSecrets:
|
||||||
optional: true
|
optional: true
|
||||||
- name: grafana-job-hunter-pg-creds
|
- name: grafana-job-hunter-pg-creds
|
||||||
optional: true
|
optional: true
|
||||||
|
- name: grafana-fire-planner-pg-creds
|
||||||
|
optional: true
|
||||||
env:
|
env:
|
||||||
GF_SERVER_ROOT_URL: https://grafana.viktorbarzin.me
|
GF_SERVER_ROOT_URL: https://grafana.viktorbarzin.me
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue