Skip to content

Storage Accounts ​

Microtec ERP uses Azure Storage Accounts in two categories: backend storage (for file attachments uploaded through the Attachment microservice) and frontend storage (for hosting Angular MFE static files). Each environment has separate storage accounts for each category.


Naming Convention ​

Storage account names must be globally unique, alphanumeric, and 3–24 characters. The formula strips hyphens from the resource prefix:

Backend:  micerpbe{env}sa    β†’ e.g. micerpbedevsa, micerpbestagesa
Frontend: micerpfr{env}sa    β†’ e.g. micerpfrdevsa, micerpfrstagesa

Alphanumeric Only

Azure Storage Account names cannot contain hyphens. The naming convention removes all hyphens from mic-erp-be-{env} and mic-erp-fr-{env} and appends sa (storage account).


Account Inventory ​

Backend Storage Accounts (Attachments) ​

EnvironmentAccount NameResource Group
devmicerpbedevsamic-erp-be-dev-storage-rg
stagemicerpbestagesamic-erp-be-stage-storage-rg
preprodmicerpbepreproΠ΄samic-erp-be-preprod-storage-rg
uatmicerpbeuatsamic-erp-be-uat-storage-rg
productionmicerpbeprodsamic-erp-be-prod-storage-rg

Frontend Storage Accounts (MFE Hosting) ​

EnvironmentAccount NameResource Group
devmicerpfrdevsamic-erp-fr-dev-storage-rg
stagemicerpfrstagesamic-erp-fr-stage-storage-rg
preprodmicerpfrpreprodsamic-erp-fr-preprod-storage-rg
uatmicerpfruatsamic-erp-fr-uat-storage-rg
productionmicerpfrprodsamic-erp-fr-prod-storage-rg

Backend Storage (Attachments) ​

The Attachment microservice stores all user-uploaded files in Blob Storage. Files are organized by tenant:

Container Structure ​

micerpbedevsa/
β”œβ”€β”€ attachments/
β”‚   β”œβ”€β”€ tenant-1/
β”‚   β”‚   β”œβ”€β”€ invoices/
β”‚   β”‚   β”‚   └── 2025/01/invoice-abc123.pdf
β”‚   β”‚   └── hr/
β”‚   β”‚       └── employee-photos/photo-456.jpg
β”‚   β”œβ”€β”€ tenant-2/
β”‚   β”‚   └── ...
β”‚   └── ...
└── temp-uploads/      (24-hour TTL, lifecycle policy)

Configuration ​

csharp
// Attachment service appsettings
{
  "Attachment": {
    "AzureStorage": {
      "ConnectionString": "{from-kv}",
      "ContainerName": "attachments",
      "TempContainerName": "temp-uploads",
      "MaxFileSizeBytes": 52428800,    // 50 MB
      "AllowedExtensions": [".pdf", ".jpg", ".png", ".xlsx", ".docx"]
    }
  }
}

The connection string is stored in Key Vault secret Attachment--AzureStorage--ConnectionString.

Frontend MFE Storage Refactor

The connection string for frontend MFE static hosting was moved to the frontend storage account (micerpfr{env}sa) in session 13 (2026-03-31). Backend services should use micerpbe{env}sa for attachments only. Do not mix the two.

Lifecycle Policy ​

Temp uploads are automatically deleted after 24 hours via a lifecycle management rule:

json
{
  "rules": [
    {
      "name": "delete-temp-uploads",
      "type": "Lifecycle",
      "definition": {
        "filters": { "blobTypes": ["blockBlob"], "prefixMatch": ["temp-uploads/"] },
        "actions": {
          "baseBlob": {
            "delete": { "daysAfterModificationGreaterThan": 1 }
          }
        }
      }
    }
  ]
}

Frontend Storage (MFE Hosting) ​

Angular MFE builds are deployed to the $web container in the frontend storage account for static website hosting. Azure Front Door serves these files globally.

Static Website Configuration ​

bicep
// storage-frontend.bicep
resource frontendStorage 'Microsoft.Storage/storageAccounts@2023-01-01' = {
  name: frontendStorageName
  properties: {
    staticWebsite: {
      enabled: true
      indexDocument: 'index.html'
      errorDocument404Path: 'index.html'  // SPA fallback routing
    }
    allowBlobPublicAccess: false           // AFD accesses via origin auth
    minimumTlsVersion: 'TLS1_2'
    supportsHttpsTrafficOnly: true
  }
}

The errorDocument404Path is set to index.html to support Angular's client-side routing β€” all 404s return the SPA, which handles routing internally.

Deployment Structure ​

micerpfrdevsa/$web/
β”œβ”€β”€ erp-home/
β”‚   └── index.html, main.{hash}.js, ...
β”œβ”€β”€ apps-accounting/
β”‚   └── index.html, main.{hash}.js, ...
β”œβ”€β”€ apps-hr/
β”‚   └── ...
β”œβ”€β”€ apps-finance/
β”œβ”€β”€ apps-sales/
β”œβ”€β”€ apps-purchase/
β”œβ”€β”€ apps-inventory/
β”œβ”€β”€ app-distribution/
└── fixed-assets/

Upload via Pipeline ​

yaml
# From unified-frontend-pipeline.yml
- task: AzureCLI@2
  displayName: 'Upload to Blob Storage'
  inputs:
    script: |
      az storage blob upload-batch \
        --account-name $(frontendStorageName) \
        --destination '$web/$(projectName)' \
        --source dist/$(projectName) \
        --overwrite true \
        --content-cache-control "max-age=31536000, immutable"

Bicep Configuration ​

bicep
// storage-backend.bicep
resource backendStorage 'Microsoft.Storage/storageAccounts@2023-01-01' = {
  name: backendStorageName
  location: location
  sku: { name: environment == 'production' ? 'Standard_GRS' : 'Standard_LRS' }
  kind: 'StorageV2'
  properties: {
    allowBlobPublicAccess: false     // Trivy: AVD-AZU-0008 compliant
    minimumTlsVersion: 'TLS1_2'
    supportsHttpsTrafficOnly: true
    networkAcls: {
      defaultAction: 'Deny'
      bypass: 'AzureServices'
      // Allow access from Container Apps outbound IPs via service endpoint
      virtualNetworkRules: [
        { id: appSubnetId, action: 'Allow' }
      ]
    }
  }
}

Production uses Standard_GRS (Geo-Redundant Storage) for 16-nine durability. Non-production environments use Standard_LRS (Locally Redundant) to minimize cost.


Access Control ​

Backend Storage Access ​

The Attachment service accesses backend storage using a connection string (stored in Key Vault). A managed-identity-based access pattern is planned for a future sprint.

Frontend Storage Access ​

AFD accesses the frontend storage $web container using origin authentication (SAS token embedded in AFD origin configuration). End users never get direct access to the storage account URL.


Monitoring ​

MetricAlert ThresholdDescription
UsedCapacity> 80% of quotaStorage getting full
Availability< 99.9%Storage service degraded
E2ELatency> 500msSlow blob reads
Transactions (4xx)> 10/minUnauthorized access attempts

Internal Documentation β€” Microtec