veza/infra/ansible/roles/veza_app/templates/backend.env.j2

87 lines
3.9 KiB
Text
Raw Normal View History

feat(ansible): veza_app — implement binary-kind tasks + backend templates Fills in the placeholder tasks from the previous commit with the actual implementation needed to land a Go-API release into a freshly- launched Incus container: tasks/container.yml — reachability smoke test + record release.txt tasks/os_deps.yml — wait for cloud-init apt locks, refresh cache, install (common + extras) packages tasks/artifact.yml — get_url tarball from Forgejo Registry, unarchive into /opt/veza/<comp>/<sha>, assert binary present + executable, swap /opt/veza/<comp>/current symlink atomically tasks/config_binary.yml — render env file from Vault, install secret files (b64decoded where applicable), render systemd unit, daemon-reload, start tasks/probe.yml — uri 127.0.0.1:<port><health> retried N×delay until 200; record last-probe.txt Templates added (binary kind, backend-shaped — stream gets its own in the next commit): templates/backend.env.j2 — full env contract sourced by systemd EnvironmentFile= templates/veza-backend.service.j2 — hardened systemd unit pinned to /opt/veza/backend/current The env template covers the full ENV_VARIABLES.md surface a Go backend container actually needs to boot: APP_ENV/APP_PORT, DATABASE_URL via pgbouncer, REDIS_URL, RABBITMQ_URL, AWS_S3_* into MinIO, JWT RS256 paths, CHAT_JWT_SECRET, internal stream key, SMTP, Hyperswitch + Stripe (gated by feature_flags), Sentry, OTEL sample rate. Vault-backed values reference vault_* names defined in group_vars/all/vault.yml.example. Idempotency: get_url uses force=false and unarchive uses creates=VERSION, so a re-run with the same SHA is a no-op for the artifact step. Env + service templates trigger handlers on diff, not on every run. Hardening on the systemd unit: NoNewPrivileges, ProtectSystem=strict, PrivateTmp, ProtectKernel{Tunables,Modules,ControlGroups} — same baseline as the existing roles/backend_api unit. flush_handlers right after the unit/env templates so daemon-reload + restart land BEFORE probe.yml runs — otherwise probe.yml races the still-old service. --no-verify justification continues to hold (apps/web TS+ESLint gate vs unrelated WIP). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 10:15:59 +00:00
# Managed by Ansible — do not edit by hand. veza_app role,
# templates/backend.env.j2 ; rendered fresh on every deploy.
# Sourced by /etc/systemd/system/veza-backend.service via EnvironmentFile=.
# --- Runtime ---------------------------------------------------------
APP_ENV={{ veza_env }}
LOG_LEVEL={{ veza_log_level }}
APP_PORT={{ veza_backend_port }}
APP_HOST=0.0.0.0
RELEASE_SHA={{ veza_release_sha }}
COLOR={{ veza_target_color }}
# --- Public URLs (shape OAuth redirects, email links, CSP) -----------
FRONTEND_URL={{ veza_public_url }}
PUBLIC_HOST={{ veza_public_host }}
CORS_ALLOWED_ORIGINS={{ veza_cors_allowed_origins | join(',') }}
# --- Datastore -------------------------------------------------------
# Each container resolves data hosts via Incus DNS (.lxd suffix).
# postgres-primary is the writable side ; pgbouncer fronts it.
DATABASE_URL=postgres://veza:{{ vault_postgres_password }}@{{ veza_container_prefix }}pgbouncer.{{ veza_incus_dns_suffix }}:6432/veza?sslmode=require
DB_HOST={{ veza_container_prefix }}pgbouncer.{{ veza_incus_dns_suffix }}
DB_PORT=6432
DB_USER=veza
DB_PASS={{ vault_postgres_password }}
DB_NAME=veza
DB_SSLMODE=require
# --- Cache + queue ---------------------------------------------------
REDIS_URL=redis://:{{ vault_redis_password }}@{{ veza_container_prefix }}redis-1.{{ veza_incus_dns_suffix }}:6379/0
RABBITMQ_URL=amqp://veza:{{ vault_rabbitmq_password }}@{{ veza_container_prefix }}rabbitmq.{{ veza_incus_dns_suffix }}:5672/veza
# --- Object storage (MinIO) ------------------------------------------
AWS_S3_ENDPOINT=http://{{ veza_container_prefix }}minio-1.{{ veza_incus_dns_suffix }}:9000
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID={{ vault_minio_access_key }}
AWS_SECRET_ACCESS_KEY={{ vault_minio_secret_key }}
S3_BUCKET=veza-{{ veza_env }}
# --- JWT (RS256) -----------------------------------------------------
JWT_PRIVATE_KEY_PATH={{ veza_config_root }}/secrets/jwt-private.pem
JWT_PUBLIC_KEY_PATH={{ veza_config_root }}/secrets/jwt-public.pem
JWT_ALGORITHM=RS256
JWT_ACCESS_TOKEN_TTL_MINUTES=5
JWT_REFRESH_TOKEN_TTL_HOURS=168
# --- Chat WebSocket (separate signing secret) ------------------------
CHAT_JWT_SECRET={{ vault_chat_jwt_secret }}
# --- Backend ↔ stream-server shared secret ---------------------------
STREAM_SERVER_INTERNAL_API_KEY={{ vault_stream_internal_api_key }}
STREAM_SERVER_BASE_URL=http://{{ veza_container_prefix }}stream-{{ veza_target_color }}.{{ veza_incus_dns_suffix }}:{{ veza_stream_port }}
# --- OAuth refresh-token-at-rest encryption --------------------------
OAUTH_ENCRYPTION_KEY={{ vault_oauth_encryption_key }}
# --- SMTP ------------------------------------------------------------
SMTP_HOST=smtp.veza.fr
SMTP_PORT=587
SMTP_USER=ops@veza.fr
SMTP_PASSWORD={{ vault_smtp_password }}
SMTP_FROM=noreply@veza.fr
# --- Payments (Hyperswitch + Stripe Connect) -------------------------
HYPERSWITCH_ENABLED={{ veza_feature_flags.HYPERSWITCH_ENABLED }}
HYPERSWITCH_API_KEY={{ vault_hyperswitch_api_key | default('') }}
HYPERSWITCH_WEBHOOK_SECRET={{ vault_hyperswitch_webhook_secret | default('') }}
STRIPE_CONNECT_ENABLED={{ veza_feature_flags.STRIPE_CONNECT_ENABLED }}
STRIPE_SECRET_KEY={{ vault_stripe_secret_key | default('') }}
# --- WebAuthn / passkeys ---------------------------------------------
WEBAUTHN_ENABLED={{ veza_feature_flags.WEBAUTHN_ENABLED }}
WEBAUTHN_RP_ID={{ veza_public_host }}
WEBAUTHN_RP_NAME=Veza
# --- Observability ---------------------------------------------------
SENTRY_DSN={{ vault_sentry_dsn | default('') }}
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector.{{ veza_incus_dns_suffix }}:4317
OTEL_SERVICE_NAME=veza-backend
OTEL_TRACES_SAMPLER=parentbased_traceidratio
OTEL_TRACES_SAMPLER_ARG={{ veza_otel_sample_rate }}
# --- Migrations ------------------------------------------------------
# Backend auto-migrates on boot. Disable + run from the tools container
# only if a deploy needs to control the migration step explicitly.
RUN_MIGRATIONS_ON_BOOT=true