Documentation
adrs/043-azure-infrastructure-architecture.md
ADR-043: Azure Infrastructure Architecture for Dynaplex
Status
Accepted
Context
Dynaplex deployments to Azure Container Apps require careful infrastructure design to support:
- IoT Device Connectivity: RFID readers and other IoT devices need reliable MQTT broker access
- Network Isolation: Container Apps should have explicit network boundaries for security
- Resource Organization: Azure resources should follow consistent naming conventions
- Identity Management: Services need secure access to Azure resources (blob storage, Key Vault, etc.)
Previous Architecture
The original deployment used:
- Auto-generated resource names with cryptic suffixes (e.g.,
config-aszxig73dxx3m) - Per-component managed identities (complex RBAC management)
- Direct TCP exposure for EMQX MQTT broker
- Default Container Apps networking (no VNet)
Challenges
- Device Configuration Fragility: Changing EMQX infrastructure required reconfiguring all IoT devices
- Resource Identification: Cryptic names made Azure portal navigation difficult
- RBAC Complexity: Multiple managed identities required extensive role assignments
- Network Visibility: No explicit network boundaries or traffic control
Decision
Implement a structured Azure infrastructure architecture with:
1. Azure CAF Naming Conventions
Use Microsoft Cloud Adoption Framework abbreviations for consistent resource naming:
{abbreviation}-{groupId}-{purpose}
Examples:
- psql-elbbudev (PostgreSQL server)
- cae-elbbudev (Container Apps Environment)
- ca-elbbudev-identity (Identity Container App)
- log-elbbudev (Log Analytics Workspace)
- vnet-elbbudev (Virtual Network)
- st{groupId} (Storage Account - no hyphens)
Resource Abbreviations
| Resource Type | Abbreviation | Example |
|---|---|---|
| Container App | ca |
ca-elbbudev-catalog |
| Container Apps Environment | cae |
cae-elbbudev |
| PostgreSQL | psql |
psql-elbbudev |
| Log Analytics | log |
log-elbbudev |
| Virtual Network | vnet |
vnet-elbbudev |
| Subnet | snet |
snet-elbbudev-infra |
| Storage Account | st |
stelbbudev |
| App Configuration | appcs |
appcs-elbbudev |
| User-Assigned Identity | id |
id-elbbudev-app |
2. VNet for Network Isolation
Deploy Container Apps Environment with a custom VNet:
Address Space: 10.0.0.0/16
Infrastructure Subnet: 10.0.0.0/23 (delegated to Microsoft.App/environments)
Benefits:
- Explicit network boundaries between environments
- Private inter-service communication within VNet
- NSG rules for traffic control
- Foundation for future VNet integration scenarios (e.g., VPN, ExpressRoute)
3. EMQX via Azure Front Door (WebSocket Architecture)
Route IoT device traffic through Azure Front Door using MQTT-over-WebSocket:
┌──────────────────┐ ┌─────────────────┐ ┌──────────────────┐
│ Zebra Readers │ wss:// │ Azure Front │ HTTP │ EMQX Container │
│ (IoT Devices) │ ──────► │ Door │ ──────► │ App (port 8083) │
└──────────────────┘ └─────────────────┘ └──────────────────┘
Key Points:
- Devices connect via
wss://acsisemqx-*.azurefd.net:443 - Front Door routes to EMQX WebSocket listener (port 8083)
- EMQX exposes HTTP ingress (not TCP) for Container Apps compatibility
- Device configuration remains stable when infrastructure changes
EMQX Configuration:
- WebSocket listener:
0.0.0.0:8083 - Unlimited queue length (
max_mqueue_len = infinity) - Unlimited session expiry (
session_expiry_interval = infinity) - Session persistence via Azure Files mount
- Environment variable configuration for all settings
4. Shared Managed Identity
Use a single user-assigned managed identity for all Container Apps:
builder.AddDynaplexAppIdentity(); // Creates: id-{groupId}-app
Benefits:
- Single set of RBAC role assignments instead of per-component
- Easier auditing and compliance tracking
- Simpler rotation and lifecycle management
- Consistent naming pattern
Implementation
DynaplexContext Extensions
// Naming helpers
context.ResourceName("ca", "identity") // → "ca-elbbudev-identity"
context.ResourceName("psql") // → "psql-elbbudev"
context.StorageAccountName() // → "stelbbudev"
// Infrastructure methods
builder.AddDynaplexAppIdentity(); // Shared managed identity
builder.AddDynaplexDatabase(); // PostgreSQL with CAF naming
builder.AddDynaplexContainerAppEnvironment(); // VNet + Log Analytics
builder.AddDynaplexMqttBroker(); // EMQX with WebSocket
builder.AddDynaplexStorage(); // Storage + EMQX file share
Front Door Configuration
After azd provision, configure Front Door origin group:
- Create origin group for EMQX WebSocket traffic
- Add EMQX Container App as origin (port 8083)
- Configure health probe for
/endpoint - Route existing EMQX hostname to new origin
Consequences
Positive
- Device Stability: IoT devices use Front Door URL, unaffected by backend changes
- Clear Resource Naming: Easy to identify resources in Azure portal
- Simplified RBAC: Single identity for all components
- Network Control: VNet provides explicit traffic boundaries
- Operational Visibility: Consistent naming aids troubleshooting
Negative
- Front Door Dependency: WebSocket traffic routes through additional service
- WebSocket Protocol: Requires MQTT-over-WebSocket capable devices (Zebra FX9600 supports this)
- Migration Effort: Existing deployments need recreation with new naming
Neutral
- VNet Overhead: Minimal additional cost for VNet resources
- Naming Changes: One-time migration from old naming scheme
Configuration Reference
Required Parameters
| Parameter | Purpose | Example |
|---|---|---|
postgres-admin-user |
PostgreSQL admin username | acsisadmin |
postgres-admin-password |
PostgreSQL admin password | (secret) |
emqx-admin-password |
EMQX dashboard password | (secret) |
emqxStorageAccountName |
Storage account for EMQX | stelbbudev |
emqxStorageAccountKey |
Storage account key | (secret) |
Environment Variables for MQTT
{
"Bbu__Mqtt__EnvironmentId": "elbbudev",
"Iot__Mqtt__EnvironmentId": "elbbudev"
}
Related ADRs
- ADR-007: Aspire Microservices Migration - Foundation for Container Apps deployment
- ADR-042: MQTT Message Delivery Architecture - Environment isolation via MQTT topics
- ADR-033: Base Orchestration Pattern - Project configuration patterns
Implementation Files
strata/orchestration/src/Acsis.Dynaplex.Strata.Orchestration/DynaplexContext.cs- Naming helpers and contextstrata/orchestration/src/Acsis.Dynaplex.Strata.Orchestration/DynaplexInfrastructureExtensions.cs- Infrastructure extension methodsprojects/bbu-rfid/src/Acsis.Dynaplex.Projects.BbuRfid/AppHost.cs- Project orchestration
Date: 2025-12-09
Author: Architecture Team
Reviewers: Development Team