fix DB password desync + migrate remaining tfvars to Vault
DB desync fix: Stacks with Vault DB engine rotation (24h) now read the password from vault-database ClusterSecretStore instead of vault-kv. 9 stacks updated with db ExternalSecrets reading from static-creds/*. Stacks fixed: speedtest, hackmd, health, trading-bot, claude-memory, woodpecker, linkwarden, nextcloud, url. terraform.tfvars migration: - plotting-book: google_client_id/secret → Vault KV + secret_key_ref - tandoor: email_password var removed (was default="", now optional ESO) - infra: ssh_private_key, vm_wizard_password, dockerhub_registry_password → Vault KV at secret/infra + data source
This commit is contained in:
parent
06a0d0599a
commit
745e43c983
12 changed files with 385 additions and 83 deletions
|
|
@ -49,6 +49,42 @@ resource "kubernetes_manifest" "external_secret" {
|
|||
depends_on = [kubernetes_namespace.claude-memory]
|
||||
}
|
||||
|
||||
# DB credentials from Vault database engine (rotated every 24h)
|
||||
resource "kubernetes_manifest" "db_external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "claude-memory-db-creds"
|
||||
namespace = "claude-memory"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-database"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "claude-memory-db-creds"
|
||||
template = {
|
||||
data = {
|
||||
DATABASE_URL = "postgresql://claude_memory:{{ .password }}@${var.postgresql_host}:5432/claude_memory"
|
||||
DB_PASSWORD = "{{ .password }}"
|
||||
}
|
||||
}
|
||||
}
|
||||
data = [{
|
||||
secretKey = "password"
|
||||
remoteRef = {
|
||||
key = "static-creds/pg-claude-memory"
|
||||
property = "password"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.claude-memory]
|
||||
}
|
||||
|
||||
module "tls_secret" {
|
||||
source = "../../modules/kubernetes/setup_tls_secret"
|
||||
namespace = kubernetes_namespace.claude-memory.metadata[0].name
|
||||
|
|
@ -143,8 +179,13 @@ resource "kubernetes_deployment" "claude-memory" {
|
|||
}
|
||||
|
||||
env {
|
||||
name = "DATABASE_URL"
|
||||
value = "postgresql://claude_memory:${data.vault_kv_secret_v2.secrets.data["db_password"]}@${var.postgresql_host}:5432/claude_memory"
|
||||
name = "DATABASE_URL"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "claude-memory-db-creds"
|
||||
key = "DATABASE_URL"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "API_KEY"
|
||||
|
|
|
|||
|
|
@ -193,7 +193,7 @@ resource "kubernetes_manifest" "external_secret" {
|
|||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-kv"
|
||||
name = "vault-database"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
|
|
@ -206,7 +206,10 @@ resource "kubernetes_manifest" "external_secret" {
|
|||
}
|
||||
data = [{
|
||||
secretKey = "db_password"
|
||||
remoteRef = { key = "hackmd", property = "db_password" }
|
||||
remoteRef = {
|
||||
key = "static-creds/mysql-codimd"
|
||||
property = "password"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ resource "kubernetes_deployment" "health" {
|
|||
name = "DATABASE_URL"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "health-secrets"
|
||||
name = "health-db-secrets"
|
||||
key = "DATABASE_URL"
|
||||
}
|
||||
}
|
||||
|
|
@ -78,7 +78,7 @@ resource "kubernetes_deployment" "health" {
|
|||
name = "SECRET_KEY"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "health-secrets"
|
||||
name = "health-kv-secrets"
|
||||
key = "secret_key"
|
||||
}
|
||||
}
|
||||
|
|
@ -163,12 +163,46 @@ module "ingress" {
|
|||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_manifest" "external_secret" {
|
||||
resource "kubernetes_manifest" "external_secret_db" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "health-secrets"
|
||||
name = "health-db-secrets"
|
||||
namespace = "health"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-database"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "health-db-secrets"
|
||||
template = {
|
||||
data = {
|
||||
DATABASE_URL = "postgresql+asyncpg://health:{{ .db_password }}@postgresql.dbaas.svc.cluster.local:5432/health"
|
||||
}
|
||||
}
|
||||
}
|
||||
data = [{
|
||||
secretKey = "db_password"
|
||||
remoteRef = {
|
||||
key = "static-creds/postgresql-health"
|
||||
property = "password"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.health]
|
||||
}
|
||||
|
||||
resource "kubernetes_manifest" "external_secret_kv" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "health-kv-secrets"
|
||||
namespace = "health"
|
||||
}
|
||||
spec = {
|
||||
|
|
@ -178,24 +212,15 @@ resource "kubernetes_manifest" "external_secret" {
|
|||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "health-secrets"
|
||||
template = {
|
||||
data = {
|
||||
DATABASE_URL = "postgresql+asyncpg://health:{{ .db_password }}@postgresql.dbaas.svc.cluster.local:5432/health"
|
||||
secret_key = "{{ .secret_key }}"
|
||||
}
|
||||
}
|
||||
name = "health-kv-secrets"
|
||||
}
|
||||
data = [
|
||||
{
|
||||
secretKey = "db_password"
|
||||
remoteRef = { key = "health", property = "db_password" }
|
||||
},
|
||||
{
|
||||
secretKey = "secret_key"
|
||||
remoteRef = { key = "health", property = "secret_key" }
|
||||
data = [{
|
||||
secretKey = "secret_key"
|
||||
remoteRef = {
|
||||
key = "health"
|
||||
property = "secret_key"
|
||||
}
|
||||
]
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.health]
|
||||
|
|
|
|||
|
|
@ -9,25 +9,17 @@
|
|||
|
||||
variable "proxmox_host" { type = string }
|
||||
|
||||
variable "ssh_private_key" {
|
||||
type = string
|
||||
default = ""
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "ssh_public_key" {
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "vm_wizard_password" {
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "k8s_join_command" { type = string }
|
||||
|
||||
variable "dockerhub_registry_password" {}
|
||||
data "vault_kv_secret_v2" "secrets" {
|
||||
mount = "secret"
|
||||
name = "infra"
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Locals
|
||||
|
|
@ -54,14 +46,14 @@ module "k8s-node-template" {
|
|||
proxmox_host = var.proxmox_host
|
||||
proxmox_user = "root" # SSH user on Proxmox host
|
||||
|
||||
ssh_private_key = var.ssh_private_key
|
||||
ssh_private_key = data.vault_kv_secret_v2.secrets.data["ssh_private_key"]
|
||||
ssh_public_key = var.ssh_public_key
|
||||
|
||||
cloud_image_url = local.cloud_init_image_url
|
||||
image_path = local.k8s_cloud_init_image_path
|
||||
template_id = 2000
|
||||
template_name = local.k8s_vm_template
|
||||
user_passwd = var.vm_wizard_password
|
||||
user_passwd = data.vault_kv_secret_v2.secrets.data["vm_wizard_password"]
|
||||
|
||||
is_k8s_template = true # provision cloud init file with k8s deps
|
||||
snippet_name = local.k8s_cloud_init_snippet_name
|
||||
|
|
@ -146,14 +138,14 @@ module "non-k8s-node-template" {
|
|||
proxmox_host = var.proxmox_host
|
||||
proxmox_user = "root" # SSH user on Proxmox host
|
||||
|
||||
ssh_private_key = var.ssh_private_key
|
||||
ssh_private_key = data.vault_kv_secret_v2.secrets.data["ssh_private_key"]
|
||||
ssh_public_key = var.ssh_public_key
|
||||
|
||||
cloud_image_url = local.cloud_init_image_url
|
||||
image_path = local.non_k8s_cloud_init_image_path
|
||||
template_id = 1000
|
||||
template_name = local.non_k8s_vm_template
|
||||
user_passwd = var.vm_wizard_password
|
||||
user_passwd = data.vault_kv_secret_v2.secrets.data["vm_wizard_password"]
|
||||
|
||||
is_k8s_template = false # provision cloud init file without k8s deps
|
||||
snippet_name = local.non_k8s_cloud_init_snippet_name
|
||||
|
|
@ -169,7 +161,7 @@ module "docker-registry-template" {
|
|||
proxmox_host = var.proxmox_host
|
||||
proxmox_user = "root" # SSH user on Proxmox host
|
||||
|
||||
ssh_private_key = var.ssh_private_key
|
||||
ssh_private_key = data.vault_kv_secret_v2.secrets.data["ssh_private_key"]
|
||||
ssh_public_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDHLhYDfyx237eJgOGVoJRECpUS95+7rEBS9vacsIxtx devvm"
|
||||
|
||||
cloud_image_url = local.cloud_init_image_url
|
||||
|
|
@ -177,7 +169,7 @@ module "docker-registry-template" {
|
|||
template_id = 1001
|
||||
template_name = "docker-registry-template"
|
||||
|
||||
user_passwd = var.vm_wizard_password
|
||||
user_passwd = data.vault_kv_secret_v2.secrets.data["vm_wizard_password"]
|
||||
|
||||
is_k8s_template = false # provision cloud init file without k8s deps
|
||||
snippet_name = "docker-registry.yaml"
|
||||
|
|
@ -212,7 +204,7 @@ module "docker-registry-template" {
|
|||
format("echo %s | base64 -d > /opt/registry/config-dockerhub.yml",
|
||||
base64encode(
|
||||
templatefile("../../modules/docker-registry/config.yaml", {
|
||||
password = var.dockerhub_registry_password
|
||||
password = data.vault_kv_secret_v2.secrets.data["dockerhub_registry_password"]
|
||||
})
|
||||
)
|
||||
),
|
||||
|
|
|
|||
|
|
@ -50,6 +50,42 @@ resource "kubernetes_manifest" "external_secret" {
|
|||
depends_on = [kubernetes_namespace.linkwarden]
|
||||
}
|
||||
|
||||
# DB credentials from Vault database engine (rotated every 24h)
|
||||
resource "kubernetes_manifest" "db_external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "linkwarden-db-creds"
|
||||
namespace = "linkwarden"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-database"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "linkwarden-db-creds"
|
||||
template = {
|
||||
data = {
|
||||
DATABASE_URL = "postgresql://linkwarden:{{ .password }}@${var.postgresql_host}:5432/linkwarden"
|
||||
DB_PASSWORD = "{{ .password }}"
|
||||
}
|
||||
}
|
||||
}
|
||||
data = [{
|
||||
secretKey = "password"
|
||||
remoteRef = {
|
||||
key = "static-creds/pg-linkwarden"
|
||||
property = "password"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.linkwarden]
|
||||
}
|
||||
|
||||
module "tls_secret" {
|
||||
source = "../../modules/kubernetes/setup_tls_secret"
|
||||
namespace = kubernetes_namespace.linkwarden.metadata[0].name
|
||||
|
|
@ -87,9 +123,9 @@ resource "kubernetes_deployment" "linkwarden" {
|
|||
app = "linkwarden"
|
||||
}
|
||||
annotations = {
|
||||
"diun.enable" = "false"
|
||||
"diun.include_tags" = "latest"
|
||||
"dependency.kyverno.io/wait-for" = "postgresql.dbaas:5432"
|
||||
"diun.enable" = "false"
|
||||
"diun.include_tags" = "latest"
|
||||
"dependency.kyverno.io/wait-for" = "postgresql.dbaas:5432"
|
||||
}
|
||||
}
|
||||
spec {
|
||||
|
|
@ -101,8 +137,13 @@ resource "kubernetes_deployment" "linkwarden" {
|
|||
container_port = 3000
|
||||
}
|
||||
env {
|
||||
name = "DATABASE_URL"
|
||||
value = "postgresql://linkwarden:${data.vault_kv_secret_v2.secrets.data["db_password"]}@${var.postgresql_host}:5432/linkwarden"
|
||||
name = "DATABASE_URL"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "linkwarden-db-creds"
|
||||
key = "DATABASE_URL"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "NEXT_PUBLIC_AUTHENTIK_ENABLED"
|
||||
|
|
|
|||
|
|
@ -61,6 +61,45 @@ resource "kubernetes_manifest" "external_secret" {
|
|||
depends_on = [kubernetes_namespace.nextcloud]
|
||||
}
|
||||
|
||||
# DB credentials from Vault database engine (rotated every 24h)
|
||||
# NOTE: Nextcloud Helm values use plan-time db_password from KV — the Helm
|
||||
# release will use the KV snapshot until the next terragrunt apply. This
|
||||
# ExternalSecret provides runtime-refreshed credentials for any future
|
||||
# migration to envFrom-based secret injection.
|
||||
resource "kubernetes_manifest" "db_external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "nextcloud-db-creds"
|
||||
namespace = "nextcloud"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-database"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "nextcloud-db-creds"
|
||||
template = {
|
||||
data = {
|
||||
DB_PASSWORD = "{{ .password }}"
|
||||
}
|
||||
}
|
||||
}
|
||||
data = [{
|
||||
secretKey = "password"
|
||||
remoteRef = {
|
||||
key = "static-creds/mysql-nextcloud"
|
||||
property = "password"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.nextcloud]
|
||||
}
|
||||
|
||||
resource "kubernetes_resource_quota" "nextcloud" {
|
||||
metadata {
|
||||
name = "nextcloud-quota"
|
||||
|
|
|
|||
|
|
@ -2,15 +2,6 @@ variable "tls_secret_name" {
|
|||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
variable "plotting_book_google_client_id" {
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
variable "plotting_book_google_client_secret" {
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
resource "kubernetes_namespace" "plotting-book" {
|
||||
metadata {
|
||||
name = "plotting-book"
|
||||
|
|
@ -125,12 +116,22 @@ resource "kubernetes_deployment" "plotting-book" {
|
|||
}
|
||||
}
|
||||
env {
|
||||
name = "GOOGLE_CLIENT_ID"
|
||||
value = var.plotting_book_google_client_id
|
||||
name = "GOOGLE_CLIENT_ID"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "plotting-book-secrets"
|
||||
key = "google_client_id"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "GOOGLE_CLIENT_SECRET"
|
||||
value = var.plotting_book_google_client_secret
|
||||
name = "GOOGLE_CLIENT_SECRET"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "plotting-book-secrets"
|
||||
key = "google_client_secret"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "GOOGLE_CALLBACK_URL"
|
||||
|
|
|
|||
|
|
@ -25,15 +25,17 @@ resource "kubernetes_manifest" "external_secret" {
|
|||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-kv"
|
||||
name = "vault-database"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "speedtest-secrets"
|
||||
}
|
||||
dataFrom = [{
|
||||
extract = {
|
||||
key = "speedtest"
|
||||
data = [{
|
||||
secretKey = "db_password"
|
||||
remoteRef = {
|
||||
key = "static-creds/mysql-speedtest"
|
||||
property = "password"
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,11 +2,6 @@ variable "tls_secret_name" {
|
|||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
variable "tandoor_email_password" {
|
||||
type = string
|
||||
default = ""
|
||||
sensitive = true
|
||||
}
|
||||
variable "nfs_server" { type = string }
|
||||
variable "postgresql_host" { type = string }
|
||||
variable "mail_host" { type = string }
|
||||
|
|
@ -158,8 +153,14 @@ resource "kubernetes_deployment" "tandoor" {
|
|||
value = "info@viktorbarzin.me"
|
||||
}
|
||||
env {
|
||||
name = "EMAIL_HOST_PASSWORD"
|
||||
value = var.tandoor_email_password
|
||||
name = "EMAIL_HOST_PASSWORD"
|
||||
value_from {
|
||||
secret_key_ref {
|
||||
name = "tandoor-secrets"
|
||||
key = "email_password"
|
||||
optional = true
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "EMAIL_USE_TLS"
|
||||
|
|
|
|||
|
|
@ -61,21 +61,18 @@ resource "kubernetes_manifest" "external_secret" {
|
|||
name = "trading-bot-secrets"
|
||||
template = {
|
||||
data = {
|
||||
TRADING_DATABASE_URL = "postgresql+asyncpg://trading:{{ .db_password }}@${var.postgresql_host}:5432/trading"
|
||||
TRADING_ALPACA_API_KEY = "{{ .alpaca_api_key }}"
|
||||
TRADING_ALPACA_SECRET_KEY = "{{ .alpaca_secret_key }}"
|
||||
TRADING_JWT_SECRET_KEY = "{{ .jwt_secret }}"
|
||||
TRADING_REDDIT_CLIENT_ID = "{{ .reddit_client_id }}"
|
||||
TRADING_REDDIT_CLIENT_SECRET = "{{ .reddit_client_secret }}"
|
||||
TRADING_ALPACA_API_KEY = "{{ .alpaca_api_key }}"
|
||||
TRADING_ALPACA_SECRET_KEY = "{{ .alpaca_secret_key }}"
|
||||
TRADING_JWT_SECRET_KEY = "{{ .jwt_secret }}"
|
||||
TRADING_REDDIT_CLIENT_ID = "{{ .reddit_client_id }}"
|
||||
TRADING_REDDIT_CLIENT_SECRET = "{{ .reddit_client_secret }}"
|
||||
TRADING_ALPHA_VANTAGE_API_KEY = "{{ .alpha_vantage_api_key }}"
|
||||
TRADING_FMP_API_KEY = "{{ .fmp_api_key }}"
|
||||
DBAAS_ROOT_PASSWORD = "{{ .dbaas_root_password }}"
|
||||
DB_PASSWORD = "{{ .db_password }}"
|
||||
TRADING_FMP_API_KEY = "{{ .fmp_api_key }}"
|
||||
DBAAS_ROOT_PASSWORD = "{{ .dbaas_root_password }}"
|
||||
}
|
||||
}
|
||||
}
|
||||
data = [
|
||||
{ secretKey = "db_password", remoteRef = { key = "trading-bot", property = "db_password" } },
|
||||
{ secretKey = "alpaca_api_key", remoteRef = { key = "trading-bot", property = "alpaca_api_key" } },
|
||||
{ secretKey = "alpaca_secret_key", remoteRef = { key = "trading-bot", property = "alpaca_secret_key" } },
|
||||
{ secretKey = "jwt_secret", remoteRef = { key = "trading-bot", property = "jwt_secret" } },
|
||||
|
|
@ -90,6 +87,42 @@ resource "kubernetes_manifest" "external_secret" {
|
|||
depends_on = [kubernetes_namespace.trading-bot]
|
||||
}
|
||||
|
||||
# DB credentials from Vault database engine (rotated every 24h)
|
||||
resource "kubernetes_manifest" "db_external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "trading-bot-db-creds"
|
||||
namespace = "trading-bot"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-database"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "trading-bot-db-creds"
|
||||
template = {
|
||||
data = {
|
||||
TRADING_DATABASE_URL = "postgresql+asyncpg://trading:{{ .password }}@${var.postgresql_host}:5432/trading"
|
||||
DB_PASSWORD = "{{ .password }}"
|
||||
}
|
||||
}
|
||||
}
|
||||
data = [{
|
||||
secretKey = "password"
|
||||
remoteRef = {
|
||||
key = "static-creds/pg-trading"
|
||||
property = "password"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.trading-bot]
|
||||
}
|
||||
|
||||
# Database init job - creates the trading database and user in PostgreSQL
|
||||
resource "kubernetes_job" "db_init" {
|
||||
metadata {
|
||||
|
|
@ -125,6 +158,11 @@ resource "kubernetes_job" "db_init" {
|
|||
name = "trading-bot-secrets"
|
||||
}
|
||||
}
|
||||
env_from {
|
||||
secret_ref {
|
||||
name = "trading-bot-db-creds"
|
||||
}
|
||||
}
|
||||
}
|
||||
restart_policy = "Never"
|
||||
}
|
||||
|
|
@ -161,6 +199,11 @@ resource "kubernetes_job" "migrations" {
|
|||
name = "trading-bot-secrets"
|
||||
}
|
||||
}
|
||||
env_from {
|
||||
secret_ref {
|
||||
name = "trading-bot-db-creds"
|
||||
}
|
||||
}
|
||||
}
|
||||
restart_policy = "Never"
|
||||
}
|
||||
|
|
@ -251,6 +294,11 @@ resource "kubernetes_deployment" "trading-bot-frontend" {
|
|||
name = "trading-bot-secrets"
|
||||
}
|
||||
}
|
||||
env_from {
|
||||
secret_ref {
|
||||
name = "trading-bot-db-creds"
|
||||
}
|
||||
}
|
||||
resources {
|
||||
requests = {
|
||||
cpu = "50m"
|
||||
|
|
@ -328,6 +376,11 @@ resource "kubernetes_deployment" "trading-bot-workers" {
|
|||
name = "trading-bot-secrets"
|
||||
}
|
||||
}
|
||||
env_from {
|
||||
secret_ref {
|
||||
name = "trading-bot-db-creds"
|
||||
}
|
||||
}
|
||||
resources {
|
||||
requests = {
|
||||
cpu = "10m"
|
||||
|
|
@ -359,6 +412,11 @@ resource "kubernetes_deployment" "trading-bot-workers" {
|
|||
name = "trading-bot-secrets"
|
||||
}
|
||||
}
|
||||
env_from {
|
||||
secret_ref {
|
||||
name = "trading-bot-db-creds"
|
||||
}
|
||||
}
|
||||
resources {
|
||||
requests = {
|
||||
cpu = "100m"
|
||||
|
|
@ -390,6 +448,11 @@ resource "kubernetes_deployment" "trading-bot-workers" {
|
|||
name = "trading-bot-secrets"
|
||||
}
|
||||
}
|
||||
env_from {
|
||||
secret_ref {
|
||||
name = "trading-bot-db-creds"
|
||||
}
|
||||
}
|
||||
resources {
|
||||
requests = {
|
||||
cpu = "10m"
|
||||
|
|
@ -421,6 +484,11 @@ resource "kubernetes_deployment" "trading-bot-workers" {
|
|||
name = "trading-bot-secrets"
|
||||
}
|
||||
}
|
||||
env_from {
|
||||
secret_ref {
|
||||
name = "trading-bot-db-creds"
|
||||
}
|
||||
}
|
||||
resources {
|
||||
requests = {
|
||||
cpu = "10m"
|
||||
|
|
@ -452,6 +520,11 @@ resource "kubernetes_deployment" "trading-bot-workers" {
|
|||
name = "trading-bot-secrets"
|
||||
}
|
||||
}
|
||||
env_from {
|
||||
secret_ref {
|
||||
name = "trading-bot-db-creds"
|
||||
}
|
||||
}
|
||||
resources {
|
||||
requests = {
|
||||
cpu = "10m"
|
||||
|
|
@ -483,6 +556,11 @@ resource "kubernetes_deployment" "trading-bot-workers" {
|
|||
name = "trading-bot-secrets"
|
||||
}
|
||||
}
|
||||
env_from {
|
||||
secret_ref {
|
||||
name = "trading-bot-db-creds"
|
||||
}
|
||||
}
|
||||
resources {
|
||||
requests = {
|
||||
cpu = "10m"
|
||||
|
|
|
|||
|
|
@ -56,6 +56,46 @@ resource "kubernetes_manifest" "external_secret" {
|
|||
depends_on = [kubernetes_namespace.shlink]
|
||||
}
|
||||
|
||||
# DB credentials from Vault database engine (rotated every 24h)
|
||||
# NOTE: The kubernetes_secret "mysql_config" still uses plan-time db_password
|
||||
# from KV. This ExternalSecret provides runtime-refreshed credentials. Once
|
||||
# the deployment is migrated to use env_from with this secret, the plan-time
|
||||
# kubernetes_secret can be removed.
|
||||
resource "kubernetes_manifest" "db_external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "url-db-creds"
|
||||
namespace = "url"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-database"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "url-db-creds"
|
||||
template = {
|
||||
data = {
|
||||
DB_USER = "shlink"
|
||||
DB_PASSWORD = "{{ .password }}"
|
||||
}
|
||||
}
|
||||
}
|
||||
data = [{
|
||||
secretKey = "password"
|
||||
remoteRef = {
|
||||
key = "static-creds/mysql-shlink"
|
||||
property = "password"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.shlink]
|
||||
}
|
||||
|
||||
module "tls_secret" {
|
||||
source = "../../modules/kubernetes/setup_tls_secret"
|
||||
namespace = kubernetes_namespace.shlink.metadata[0].name
|
||||
|
|
@ -167,7 +207,7 @@ resource "kubernetes_deployment" "shlink" {
|
|||
# }
|
||||
env_from {
|
||||
secret_ref {
|
||||
name = "mysql-config"
|
||||
name = "url-db-creds"
|
||||
}
|
||||
}
|
||||
# env {
|
||||
|
|
|
|||
|
|
@ -70,6 +70,45 @@ resource "kubernetes_manifest" "external_secret" {
|
|||
depends_on = [kubernetes_namespace.woodpecker]
|
||||
}
|
||||
|
||||
# DB credentials from Vault database engine (rotated every 24h)
|
||||
# NOTE: Woodpecker Helm values use plan-time db_password from KV — the Helm
|
||||
# release will use the KV snapshot until the next terragrunt apply. This
|
||||
# ExternalSecret provides runtime-refreshed credentials for any future
|
||||
# migration to envFrom-based secret injection.
|
||||
resource "kubernetes_manifest" "db_external_secret" {
|
||||
manifest = {
|
||||
apiVersion = "external-secrets.io/v1beta1"
|
||||
kind = "ExternalSecret"
|
||||
metadata = {
|
||||
name = "woodpecker-db-creds"
|
||||
namespace = "woodpecker"
|
||||
}
|
||||
spec = {
|
||||
refreshInterval = "15m"
|
||||
secretStoreRef = {
|
||||
name = "vault-database"
|
||||
kind = "ClusterSecretStore"
|
||||
}
|
||||
target = {
|
||||
name = "woodpecker-db-creds"
|
||||
template = {
|
||||
data = {
|
||||
DB_PASSWORD = "{{ .password }}"
|
||||
}
|
||||
}
|
||||
}
|
||||
data = [{
|
||||
secretKey = "password"
|
||||
remoteRef = {
|
||||
key = "static-creds/pg-woodpecker"
|
||||
property = "password"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
depends_on = [kubernetes_namespace.woodpecker]
|
||||
}
|
||||
|
||||
resource "kubernetes_config_map" "git_crypt_key" {
|
||||
metadata {
|
||||
name = "git-crypt-key"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue