Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 8, 2026

Adds GitOps-based database provisioning for NetBox using 1Password Operator for credential management, with namespace isolation between admin and runtime credentials.

Architecture

Three-phase sync wave orchestration:

  • Wave 10: netbox-secrets → Provision 1Password-backed secrets in infra-netbox
  • Wave 15: netbox-db-provisioner → Run PreSync hook to create database/role in db-postgres
  • Wave 20: netbox → Deploy application

Namespace isolation:

  • db-postgres: Contains postgres-admin and netbox-db-credentials (admin context)
  • infra-netbox: Contains netbox-db-credentials, netbox-redis-credentials, netbox-django-secret, netbox-superuser (app context)

Implementation

DB Provisioning (k8s/db-provisioning/netbox/)

  • PreSync Job creates role and database idempotently
  • Uses psql --set variables + PostgreSQL format(%I, %L) for SQL injection protection
  • TTL: 3600s, hook delete policy: HookSucceeded
# Parameterized SQL via psql variables (no string interpolation)
psql -v ON_ERROR_STOP=1 \
  --set=netbox_db_name=netbox \
  --set=netbox_user="$NETBOX_DB_USER" \
  --set=netbox_password="$NETBOX_DB_PASSWORD" \
  -f /tmp/provision.sql
-- Safe identifier and literal handling
EXECUTE format(
  'CREATE DATABASE %I WITH OWNER = %I',
  :'netbox_db_name',
  :'netbox_user'
);

App Configuration (argocd/apps/infra/netbox.yml)

  • Wired NetBox Helm chart to use existingSecret for all credentials
  • Configured externalDatabase, tasksDatabase, cachingDatabase, Django secret, and superuser

