Appearance
Pre-Production Environment
CRITICAL — VNet CIDR Correction
The preprod VNet is 10.6.0.0/16.
Some older documents, Bicep parameters, and runbooks incorrectly show 10.3.0.0/16 for preprod. This is WRONG. Always use 10.6.0.0/16. If you encounter 10.3 anywhere in infrastructure code or documentation, it must be corrected.
Overview
The Pre-Production environment is the final validation gate before production deployments. It mirrors production infrastructure as closely as possible while using production-like (but not real) customer data.
| Property | Value |
|---|---|
| Environment name | preprod |
| VNet CIDR | 10.6.0.0/16 (NOT 10.3!) |
| Key Vault | mic-erp-be-preprod-skv |
| ACR | micerpbepreprodacr |
| Branch trigger | PreProd or preprod |
| Auto-deploy | Yes (no approval gate) |
| Approval gate | None (only production requires approval) |
Purpose
PreProd serves three distinct purposes:
- Final integration validation — Confirms that all services work correctly together with production-equivalent configuration before customer-facing deployment.
- Performance baseline — Load tests run in preprod to establish baseline metrics without impacting production.
- Release candidate verification — Product owners and QA team sign off on the release candidate in preprod before the team requests a production deployment approval.
Infrastructure Specifications
Compute
Public CAE (preprod-cae-public):
- Gateway.API
- Keycloak
Subnet: 10.6.1.0/24
Private CAE (preprod-cae-private):
- All 13 backend microservices
- mTLS enabled between services
Subnet: 10.6.2.0/23Storage and Data
| Resource | SKU | Notes |
|---|---|---|
| Redis Cache | Balanced_B0 (Azure Managed Redis) | SSL enforced |
| SQL Server | Shared VM | Separate preprod databases |
| Service Bus | Standard | Namespace: mic-erp-be-preprod-sb |
| Blob Storage | LRS | Not ZRS (unlike production) |
| MongoDB | VM-hosted | Same VM as other non-prod envs |
Networking
| Subnet | CIDR | Usage |
|---|---|---|
| public-apps | 10.6.1.0/24 | Internet-facing CAE |
| private-apps | 10.6.2.0/23 | Internal services CAE |
| appService | 10.6.4.0/24 | App Service integration |
| functionApps | 10.6.5.0/24 | Function App integration |
| private-endpoints | 10.6.6.0/24 | PaaS private endpoints |
Key Vault (mic-erp-be-preprod-skv)
All service configuration secrets for preprod are stored here. The double-dash convention applies:
ConnectionStrings--DefaultConnection → ConnectionStrings:DefaultConnection
RedisConfiguration--Password → RedisConfiguration:Password
MonogoDb--ConnectionString → MonogoDb:ConnectionString (typo intentional!)
AzureServiceBus--ConnectionString → AzureServiceBus:ConnectionString
Keycloak--ClientSecret → Keycloak:ClientSecretSee also: config-management.md for the full KV reference pattern.
Data Policy
PrepProd data must:
- Be anonymized or synthetic — no real customer data
- Contain a representative sample of all entity types (tenants, accounts, transactions)
- Be refreshed at least monthly using the data masking pipeline
- Never include production encryption keys or certificates
The data refresh pipeline (DevOps/scripts/preprod-data-refresh.ps1) runs the first Sunday of each month.
Deployment Process
1. Developer raises PR against `preprod` branch
2. DevSecOps pipeline runs all 16 stages
3. If all stages pass, the merge deploys automatically
4. Container image tagged: {service}:preprod-{buildId}
5. Image pushed to micerpbepreprodacr
6. Container Apps revision updated via az containerapp update
7. Health check: /health endpoints verified across all services
8. Deployment notification sent to #deployments Teams channelRollback
If a preprod deployment causes regressions:
bash
# List recent revisions
az containerapp revision list \
--name mic-erp-gateway \
--resource-group mic-erp-be-preprod-apps-public-rg \
--output table
# Activate a previous revision
az containerapp revision activate \
--name mic-erp-gateway \
--resource-group mic-erp-be-preprod-apps-public-rg \
--revision mic-erp-gateway--{previousRevisionSuffix}Differences from Production
| Feature | PreProd | Production |
|---|---|---|
| VNet CIDR | 10.6.0.0/16 | 10.2.0.0/16 |
| Approval gate | None | Required |
| Deployment window | Any time | Maintenance window only |
| Redis SKU | Balanced_B0 (Azure Managed Redis) | Balanced_B1 (Azure Managed Redis) |
| Storage redundancy | LRS | ZRS / GRS |
| MongoDB backend | VM-hosted | Azure Cosmos DB |
| Real customer data | No | Yes |
| Application Insights | Yes | Yes |
| Log retention | 30 days | 90 days |
| WAF (Front Door) | Yes | Yes |
Common Preprod Issues
"10.3.0.0/16 not found in DNS"
This is a symptom of the incorrect CIDR being used. Check:
bash
# Verify actual preprod VNet CIDR
az network vnet show \
--resource-group mic-erp-be-preprod-network-rg \
--name mic-erp-be-preprod-vnet \
--query "addressSpace.addressPrefixes"
# Expected output: ["10.6.0.0/16"]If the VNet was provisioned with 10.3.0.0/16, raise an infrastructure ticket to re-provision using the correct CIDR from Devops/azure/infrastructure/main.bicep.
Service-to-Service mTLS failures
Private CAE services communicate via mTLS. If a new service fails to reach internal services:
- Verify the service is deployed to the private CAE, not the public one.
- Check that
ASPNETCORE_ENVIRONMENT=preprodis set. - Verify the managed identity has
acrPullrole onmicerpbepreprodacr.
Monitoring
PrepProd shares the Application Insights workspace with dev and stage for cost efficiency.
- Application Insights:
mic-erp-be-preprod-ai - Log Analytics Workspace:
mic-erp-be-shared-law - Seq log stream: Not available in preprod (Seq runs in dev only)
- Alert rules: Basic availability alerts only (no pager-duty integration)