Skip to content

Settings and Secrets

This guide explains how to manage application settings and secrets in the Developer Platform.

πŸ“‹ Overview

The platform uses a two-tier approach for configuration management:

  • Settings: Non-sensitive configuration values stored in settings.yml and deployed to Azure App Configuration βš™οΈ
  • Secrets: Sensitive values stored in Azure DevOps Libraries and deployed to Azure Key Vault πŸ”

βš™οΈ Settings Management

πŸ“Settings File Structure

Settings are defined in a settings.yml file located in the infra/api/ folder of each project. The file uses a structured format that supports environment-specific overrides.

File Location

<project-root>/
β”œβ”€β”€ infra/
β”‚   └── app/
β”‚       └── settings.yml

Settings File Format

# This is the settings.yml file used for configuration settings in the application.
# The settings are defined as a list of dictionaries, where each dictionary represents a setting.

# Example of a setting:
# - name: setting1          # The name of the setting
#   value: defaultvalue      # The default value of the setting
#   overrides:              # Optional overrides for specific environments
#     - env: test           # The environment where the override applies
#       value: testvalue    # The value of the setting for the specified environment

# Overrides allow you to specify different values for settings based on the environment.
# For example, you might have a default value for a setting that applies to all environments,
# but you can override this value for specific environments like 'test', 'qa', 'uat', or 'prod'.
# This is useful for managing environment-specific configurations without duplicating the entire settings structure.

- name: DatabaseConnectionTimeout
  value: '30'
  overrides:
    - env: test
      value: '10'
    - env: prod
      value: '60'

- name: ApiBaseUrl
  value: 'https://api.dev.example.com'
  overrides:
    - env: test
      value: 'https://api.test.example.com'
    - env: qa
      value: 'https://api.qa.example.com'
    - env: uat
      value: 'https://api.uat.example.com'
    - env: prod
      value: 'https://api.prod.example.com'

- name: LogLevel
  value: 'Debug'
  overrides:
    - env: prod
      value: 'Information'

Environment-Specific Overrides

The override system allows you to:

  • Define a default value that applies to all environments
  • Override specific values for targeted environments (test, qa, uat, prod)
  • Avoid duplicating configuration across environments

πŸš€ Settings Deployment Process

  1. Development: Define settings in settings.yml in your project
  2. Pipeline Processing: The deployment pipeline reads the settings file
  3. Environment Resolution: The pipeline applies environment-specific overrides
  4. Azure App Configuration: Final settings are pushed to Azure App Configuration
  5. Application Access: Applications retrieve settings from App Configuration

πŸ” Secrets Management

πŸ“š Azure DevOps Library Setup

Secrets are managed through Azure DevOps Variable Groups (Libraries) with the following structure:

Create the Variable Group

A variable group is not created for you β€” create it once per project before your pipeline needs secrets:

  1. In your Azure DevOps project, go to Pipelines β†’ Library
  2. Select + Variable group
  3. Set Variable group name to match the SecretsVariableGroupName you configure in your AppHost (WithPipelineDefaults) β€” see Aspire Publish. The name is otherwise up to you; the project ID is a common, collision-free default.
  4. Add your secrets (see Secret Configuration Requirements), marking each as Secret
  5. Save, then grant pipeline access to the group if prompted (Pipeline permissions β†’ allow your project's pipelines)

Library Naming Convention

  • Library Name: Must exactly match the SecretsVariableGroupName value configured in your AppHost β€” the project ID is recommended if you have no other convention to follow
  • Example: If your project ID is it-api-exp-appname, set SecretsVariableGroupName = "it-api-exp-appname" and name the library it-api-exp-appname

Pipeline Configuration

To pass the Azure DevOps Library to your pipeline templates, add the secretsVariableGroupName parameter to both your main pipeline and PR pipeline:

extends:
  template: azure-dotnet-api-v3.yml@templates
  parameters:
    applicationName: ${{ variables.ApplicationName }}
    projectId: ${{ variables.ProjectId }}
    openAPIFileName: ${{ variables.OpenAPIFileName }}
    dotNetVersion: '10.x'
    secretsVariableGroupName: 'ProjectId1' # πŸ”‘ Azure DevOps Library name

Key Points:

  • The secretsVariableGroupName parameter tells the pipeline template which Azure DevOps Library contains your secrets
  • Add this parameter to both pipelines: Configure it in your main deployment pipeline (azure-pipelines-api.yml) and your PR validation pipeline (azure-pipelines-api-pr.yml)
  • It is recommended that the value matches your Project ID and the variable group name defined in the variables section of your pipeline
  • Example: If your project ID is it-api-exp-appname, use secretsVariableGroupName: 'it-api-exp-appname'

Secret Naming Convention

[ENV]<settingname>

Where:

  • ENV: Environment prefix ([GLOBAL], [TEST], [QA], [UAT], [PROD])
  • settingname: The name of the secret setting

Environment Prefix Options:

  • [GLOBAL]: Applied to all environments by default (can be overridden)
  • [TEST]: Test environment specific
  • [QA]: QA environment specific
  • [UAT]: UAT environment specific
  • [PROD]: Production environment specific

Override Behavior: Environment-specific secrets take precedence over global secrets. For example:

  • [GLOBAL]DatabasePassword applies to all environments
  • [PROD]DatabasePassword overrides the global setting for production only
  • Other environments (TEST, QA, UAT) continue using the global value

Examples

# Global secrets (applied to all environments)
[GLOBAL]DatabasePassword
[GLOBAL]ApiKey
[GLOBAL]ServiceUrl

# Environment-specific secrets (override global if present)
[TEST]DatabasePassword      # Overrides global for TEST
[QA]DatabasePassword        # Overrides global for QA
[UAT]DatabasePassword       # Overrides global for UAT
[PROD]DatabasePassword      # Overrides global for PROD

# Mixed example - ApiKey uses global, DatabasePassword has env-specific overrides
[GLOBAL]ApiKey             # Used by all environments
[GLOBAL]DatabasePassword   # Used by QA and UAT
[TEST]DatabasePassword     # Overrides global for TEST
[PROD]DatabasePassword     # Overrides global for PROD

Secret Configuration Requirements

For each secret in the Azure DevOps Library:

  1. Variable Type: Must be set to Secret (not Variable)
  2. Environment Prefix: Use uppercase environment names ([GLOBAL], [TEST], [QA], [UAT], [PROD])
  3. Consistent Naming: Use the same base name across all environments
  4. Override Hierarchy: Environment-specific secrets override global secrets for that environment

Secret Resolution Order:

  1. Check for environment-specific secret (e.g., [PROD]DatabasePassword)
  2. If not found, use global secret (e.g., [GLOBAL]DatabasePassword)
  3. If neither exists, the secret is not available

πŸš€ Secrets Deployment Process

  1. Azure DevOps Library: Define secrets with proper naming convention
  2. Variable Type: Ensure all secrets are marked as Secret type
  3. Pipeline Detection: Deployment pipeline automatically detects secrets
  4. Key Vault Storage: Secrets are securely stored in Azure Key Vault
  5. App Configuration Reference: App Configuration receives references to Key Vault secrets
  6. Application Access: Applications access secrets through App Configuration with Key Vault integration

✨ Best Practices

βš™οΈ Settings Best Practices

  • Use Descriptive Names: Choose clear, self-explanatory setting names
  • Default Values: Always provide sensible default values
  • Environment Consistency: Maintain consistent setting names across environments
  • Documentation: Comment complex settings in the YAML file
  • Validation: Test settings in lower environments before production

πŸ” Secrets Best Practices

  • Minimal Exposure: Only store truly sensitive data as secrets
  • Rotation: Regularly rotate secrets, especially API keys and passwords
  • Access Control: Limit access to Azure DevOps Libraries containing secrets
  • Audit Trail: Monitor access to secrets in Azure Key Vault
  • Naming Convention: Strictly follow the [ENV]<settingname> format

πŸ›‘οΈ Security Considerations

  1. Secrets Never in Code: Never commit secrets to source control
  2. Environment Separation: Ensure complete separation between environment secrets
  3. Least Privilege: Grant minimum necessary permissions for accessing secrets
  4. Regular Review: Periodically review and cleanup unused secrets
  5. Monitoring: Enable monitoring and alerting for secret access

πŸ” Troubleshooting

⚠️ Common Issues

Settings Not Appearing in App Configuration

  • βœ… Verify settings.yml exists in infra/api/ folder
  • βœ… Check YAML syntax is valid
  • βœ… Ensure pipeline has permissions to App Configuration
  • βœ… Confirm environment name matches expected values

Secrets Not Accessible

  • βœ… Verify Azure DevOps Library name matches what is specified in secretsVariableGroupName
  • βœ… Check secret naming follows [ENV]<settingname> format
  • βœ… Ensure variable type is set to Secret
  • βœ… Confirm pipeline has access to the variable group
  • βœ… Verify Key Vault permissions are correctly configured

Environment-Specific Values Not Working

  • βœ… Check environment name spelling in overrides
  • βœ… Verify deployment pipeline is using correct environment parameter
  • βœ… Ensure override structure follows the correct YAML format

πŸ’¬ Getting Help

If you encounter issues with settings or secrets configuration:

  1. Check Pipeline Logs: Review deployment pipeline output for errors
  2. Validate Configuration: Use YAML validation tools for settings files
  3. Verify Permissions: Ensure proper access to Azure resources
  4. Contact Platform Team: Reach out for assistance with complex configurations

πŸ“‚ Example Project Structure

AppnameApplication/
β”œβ”€β”€ src/
β”‚   └── [application code]
β”œβ”€β”€ infra/
β”‚   β”œβ”€β”€ app/
β”‚   β”‚   └── settings.yml          # Application settings
β”‚   └── [infrastructure code]
└── azure-pipelines.yml           # Pipeline configuration

Azure DevOps Library: it-api-exp-appname (matching project ID)

# Global secrets (used by all environments unless overridden)
[GLOBAL]ApiKey = [secret]
[GLOBAL]ServiceUrl = [secret]

# Environment-specific secrets (override global when present)
[TEST]DatabasePassword = [secret]
[QA]DatabasePassword = [secret]
[UAT]DatabasePassword = [secret]
[PROD]DatabasePassword = [secret]

# Mixed example: EmailApiKey uses global for all environments
[GLOBAL]EmailApiKey = [secret]

This approach ensures secure, manageable, and environment-appropriate configuration for all applications in the Developer Platform.

πŸ’» Using These Settings in Applications

πŸ”΅ .NET Applications

For detailed information on how to consume these settings in your .NET applications, see the official Microsoft documentation: Configuration in .NET

This guide covers:

  • How to read configuration values in your application
  • Working with Azure App Configuration provider
  • Integrating with dependency injection
  • Best practices for configuration management in .NET