OnePasswordItems

  • Two sets: one in db-postgres for provisioning, one in infra-netbox for runtime
  • Points to vaults/HomeLab/items/* for centralized credential management

Security

  • No admin credentials in app namespace
  • No changes to Bitnami PostgreSQL or Paperless configuration
  • Password rotation via 1Password Operator triggers job rerun
  • All SQL operations idempotent (safe reruns)

Pattern for Future Apps

Copy k8s/db-provisioning/netbox/ and k8s/infra/netbox/, update:

  1. Database name and username variables
  2. 1Password item paths
  3. Argo Application names and sync waves
Original prompt

This section details on the original issue you should resolve

<issue_title>NetBox DB Provisioning + App Deployment via GitOps + 1Password Operator</issue_title>
<issue_description>## Goals

  1. Provision NetBox database + user in the shared Postgres cluster without impacting Paperless.
  2. Keep DB admin credentials confined to the db-postgres namespace.
  3. Keep app runtime credentials confined to the app namespace (infra-netbox).
  4. Support repeatable onboarding for future apps by copying a folder and changing names.

Non-goals

  • No changes to the Bitnami Postgres Helm release.
  • No changes to Paperless role/password/database.
  • No “trust” edits to pg_hba.conf (we already recovered; now we operate normally).

Repo Layout

Create two new GitOps apps:

argocd/
  apps/
    db/
      netbox-db-provisioner.yml
    infra/
      netbox.yml

k8s/
  db-provisioning/
    netbox/
      00-onepassworditems-db-postgres.yaml
      10-netbox-db-provision-job.yaml
  infra/
    netbox/
      00-onepassworditems-infra-netbox.yaml
      10-netbox-application.yaml   (or keep Argo Application in argocd/apps/infra)

(Exact placement is flexible; the key is separation by concern: db-provisioning/* vs infra/*.)


Prereqs

  • 1Password Operator is already installed and working.
  • A 1Password vault exists for Coachlight secrets.
  • coachlight_admin exists in Postgres and has superuser (or at least createdb/createrole).

1Password Items Required (in 1Password)

Create these items in 1Password (single source of truth):

A) postgres-admin (DBA identity)

Fields:

  • username: coachlight_admin
  • password: <strong password>

B) netbox-db-credentials (app identity)

Fields:

  • username: netbox
  • password: <strong password>

C) netbox-redis-credentials (optional if Redis requires auth)

Fields:

  • password: <strong password>

D) netbox-django-secret

Fields:

  • secretKey: <strong random string>

E) netbox-superuser

Fields:

  • password: <strong password>
    (Email can stay in Helm values.)

Argo Application 1: DB Provisioning (lives with database)

File: argocd/apps/db/netbox-db-provisioner.yml

  • Target namespace: db-postgres
  • Sync wave: earlier than NetBox app (e.g. "15" if NetBox is "20")

Responsibilities

  • Create secrets in db-postgres using OnePasswordItem:

    • postgres-admin
    • netbox-db-credentials
  • Run a Job that:

    • Creates role netbox if missing
    • Creates database netbox if missing
    • Ensures ownership/grants
    • Ensures password matches 1Password value (rotation-friendly)

Manifest: k8s/db-provisioning/netbox/00-onepassworditems-db-postgres.yaml

Create Two OnePasswordItems in namespace db-postgres:

  • postgres-admin → points at 1Password item postgres-admin
  • netbox-db-credentials → points at 1Password item netbox-db-credentials

Naming contract:

  • K8s Secret name == OnePasswordItem name
  • Keys inside Secret match 1Password fields (username, password)

Manifest: k8s/db-provisioning/netbox/10-netbox-db-provision-job.yaml

Job requirements

  • Namespace: db-postgres

  • Uses a container with psql available (Bitnami postgres image is fine).

  • Reads env from Secrets:

    • POSTGRES_ADMIN_USER / POSTGRES_ADMIN_PASSWORD from postgres-admin secret keys username/password
    • NETBOX_DB_USER / NETBOX_DB_PASSWORD from netbox-db-credentials secret keys username/password
  • Connects to the Postgres service:

    • host: postgres-postgresql.db-postgres.svc.cluster.local
    • port: 5432
    • db: postgres (maintenance DB)
  • Runs idempotent SQL.

SQL contract (idempotent)

Run via psql with ON_ERROR_STOP=1.

Use one transaction-safe sequence:

  1. Create role if missing (or ensure it can login)
  2. Set role password to match NETBOX_DB_PASSWORD (rotate-friendly)
  3. Create DB if missing with owner netbox
  4. Ensure privileges

Implementation detail: use DO $$ ... $$; blocks for “IF NOT EXISTS” and always run ALTER ROLE ... PASSWORD.

Example SQL logic (Copilot should implement exactly this behavior):

  • DO create role only if not exists
  • ALTER ROLE netbox WITH LOGIN PASSWORD '<from secret>';
  • DO create database only if not exists
  • ALTER DATABASE netbox OWNER TO netbox; (safe even if already)
  • GRANT CONNECT ON DATABASE netbox TO netbox;

Argo hook behavior

Choose ONE:

Option 1 (recommended): normal Job, idempotent

  • Pros: Argo doesn’t need hook semantics; reruns only if changed
  • Cons: Job object persists unless TTL used

Option 2: Argo PreSync hook Job

  • Add annotations:

    • argocd.argoproj.io/hook: PreSync
    • argocd.argoproj.io/hook-delete-policy: HookSucceeded
  • Pros: runs automatically before sync and cleans up

  • Cons: reruns more often; still fine because SQL is idempotent

Pick Option 2 if you want strict ordering every sync; otherwise Option 1.

TTL

Set `spec.ttlSecondsA...


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 6 commits January 8, 2026 04:21
Co-authored-by: SRF-Audio <16975040+SRF-Audio@users.noreply.github.com>
…integration

Co-authored-by: SRF-Audio <16975040+SRF-Audio@users.noreply.github.com>
Co-authored-by: SRF-Audio <16975040+SRF-Audio@users.noreply.github.com>
…mization files

Co-authored-by: SRF-Audio <16975040+SRF-Audio@users.noreply.github.com>
Co-authored-by: SRF-Audio <16975040+SRF-Audio@users.noreply.github.com>
Co-authored-by: SRF-Audio <16975040+SRF-Audio@users.noreply.github.com>
Copilot AI changed the title [WIP] Provision NetBox database and app deployment via GitOps Implement NetBox DB provisioning and deployment via GitOps with 1Password Operator Jan 8, 2026
Copilot AI requested a review from SRF-Audio January 8, 2026 04:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NetBox DB Provisioning + App Deployment via GitOps + 1Password Operator

2 participants