Cloud-Native Mindset¶
This document defines ConnectSoft's cloud-native architecture principles. It is written for architects and engineers building systems for Azure Kubernetes and cloud infrastructure.
Everything runs as containers with Infrastructure-as-Code, autoscaling, multi-tenant-safe design, and observability built-in. Cloud-native is not optional—it's the default for all ConnectSoft-generated systems.
Important
All systems must be multi-tenant-safe by design, containerized, and deployable via Infrastructure-as-Code. Autoscaling and observability are not afterthoughts—they're built into every template.
Principles We Follow¶
ConnectSoft follows cloud-native principles inspired by the 12-Factor App methodology:
Stateless Services¶
- No local state - Services don't store state in memory or local files
- State in external stores - Databases, caches, object storage
- Session state externalized - Sessions stored in Redis or database
Configuration from Environment¶
- Environment variables - Configuration via environment variables
- External config service - Use ConnectSoft Config Platform for runtime config
- Secrets in Key Vault - Never hardcode secrets, use Azure Key Vault
Logs as Streams¶
- Structured logging - JSON logs with correlation IDs
- Log aggregation - Logs sent to Azure Log Analytics
- No file-based logs - Logs are streams, not files
Disposability¶
- Fast startup - Services start in seconds, not minutes
- Graceful shutdown - Handle shutdown signals, finish in-flight requests
- Crash recovery - Kubernetes restarts failed containers automatically
Multi-Tenant Safe¶
- Tenant isolation - Tenant context at every layer
- No data leakage - Strict tenant filtering in queries
- Tenant-aware scaling - Scale per tenant if needed
Observability Built-In¶
- Logging, tracing, metrics - All three pillars from day one
- Health checks - Built-in health check endpoints
- Distributed tracing - OpenTelemetry integration
Stateless Services and Scalability¶
Stateless Design¶
Why: Stateless services scale horizontally without coordination.
How Templates Encourage Statelessness:
- No in-memory state - All state in databases or caches
- Session externalization - Sessions in Redis or database
- Request-scoped dependencies - Dependencies created per request
Example:
// Stateless - no instance variables
public class InvoiceService
{
private readonly IInvoiceRepository _repository; // Injected per request
public async Task<Invoice> GetInvoiceAsync(Guid id)
{
return await _repository.GetByIdAsync(id); // State in database
}
}
Horizontal Scaling¶
How It Works: - Kubernetes creates multiple pod replicas - Load balancer distributes requests across replicas - Each replica handles requests independently - No coordination needed between replicas
Scaling Triggers: - CPU utilization - Memory usage - Request rate - Custom metrics (e.g., queue length)
Configuration and Secrets¶
Configuration Management¶
External Config Service: - Use ConnectSoft Config Platform for runtime configuration - Feature flags, connection strings, business rules - Changes without redeployment
Environment Variables: - Deployment-time configuration (e.g., environment name, region) - Set in Kubernetes ConfigMaps - Different values per environment
Example:
# Kubernetes ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: invoice-service-config
data:
Environment: production
Region: eastus
LogLevel: Information
Secrets Management¶
Azure Key Vault: - Store secrets (connection strings, API keys, certificates) - Access via managed identity - Automatic rotation support
User Secrets (Development):
- Local development uses user secrets
- Never commit secrets to source control
- .gitignore includes secrets files
Example:
// Access Key Vault via managed identity
var secretClient = new SecretClient(
new Uri("https://myvault.vault.azure.net/"),
new DefaultAzureCredential());
var connectionString = await secretClient.GetSecretAsync("DatabaseConnectionString");
Tip
Always use Azure Key Vault for secrets in production. Never hardcode secrets or commit them to source control. Use managed identities for Key Vault access—no secrets needed to access secrets.
Resilience and Fault Tolerance¶
Retry Policies¶
Built-in Retries: - HTTP clients retry transient failures - Database connections retry on timeout - Event publishing retries on failure
Exponential Backoff: - First retry: immediate - Subsequent retries: exponential delay - Max retries: 3-5 attempts
Circuit Breakers¶
Purpose: Prevent cascading failures when downstream service is down.
How It Works: - Monitor failure rate - Open circuit after threshold failures - Fail fast while circuit is open - Close circuit after timeout
Library: ConnectSoft.Extensions.Http provides circuit breaker support
Timeouts¶
Request Timeouts: - All external calls have timeouts - Default: 30 seconds - Configurable per service
Connection Timeouts: - Database connections timeout after 15 seconds - HTTP connections timeout after 10 seconds
Health Checks¶
Built-in Health Checks:
- /health endpoint for Kubernetes liveness probe
- /health/ready endpoint for readiness probe
- Checks database connectivity, external services
Example:
builder.Services.AddHealthChecks()
.AddCheck<DatabaseHealthCheck>("database")
.AddCheck<ExternalServiceHealthCheck>("external-service");
Tip
Use built-in resilience libraries (ConnectSoft.Extensions.Http, Polly) for retries, circuit breakers, and timeouts. Don't implement resilience logic yourself—use proven libraries.
Deployment Targets¶
Azure Container Apps¶
When to Use: - Serverless container workloads - Auto-scaling based on HTTP traffic - Simple deployment model
Characteristics: - Managed Kubernetes (simplified) - Pay per use - Built-in scaling
Azure Kubernetes Service (AKS)¶
When to Use: - Full Kubernetes control - Complex orchestration needs - Multi-region deployments
Characteristics: - Full Kubernetes API - Node pools and autoscaling - Advanced networking
Azure App Service (Legacy)¶
When to Use: - Simple web apps (legacy) - Not recommended for new services
Characteristics: - Platform-as-a-Service - Less control than containers - Easier deployment
Container-First Thinking¶
All Services Are Containerized: - Docker images for all services - Kubernetes manifests for deployment - Container registry (Azure Container Registry)
Benefits: - Consistent runtime environment - Easy local development (same as production) - Portable across environments - Version control for deployments
Example:
# Dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app
COPY . .
ENTRYPOINT ["dotnet", "InvoiceService.Api.dll"]
Related Documents¶
- Clean Architecture & DDD - How Clean Architecture enables cloud-native
- Event-Driven Mindset - How events enable cloud-native scaling
- Observability-Driven Design - Observability in cloud-native systems
- Microservice Template - Cloud-native templates