Skip to main content
Glama
sepal7
by sepal7
azure-deploy.bicep5.86 kB
// Bicep template for minimal-cost Azure deployment // Designed for team sharing - deploy once, everyone uses it // Follows standard naming conventions // Estimated cost: $5-15/month @description('Project code (xx in naming convention, e.g., mcp, ado)') param projectCode string = 'mcp' @description('Environment code (dv = dev, qa = qa, pr = prod)') param environment string = 'dv' @description('Location code (eus2 = eastus2)') param locationCode string = 'eus2' @description('Instance number (001, 002, etc.)') param instanceNumber string = '001' // ACR names can only contain alphanumeric (no dashes) var containerRegistryName = 'acr00${environment}${projectCode}${instanceNumber}' @description('Azure DevOps organization name') param orgName string = 'YourOrganization' @description('Azure DevOps project name') param projectName string = 'Integration' @description('Azure DevOps Personal Access Token (stored in Key Vault)') @secure() param adoPat string @description('Location for resources') param location string = 'eastus2' @description('Enable external ingress for team access (optional)') param enableExternalIngress bool = false // Naming following standard conventions var resourceGroupName = 'rg-00-integration-${projectCode}-${environment}-${locationCode}-${instanceNumber}' var containerAppName = 'cap-00-${environment}-${projectCode}-${instanceNumber}' var containerRegistryName = 'acr-00-${environment}-${projectCode}-${instanceNumber}' var keyVaultName = 'kyt-00-${environment}-${projectCode}-${instanceNumber}' var containerAppEnvName = 'cae-00-${environment}-${projectCode}-${instanceNumber}' var identityName = '${containerAppName}-identity' // Key Vault for storing PAT securely resource keyVault 'Microsoft.KeyVault/vaults@2023-07-01' = { name: keyVaultName location: location properties: { sku: { family: 'A' name: 'standard' } tenantId: subscription().tenantId enabledForDeployment: false enabledForTemplateDeployment: true enabledForDiskEncryption: false accessPolicies: [] enableSoftDelete: true softDeleteRetentionInDays: 7 enableRbacAuthorization: false } } // Store PAT in Key Vault resource adoPatSecret 'Microsoft.KeyVault/vaults/secrets@2023-07-01' = { parent: keyVault name: 'AzureDevOpsPAT' properties: { value: adoPat } } // Container Registry (Basic tier - $5/month) // Note: ACR names can only contain alphanumeric (no dashes) resource containerRegistry 'Microsoft.ContainerRegistry/registries@2023-01-01-preview' = { name: containerRegistryName location: location sku: { name: 'Basic' } properties: { adminUserEnabled: true } } // Container Apps Environment (consumption plan - scales to zero) resource containerAppEnv 'Microsoft.App/managedEnvironments@2023-05-01' = { name: containerAppEnvName location: location properties: { appLogsConfiguration: { destination: 'log-analytics' } } } // System-assigned managed identity for ACR pull resource systemAssignedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { name: identityName location: location } // Grant ACR pull permissions resource acrPullRole 'Microsoft.ContainerRegistry/registries/roleAssignments@2023-01-01-preview' = { parent: containerRegistry name: guid(containerRegistry.id, systemAssignedIdentity.id, 'AcrPull') properties: { principalId: systemAssignedIdentity.properties.principalId roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe0d1da4b5') // AcrPull } } // Container App (minimal resources - consumption plan) resource containerApp 'Microsoft.App/containerApps@2023-05-01' = { name: containerAppName location: location properties: { managedEnvironmentId: containerAppEnv.id configuration: { ingress: { external: enableExternalIngress targetPort: 3000 transport: 'http' allowInsecure: false } registries: [ { server: containerRegistry.properties.loginServer identity: systemAssignedIdentity.id } ] } template: { containers: [ { image: '${containerRegistry.properties.loginServer}/mcp-ado-server:latest' name: containerAppName resources: { cpu: json('0.25') // Minimal CPU memory: '0.5Gi' // Minimal memory } env: [ { name: 'AZURE_DEVOPS_ORG' value: orgName } { name: 'AZURE_DEVOPS_PROJECT' value: projectName } { name: 'AZURE_DEVOPS_PAT' secretRef: 'azure-devops-pat' } { name: 'NODE_ENV' value: 'production' } ] } ] scale: { minReplicas: 0 // Scale to zero when not in use maxReplicas: 2 // Max 2 replicas for team sharing } } } } // Reference to Key Vault secret for Container App resource keyVaultSecretRef 'Microsoft.App/containerApps/secrets@2023-05-01' = { parent: containerApp name: 'azure-devops-pat' properties: { keyVaultUrl: adoPatSecret.properties.secretUriWithVersion identity: systemAssignedIdentity.id } } // Outputs output resourceGroupName string = resourceGroupName output containerAppName string = containerApp.name output containerAppFqdn string = containerApp.properties.configuration.ingress.fqdn output keyVaultName string = keyVault.name output containerRegistryName string = containerRegistry.name output estimatedMonthlyCost string = '$5-15/month (Container Registry: $5, Container Apps: $0-10, Key Vault: $0.03)' output deploymentNote string = 'Deploy once, share with your entire team!'

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sepal7/mcp-ado'

If you have feedback or need assistance with the MCP directory API, please join our Discord server