Config Platform - Deployment Blueprint¶
Overview¶
This document provides concrete deployment patterns and configurations for Config Platform services. Use these patterns to generate deployment manifests, infrastructure code, and CI/CD pipelines.
Container Deployment¶
Dockerfile Pattern¶
FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /src
COPY ["ConfigRegistry/ConfigRegistry.csproj", "ConfigRegistry/"]
RUN dotnet restore "ConfigRegistry/ConfigRegistry.csproj"
COPY . .
WORKDIR "/src/ConfigRegistry"
RUN dotnet build "ConfigRegistry.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "ConfigRegistry.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "ConfigRegistry.dll"]
Container Image Configuration¶
# Container registry and image
image: connectsoft.azurecr.io/config-registry:1.0.0
ports:
- containerPort: 80
protocol: TCP
- containerPort: 443
protocol: TCP
env:
- name: ASPNETCORE_ENVIRONMENT
value: "Production"
- name: ASPNETCORE_URLS
value: "http://+:80"
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 2000m
memory: 2Gi
Kubernetes Deployment¶
Config Registry Deployment¶
apiVersion: apps/v1
kind: Deployment
metadata:
name: config-registry
namespace: config-platform
labels:
app: config-registry
version: v1
spec:
replicas: 3
selector:
matchLabels:
app: config-registry
template:
metadata:
labels:
app: config-registry
version: v1
spec:
containers:
- name: config-registry
image: connectsoft.azurecr.io/config-registry:1.0.0
ports:
- containerPort: 80
name: http
env:
- name: ConnectionStrings__DefaultConnection
valueFrom:
secretKeyRef:
name: config-registry-secrets
key: database-connection
- name: Redis__ConnectionString
valueFrom:
secretKeyRef:
name: config-registry-secrets
key: redis-connection
- name: EventBus__ConnectionString
valueFrom:
secretKeyRef:
name: config-registry-secrets
key: eventbus-connection
livenessProbe:
httpGet:
path: /health/live
port: 80
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /health/ready
port: 80
initialDelaySeconds: 10
periodSeconds: 5
startupProbe:
httpGet:
path: /health/startup
port: 80
initialDelaySeconds: 0
periodSeconds: 10
failureThreshold: 30
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 2000m
memory: 2Gi
---
apiVersion: v1
kind: Service
metadata:
name: config-registry
namespace: config-platform
spec:
selector:
app: config-registry
ports:
- port: 80
targetPort: 80
protocol: TCP
type: ClusterIP
Horizontal Pod Autoscaler¶
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: config-registry-hpa
namespace: config-platform
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: config-registry
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 50
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
- type: Pods
value: 2
periodSeconds: 60
selectPolicy: Max
ConfigMap for Application Settings¶
apiVersion: v1
kind: ConfigMap
metadata:
name: config-registry-config
namespace: config-platform
data:
appsettings.json: |
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"ConfigPlatform": {
"CacheTTL": "01:00:00",
"MaxCacheSize": "1000"
}
}
Secrets Management¶
apiVersion: v1
kind: Secret
metadata:
name: config-registry-secrets
namespace: config-platform
type: Opaque
stringData:
database-connection: "Server=cockroachdb;Database=config;..."
redis-connection: "config-redis:6379"
eventbus-connection: "Endpoint=sb://..."
Azure App Service Deployment¶
App Service Configuration¶
{
"name": "config-registry",
"type": "Microsoft.Web/sites",
"location": "East US",
"properties": {
"serverFarmId": "/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Web/serverfarms/config-platform-plan",
"siteConfig": {
"linuxFxVersion": "DOCKER|connectsoft.azurecr.io/config-registry:1.0.0",
"alwaysOn": true,
"http20Enabled": true,
"minTlsVersion": "1.2",
"ftpsState": "Disabled",
"appSettings": [
{
"name": "ASPNETCORE_ENVIRONMENT",
"value": "Production"
},
{
"name": "ConnectionStrings__DefaultConnection",
"value": "@Microsoft.KeyVault(SecretUri=https://vault.vault.azure.net/secrets/db-connection/)"
}
]
},
"httpsOnly": true
}
}
App Service Plan¶
{
"name": "config-platform-plan",
"type": "Microsoft.Web/serverfarms",
"location": "East US",
"sku": {
"name": "P1v2",
"tier": "PremiumV2",
"capacity": 3
},
"properties": {
"reserved": true
}
}
Database Migration Patterns¶
NHibernate Schema Update¶
public class DatabaseMigrationService
{
private readonly ISessionFactory _sessionFactory;
public async Task MigrateAsync()
{
var configuration = new Configuration();
configuration.Configure();
configuration.AddAssembly(typeof(ConfigItem).Assembly);
var schemaUpdate = new SchemaUpdate(configuration);
await Task.Run(() => schemaUpdate.Execute(false, true));
}
}
Flyway Migration Script¶
-- V1__Initial_schema.sql
CREATE TABLE config_items (
id UUID PRIMARY KEY,
key VARCHAR(500) NOT NULL,
value TEXT NOT NULL,
content_type VARCHAR(100),
is_secret BOOLEAN DEFAULT FALSE,
is_feature_toggle BOOLEAN DEFAULT FALSE,
labels TEXT[],
description VARCHAR(1000),
version INTEGER NOT NULL,
etag VARCHAR(64) NOT NULL,
created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL,
created_by VARCHAR(200) NOT NULL,
updated_by VARCHAR(200) NOT NULL,
config_set_id UUID NOT NULL,
tenant_id UUID NOT NULL,
CONSTRAINT fk_config_set FOREIGN KEY (config_set_id)
REFERENCES config_bundles(id),
CONSTRAINT uk_config_key UNIQUE (config_set_id, tenant_id, key)
);
CREATE INDEX idx_config_items_tenant ON config_items(tenant_id);
CREATE INDEX idx_config_items_config_set ON config_items(config_set_id);
Migration Job¶
apiVersion: batch/v1
kind: Job
metadata:
name: config-registry-migration
namespace: config-platform
spec:
template:
spec:
containers:
- name: migration
image: connectsoft.azurecr.io/config-registry:1.0.0
command: ["dotnet", "ConfigRegistry.dll", "migrate"]
env:
- name: ConnectionStrings__DefaultConnection
valueFrom:
secretKeyRef:
name: config-registry-secrets
key: database-connection
restartPolicy: Never
backoffLimit: 3
Environment Configuration¶
Development Environment¶
# k8s/dev/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: config-platform-dev
---
# k8s/dev/config-registry-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: config-registry
namespace: config-platform-dev
spec:
replicas: 1
# ... (same as production but with dev-specific settings)
Production Environment¶
# k8s/prod/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: config-platform-prod
---
# k8s/prod/config-registry-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: config-registry
namespace: config-platform-prod
spec:
replicas: 5
# ... (production settings with higher resources)
Scaling Patterns¶
Auto-Scaling Based on Metrics¶
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: config-registry-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: config-registry
minReplicas: 3
maxReplicas: 20
metrics:
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "100"
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
Database Connection Pooling¶
services.AddNHibernate(options =>
{
options.ConnectionString = configuration.GetConnectionString("DefaultConnection");
options.ConnectionPoolSize = 20;
options.MaxPoolSize = 100;
options.MinPoolSize = 5;
});
High Availability Patterns¶
Multi-Region Deployment¶
# Primary region
apiVersion: apps/v1
kind: Deployment
metadata:
name: config-registry-us-east
namespace: config-platform
labels:
region: us-east
spec:
replicas: 5
# ...
# Secondary region
apiVersion: apps/v1
kind: Deployment
metadata:
name: config-registry-us-west
namespace: config-platform
labels:
region: us-west
spec:
replicas: 3
# ...
Redis Cluster Configuration¶
apiVersion: v1
kind: ConfigMap
metadata:
name: redis-config
data:
redis.conf: |
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
Health Checks¶
Liveness Probe¶
app.MapHealthChecks("/health/live", new HealthCheckOptions
{
Predicate = check => check.Tags.Contains("live")
});
Readiness Probe¶
app.MapHealthChecks("/health/ready", new HealthCheckOptions
{
Predicate = check => check.Tags.Contains("ready")
});
Startup Probe¶
app.MapHealthChecks("/health/startup", new HealthCheckOptions
{
Predicate = check => check.Tags.Contains("startup")
});
References¶
- Solution Architecture - Deployment architecture details
- Service Integration Blueprint - Service communication patterns