Skip to content

tonyjoanes/azure-config-demo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Azure Configuration Management Demo

This project demonstrates best practices for managing configuration in Azure applications, showing how to use:

  • Environment Variables
  • Application Settings (appsettings.json)
  • Azure Key Vault
  • Infrastructure as Code (Bicep)
  • CI/CD Pipeline Configuration

Project Structure

.
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ Program.cs                 # Main application entry point
β”‚   β”œβ”€β”€ AppSettings.cs            # Strongly-typed configuration class
β”‚   β”œβ”€β”€ appsettings.json          # Base configuration
β”‚   β”œβ”€β”€ appsettings.Development.json  # Development environment settings
β”‚   β”œβ”€β”€ appsettings.Staging.json      # Staging environment settings
β”‚   └── appsettings.Production.json   # Production environment settings
β”œβ”€β”€ infra/
β”‚   └── main.bicep                # Infrastructure as Code template
└── azure-pipelines.yml           # CI/CD pipeline configuration

Configuration Types and Use Cases

1. Environment Variables

  • Use Case: Runtime overrides, sensitive data, environment-specific values
  • Example: ASPNETCORE_ENVIRONMENT, ConnectionStrings__DefaultConnection
  • Best Practice: Use for values that change between environments or contain sensitive data

2. Application Settings (appsettings.json)

  • Use Case: Default configuration, non-sensitive settings
  • Structure:
    {
      "AppSettings": {
        "Environment": "Development",
        "ApiSettings": {
          "BaseUrl": "https://api.dev.example.com",
          "Timeout": 30,
          "RetryCount": 3
        }
      }
    }
  • Best Practice: Use for default values and non-sensitive configuration

3. Azure Key Vault

  • Use Case: Secrets management, sensitive configuration
  • Example: API keys, connection strings, certificates
  • Best Practice: Use for all sensitive data, never store secrets in code or configuration files

Configuration Hierarchy

The application follows this configuration hierarchy (highest to lowest priority):

  1. Environment Variables
  2. Azure Key Vault
  3. Environment-specific appsettings.json (Development/Staging/Production)
  4. Base appsettings.json

Environment-Specific Configuration

Each environment has its own configuration file with appropriate settings:

Development

{
  "AppSettings": {
    "Environment": "Development",
    "ApiSettings": {
      "BaseUrl": "https://api.dev.example.com",
      "Timeout": 30,
      "RetryCount": 3
    }
  }
}

Staging

{
  "AppSettings": {
    "Environment": "Staging",
    "ApiSettings": {
      "BaseUrl": "https://api.staging.example.com",
      "Timeout": 45,
      "RetryCount": 5
    }
  }
}

Production

{
  "AppSettings": {
    "Environment": "Production",
    "ApiSettings": {
      "BaseUrl": "https://api.example.com",
      "Timeout": 60,
      "RetryCount": 3
    }
  }
}

Infrastructure as Code

The project uses Bicep for infrastructure deployment:

// Key Vault setup
resource keyVault 'Microsoft.KeyVault/vaults@2023-02-01' = {
  name: '${namePrefix}-kv'
  // ... other properties
}

// App Service setup
resource appService 'Microsoft.Web/sites@2022-09-01' = {
  name: '${namePrefix}-app'
  // ... other properties
}

CI/CD Pipeline

The Azure Pipeline (azure-pipelines.yml) handles:

  1. Build Stage:

    • Builds the application
    • Transforms configuration for each environment
    • Creates deployment packages
  2. Deploy Stage:

    • Deploys infrastructure using Bicep
    • Copies environment-specific configuration
    • Deploys application to Azure Web App

Pipeline Configuration Flow

  1. Build Process:

    - task: FileTransform@1
      inputs:
        folderPath: '$(System.DefaultWorkingDirectory)/src'
        fileType: 'json'
        targetFiles: 'appsettings.json'
        transformFile: 'appsettings.Development.json'
  2. Deployment Process:

    - task: CopyFiles@2
      inputs:
        SourceFolder: '$(Pipeline.Workspace)/drop/Development'
        Contents: 'appsettings.json'
        TargetFolder: '$(Pipeline.Workspace)/drop'

Security Best Practices

  1. Never store secrets in:

    • Source code
    • Configuration files
    • Environment variables in source control
  2. Always use Azure Key Vault for:

    • Connection strings
    • API keys
    • Certificates
    • Other sensitive data
  3. Environment-specific security:

    • Development: Minimal security for easy debugging
    • Staging: Mirror production security
    • Production: Maximum security, strict access controls

Getting Started

  1. Local Development:

    dotnet run --environment Development
  2. Azure Setup:

    # Deploy infrastructure
    az deployment group create \
      --resource-group $(resourceGroup) \
      --template-file infra/main.bicep \
      --parameters environment=dev
  3. Pipeline Setup:

    • Configure Azure DevOps pipeline
    • Set up environment variables
    • Configure service connections

Testing Configuration

  1. Local Testing:

    # Override settings
    $env:ApiSettings__BaseUrl = "https://localhost:5001"
    dotnet run
  2. Azure Testing:

    • Use Azure Portal to verify Key Vault integration
    • Check App Service configuration
    • Monitor application logs

Best Practices

  1. Configuration Management:

    • Use strongly-typed configuration
    • Implement configuration validation
    • Follow the configuration hierarchy
  2. Security:

    • Use Key Vault for all secrets
    • Implement proper access controls
    • Regular secret rotation
  3. Deployment:

    • Use infrastructure as code
    • Automate all deployments
    • Implement proper testing
  4. Monitoring:

    • Log configuration changes
    • Monitor Key Vault access
    • Track configuration errors

About

πŸ”§ From chaos to clarity β€” mastering config in Azure.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published