ansible/scripts/vault-export-env.sh
ilia de49b34cdc
Some checks failed
CI / skip-ci-check (pull_request) Successful in 6s
CI / lint-and-test (pull_request) Failing after 9s
CI / ansible-validation (pull_request) Failing after 6s
CI / secret-scanning (pull_request) Successful in 5s
CI / dependency-scan (pull_request) Successful in 8s
CI / sast-scan (pull_request) Failing after 5s
CI / license-check (pull_request) Successful in 11s
CI / vault-check (pull_request) Failing after 6s
CI / playbook-test (pull_request) Failing after 6s
CI / container-scan (pull_request) Failing after 6s
CI / sonar-analysis (pull_request) Failing after 2s
CI / workflow-summary (pull_request) Successful in 4s
Add homelab monitoring, portfolio site, and vault tooling.
Document pve10 static IPs, monitoring stack, and site LXCs; add portfolio
to inventory; Mailcow mailbox automation; vault import/export scripts;
security audit guides and UniFi DHCP reference.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 16:25:07 -04:00

82 lines
2.8 KiB
Bash
Executable File

#!/usr/bin/env bash
# Write Ansible vault secrets into .env (for local scripts / reference).
# Does not print secret values. Does not overwrite non-empty .env keys.
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
ENV_FILE="${1:-${REPO_ROOT}/.env}"
VAULT_FILE="${REPO_ROOT}/inventories/production/group_vars/all/vault.yml"
VAULT_PASS="${HOME}/.ansible-vault-pass"
ANSIBLE_VAULT="${REPO_ROOT}/.venv/bin/ansible-vault"
[[ -f "${VAULT_PASS}" ]] || { echo "Missing ${VAULT_PASS}" >&2; exit 1; }
"${REPO_ROOT}/.venv/bin/python3" - "${ENV_FILE}" "${VAULT_FILE}" "${VAULT_PASS}" "${ANSIBLE_VAULT}" <<'PY'
import subprocess, sys, yaml
from pathlib import Path
env_file, vault_file, vault_pass, ansible_vault = sys.argv[1:5]
# vault key -> .env key
MAP = {
"vault_mailcow_api_key": "MAILCOW_API_KEY",
"vault_alerts_mailbox_password": "ALERTS_PASSWORD",
"vault_uptime_kuma_password": "KUMA_PASSWORD",
"vault_uptime_kuma_user": "KUMA_USER",
"vault_uptime_kuma_url": "KUMA_URL",
"vault_umami_admin_password": "UMAMI_ADMIN_PASSWORD",
"vault_umami_db_password": "UMAMI_DB_PASS",
"vault_umami_app_secret": "UMAMI_APP_SECRET",
"vault_kuma_smtp_host": "SMTP_HOST",
"vault_kuma_smtp_port": "SMTP_PORT",
"vault_kuma_smtp_user": "SMTP_USER",
"vault_kuma_smtp_password": "SMTP_PASS",
"vault_kuma_smtp_to": "SMTP_TO",
"vault_mattermost_url": "MATTERMOST_URL",
"vault_mattermost_token": "MATTERMOST_TOKEN",
"vault_mattermost_allowed_users": "MATTERMOST_ALLOWED_USERS",
}
def parse_env(text):
d = {}
for line in text.splitlines():
line = line.strip()
if not line or line.startswith("#") or "=" not in line:
continue
k, _, v = line.partition("=")
d[k.strip()] = v.strip().strip("'").strip('"')
return d
text = subprocess.check_output(
[ansible_vault, "view", vault_file, "--vault-password-file", vault_pass],
text=True,
)
data = yaml.safe_load(text) or {}
existing = parse_env(Path(env_file).read_text()) if Path(env_file).exists() else {}
merged = dict(existing)
for vk, ek in MAP.items():
val = data.get(vk)
if val is None or val == "":
continue
if merged.get(ek):
continue
merged[ek] = str(val)
pw = data.get("vault_mailcow_mailbox_passwords") or {}
if pw.get("alerts") and not merged.get("ALERTS_PASSWORD"):
merged["ALERTS_PASSWORD"] = str(pw["alerts"])
header = """# Merged from Ansible vault (make vault-export-env). Fill gaps manually.
# vault → .env: make vault-export-env
# .env → vault: make vault-import-env
# hosts → .env → vault: make vault-pull-infra-secrets
"""
body = "\n".join(f"{k}={v}" for k, v in sorted(merged.items())) + "\n"
Path(env_file).write_text(header + body)
print(f"Wrote {len(merged)} keys to {env_file} (existing non-empty keys kept)")
PY
chmod 600 "${ENV_FILE}" 2>/dev/null || true