Skip to content

03 - Configuration, Secrets, and Dapr

This step configures runtime settings in Azure Container Apps, including environment variables, secrets, KEDA scaling rules, and Dapr sidecar options.

Infrastructure Context

Service: Container Apps (Consumption) | Network: VNet integrated | VNet: ✅

This tutorial assumes a production-ready Container Apps deployment with a custom VNet, ACR with managed identity pull, and private endpoints for backend services.

flowchart TD
    INET[Internet] -->|HTTPS| CA["Container App\nConsumption\nLinux Node 18 LTS"]

    subgraph VNET["VNet 10.0.0.0/16"]
        subgraph ENV_SUB["Environment Subnet 10.0.0.0/23\nDelegation: Microsoft.App/environments"]
            CAE[Container Apps Environment]
            CA
        end
        subgraph PE_SUB["Private Endpoint Subnet 10.0.2.0/24"]
            PE_ACR[PE: ACR]
            PE_KV[PE: Key Vault]
            PE_ST[PE: Storage]
        end
    end

    PE_ACR --> ACR[Azure Container Registry]
    PE_KV --> KV[Key Vault]
    PE_ST --> ST[Storage Account]

    subgraph DNS[Private DNS Zones]
        DNS_ACR[privatelink.azurecr.io]
        DNS_KV[privatelink.vaultcore.azure.net]
        DNS_ST[privatelink.blob.core.windows.net]
    end

    PE_ACR -.-> DNS_ACR
    PE_KV -.-> DNS_KV
    PE_ST -.-> DNS_ST

    CA -.->|System-Assigned MI| ENTRA[Microsoft Entra ID]
    CAE --> LOG[Log Analytics]
    CA --> AI[Application Insights]

    style CA fill:#107c10,color:#fff
    style VNET fill:#E8F5E9,stroke:#4CAF50
    style DNS fill:#E3F2FD

Configuration Flow

graph TD
    ENV[Env Vars] --> ACA[Container App]
    SEC[Secrets] --> ACA
    DAPR[Dapr] --> ACA
    ACA --> APP[Application]

Prerequisites

Step-by-step

  1. Set standard variables

    RG="rg-nodejs-guide"
    BASE_NAME="nodejs-guide"
    DEPLOYMENT_NAME="main"
    
    APP_NAME=$(az deployment group show \
      --name "$DEPLOYMENT_NAME" \
      --resource-group "$RG" \
      --query "properties.outputs.containerAppName.value" \
      --output tsv)
    
    Command Purpose
    APP_NAME=$(az deployment group show --name "$DEPLOYMENT_NAME" --resource-group "$RG" --query "properties.outputs.containerAppName.value" --output tsv) Captures the existing Container App name from the deployment outputs so configuration changes apply to the correct Node.js app.
  2. Set environment variables

    az containerapp update \
      --name "$APP_NAME" \
      --resource-group "$RG" \
      --set-env-vars "LOG_LEVEL=INFO" "FEATURE_FLAG=true"
    
    Command Why it is used
    az containerapp update ... Updates the existing Container App configuration without recreating the app.
    Expected output
    {
      "name": "ca-nodejs-guide-<unique-suffix>",
      "provisioningState": "Succeeded"
    }
    
  3. Store and reference a secret

    az containerapp secret set \
      --name "$APP_NAME" \
      --resource-group "$RG" \
      --secrets "db-password=<secret-value>"
    
    Command Why it is used
    az containerapp secret set ... Manages Container Apps secrets without exposing secret values in plain configuration.
    Expected output

    Containerapp must be restarted in order for secret changes to take effect.
    
    [
      {
        "name": "db-password"
      }
    ]
    

    az containerapp update \
      --name "$APP_NAME" \
      --resource-group "$RG" \
      --set-env-vars "DB_PASSWORD=secretref:db-password"
    
    Command Why it is used
    az containerapp update ... Updates the existing Container App configuration without recreating the app.
    Expected output
    {
      "name": "ca-nodejs-guide-<unique-suffix>",
      "provisioningState": "Succeeded"
    }
    
  4. Configure KEDA HTTP autoscaling

    az containerapp update \
      --name "$APP_NAME" \
      --resource-group "$RG" \
      --min-replicas 0 \
      --max-replicas 10 \
      --scale-rule-name "http-scale" \
      --scale-rule-type "http" \
      --scale-rule-http-concurrency 50
    
    Command Why it is used
    az containerapp update ... Updates the existing Container App configuration without recreating the app.
    Expected output
    {
      "name": "ca-nodejs-guide-<unique-suffix>",
      "provisioningState": "Succeeded"
    }
    
  5. Enable Dapr sidecar

    az containerapp dapr enable \
      --name "$APP_NAME" \
      --resource-group "$RG" \
      --dapr-app-id "$APP_NAME" \
      --dapr-app-port 8000
    
    Command Why it is used
    az containerapp dapr enable ... Configures Dapr sidecar settings for the Container App.
    Expected output
    {
      "appId": "ca-nodejs-guide-<unique-suffix>",
      "appPort": 8000,
      "appProtocol": "http",
      "enabled": true
    }
    

Verify configuration in Azure Portal

ca-nodejs-d38538 | Container App | Containers | Refresh | Send us your feedback | Container | Properties | Environment variables | Health probes | Volume mounts | Container details | Name | ca-nodejs-d38538 | Image source | Azure Container Registry | Authentication | Managed identity | Subscription | Visual Studio Enterprise Subscription | Registry | acrbasicsd38538.azurecr.io | Image | nodejs-sample | Image tag | v1 | Command override | Arguments override | Application | Revisions and replicas | Containers | Scale | Volumes | Settings | Networking | Ingress | Custom domains | CORS | Security | Monitoring | Log stream | Logs | Console | Alerts | Metrics

[Observed] ca-nodejs-d38538. Container App. Containers. Refresh. Send us your feedback. Container. Properties. Environment variables. Health probes. Volume mounts. Container details. Name. ca-nodejs-d38538. Image source. Azure Container Registry. Docker Hub or other registries. Authentication. Managed identity. Secrets. Identity. System assigned. Subscription. Visual Studio Enterprise Subscription. Registry. acrbasicsd38538.azurecr.io. Image. nodejs-sample. Image tag. v1. Command override. Arguments override. Application. Revisions and replicas. Containers. Scale. Volumes. Settings. Networking. Ingress. Custom domains. CORS. Security. Monitoring. Log stream. Logs. Console. Alerts. Metrics.

[Inferred] The Environment variables tab appears to map to the same name=value pairs supplied via --set-env-vars in Step-by-step. The Image field value nodejs-sample and Image tag value v1 appear consistent with the --image reference set across Step-by-step. The Registry field value acrbasicsd38538.azurecr.io is consistent with the ACR login server referenced throughout Step-by-step. The left-navigation entry Scale is consistent with the --scale-rule-* levers configurable via the operations referenced in Step-by-step.

[Not Proven] Additional configuration detail, secret-binding detail, and integration detail are not visible on this view.

Node.js example: read config safely

In Node.js, environment variables are accessed via process.env. Use the dotenv package (already included in the reference app) for local development.

// src/config.js
const LOG_LEVEL = process.env.LOG_LEVEL || 'INFO';
const FEATURE_FLAG = process.env.FEATURE_FLAG === 'true';
const DB_PASSWORD = process.env.DB_PASSWORD;

module.exports = { LOG_LEVEL, FEATURE_FLAG, DB_PASSWORD };

Advanced Topics

  • Use Managed Identity to pull secrets directly from Azure Key Vault.
  • Implement a custom KEDA scaler (e.g., Azure Service Bus) for event-driven processing.
  • Use Dapr components for state management and pub/sub without writing SDK-specific code.

See Also

Sources