The services that carry the load
- App Service & AKS: App Service for straightforward API workloads, Kubernetes where charger-connection fan-out needs custom scaling logic.
- Azure Database for MySQL / SQL: managed data with point-in-time restore — the backup you never think about until you desperately need it.
- Service Bus & Event Hubs: alongside RabbitMQ where managed queuing or telemetry-scale ingestion fits better.
- Key Vault + Managed Identity: no connection string has lived in a config file since 2021.
- Application Insights: distributed tracing across every microservice; the first tab open in any incident.
- Azure OpenAI: the newest layer — RAG-based knowledge systems and support automation over EV ecosystem data.
Architecture decisions that mattered
- Zone-redundant deployments for the charging path; a single-zone failure must be invisible to a driver mid-session.
- Front Door + API Management at the edge: WAF, partner rate limits, and OCPI version routing handled before traffic reaches services.
- Hub-spoke networking with private endpoints — data services never face the public internet.
- Infrastructure as code (Bicep) from day one; a hand-configured environment is an unreproducible environment.
Cost, honestly
Cloud cost is an architecture property, not a finance problem. Reserved instances for the always-on charging core, autoscale-to-zero for batch and reporting workloads, tiered storage for telemetry (hot 30 days, archive beyond), and monthly cost reviews with the same seriousness as uptime reviews. The 20–30% savings are usually sitting in oversized non-production environments.
Worked example: zone-redundant service in Bicep
Infrastructure as code for a charging-path API — zone redundancy, managed identity, and Key Vault references instead of connection strings:
resource plan 'Microsoft.Web/serverfarms@2023-12-01' = {
name: 'asp-charging-prod'
location: location
sku: { name: 'P1v3', capacity: 3 }
properties: { zoneRedundant: true }
}
resource api 'Microsoft.Web/sites@2023-12-01' = {
name: 'app-sessions-prod'
location: location
identity: { type: 'SystemAssigned' }
properties: {
serverFarmId: plan.id
siteConfig: {
healthCheckPath: '/health'
appSettings: [
{ name: 'Db__ConnectionString'
value: '@Microsoft.KeyVault(SecretUri=${kv.properties.vaultUri}secrets/db-conn)' }
]
}
}
}
The managed identity reads the secret at runtime — no credential exists in config, pipeline variables, or anyone’s laptop.
FAQ
Both are capable; I choose based on the client’s existing estate, team skills, and enterprise agreements. My EV platforms run Azure largely for its .NET toolchain depth and enterprise identity integration.
Yes — not for the badge, but because it forces breadth: networking, identity, and governance areas that hands-on work lets you avoid until they bite.
App Service until you have a concrete requirement it cannot meet (custom networking, sidecars, fine-grained scaling). Kubernetes is powerful and a permanent operational tax — pay it only for a reason.