Table of Contents

Azure Open AI Chatbot Deployment Checklist

✅ Azure OpenAI Chatbot Deployment Checklist

1. Local Build and Testing

2. Azure Resources Setup

3. Docker Image Build and Push

4. Deployment Parameters

5. Bicep Deployment

6. Testing After Deployment

7. Security and Scaling

8. Observability

9. Log Analytics and Monitoring

AppContainerAppConsoleLogs_CL \\
| where ContainerAppName_s == "<your-container-app-name>"\\
| sort by TimeGenerated desc

10. Alerts Setup

Example KQL for HTTP 500 Errors:

AppContainerAppConsoleLogs_CL
| where Log_s contains "500"
| summarize Count = count() by bin(TimeGenerated, 5m)

Example Alert Setup Steps:

  1. Go to Azure Monitor > Alerts.
  2. Click + New Alert Rule.
  3. Select Resource: Your Container App or Log Analytics Workspace.
  4. Condition: Add a metric or log query condition.
  5. Action Group: Create or select action groups (email, Teams, webhook, etc.).
  6. Alert Details: Name and severity.

Bicep Definitions To Create Alerts

param containerAppResourceId string
param logAnalyticsWorkspaceId string
param actionGroupId string

@description('Create CPU High Usage Alert')
resource cpuAlert 'Microsoft.Insights/metricAlerts@2018-03-01' = {
  name: 'cpu-high-usage'
  location: 'global'
  properties: {
    description: 'Alert when CPU usage exceeds 80%'
    severity: 3
    enabled: true
    scopes: [containerAppResourceId]
    evaluationFrequency: 'PT1M'
    windowSize: 'PT5M'
    criteria: {
      allOf: [
        {
          metricName: 'cpuUsagePercentage'
          metricNamespace: 'Microsoft.App/containerApps'
          operator: 'GreaterThan'
          threshold: 80
          timeAggregation: 'Average'
        }
      ]
    }
    actions: [
      {
        actionGroupId: actionGroupId
      }
    ]
  }
}

@description('Create Memory High Usage Alert')
resource memoryAlert 'Microsoft.Insights/metricAlerts@2018-03-01' = {
  name: 'memory-high-usage'
  location: 'global'
  properties: {
    description: 'Alert when memory usage exceeds 75%'
    severity: 3
    enabled: true
    scopes: [containerAppResourceId]
    evaluationFrequency: 'PT1M'
    windowSize: 'PT5M'
    criteria: {
      allOf: [
        {
          metricName: 'memoryWorkingSetBytes'
          metricNamespace: 'Microsoft.App/containerApps'
          operator: 'GreaterThan'
          threshold: 75
          timeAggregation: 'Average'
        }
      ]
    }
    actions: [
      {
        actionGroupId: actionGroupId
      }
    ]
  }
}

KQL Code for HTTP 500 Errors

AppContainerAppConsoleLogs_CL
| where Log_s contains "500"
| summarize Count=count() by bin(TimeGenerated, 5m)
| where Count > 0

Bicep Template for Log Query Alert

param logAnalyticsWorkspaceId string
param actionGroupId string

@description('Create HTTP 500 Error Log Alert')
resource errorLogAlert 'Microsoft.Insights/scheduledQueryRules@2021-08-01' = {
  name: 'http-500-error-alert'
  location: 'global'
  properties: {
    description: 'Alert when HTTP 500 errors are detected in logs'
    enabled: true
    source: {
      query: '''
        AppContainerAppConsoleLogs_CL
        | where Log_s contains "500"
        | summarize Count=count() by bin(TimeGenerated, 5m)
        | where Count > 0
      '''
      dataSourceId: logAnalyticsWorkspaceId
      queryType: 'ResultCount'
    }
    schedule: {
      frequencyInMinutes: 5
      timeWindowInMinutes: 5
    }
    action: {
      severity: 3
      trigger: {
        thresholdOperator: 'GreaterThan'
        threshold: 0
      }
      actions: [
        {
          actionGroupId: actionGroupId
        }
      ]
    }
  }
}

Deployment Example

az deployment group create \
  --resource-group MyResourceGroup \
  --template-file log-alert.bicep \
  --parameters \
    logAnalyticsWorkspaceId="/subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.OperationalInsights/workspaces/<workspace-name>" \
    actionGroupId="/subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.Insights/actionGroups/NotifyTeam"

✅ What This Provides

Complete Bicep Bundle

param containerAppResourceId string
param logAnalyticsWorkspaceId string
param actionGroupId string

// CPU High Usage Alert
resource cpuAlert 'Microsoft.Insights/metricAlerts@2018-03-01' = {
  name: 'cpu-high-usage'
  location: 'global'
  properties: {
    description: 'Alert when CPU usage exceeds 80%'
    severity: 3
    enabled: true
    scopes: [containerAppResourceId]
    evaluationFrequency: 'PT1M'
    windowSize: 'PT5M'
    criteria: {
      allOf: [
        {
          metricName: 'cpuUsagePercentage'
          metricNamespace: 'Microsoft.App/containerApps'
          operator: 'GreaterThan'
          threshold: 80
          timeAggregation: 'Average'
        }
      ]
    }
    actions: [
      {
        actionGroupId: actionGroupId
      }
    ]
  }
}

// Memory High Usage Alert
resource memoryAlert 'Microsoft.Insights/metricAlerts@2018-03-01' = {
  name: 'memory-high-usage'
  location: 'global'
  properties: {
    description: 'Alert when memory usage exceeds 75%'
    severity: 3
    enabled: true
    scopes: [containerAppResourceId]
    evaluationFrequency: 'PT1M'
    windowSize: 'PT5M'
    criteria: {
      allOf: [
        {
          metricName: 'memoryWorkingSetBytes'
          metricNamespace: 'Microsoft.App/containerApps'
          operator: 'GreaterThan'
          threshold: 75
          timeAggregation: 'Average'
        }
      ]
    }
    actions: [
      {
        actionGroupId: actionGroupId
      }
    ]
  }
}

// HTTP 500 Log Alert
resource errorLogAlert 'Microsoft.Insights/scheduledQueryRules@2021-08-01' = {
  name: 'http-500-error-alert'
  location: 'global'
  properties: {
    description: 'Alert when HTTP 500 errors are detected in logs'
    enabled: true
    source: {
      query: '''
        AppContainerAppConsoleLogs_CL
        | where Log_s contains "500"
        | summarize Count=count() by bin(TimeGenerated, 5m)
        | where Count > 0
      '''
      dataSourceId: logAnalyticsWorkspaceId
      queryType: 'ResultCount'
    }
    schedule: {
      frequencyInMinutes: 5
      timeWindowInMinutes: 5
    }
    action: {
      severity: 3
      trigger: {
        thresholdOperator: 'GreaterThan'
        threshold: 0
      }
      actions: [
        {
          actionGroupId: actionGroupId
        }
      ]
    }
  }
}

Deployment Command Example

az deployment group create \
  --resource-group MyResourceGroup \
  --template-file complete-alerts.bicep \
  --parameters \
    containerAppResourceId="/subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.App/containerApps/<app-name>" \
    logAnalyticsWorkspaceId="/subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.OperationalInsights/workspaces/<workspace-name>" \
    actionGroupId="/subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.Insights/actionGroups/NotifyTeam"