Storage¶
Target Architecture — Final-State Design
Each store below is owned by exactly one microservice and accessed only through that service. Stores are tenant-partitioned, and all are provisioned by Pulumi alongside the environments they serve.
The platform uses a small set of purpose-fit Azure stores. Relational data (inventory, config, deployment, scaling, drift metadata) lives in Azure SQL / PostgreSQL via NHibernate. Secrets live exclusively in Azure Key Vault. Artifacts and logs live in Azure Blob. Health telemetry flows to Application Insights. High-churn state snapshots use Cosmos DB.
Storage Map¶
| Data | Store | Owner Service | Access Pattern | Retention | Notes |
|---|---|---|---|---|---|
| Runtime environments & inventory | Azure SQL / PostgreSQL | RuntimeEnvironmentService, ServiceCatalogRuntimeService | Read-heavy point + range queries by environment/tenant | Lifetime; retired services 90 days | System of record; NHibernate; tenant-scoped |
| Deployment metadata & history | Azure SQL / PostgreSQL | DeploymentService | Write on rollout, read for status/rollback | 1 year | State machine + rollback targets |
| Runtime configuration | Azure SQL / PostgreSQL | RuntimeConfigurationService | Versioned writes, read on sync | 1 year (all versions) | No secret values stored — references only |
| Secret bindings (metadata) | Azure SQL / PostgreSQL | SecretBindingService | Low-volume CRUD | 1 year | Metadata only; values stay in Key Vault |
| Secret material | Azure Key Vault | SecretBindingService | Resolve by managed identity at runtime | Per rotation policy | Never materialized into config or logs |
| Scaling policies & history | Azure SQL / PostgreSQL | RuntimeScalingService | Read on evaluation, append scaling events | 1 year | Drives HPA/KEDA/ACA rules |
| Tenant bindings & quotas | Azure SQL / PostgreSQL | TenantRuntimeIsolationService | Read on every tenant-scoped op | Lifetime | Isolation boundary |
| Health results (recent) | Azure SQL / PostgreSQL | RuntimeHealthService | Append + latest-by-service reads | 30 days | Recent results for UI/scaling |
| Health telemetry (detail) | Application Insights | RuntimeHealthService | Time-series ingest + query (KQL) | App Insights policy | Probe latencies, dependency maps, traces |
| Deployment artifacts & logs | Azure Blob Storage | DeploymentService | Write on rollout, read on demand | 90 days then cool tier | Step logs, rendered manifests, rollout artifacts |
| Drift findings | Azure SQL / PostgreSQL | RuntimeDriftDetectionService | Append + query by environment | 1 year resolved / indefinite open | Findings + remediation history |
| Drift state snapshots | Cosmos DB | RuntimeDriftDetectionService | High-churn document writes/reads | 30 days rolling | Full actual-vs-desired snapshots |
| Container images | Azure Container Registry | DeploymentService (consumes) | Pull on deploy | Per ACR retention policy | Built by DevOps platform; runtime is a consumer |
Persistence Conventions¶
- NHibernate is the relational ORM for all Azure SQL / PostgreSQL stores, per the
ConnectSoft.MicroserviceTemplatePersistenceModel.NHibernatelayer. - Database-per-service — every service owns its schema; cross-service data is obtained via APIs or events, never shared tables.
- Tenant partitioning —
tenantIdis a mandatory, indexed column on every table; pooled tenants are isolated by row-level predicates and siloed tenants by dedicated databases. - Migrations — schema changes ship as
DatabaseModel.Migrationsand are applied by the deployment pipeline before workload rollout.
Secret Handling¶
Secrets are a first-class storage concern handled exclusively by Azure Key Vault:
SecretBindingrecords hold references (keyVaultRef,secretName,currentVersion) — never values.- Workloads resolve secrets at runtime via managed identity; no secret is written to
RuntimeConfiguration, Blob, logs, or telemetry. - Rotation is performed by the SecretRotationWorker, which produces a new Key Vault version and emits
SecretRotated.
Provisioning¶
All stores are declared as Pulumi (.NET/C#) resources and provisioned with the environment by RuntimeEnvironmentService, so storage topology is reproducible, diffable, and reconciled by the DriftDetectionWorker.