Skip to content

JeffreyCA/azd-dev-prod

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

34 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐ŸŒ Multi-Region Scale Unit Architecture

This project implements a highly available, multi-region Flask application with automatic failover and global load balancing using Azure services. The infrastructure is organized into global and regional modules for better maintainability and deployment efficiency.

Note

Recommended regions: Poland Central and Canada Central (due to ongoing capacity constraints in other regions)

๐Ÿš€ Quick Start

Prerequisites

Quick Deployment

# Clone and navigate to the project
cd azd-dev-prod

# Deploy using azd (AZURE_ENV_TYPE=dev by default)
azd up

# Or deploy specific environment
azd env set AZURE_ENV_TYPE prod
azd up

GitHub Actions Setup

# Clone and navigate to the project
cd azd-dev-prod

# Configure CI/CD pipeline
azd pipeline config

Follow the interactive prompts:

  1. Environment name: Enter a unique environment name
  2. Provider: Select GitHub
  3. Azure Subscription: Choose your target subscription
  4. Primary Location: Select primary region (recommended: Canada Central)
  5. Secondary Location: Select secondary region (recommended: Poland Central)
  6. Authentication: Select Federated User Managed Identity (MSI + OIDC)
  7. User Managed Identity: Choose to use existing or create new MSI

Post-Configuration Steps

After running azd pipeline config, you'll need to add environment-specific federated credentials to the User Assigned Managed Identity in Azure:

  1. Navigate to your User Assigned Managed Identity resource in the Azure portal

  2. Follow the Microsoft documentation to create federated credentials. Do this twice for the dev and prod environments:

    • Federated credential scenario: Configure a GitHub issued token to impersonate this application and deploy to Azure
    • Entity: Environment
    • Environment: dev / prod Federated Credentials
  3. Verify you have 4 federated credentials in total: Federated Credentials

  4. Commit and Push: After setting up federated credentials, manually trigger the Deploy workflow or commit your changes to trigger the pipeline

๐Ÿ—๏ธ Architecture Overview

Infrastructure Organization

Modular Bicep infrastructure:

infra/
โ”œโ”€โ”€ main.bicep                    # Main orchestration (subscription scope)
โ”œโ”€โ”€ main.parameters.json          # Environment parameters
โ”œโ”€โ”€ abbreviations.json            # Azure resource naming abbreviations
โ”œโ”€โ”€ global/                       # Global infrastructure components
โ”‚   โ”œโ”€โ”€ main.bicep               # Global resources (Front Door, DNS, shared storage)
โ”‚   โ””โ”€โ”€ front-door-config.bicep  # Front Door endpoint configuration
โ””โ”€โ”€ regional/                     # Regional infrastructure components
    โ”œโ”€โ”€ main.bicep               # Regional orchestration
    โ”œโ”€โ”€ app.bicep                # App Service and hosting
    โ”œโ”€โ”€ storage.bicep            # Regional storage
    โ”œโ”€โ”€ network.bicep            # VNet and networking
    โ”œโ”€โ”€ monitoring.bicep         # Regional monitoring
    โ””โ”€โ”€ modules/                 # Additional modules
        โ”œโ”€โ”€ applicationinsights-dashboard.bicep  # Application Insights dashboard
        โ””โ”€โ”€ vnet-link.bicep      # VNet links for private DNS zones

Deployment Model

  • Multi-Resource Group: Resources are deployed to separate resource groups (primary, secondary, global)
  • Global Components: Front Door, DNS zones, and shared storage deployed once to global resource group
  • Regional Components: App Services, regional storage, and monitoring deployed per region to regional resource groups
  • VNet Integration: Private DNS zone links created for production environments
  • Service Configuration: Two azd services (app-primary and app-secondary) for automatic deployment

