migrate all secrets from SOPS to Vault KV
- Add vault provider to root terragrunt.hcl (generated providers.tf) - Delete stacks/vault/vault_provider.tf (now in generated providers.tf) - Add 124 variable declarations + 43 vault_kv_secret_v2 resources to vault/main.tf to populate Vault KV at secret/<stack-name> - Migrate 43 consuming stacks to read secrets from Vault KV via data "vault_kv_secret_v2" instead of SOPS var-file - Add dependency "vault" to all migrated stacks' terragrunt.hcl - Complex types (maps/lists) stored as JSON strings, decoded with jsondecode() in locals blocks Bootstrap secrets (vault_root_token, vault_authentik_client_id, vault_authentik_client_secret) remain in SOPS permanently. Apply order: vault stack first (populates KV), then all others.
This commit is contained in:
parent
39b7dac1a9
commit
a8d944eb9b
126 changed files with 1635 additions and 817 deletions
|
|
@ -8,6 +8,10 @@ variable "vault_authentik_client_secret" {
|
|||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "nfs_server" {
|
||||
type = string
|
||||
}
|
||||
resource "kubernetes_namespace" "vault" {
|
||||
metadata {
|
||||
name = "vault"
|
||||
|
|
@ -30,61 +34,111 @@ resource "helm_release" "vault" {
|
|||
repository = "https://helm.releases.hashicorp.com"
|
||||
chart = "vault"
|
||||
version = "0.29.1"
|
||||
atomic = true
|
||||
timeout = 300
|
||||
atomic = false # HA pods start sealed — readiness probes fail until unsealed
|
||||
timeout = 600
|
||||
|
||||
values = [yamlencode({
|
||||
global = {
|
||||
enabled = true
|
||||
}
|
||||
global = { enabled = true }
|
||||
|
||||
server = {
|
||||
enabled = true
|
||||
|
||||
resources = {
|
||||
requests = { memory = "64Mi", cpu = "50m" }
|
||||
limits = { memory = "256Mi" }
|
||||
requests = { memory = "128Mi", cpu = "100m" }
|
||||
limits = { memory = "512Mi" }
|
||||
}
|
||||
|
||||
# Allow scheduling on GPU node (node1)
|
||||
tolerations = [{
|
||||
key = "nvidia.com/gpu"
|
||||
operator = "Exists"
|
||||
effect = "NoSchedule"
|
||||
}]
|
||||
|
||||
dataStorage = {
|
||||
enabled = true
|
||||
size = "1Gi"
|
||||
storageClass = "nfs-truenas"
|
||||
size = "2Gi"
|
||||
storageClass = "nfs-truenas" # NFS — iSCSI CSI driver not available on all nodes
|
||||
}
|
||||
|
||||
standalone = {
|
||||
enabled = true
|
||||
config = <<-EOT
|
||||
ui = true
|
||||
|
||||
listener "tcp" {
|
||||
tls_disable = 1
|
||||
address = "[::]:8200"
|
||||
cluster_address = "[::]:8201"
|
||||
}
|
||||
|
||||
storage "file" {
|
||||
path = "/vault/data"
|
||||
}
|
||||
EOT
|
||||
auditStorage = {
|
||||
enabled = true
|
||||
size = "2Gi"
|
||||
storageClass = "nfs-truenas" # NFS fine for append-only audit logs
|
||||
}
|
||||
|
||||
standalone = { enabled = false }
|
||||
|
||||
ha = {
|
||||
enabled = false
|
||||
enabled = true
|
||||
replicas = 3
|
||||
|
||||
raft = {
|
||||
enabled = true
|
||||
setNodeId = true
|
||||
config = <<-EOT
|
||||
ui = true
|
||||
|
||||
listener "tcp" {
|
||||
tls_disable = 1
|
||||
address = "[::]:8200"
|
||||
cluster_address = "[::]:8201"
|
||||
}
|
||||
|
||||
storage "raft" {
|
||||
path = "/vault/data"
|
||||
retry_join {
|
||||
leader_api_addr = "http://vault-0.vault-internal:8200"
|
||||
}
|
||||
retry_join {
|
||||
leader_api_addr = "http://vault-1.vault-internal:8200"
|
||||
}
|
||||
retry_join {
|
||||
leader_api_addr = "http://vault-2.vault-internal:8200"
|
||||
}
|
||||
}
|
||||
|
||||
service_registration "kubernetes" {}
|
||||
EOT
|
||||
}
|
||||
}
|
||||
|
||||
# Mount unseal key secret
|
||||
extraVolumes = [{
|
||||
type = "secret"
|
||||
name = "vault-unseal-key"
|
||||
}]
|
||||
|
||||
# Auto-unseal sidecar — polls every 10s, unseals if sealed
|
||||
extraContainers = [{
|
||||
name = "auto-unseal"
|
||||
image = "hashicorp/vault:1.18.1"
|
||||
command = ["/bin/sh", "-c"]
|
||||
args = [join("", [
|
||||
"while true; do ",
|
||||
"sealed=$(VAULT_ADDR=http://127.0.0.1:8200 vault status -format=json 2>/dev/null | grep '\"sealed\"' | grep -o 'true\\|false'); ",
|
||||
"if [ \"$sealed\" = \"true\" ]; then ",
|
||||
"echo \"$(date): Vault is sealed, unsealing...\"; ",
|
||||
"VAULT_ADDR=http://127.0.0.1:8200 vault operator unseal $(cat /vault/unseal-key/unseal-key); ",
|
||||
"fi; ",
|
||||
"sleep 10; ",
|
||||
"done"
|
||||
])]
|
||||
volumeMounts = [{
|
||||
name = "userconfig-vault-unseal-key" # Helm chart prefixes extraVolumes with "userconfig-"
|
||||
mountPath = "/vault/unseal-key"
|
||||
readOnly = true
|
||||
}]
|
||||
resources = {
|
||||
requests = { cpu = "10m", memory = "32Mi" }
|
||||
limits = { memory = "64Mi" }
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
||||
ui = {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
injector = {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
csi = {
|
||||
enabled = false
|
||||
}
|
||||
ui = { enabled = true }
|
||||
injector = { enabled = false }
|
||||
csi = { enabled = false }
|
||||
})]
|
||||
}
|
||||
|
||||
|
|
@ -155,3 +209,715 @@ module "ingress" {
|
|||
"gethomepage.dev/pod-selector" = ""
|
||||
}
|
||||
}
|
||||
|
||||
# --- Audit Logging ---
|
||||
|
||||
resource "vault_audit" "file" {
|
||||
type = "file"
|
||||
options = {
|
||||
file_path = "/vault/audit/vault-audit.log"
|
||||
}
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
# --- Raft Snapshot Backups ---
|
||||
|
||||
module "vault_backup_nfs" {
|
||||
source = "../../modules/kubernetes/nfs_volume"
|
||||
name = "vault-backup"
|
||||
namespace = kubernetes_namespace.vault.metadata[0].name
|
||||
nfs_server = var.nfs_server
|
||||
nfs_path = "/mnt/main/vault-backup"
|
||||
storage = "5Gi"
|
||||
}
|
||||
|
||||
resource "kubernetes_cron_job_v1" "vault_backup" {
|
||||
metadata {
|
||||
name = "vault-raft-backup"
|
||||
namespace = kubernetes_namespace.vault.metadata[0].name
|
||||
}
|
||||
spec {
|
||||
schedule = "0 2 * * *"
|
||||
successful_jobs_history_limit = 3
|
||||
failed_jobs_history_limit = 3
|
||||
concurrency_policy = "Forbid"
|
||||
job_template {
|
||||
metadata {}
|
||||
spec {
|
||||
template {
|
||||
metadata {}
|
||||
spec {
|
||||
container {
|
||||
name = "backup"
|
||||
image = "hashicorp/vault:1.18.1"
|
||||
command = ["/bin/sh", "-c"]
|
||||
args = [join("", [
|
||||
"export VAULT_ADDR=http://vault-active.vault.svc.cluster.local:8200 && ",
|
||||
"export VAULT_TOKEN=$(cat /vault/token/vault-root-token) && ",
|
||||
"TIMESTAMP=$(date +%Y%m%d-%H%M%S) && ",
|
||||
"vault operator raft snapshot save /backup/vault-raft-$TIMESTAMP.db && ",
|
||||
"find /backup -name '*.db' -mtime +30 -delete && ",
|
||||
"echo \"Backup done: vault-raft-$TIMESTAMP.db\" && ls -lh /backup/"
|
||||
])]
|
||||
volume_mount {
|
||||
mount_path = "/backup"
|
||||
name = "backup-storage"
|
||||
}
|
||||
volume_mount {
|
||||
mount_path = "/vault/token"
|
||||
name = "vault-token"
|
||||
read_only = true
|
||||
}
|
||||
}
|
||||
restart_policy = "OnFailure"
|
||||
volume {
|
||||
name = "backup-storage"
|
||||
persistent_volume_claim {
|
||||
claim_name = module.vault_backup_nfs.claim_name
|
||||
}
|
||||
}
|
||||
volume {
|
||||
name = "vault-token"
|
||||
secret {
|
||||
secret_name = "vault-root-token"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
# Vault KV Secret Population
|
||||
# =============================================================================
|
||||
# Reads secrets from SOPS (-var-file) and writes them to Vault KV v2 at
|
||||
# secret/<stack-name>. Consuming stacks read from Vault instead of SOPS.
|
||||
# =============================================================================
|
||||
|
||||
# --- Variable Declarations (secrets consumed by other stacks) ---
|
||||
|
||||
# Simple string secrets
|
||||
variable "speedtest_db_password" { type = string; sensitive = true }
|
||||
variable "hackmd_db_password" { type = string; sensitive = true }
|
||||
variable "n8n_postgresql_password" { type = string; sensitive = true }
|
||||
variable "tandoor_database_password" { type = string; sensitive = true }
|
||||
variable "shadowsocks_password" { type = string; sensitive = true }
|
||||
variable "coturn_turn_secret" { type = string; sensitive = true }
|
||||
variable "wealthfolio_password_hash" { type = string; sensitive = true }
|
||||
variable "plotting_book_session_secret" { type = string; sensitive = true }
|
||||
variable "discord_user_token" { type = string; sensitive = true }
|
||||
variable "health_postgresql_password" { type = string; sensitive = true }
|
||||
variable "health_secret_key" { type = string; sensitive = true }
|
||||
variable "onlyoffice_db_password" { type = string; sensitive = true }
|
||||
variable "onlyoffice_jwt_token" { type = string; sensitive = true }
|
||||
variable "netbox_db_password" { type = string; sensitive = true }
|
||||
variable "netbox_superuser_password" { type = string; sensitive = true }
|
||||
variable "clickhouse_password" { type = string; sensitive = true }
|
||||
variable "clickhouse_postgres_password" { type = string; sensitive = true }
|
||||
variable "diun_nfty_token" { type = string; sensitive = true }
|
||||
variable "diun_slack_url" { type = string; sensitive = true }
|
||||
variable "forgejo_authentik_client_id" { type = string; sensitive = true }
|
||||
variable "forgejo_authentik_client_secret" { type = string; sensitive = true }
|
||||
variable "dawarich_database_password" { type = string; sensitive = true }
|
||||
variable "geoapify_api_key" { type = string; sensitive = true }
|
||||
variable "resume_auth_secret" { type = string; sensitive = true }
|
||||
variable "url_shortener_api_key" { type = string; sensitive = true }
|
||||
variable "url_shortener_geolite_license_key" { type = string; sensitive = true }
|
||||
variable "url_shortener_mysql_password" { type = string; sensitive = true }
|
||||
variable "linkwarden_authentik_client_id" { type = string; sensitive = true }
|
||||
variable "linkwarden_authentik_client_secret" { type = string; sensitive = true }
|
||||
variable "linkwarden_postgresql_password" { type = string; sensitive = true }
|
||||
variable "tiny_tuya_api_key" { type = string; sensitive = true }
|
||||
variable "tiny_tuya_api_secret" { type = string; sensitive = true }
|
||||
variable "tiny_tuya_service_secret" { type = string; sensitive = true }
|
||||
variable "tiny_tuya_slack_url" { type = string; sensitive = true }
|
||||
variable "claude_memory_api_key" { type = string; sensitive = true }
|
||||
variable "dbaas_postgresql_root_password" { type = string; sensitive = true }
|
||||
variable "openrouter_api_key" { type = string; sensitive = true }
|
||||
variable "slack_bot_token" { type = string; sensitive = true }
|
||||
variable "woodpecker_agent_secret" { type = string; sensitive = true }
|
||||
variable "woodpecker_db_password" { type = string; sensitive = true }
|
||||
variable "woodpecker_forgejo_client_id" { type = string; sensitive = true }
|
||||
variable "woodpecker_forgejo_client_secret" { type = string; sensitive = true }
|
||||
variable "woodpecker_github_client_id" { type = string; sensitive = true }
|
||||
variable "woodpecker_github_client_secret" { type = string; sensitive = true }
|
||||
variable "webhook_handler_secret" { type = string; sensitive = true }
|
||||
variable "webhook_handler_fb_verify_token" { type = string; sensitive = true }
|
||||
variable "webhook_handler_fb_page_token" { type = string; sensitive = true }
|
||||
variable "webhook_handler_fb_app_secret" { type = string; sensitive = true }
|
||||
variable "webhook_handler_git_user" { type = string; sensitive = true }
|
||||
variable "webhook_handler_git_token" { type = string; sensitive = true }
|
||||
variable "webhook_handler_ssh_key" { type = string; sensitive = true }
|
||||
variable "trading_bot_db_password" { type = string; sensitive = true }
|
||||
variable "trading_bot_alpaca_api_key" { type = string; sensitive = true }
|
||||
variable "trading_bot_alpaca_secret_key" { type = string; sensitive = true }
|
||||
variable "trading_bot_jwt_secret" { type = string; sensitive = true }
|
||||
variable "trading_bot_reddit_client_id" { type = string; sensitive = true }
|
||||
variable "trading_bot_reddit_client_secret" { type = string; sensitive = true }
|
||||
variable "trading_bot_alpha_vantage_api_key" { type = string; sensitive = true }
|
||||
variable "trading_bot_fmp_api_key" { type = string; sensitive = true }
|
||||
variable "openclaw_ssh_key" { type = string; sensitive = true }
|
||||
variable "llama_api_key" { type = string; sensitive = true }
|
||||
variable "brave_api_key" { type = string; sensitive = true }
|
||||
variable "nvidia_api_key" { type = string; sensitive = true }
|
||||
variable "anthropic_api_key" { type = string; sensitive = true }
|
||||
variable "openclaw_telegram_bot_token" { type = string; sensitive = true }
|
||||
variable "forgejo_api_token" { type = string; sensitive = true }
|
||||
variable "affine_postgresql_password" { type = string; sensitive = true }
|
||||
variable "immich_postgresql_password" { type = string; sensitive = true }
|
||||
variable "immich_frame_api_key" { type = string; sensitive = true }
|
||||
variable "nextcloud_db_password" { type = string; sensitive = true }
|
||||
variable "paperless_db_password" { type = string; sensitive = true }
|
||||
variable "realestate_crawler_db_password" { type = string; sensitive = true }
|
||||
variable "aiostreams_database_connection_string" { type = string; sensitive = true }
|
||||
|
||||
# Platform-specific secrets
|
||||
variable "dbaas_root_password" { type = string; sensitive = true }
|
||||
variable "dbaas_pgadmin_password" { type = string; sensitive = true }
|
||||
variable "ingress_crowdsec_api_key" { type = string; sensitive = true }
|
||||
variable "auth_fallback_htpasswd" { type = string; sensitive = true; default = "" }
|
||||
variable "technitium_db_password" { type = string; sensitive = true }
|
||||
variable "authentik_secret_key" { type = string; sensitive = true }
|
||||
variable "authentik_postgres_password" { type = string; sensitive = true }
|
||||
variable "crowdsec_enroll_key" { type = string; sensitive = true }
|
||||
variable "crowdsec_db_password" { type = string; sensitive = true }
|
||||
variable "crowdsec_dash_api_key" { type = string; sensitive = true }
|
||||
variable "crowdsec_dash_machine_id" { type = string; sensitive = true }
|
||||
variable "crowdsec_dash_machine_password" { type = string; sensitive = true }
|
||||
variable "alertmanager_slack_api_url" { type = string; sensitive = true }
|
||||
variable "cloudflare_api_key" { type = string; sensitive = true }
|
||||
variable "cloudflare_tunnel_token" { type = string; sensitive = true }
|
||||
variable "alertmanager_account_password" { type = string; sensitive = true }
|
||||
variable "monitoring_idrac_password" { type = string; sensitive = true }
|
||||
variable "haos_api_token" { type = string; sensitive = true }
|
||||
variable "pve_password" { type = string; sensitive = true }
|
||||
variable "grafana_db_password" { type = string; sensitive = true }
|
||||
variable "grafana_admin_password" { type = string; sensitive = true }
|
||||
variable "vaultwarden_smtp_password" { type = string; sensitive = true }
|
||||
variable "technitium_username" { type = string; sensitive = true }
|
||||
variable "technitium_password" { type = string; sensitive = true }
|
||||
variable "truenas_api_key" { type = string; sensitive = true }
|
||||
variable "truenas_ssh_private_key" { type = string; sensitive = true }
|
||||
variable "xray_reality_private_key" { type = string; sensitive = true }
|
||||
variable "mailserver_roundcubemail_db_password" { type = string; sensitive = true }
|
||||
variable "headscale_config" { type = string; sensitive = true }
|
||||
variable "headscale_acl" { type = string; sensitive = true }
|
||||
variable "wireguard_wg_0_conf" { type = string; sensitive = true }
|
||||
variable "wireguard_wg_0_key" { type = string; sensitive = true }
|
||||
variable "wireguard_firewall_sh" { type = string; sensitive = true }
|
||||
|
||||
# Complex type secrets
|
||||
variable "homepage_credentials" { type = map(any); sensitive = true }
|
||||
variable "mailserver_accounts" { sensitive = true }
|
||||
variable "mailserver_aliases" { sensitive = true }
|
||||
variable "mailserver_opendkim_key" { sensitive = true }
|
||||
variable "mailserver_sasl_passwd" { sensitive = true }
|
||||
variable "actualbudget_credentials" { type = map(any); sensitive = true }
|
||||
variable "freedify_credentials" { type = map(any); sensitive = true }
|
||||
variable "ollama_api_credentials" { type = map(string); sensitive = true }
|
||||
variable "owntracks_credentials" { type = map(string); sensitive = true }
|
||||
variable "realestate_crawler_notification_settings" { type = map(string); sensitive = true }
|
||||
variable "openclaw_skill_secrets" { type = map(string); sensitive = true }
|
||||
variable "k8s_users" { type = map(any); sensitive = true; default = {} }
|
||||
variable "xray_reality_clients" { type = list(map(string)); sensitive = true }
|
||||
variable "xray_reality_short_ids" { type = list(string); sensitive = true }
|
||||
|
||||
# =============================================================================
|
||||
# KV Secret Resources — one per consuming stack
|
||||
# =============================================================================
|
||||
|
||||
resource "vault_kv_secret_v2" "speedtest" {
|
||||
mount = "secret"
|
||||
name = "speedtest"
|
||||
data_json = jsonencode({
|
||||
db_password = var.speedtest_db_password
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "hackmd" {
|
||||
mount = "secret"
|
||||
name = "hackmd"
|
||||
data_json = jsonencode({
|
||||
db_password = var.hackmd_db_password
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "n8n" {
|
||||
mount = "secret"
|
||||
name = "n8n"
|
||||
data_json = jsonencode({
|
||||
db_password = var.n8n_postgresql_password
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "tandoor" {
|
||||
mount = "secret"
|
||||
name = "tandoor"
|
||||
data_json = jsonencode({
|
||||
db_password = var.tandoor_database_password
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "shadowsocks" {
|
||||
mount = "secret"
|
||||
name = "shadowsocks"
|
||||
data_json = jsonencode({
|
||||
password = var.shadowsocks_password
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "coturn" {
|
||||
mount = "secret"
|
||||
name = "coturn"
|
||||
data_json = jsonencode({
|
||||
turn_secret = var.coturn_turn_secret
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "wealthfolio" {
|
||||
mount = "secret"
|
||||
name = "wealthfolio"
|
||||
data_json = jsonencode({
|
||||
password_hash = var.wealthfolio_password_hash
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "plotting-book" {
|
||||
mount = "secret"
|
||||
name = "plotting-book"
|
||||
data_json = jsonencode({
|
||||
session_secret = var.plotting_book_session_secret
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "f1-stream" {
|
||||
mount = "secret"
|
||||
name = "f1-stream"
|
||||
data_json = jsonencode({
|
||||
discord_user_token = var.discord_user_token
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "health" {
|
||||
mount = "secret"
|
||||
name = "health"
|
||||
data_json = jsonencode({
|
||||
db_password = var.health_postgresql_password
|
||||
secret_key = var.health_secret_key
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "onlyoffice" {
|
||||
mount = "secret"
|
||||
name = "onlyoffice"
|
||||
data_json = jsonencode({
|
||||
db_password = var.onlyoffice_db_password
|
||||
jwt_token = var.onlyoffice_jwt_token
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "netbox" {
|
||||
mount = "secret"
|
||||
name = "netbox"
|
||||
data_json = jsonencode({
|
||||
db_password = var.netbox_db_password
|
||||
superuser_password = var.netbox_superuser_password
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "rybbit" {
|
||||
mount = "secret"
|
||||
name = "rybbit"
|
||||
data_json = jsonencode({
|
||||
clickhouse_password = var.clickhouse_password
|
||||
postgres_password = var.clickhouse_postgres_password
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "diun" {
|
||||
mount = "secret"
|
||||
name = "diun"
|
||||
data_json = jsonencode({
|
||||
nfty_token = var.diun_nfty_token
|
||||
slack_url = var.diun_slack_url
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "forgejo" {
|
||||
mount = "secret"
|
||||
name = "forgejo"
|
||||
data_json = jsonencode({
|
||||
authentik_client_id = var.forgejo_authentik_client_id
|
||||
authentik_client_secret = var.forgejo_authentik_client_secret
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "dawarich" {
|
||||
mount = "secret"
|
||||
name = "dawarich"
|
||||
data_json = jsonencode({
|
||||
db_password = var.dawarich_database_password
|
||||
geoapify_api_key = var.geoapify_api_key
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "resume" {
|
||||
mount = "secret"
|
||||
name = "resume"
|
||||
data_json = jsonencode({
|
||||
auth_secret = var.resume_auth_secret
|
||||
mailserver_accounts = jsonencode(var.mailserver_accounts)
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "url" {
|
||||
mount = "secret"
|
||||
name = "url"
|
||||
data_json = jsonencode({
|
||||
api_key = var.url_shortener_api_key
|
||||
geolite_license_key = var.url_shortener_geolite_license_key
|
||||
db_password = var.url_shortener_mysql_password
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "linkwarden" {
|
||||
mount = "secret"
|
||||
name = "linkwarden"
|
||||
data_json = jsonencode({
|
||||
authentik_client_id = var.linkwarden_authentik_client_id
|
||||
authentik_client_secret = var.linkwarden_authentik_client_secret
|
||||
db_password = var.linkwarden_postgresql_password
|
||||
homepage_credentials = jsonencode(var.homepage_credentials)
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "tuya-bridge" {
|
||||
mount = "secret"
|
||||
name = "tuya-bridge"
|
||||
data_json = jsonencode({
|
||||
api_key = var.tiny_tuya_api_key
|
||||
api_secret = var.tiny_tuya_api_secret
|
||||
service_secret = var.tiny_tuya_service_secret
|
||||
slack_url = var.tiny_tuya_slack_url
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "claude-memory" {
|
||||
mount = "secret"
|
||||
name = "claude-memory"
|
||||
data_json = jsonencode({
|
||||
api_key = var.claude_memory_api_key
|
||||
dbaas_root_password = var.dbaas_postgresql_root_password
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "ytdlp" {
|
||||
mount = "secret"
|
||||
name = "ytdlp"
|
||||
data_json = jsonencode({
|
||||
openrouter_api_key = var.openrouter_api_key
|
||||
slack_bot_token = var.slack_bot_token
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "woodpecker" {
|
||||
mount = "secret"
|
||||
name = "woodpecker"
|
||||
data_json = jsonencode({
|
||||
dbaas_root_password = var.dbaas_postgresql_root_password
|
||||
agent_secret = var.woodpecker_agent_secret
|
||||
db_password = var.woodpecker_db_password
|
||||
forgejo_client_id = var.woodpecker_forgejo_client_id
|
||||
forgejo_client_secret = var.woodpecker_forgejo_client_secret
|
||||
github_client_id = var.woodpecker_github_client_id
|
||||
github_client_secret = var.woodpecker_github_client_secret
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "webhook_handler" {
|
||||
mount = "secret"
|
||||
name = "webhook-handler"
|
||||
data_json = jsonencode({
|
||||
secret = var.webhook_handler_secret
|
||||
fb_verify_token = var.webhook_handler_fb_verify_token
|
||||
fb_page_token = var.webhook_handler_fb_page_token
|
||||
fb_app_secret = var.webhook_handler_fb_app_secret
|
||||
git_user = var.webhook_handler_git_user
|
||||
git_token = var.webhook_handler_git_token
|
||||
ssh_key = var.webhook_handler_ssh_key
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "trading-bot" {
|
||||
mount = "secret"
|
||||
name = "trading-bot"
|
||||
data_json = jsonencode({
|
||||
dbaas_root_password = var.dbaas_postgresql_root_password
|
||||
db_password = var.trading_bot_db_password
|
||||
alpaca_api_key = var.trading_bot_alpaca_api_key
|
||||
alpaca_secret_key = var.trading_bot_alpaca_secret_key
|
||||
jwt_secret = var.trading_bot_jwt_secret
|
||||
reddit_client_id = var.trading_bot_reddit_client_id
|
||||
reddit_client_secret = var.trading_bot_reddit_client_secret
|
||||
alpha_vantage_api_key = var.trading_bot_alpha_vantage_api_key
|
||||
fmp_api_key = var.trading_bot_fmp_api_key
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "openclaw" {
|
||||
mount = "secret"
|
||||
name = "openclaw"
|
||||
data_json = jsonencode({
|
||||
ssh_key = var.openclaw_ssh_key
|
||||
skill_secrets = jsonencode(var.openclaw_skill_secrets)
|
||||
llama_api_key = var.llama_api_key
|
||||
brave_api_key = var.brave_api_key
|
||||
openrouter_api_key = var.openrouter_api_key
|
||||
nvidia_api_key = var.nvidia_api_key
|
||||
anthropic_api_key = var.anthropic_api_key
|
||||
telegram_bot_token = var.openclaw_telegram_bot_token
|
||||
forgejo_api_token = var.forgejo_api_token
|
||||
claude_memory_api_key = var.claude_memory_api_key
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "affine" {
|
||||
mount = "secret"
|
||||
name = "affine"
|
||||
data_json = jsonencode({
|
||||
db_password = var.affine_postgresql_password
|
||||
mailserver_accounts = jsonencode(var.mailserver_accounts)
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "grampsweb" {
|
||||
mount = "secret"
|
||||
name = "grampsweb"
|
||||
data_json = jsonencode({
|
||||
mailserver_accounts = jsonencode(var.mailserver_accounts)
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
# --- Homepage-only stacks ---
|
||||
|
||||
resource "vault_kv_secret_v2" "audiobookshelf" {
|
||||
mount = "secret"
|
||||
name = "audiobookshelf"
|
||||
data_json = jsonencode({
|
||||
homepage_credentials = jsonencode(var.homepage_credentials)
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "calibre" {
|
||||
mount = "secret"
|
||||
name = "calibre"
|
||||
data_json = jsonencode({
|
||||
homepage_credentials = jsonencode(var.homepage_credentials)
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "changedetection" {
|
||||
mount = "secret"
|
||||
name = "changedetection"
|
||||
data_json = jsonencode({
|
||||
homepage_credentials = jsonencode(var.homepage_credentials)
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "freshrss" {
|
||||
mount = "secret"
|
||||
name = "freshrss"
|
||||
data_json = jsonencode({
|
||||
homepage_credentials = jsonencode(var.homepage_credentials)
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "navidrome" {
|
||||
mount = "secret"
|
||||
name = "navidrome"
|
||||
data_json = jsonencode({
|
||||
homepage_credentials = jsonencode(var.homepage_credentials)
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "servarr" {
|
||||
mount = "secret"
|
||||
name = "servarr"
|
||||
data_json = jsonencode({
|
||||
homepage_credentials = jsonencode(var.homepage_credentials)
|
||||
aiostreams_database_connection_string = var.aiostreams_database_connection_string
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
# --- Complex stacks (map secrets) ---
|
||||
|
||||
resource "vault_kv_secret_v2" "actualbudget" {
|
||||
mount = "secret"
|
||||
name = "actualbudget"
|
||||
data_json = jsonencode({
|
||||
credentials = jsonencode(var.actualbudget_credentials)
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "freedify" {
|
||||
mount = "secret"
|
||||
name = "freedify"
|
||||
data_json = jsonencode({
|
||||
credentials = jsonencode(var.freedify_credentials)
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "ollama" {
|
||||
mount = "secret"
|
||||
name = "ollama"
|
||||
data_json = jsonencode({
|
||||
api_credentials = jsonencode(var.ollama_api_credentials)
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "owntracks" {
|
||||
mount = "secret"
|
||||
name = "owntracks"
|
||||
data_json = jsonencode({
|
||||
credentials = jsonencode(var.owntracks_credentials)
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "real-estate-crawler" {
|
||||
mount = "secret"
|
||||
name = "real-estate-crawler"
|
||||
data_json = jsonencode({
|
||||
db_password = var.realestate_crawler_db_password
|
||||
notification_settings = jsonencode(var.realestate_crawler_notification_settings)
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
# --- Stacks with homepage_credentials + other secrets ---
|
||||
|
||||
resource "vault_kv_secret_v2" "immich" {
|
||||
mount = "secret"
|
||||
name = "immich"
|
||||
data_json = jsonencode({
|
||||
db_password = var.immich_postgresql_password
|
||||
frame_api_key = var.immich_frame_api_key
|
||||
homepage_credentials = jsonencode(var.homepage_credentials)
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "nextcloud" {
|
||||
mount = "secret"
|
||||
name = "nextcloud"
|
||||
data_json = jsonencode({
|
||||
db_password = var.nextcloud_db_password
|
||||
homepage_credentials = jsonencode(var.homepage_credentials)
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_v2" "paperless-ngx" {
|
||||
mount = "secret"
|
||||
name = "paperless-ngx"
|
||||
data_json = jsonencode({
|
||||
db_password = var.paperless_db_password
|
||||
homepage_credentials = jsonencode(var.homepage_credentials)
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
# --- Platform stack (largest — all core/cluster secrets) ---
|
||||
|
||||
resource "vault_kv_secret_v2" "platform" {
|
||||
mount = "secret"
|
||||
name = "platform"
|
||||
data_json = jsonencode({
|
||||
dbaas_root_password = var.dbaas_root_password
|
||||
dbaas_postgresql_root_password = var.dbaas_postgresql_root_password
|
||||
dbaas_pgadmin_password = var.dbaas_pgadmin_password
|
||||
ingress_crowdsec_api_key = var.ingress_crowdsec_api_key
|
||||
auth_fallback_htpasswd = var.auth_fallback_htpasswd
|
||||
technitium_db_password = var.technitium_db_password
|
||||
homepage_credentials = jsonencode(var.homepage_credentials)
|
||||
headscale_config = var.headscale_config
|
||||
headscale_acl = var.headscale_acl
|
||||
authentik_secret_key = var.authentik_secret_key
|
||||
authentik_postgres_password = var.authentik_postgres_password
|
||||
k8s_users = jsonencode(var.k8s_users)
|
||||
crowdsec_enroll_key = var.crowdsec_enroll_key
|
||||
crowdsec_db_password = var.crowdsec_db_password
|
||||
crowdsec_dash_api_key = var.crowdsec_dash_api_key
|
||||
crowdsec_dash_machine_id = var.crowdsec_dash_machine_id
|
||||
crowdsec_dash_machine_password = var.crowdsec_dash_machine_password
|
||||
alertmanager_slack_api_url = var.alertmanager_slack_api_url
|
||||
cloudflare_api_key = var.cloudflare_api_key
|
||||
cloudflare_tunnel_token = var.cloudflare_tunnel_token
|
||||
alertmanager_account_password = var.alertmanager_account_password
|
||||
monitoring_idrac_password = var.monitoring_idrac_password
|
||||
tiny_tuya_service_secret = var.tiny_tuya_service_secret
|
||||
haos_api_token = var.haos_api_token
|
||||
pve_password = var.pve_password
|
||||
grafana_db_password = var.grafana_db_password
|
||||
grafana_admin_password = var.grafana_admin_password
|
||||
vaultwarden_smtp_password = var.vaultwarden_smtp_password
|
||||
wireguard_wg_0_conf = var.wireguard_wg_0_conf
|
||||
wireguard_wg_0_key = var.wireguard_wg_0_key
|
||||
wireguard_firewall_sh = var.wireguard_firewall_sh
|
||||
xray_reality_clients = jsonencode(var.xray_reality_clients)
|
||||
xray_reality_private_key = var.xray_reality_private_key
|
||||
xray_reality_short_ids = jsonencode(var.xray_reality_short_ids)
|
||||
mailserver_accounts = jsonencode(var.mailserver_accounts)
|
||||
mailserver_aliases = jsonencode(var.mailserver_aliases)
|
||||
mailserver_opendkim_key = jsonencode(var.mailserver_opendkim_key)
|
||||
mailserver_sasl_passwd = jsonencode(var.mailserver_sasl_passwd)
|
||||
mailserver_roundcubemail_db_password = var.mailserver_roundcubemail_db_password
|
||||
webhook_handler_git_user = var.webhook_handler_git_user
|
||||
webhook_handler_git_token = var.webhook_handler_git_token
|
||||
technitium_username = var.technitium_username
|
||||
technitium_password = var.technitium_password
|
||||
truenas_api_key = var.truenas_api_key
|
||||
truenas_ssh_private_key = var.truenas_ssh_private_key
|
||||
})
|
||||
depends_on = [helm_release.vault]
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
terraform {
|
||||
required_providers {
|
||||
vault = {
|
||||
source = "hashicorp/vault"
|
||||
version = "~> 4.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
variable "vault_root_token" {
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
provider "vault" {
|
||||
address = "https://vault.viktorbarzin.me"
|
||||
token = var.vault_root_token
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue