Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 

README.md

Jarvis Bicep Deployment - Implementation Status

✅ Completed Bicep Templates

1. Main Orchestrator (bicep/main.bicep)

  • ✅ Subscription-level deployment
  • ✅ Parameters for all environments
  • ✅ Module orchestration with proper dependencies
  • ✅ Comprehensive outputs
  • ✅ Deployment summary object

2. Network Module (bicep/modules/network.bicep)

  • ✅ Virtual Network (VNet) with 2 subnets
  • ✅ Network Security Group with 4 rules (HTTPS, HTTP, RDP, Deny All)
  • ✅ Static Public IP with DNS label
  • ✅ Support for custom domain

3. Monitoring Module (bicep/modules/monitoring.bicep)

  • ✅ Log Analytics Workspace (90-day retention)
  • ✅ Application Insights (workspace-based)
  • ✅ Full integration and outputs

4. Alerts Module (bicep/modules/alerts.bicep)

  • ✅ Action Group with email notifications
  • ✅ 5 Alert Rules:
    • High CPU (>90% for 15 min)
    • High Memory (<1GB available)
    • Application Errors (>10 in 5 min)
    • Slow Response (>3s avg)
    • Bot Offline (no heartbeat for 10 min)

📝 Remaining Bicep Templates

To complete the deployment, you still need to create:

5. Availability Tests Module (bicep/modules/availability-tests.bicep)

Purpose: Synthetic monitoring for health checks

Resources Needed:

  • Microsoft.Insights/webTests - Health check test (every 5 min)
  • Microsoft.Insights/webTests - Bot endpoint test (every 15 min)
  • Link to Action Group for alerts

Key Properties:

resource healthCheckTest 'Microsoft.Insights/webTests@2022-06-15' = {
  name: '${prefix}-avtest-health-${environmentName}'
  location: location
  tags: union(tags, {
    'hidden-link:${appInsightsId}': 'Resource'
  })
  properties: {
    SyntheticMonitorId: '${prefix}-avtest-health-${environmentName}'
    Name: 'Jarvis Health Check'
    Enabled: true
    Frequency: 300 // 5 minutes
    Timeout: 30
    Kind: 'ping'
    RetryEnabled: true
    Locations: [
      { Id: 'us-va-ash-azr' }      // East US
      { Id: 'us-ca-sjc-azr' }      // West US
      { Id: 'emea-nl-ams-azr' }    // West Europe
      { Id: 'apac-sg-sin-azr' }    // Southeast Asia
      { Id: 'apac-au-syd-azr' }    // Australia East
    ]
    Configuration: {
      WebTest: '<WebTest><Items><Request Url="https://${testUrl}/healthz" /></Items></WebTest>'
    }
  }
}

6. Key Vault Module (bicep/modules/keyvault.bicep)

Purpose: Secure secrets and certificate storage

Resources Needed:

  • Microsoft.KeyVault/vaults - Key Vault with soft delete + purge protection
  • Access policies (will be set by identity module)
  • Diagnostic settings to Log Analytics

Key Properties:

resource keyVault 'Microsoft.KeyVault/vaults@2023-07-01' = {
  name: keyVaultName
  location: location
  tags: tags
  properties: {
    sku: {
      family: 'A'
      name: 'standard'
    }
    tenantId: subscription().tenantId
    enabledForDeployment: true
    enabledForTemplateDeployment: true
    enabledForDiskEncryption: false
    enableSoftDelete: true
    softDeleteRetentionInDays: 90
    enablePurgeProtection: true
    enableRbacAuthorization: false
    accessPolicies: [] // Set by identity module
    networkAcls: {
      defaultAction: 'Deny'
      bypass: 'AzureServices'
      ipRules: []
      virtualNetworkRules: []
    }
    publicNetworkAccess: 'Enabled'
  }
}

7. Storage Module (bicep/modules/storage.bicep)

Purpose: Boot diagnostics, logs, backups

Resources Needed:

  • Microsoft.Storage/storageAccounts - Standard LRS storage
  • Blob containers: boot-diagnostics, app-logs, backups
  • Lifecycle management policy
  • Soft delete enabled

Key Properties:

resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = {
  name: storageAccountName
  location: location
  tags: tags
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
  properties: {
    accessTier: 'Hot'
    minimumTlsVersion: 'TLS1_2'
    supportsHttpsTrafficOnly: true
    allowBlobPublicAccess: false
    networkAcls: {
      defaultAction: 'Deny'
      bypass: 'AzureServices'
    }
    encryption: {
      services: {
        blob: {
          enabled: true
        }
      }
      keySource: 'Microsoft.Storage'
    }
  }
}

8. Cognitive Services Module (bicep/modules/cognitive.bicep)

Purpose: Azure OpenAI + Speech Services

Resources Needed:

  • Microsoft.CognitiveServices/accounts - Azure OpenAI (Kind: 'OpenAI')
  • Microsoft.CognitiveServices/accounts/deployments - GPT model deployment
  • Microsoft.CognitiveServices/accounts - Speech Services (Kind: 'SpeechServices')
  • Diagnostic settings to Log Analytics

Important Note:

  • OpenAI deployments require @2023-05-01 API version or later
  • Model deployment is a child resource

9. Bot Service Module (bicep/modules/bot-service.bicep)

Purpose: Bot Framework Service for Teams

Resources Needed:

  • Microsoft.BotService/botServices - Bot Channels Registration
  • Teams channel configuration

Key Properties:

resource botService 'Microsoft.BotService/botServices@2023-09-15-preview' = {
  name: botServiceName
  location: 'global'
  sku: {
    name: 'S1'
  }
  kind: 'azurebot'
  properties: {
    displayName: 'Jarvis Meeting Bot'
    endpoint: 'https://${customDomain}/api/messages'
    msaAppId: botAppId
    msaAppType: 'MultiTenant'
    msaAppTenantId: subscription().tenantId
  }
}

resource teamsChannel 'Microsoft.BotService/botServices/channels@2023-09-15-preview' = {
  parent: botService
  name: 'MsTeamsChannel'
  location: 'global'
  properties: {
    channelName: 'MsTeamsChannel'
    properties: {
      enableCalling: true
      isEnabled: true
    }
  }
}

10. Compute Module (bicep/modules/compute.bicep)

Purpose: Windows Server VM for hosting Jarvis

Resources Needed:

  • Microsoft.Compute/virtualMachines - Windows Server 2022 VM
  • System-assigned Managed Identity
  • VM Extensions: AzureMonitorWindowsAgent, CustomScriptExtension
  • Network Interface
  • OS Disk (Premium SSD)
  • Data Disk (Premium SSD)

Key Properties:

identity: {
  type: 'SystemAssigned'
}
properties: {
  hardwareProfile: {
    vmSize: vmSize
  }
  osProfile: {
    computerName: vmName
    adminUsername: adminUsername
    adminPassword: adminPassword
    windowsConfiguration: {
      enableAutomaticUpdates: true
      patchSettings: {
        patchMode: 'AutomaticByPlatform'
      }
    }
  }
  storageProfile: {
    imageReference: {
      publisher: 'MicrosoftWindowsServer'
      offer: 'WindowsServer'
      sku: '2022-datacenter-azure-edition'
      version: 'latest'
    }
    osDisk: {
      createOption: 'FromImage'
      managedDisk: {
        storageAccountType: 'Premium_LRS'
      }
      diskSizeGB: 127
    }
    dataDisks: [
      {
        lun: 0
        createOption: 'Empty'
        diskSizeGB: 128
        managedDisk: {
          storageAccountType: 'Premium_LRS'
        }
      }
    ]
  }
  diagnosticsProfile: {
    bootDiagnostics: {
      enabled: true
      storageUri: 'https://${storageAccountName}.blob.${environment().suffixes.storage}/'
    }
  }
}

11. Identity Module (bicep/modules/identity.bicep)

Purpose: RBAC role assignments for Managed Identity

Resources Needed:

  • Microsoft.Authorization/roleAssignments (multiple)

Role Assignments:

// Key Vault Secrets User
resource kvRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(keyVaultId, vmPrincipalId, '4633458b-17de-408a-b874-0445c86b69e6')
  scope: resourceId('Microsoft.KeyVault/vaults', keyVaultName)
  properties: {
    roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4633458b-17de-408a-b874-0445c86b69e6')
    principalId: vmPrincipalId
    principalType: 'ServicePrincipal'
  }
}

// Cognitive Services User (for OpenAI)
// Cognitive Services User (for Speech)
// Storage Blob Data Contributor
// Monitoring Metrics Publisher

12. Parameter Files

Create 3 parameter files in bicep/parameters/:

prod.parameters.json:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "environmentName": {
      "value": "prod"
    },
    "location": {
      "value": "eastus"
    },
    "prefix": {
      "value": "jarvis"
    },
    "adminUsername": {
      "value": "jarvadmin"
    },
    "adminPassword": {
      "reference": {
        "keyVault": {
          "id": "/subscriptions/<sub-id>/resourceGroups/jarvis-secrets/providers/Microsoft.KeyVault/vaults/jarvis-secrets-kv"
        },
        "secretName": "vmAdminPassword"
      }
    },
    "vmSize": {
      "value": "Standard_D8s_v3"
    },
    "adminSourceIP": {
      "value": "0.0.0.0/32"
    },
    "customDomain": {
      "value": "jarvis.aicollaborator.net"
    },
    "openAIDeploymentName": {
      "value": "gpt-4o-mini"
    },
    "openAIModelName": {
      "value": "gpt-4o-mini"
    },
    "openAIModelVersion": {
      "value": "2024-07-18"
    },
    "botAppId": {
      "value": ""
    }
  }
}

dev.parameters.json and staging.parameters.json - Similar structure with smaller VM sizes and different environment values.

🚀 Deployment Scripts

Create: scripts/deploy-bicep.ps1

param(
    [Parameter(Mandatory=$true)]
    [ValidateSet('dev','staging','prod')]
    [string]$Environment,
    
    [Parameter(Mandatory=$false)]
    [string]$Location = 'eastus',
    
    [Parameter(Mandatory=$false)]
    [switch]$WhatIf
)

$ErrorActionPreference = 'Stop'

Write-Host "🚀 Deploying Jarvis infrastructure to: $Environment" -ForegroundColor Cyan

# Validate Bicep
Write-Host "`n✅ Validating Bicep templates..." -ForegroundColor Yellow
az bicep build --file bicep/main.bicep

# Deploy
$deploymentName = "jarvis-$Environment-$(Get-Date -Format 'yyyyMMddHHmmss')"

$params = @(
    '--location', $Location,
    '--template-file', 'bicep/main.bicep',
    '--parameters', "bicep/parameters/$Environment.parameters.json",
    '--name', $deploymentName
)

if ($WhatIf) {
    $params += '--what-if'
}

Write-Host "`n🏗️  Starting deployment: $deploymentName" -ForegroundColor Yellow
az deployment sub create @params --verbose

Write-Host "`n✅ Deployment complete!" -ForegroundColor Green

Create: scripts/create-entra-app.ps1

# Script to create Entra ID app registration for Jarvis bot
# Grants required Microsoft Graph API permissions
# Stores App ID and Secret in Key Vault

Create: scripts/post-deploy-vm.ps1

# Run on VM after deployment
# Installs .NET 8.0 Runtime
# Configures Windows Service
# Sets up SSL certificate
# Configures environment variables

📊 Deployment Timeline

  1. Create remaining Bicep modules: 2-3 hours
  2. Test deployment in dev: 1 hour
  3. Fix any issues: 1 hour
  4. Deploy to prod: 30 minutes
  5. Post-deployment configuration: 1 hour

Total: ~6 hours

✅ Next Steps

  1. Complete remaining modules 5-11 using the guidance above
  2. Create parameter files for each environment
  3. Test deployment in dev environment
  4. Create PowerShell scripts for Entra app and post-deployment
  5. Deploy to production

All the architecture and patterns are in place. The remaining modules follow the same patterns as the completed ones!