Production Environment (envType = 'prod')

  • VNet integration with private endpoints
  • Private storage access only
  • Private DNS zones with VNet links
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                           Azure Front Door                          โ”‚
โ”‚                    (Global Load Balancer + CDN)                     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
              โ”‚                                   โ”‚
    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
    โ”‚   PRIMARY REGION  โ”‚                โ”‚  SECONDARY REGION โ”‚
    โ”‚                   โ”‚                โ”‚                   โ”‚
    โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚                โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
    โ”‚  โ”‚ App Service โ”‚  โ”‚                โ”‚  โ”‚ App Service โ”‚  โ”‚
    โ”‚  โ”‚ (VNet Integ)โ”‚  โ”‚                โ”‚  โ”‚ (VNet Integ)โ”‚  โ”‚
    โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚                โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
    โ”‚         โ”‚         โ”‚                โ”‚         โ”‚         โ”‚
    โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚                โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
    โ”‚  โ”‚ VNet + Priv โ”‚  โ”‚                โ”‚  โ”‚ VNet + Priv โ”‚  โ”‚
    โ”‚  โ”‚ Endpoints   โ”‚  โ”‚                โ”‚  โ”‚ Endpoints   โ”‚  โ”‚
    โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚                โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
    โ”‚         โ”‚         โ”‚                โ”‚         โ”‚         โ”‚
    โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚                โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
    โ”‚  โ”‚ Storage     โ”‚  โ”‚                โ”‚  โ”‚ Storage     โ”‚  โ”‚
    โ”‚  โ”‚ (Private)   โ”‚  โ”‚                โ”‚  โ”‚ (Private)   โ”‚  โ”‚
    โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚                โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
              โ”‚                                   โ”‚
              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                            โ”‚
                   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                   โ”‚ Global Storage  โ”‚
                   โ”‚ (Shared Config) โ”‚
                   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Development Environment (envType = 'dev')

  • Public storage access with managed identity auth
  • No VNet or private endpoints
  • Simplified networking for faster deployment
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                           Azure Front Door                          โ”‚
โ”‚                    (Global Load Balancer + CDN)                     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
              โ”‚                                   โ”‚
    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
    โ”‚   PRIMARY REGION  โ”‚                โ”‚  SECONDARY REGION โ”‚
    โ”‚                   โ”‚                โ”‚                   โ”‚
    โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚                โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
    โ”‚  โ”‚ App Service โ”‚  โ”‚                โ”‚  โ”‚ App Service โ”‚  โ”‚
    โ”‚  โ”‚ (Simplified)โ”‚  โ”‚                โ”‚  โ”‚ (Simplified)โ”‚  โ”‚
    โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚                โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
    โ”‚         โ”‚         โ”‚                โ”‚         โ”‚         โ”‚
    โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚                โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
    โ”‚  โ”‚ Storage     โ”‚  โ”‚                โ”‚  โ”‚ Storage     โ”‚  โ”‚
    โ”‚  โ”‚ (Public +   โ”‚  โ”‚                โ”‚  โ”‚ (Public +   โ”‚  โ”‚
    โ”‚  โ”‚  MI Auth)   โ”‚  โ”‚                โ”‚  โ”‚  MI Auth)   โ”‚  โ”‚
    โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚                โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ”ง Configuration Options

Environment Variables

Variable Description Default Example
AZURE_ENV_NAME Environment name for resource naming - my-scale-unit
AZURE_ENV_TYPE Environment type (dev/test/prod) dev prod
AZURE_LOCATION Primary region eastus eastus2
AZURE_SECONDARY_LOCATION Secondary region westus2 southcentralus

Environment Types

Environment Networking Security Use Case
dev Public access with MI auth Basic Development, testing
prod VNet integration + private endpoints High Production workloads

๐Ÿ“Š Monitoring & Health Checks

Built-in Health Endpoints

  • /health - Health check endpoint for Front Door health probes
  • /info - Application information and diagnostics

Testing Failover

The application includes a Health Status Control section on the main page for testing load balancer and Front Door failover:

  1. Open Front Door endpoint
  2. Click "Make Unhealthy (120s)" button
  3. Refresh page - traffic should route to the other region

Note

Alternatively, you can use az webapp stop --name <app-service-name> --resource-group <resource-group> to stop one of the apps.

๏ธ Infrastructure Details

Bicep Module Organization

Main Orchestration (main.bicep):

  • Subscription-scoped deployment creating separate resource groups
  • Orchestrates global and regional deployments in parallel
  • Manages VNet links for private DNS zones in production
  • Parameter management and output aggregation

Global Infrastructure (global/):

  • main.bicep: Front Door profile, private DNS zones, global storage
  • front-door-config.bicep: Endpoint and origin configuration (post-deployment)

Regional Infrastructure (regional/):

  • main.bicep: Regional orchestration and resource coordination
  • app.bicep: App Service Plan and App Service configuration
  • storage.bicep: Regional storage accounts and containers
  • network.bicep: VNet, subnets, and private endpoints (prod only)
  • monitoring.bicep: Application Insights, Log Analytics, and dashboards
  • modules/applicationinsights-dashboard.bicep: Monitoring dashboard
  • modules/vnet-link.bicep: VNet links to private DNS zones (prod only)

Deployment Flow

  1. Resource Groups: Primary, secondary, and global resource groups created
  2. Global Resources: DNS zones, Front Door profile, shared storage
  3. Regional Resources: App Services, regional storage, monitoring (parallel deployment)
  4. VNet Links: Private DNS zone links for production environments
  5. Front Door Configuration: Endpoints and origins (after App Services are ready)
  6. Application Deployment: Code deployment to both regions via azd services

๐Ÿ”ฎ Advanced Scenarios

๐Ÿ”ฎ Advanced Scenarios

Extending the Architecture

Adding More Regions:

  1. Modify main.bicep to add additional regional deployments
  2. Update azure.yaml to include new service configurations
  3. Configure Front Door origin groups for additional regions

Custom Domains & SSL:

  1. Configure custom domain in Front Door endpoint
  2. Upload SSL certificates or use managed certificates
  3. Update DNS CNAME records to point to Front Door

Database Integration:

  1. Add Azure SQL Database with geo-replication to global/main.bicep
  2. Configure connection strings per region in regional/app.bicep
  3. Implement database failover logic in application code

Production Hardening

Security Enhancements:

  • Enable WAF (Web Application Firewall) on Front Door
  • Configure App Service IP restrictions to Front Door only
  • Add Azure Key Vault for secrets management
  • Enable Azure AD authentication

Performance Optimization:

  • Configure Front Door caching rules
  • Enable compression and optimization
  • Add Application Gateway for advanced load balancing
  • Implement Redis cache for session state

๐Ÿ“š Additional Resources

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •