Naming Conventions
Purpose: Define consistent naming patterns for all files, resources, and identifiers in the urbalurba-infrastructure project.
Principle: Predictable names enable automation and make the codebase easier to navigate.
File Naming Conventions
Manifest Files (manifests/*.yaml)
Pattern: NNN-component-type.yaml
Number Ranges:
- 000-029: Core infrastructure (storage, ingress, DNS, networking)
- 030-039: Monitoring and observability
- 040-069: Data services (databases, caches, message queues)
- 070-079: Authentication and authorization
- 080-099: Reserved for future core services
- 200-229: AI and ML services
- 230-299: Application services
- 600-799: Management and admin tools
- 800-899: Development and testing
- 900-999: Reserved for custom/experimental
Type Suffixes:
-config.yaml- Helm values configuration-ingressroute.yaml- Traefik IngressRoute definition-configmap.yaml- Kubernetes ConfigMap-secret.yaml- Kubernetes Secret (never committed)-dashboards.yaml- Grafana dashboard ConfigMaps
Examples:
030-prometheus-config.yaml # Prometheus Helm values
031-tempo-config.yaml # Tempo Helm values
032-loki-config.yaml # Loki Helm values
033-otel-collector-config.yaml # OTEL Collector Helm values
034-grafana-config.yaml # Grafana Helm values
035-grafana-dashboards.yaml # Installation test dashboards
036-grafana-sovdev-verification.yaml # sovdev-logger verification dashboard
037-grafana-loggeloven-dashboards.yaml # Loggeloven test suite
038-grafana-ingressroute.yaml # Grafana UI ingress
039-otel-collector-ingressroute.yaml # OTEL ingress
040-postgresql-config.yaml # PostgreSQL
041-mysql-config.yaml # MySQL
042-mongodb-config.yaml # MongoDB
043-redis-config.yaml # Redis
070-authentik-config.yaml # Authentik SSO
071-authentik-blueprints.yaml # Authentik user/group definitions
076-authentik-csp-middleware.yaml # CSP headers middleware
200-openwebui-config.yaml # OpenWebUI
201-ollama-config.yaml # Ollama
202-litellm-config.yaml # LiteLLM
Numbering Rules:
- Main component gets base number (e.g., 030 for Prometheus)
- Related configs use sequential numbers (031, 032, 033...)
- IngressRoutes use component's number + 8 (e.g., Grafana=034, Ingress=038)
- Dashboards use component's number + variations (035, 036, 037)
- Leave gaps for future expansion within each range
Ansible Playbooks (ansible/playbooks/*.yml)
Pattern: NNN-action-component.yml
Number: Must match corresponding manifest file number
Actions:
setup-- Deploy/install componentremove-- Uninstall/delete componentupdate-- Modify existing componenttest-- Verification/testing playbook
Examples:
030-setup-prometheus.yml # Deploys using manifests/030-prometheus-config.yaml
030-remove-prometheus.yml # Removes Prometheus
031-setup-tempo.yml # Deploys using manifests/031-tempo-config.yaml
031-remove-tempo.yml # Removes Tempo
033-setup-otel-collector.yml # Deploys OTEL Collector
033-remove-otel-collector.yml # Removes OTEL Collector
034-setup-grafana.yml # Deploys Grafana
034-remove-grafana.yml # Removes Grafana
Pattern Rules:
- Setup playbook references external manifest via
values_files: ["{{ config_file }}"]or-f {{ config_file }} - Remove playbook just removes Helm chart
- Number MUST match manifest file (030 playbook uses 030 manifest)
- Never use inline Helm values - always reference external manifest
Service Metadata Files (provision-host/uis/services/)
Pattern: service-[name].sh
Location: provision-host/uis/services/<category>/
Relationship to Playbooks:
- Metadata file declares which Ansible playbook to run (
SCRIPT_PLAYBOOK) - The UIS CLI reads the metadata and calls the playbook automatically
- No imperative code — metadata files are declarative variable assignments
- Files starting with
_are skipped by the scanner (used for helper scripts)
Examples:
provision-host/uis/services/
├── observability/
│ ├── service-prometheus.sh # SCRIPT_PLAYBOOK="030-setup-prometheus.yml"
│ ├── service-tempo.sh # SCRIPT_PLAYBOOK="031-setup-tempo.yml"
│ ├── service-loki.sh # SCRIPT_PLAYBOOK="032-setup-loki.yml"
│ ├── service-otel-collector.sh # SCRIPT_PLAYBOOK="033-setup-otel-collector.yml"
│ └── service-grafana.sh # SCRIPT_PLAYBOOK="034-setup-grafana.yml"
├── databases/
│ ├── service-postgresql.sh # SCRIPT_PLAYBOOK="040-database-postgresql.yml"
│ ├── service-mysql.sh # SCRIPT_PLAYBOOK="041-database-mysql.yml"
│ └── service-redis.sh # SCRIPT_PLAYBOOK="043-setup-redis.yml"
└── ai/
├── service-litellm.sh # SCRIPT_PLAYBOOK="210-setup-litellm.yml"
└── service-openwebui.sh # SCRIPT_PLAYBOOK="208-setup-openwebui.yml"
Metadata File Structure:
#!/bin/bash
# service-[name].sh - [Service] service metadata
# === Required ===
SCRIPT_ID="name" # Unique CLI identifier
SCRIPT_NAME="Display Name" # Human-readable name
SCRIPT_DESCRIPTION="Brief description"
SCRIPT_CATEGORY="CATEGORY_ID" # One of the 9 categories
# === Deployment (Optional) ===
SCRIPT_PLAYBOOK="NNN-setup-name.yml" # Ansible playbook
SCRIPT_REMOVE_PLAYBOOK="NNN-remove-name.yml"
SCRIPT_CHECK_COMMAND="kubectl get pods ..."
SCRIPT_REQUIRES="" # Space-separated service IDs
SCRIPT_PRIORITY="50" # Deploy order (lower = earlier)
# === Extended Metadata (Optional) ===
SCRIPT_KIND="Component" # Component | Resource
SCRIPT_TYPE="service" # service | tool | library | database | cache | message-broker
SCRIPT_OWNER="platform-team" # platform-team | app-team
SCRIPT_PROVIDES_APIS="" # API names this service provides
SCRIPT_CONSUMES_APIS="" # API names this service consumes
Extended Metadata allowed values:
| Field | Allowed Values | Description |
|---|---|---|
SCRIPT_KIND | Component, Resource | Component for software services and tools; Resource for infrastructure (databases, caches, message brokers) |
SCRIPT_TYPE | service, tool, library, database, cache, message-broker | What the component or resource provides |
SCRIPT_OWNER | platform-team, app-team | platform-team for core infrastructure; app-team for user-facing applications |
Directory Structure
UIS Service Directory — services organized by category:
provision-host/uis/services/
├── ai/ # AI & ML services
├── analytics/ # Data science and analytics
├── databases/ # Data storage and caching
├── identity/ # Identity and access management
├── integration/ # Messaging and API gateways
├── management/ # Admin tools and GitOps
├── networking/ # VPN tunnels and network access
├── observability/ # Metrics, logs, and tracing
└── storage/ # Platform storage infrastructure
Supporting Directories:
provision-host/uis/
├── lib/ # Core libraries (categories, stacks, deployment logic)
├── manage/ # CLI entry point (uis-cli.sh)
├── services/ # Service metadata files (see above)
└── templates/ # Config templates and defaults
Rules:
- Category directories match the 9 UIS categories (lowercase)
- Service files use
service-[name].shnaming pattern - Helper files use
_prefix (skipped by scanner)
Kubernetes Resource Naming
Namespaces
Pattern: lowercase-descriptive
Most services deploy to the default namespace. Dedicated namespaces are used when a service requires isolation or when the Helm chart creates its own namespace.
Examples:
default # Most services (PostgreSQL, MySQL, Redis, pgAdmin, whoami, LiteLLM, etc.)
monitoring # Observability stack (Prometheus, Grafana, Loki, Tempo, OTEL)
authentik # Authentik SSO
kube-system # Kubernetes system
traefik # Traefik ingress controller
Rules:
- Single word or hyphenated
- All lowercase
- Prefer
defaultnamespace unless isolation is needed - No version numbers
Helm Release Names
Pattern: component-name
Examples:
prometheus # Prometheus monitoring
tempo # Tempo tracing
loki # Loki log aggregation
otel-collector # OpenTelemetry Collector
grafana # Grafana visualization
authentik # Authentik SSO
openwebui # OpenWebUI
Rules:
- Match component name
- Lowercase with hyphens
- No namespace prefix (namespace is separate)
- Use official chart name when possible
ConfigMap Names
Pattern: component-purpose or component-purpose-generated
Examples:
grafana-dashboards-installation # Installation test dashboards
grafana-dashboards-sovdev # sovdev-logger verification
grafana-dashboards-loggeloven # Loggeloven test suite
otel-collector-config # OTEL Collector configuration
Rules:
- Start with component name
- Add descriptive suffix
- Use
-generatedsuffix for auto-generated content - All lowercase with hyphens
IngressRoute Names
Pattern: component or component-variant
Examples:
grafana # Grafana UI ingress
otel-collector # OTEL Collector ingress
prometheus # Prometheus UI ingress (if needed)
authentik # Authentik SSO ingress
whoami-protected # Test service with auth
whoami-public # Test service without auth
Rules:
- Match component name
- Add variant suffix if multiple routes for same component
- Use descriptive suffixes:
-protected,-public,-api,-ui
Git and Version Control
Branch Names
Pattern: type/description
Types:
feature/- New feature developmentfix/- Bug fixesdocs/- Documentation changesrefactor/- Code refactoringtest/- Testing changes
Examples:
feature/monitoring-stack-migration
feature/sovdev-logger-integration
fix/authentik-csp-headers
docs/development-workflow
refactor/monitoring-030-039
Rules:
- Lowercase with hyphens
- Descriptive but concise
- Type prefix required
- No ticket numbers (use PR description)
Commit Messages
Pattern:
<type>: <subject>
<body>
<footer>
Types:
feat:- New featurefix:- Bug fixdocs:- Documentationrefactor:- Code refactoringtest:- Testschore:- Maintenance
Examples:
feat: Add sovdev-logger TypeScript implementation
- Multi-transport architecture (Console + File + OTLP)
- Smart defaults for production vs development
- Full Loggeloven compliance with credential filtering
Closes #123
---
fix: OTLP collector ingress Host header routing
Add missing Host header to OTEL Collector IngressRoute
to enable proper Traefik routing for external OTLP ingestion.
---
docs: Create development workflow rules
Add docs/rules-development-workflow.md explaining
Claude Code vs manual workflows and path conventions.
Rules:
- Subject line: 50 chars max, imperative mood, no period
- Body: Wrap at 72 chars, explain what and why
- Footer: Reference issues/PRs
- Use type prefix
Summary
Key Principles:
- ✅ Numbers indicate deployment order and relationships
- ✅ Manifest number = Playbook number (030 manifest → 030 playbook)
- ✅ Scripts are sequential within directory (01, 02, 03...)
- ✅ All lowercase with hyphens for most names
- ✅ Descriptive suffixes for variants (-config, -ingressroute, -dashboards)
- ✅ Leave gaps in numbering for future expansion
- ✅ External manifest files, never inline Helm values
- ✅ Consistent patterns across all file types
When adding new components:
- Create a service metadata file in
provision-host/uis/services/<category>/service-<name>.sh - Choose appropriate manifest number range for the category
- Create manifest config file(s) in
manifests/ - Create matching Ansible playbooks (setup + remove) in
ansible/playbooks/ - Set
SCRIPT_PLAYBOOK,SCRIPT_REMOVE_PLAYBOOK, andSCRIPT_CHECK_COMMANDin metadata - Declare dependencies with
SCRIPT_REQUIRESif needed - Test with
./uis deploy <name>and./uis status
Reference:
- doc/rules-development-workflow.md - Workflow and command execution
- doc/rules-automated-kubernetes-deployment.md - UIS deployment system
- doc/rules-ingress-traefik.md - IngressRoute patterns