Migrate all repos into monorepo context folders
Bahn: aisupport, Analyse-O2C-C2S, awesome-bahn-mcp-servers, beam-mcp,
Confluence_Bot, db-planet-mcp-server, O2C-Harness, project-audit,
Projekt-KIQ-HP, teamlandkarte-mcp
Dhive: Jury-Voting
Privat: CV, NoteGraph (NOTE: NoteGraph needs complete redo after consolidation)
Shared: AI-Orchestrator, OrgMyLife, power_skills_and_more
Shared/references: symphony (read-only)
Bahn repos remain available as independent remotes - this monorepo
pulls them in via subtree, the originals are untouched.
This commit is contained in:
@@ -0,0 +1,206 @@
|
||||
// Container App module for DB Planet MCP Server
|
||||
|
||||
@description('The environment name (DEV, IAT, Prod)')
|
||||
param environment string
|
||||
|
||||
@description('The location for the Container App')
|
||||
param location string
|
||||
|
||||
@description('Tags to apply to resources')
|
||||
param tags object
|
||||
|
||||
@description('Unique token for resource naming')
|
||||
param resourceToken string
|
||||
|
||||
@description('Existing central Key Vault name (shared secrets)')
|
||||
param centralKeyVaultName string
|
||||
|
||||
@description('Existing central Key Vault resource group')
|
||||
param centralKeyVaultResourceGroup string
|
||||
|
||||
@description('App-specific Key Vault URI (created by keyvault.bicep)')
|
||||
param appKeyVaultUri string
|
||||
|
||||
@description('Existing Container App Environment name')
|
||||
param containerAppEnvironmentName string
|
||||
|
||||
@description('Existing Container App Environment resource group')
|
||||
param containerAppEnvironmentResourceGroup string
|
||||
|
||||
@description('Artifactory server URL for container registry')
|
||||
param artifactoryServer string
|
||||
|
||||
@description('Registry username for container registry authentication')
|
||||
param registryUsername string
|
||||
|
||||
@description('Managed Identity ID for Key Vault access')
|
||||
param managedIdentityId string
|
||||
|
||||
@description('Container image tag/version')
|
||||
param imageTag string = 'latest'
|
||||
|
||||
@description('DB Planet base URL (staging vs production)')
|
||||
param dbplanetBaseUrl string
|
||||
|
||||
@description('Custom domain name for the Container App')
|
||||
param customDomainName string = ''
|
||||
|
||||
@description('Container App Certificate ID (if custom domain is configured)')
|
||||
param containerAppCertificateId string = ''
|
||||
|
||||
var containerAppName = 'ca-dbp-${toLower(environment)}-${take(resourceToken, 8)}'
|
||||
|
||||
// Custom domain configuration
|
||||
var customDomain = !empty(customDomainName) && !empty(containerAppCertificateId) ? [
|
||||
{
|
||||
name: customDomainName
|
||||
certificateId: containerAppCertificateId
|
||||
bindingType: 'SniEnabled'
|
||||
}
|
||||
] : []
|
||||
|
||||
// Reference existing central Key Vault
|
||||
resource centralKeyVault 'Microsoft.KeyVault/vaults@2024-11-01' existing = {
|
||||
name: centralKeyVaultName
|
||||
scope: resourceGroup(centralKeyVaultResourceGroup)
|
||||
}
|
||||
|
||||
|
||||
// Reference existing Container App Environment
|
||||
resource containerAppEnvironment 'Microsoft.App/managedEnvironments@2025-01-01' existing = {
|
||||
name: containerAppEnvironmentName
|
||||
scope: resourceGroup(containerAppEnvironmentResourceGroup)
|
||||
}
|
||||
|
||||
// Container App
|
||||
resource containerApp 'Microsoft.App/containerApps@2025-01-01' = {
|
||||
name: containerAppName
|
||||
location: location
|
||||
tags: tags
|
||||
identity: {
|
||||
type: 'SystemAssigned, UserAssigned'
|
||||
userAssignedIdentities: {
|
||||
'${managedIdentityId}': {}
|
||||
}
|
||||
}
|
||||
properties: {
|
||||
managedEnvironmentId: containerAppEnvironment.id
|
||||
workloadProfileName: 'Consumption'
|
||||
configuration: {
|
||||
ingress: {
|
||||
external: true
|
||||
targetPort: 4000
|
||||
allowInsecure: false
|
||||
customDomains: customDomain
|
||||
traffic: [
|
||||
{
|
||||
weight: 100
|
||||
latestRevision: true
|
||||
}
|
||||
]
|
||||
}
|
||||
secrets: [
|
||||
{
|
||||
name: 'artifactory-token'
|
||||
keyVaultUrl: '${centralKeyVault.properties.vaultUri}secrets/artifactory-registry-token'
|
||||
identity: managedIdentityId
|
||||
}
|
||||
{
|
||||
name: 'appinsights-connection-string'
|
||||
keyVaultUrl: '${appKeyVaultUri}secrets/applicationinsights-connection-string'
|
||||
identity: 'system'
|
||||
}
|
||||
{
|
||||
name: 'dbplanet-username'
|
||||
keyVaultUrl: '${appKeyVaultUri}secrets/DBPLANET-USERNAME'
|
||||
identity: 'system'
|
||||
}
|
||||
{
|
||||
name: 'dbplanet-password'
|
||||
keyVaultUrl: '${appKeyVaultUri}secrets/DBPLANET-PASSWORD'
|
||||
identity: 'system'
|
||||
}
|
||||
{
|
||||
name: 'dbplanet-client-id'
|
||||
keyVaultUrl: '${appKeyVaultUri}secrets/DBPLANET-CLIENT-ID'
|
||||
identity: 'system'
|
||||
}
|
||||
{
|
||||
name: 'dbplanet-client-secret'
|
||||
keyVaultUrl: '${appKeyVaultUri}secrets/DBPLANET-CLIENT-SECRET'
|
||||
identity: 'system'
|
||||
}
|
||||
]
|
||||
registries: [
|
||||
{
|
||||
server: artifactoryServer
|
||||
username: registryUsername
|
||||
passwordSecretRef: 'artifactory-token'
|
||||
}
|
||||
]
|
||||
}
|
||||
template: {
|
||||
containers: [
|
||||
{
|
||||
name: 'dbplanet-mcp'
|
||||
image: '${artifactoryServer}/db-planet-mcp-server:${imageTag}'
|
||||
resources: {
|
||||
cpu: json(environment == 'Prod' ? '1.0' : '0.5')
|
||||
memory: environment == 'Prod' ? '2Gi' : '1Gi'
|
||||
}
|
||||
env: [
|
||||
{ name: 'DBPLANET_BASE_URL', value: dbplanetBaseUrl }
|
||||
{ name: 'DBPLANET_USERNAME', secretRef: 'dbplanet-username' }
|
||||
{ name: 'DBPLANET_PASSWORD', secretRef: 'dbplanet-password' }
|
||||
{ name: 'DBPLANET_CLIENT_ID', secretRef: 'dbplanet-client-id' }
|
||||
{ name: 'DBPLANET_CLIENT_SECRET', secretRef: 'dbplanet-client-secret' }
|
||||
{ name: 'NODE_ENV', value: environment == 'Prod' ? 'production' : 'development' }
|
||||
{ name: 'HTTP_PROXY', value: 'http://webproxy.comp.db.de:8080' }
|
||||
{ name: 'HTTPS_PROXY', value: 'http://webproxy.comp.db.de:8080' }
|
||||
{ name: 'http_proxy', value: 'http://webproxy.comp.db.de:8080' }
|
||||
{ name: 'https_proxy', value: 'http://webproxy.comp.db.de:8080' }
|
||||
{ name: 'NO_PROXY', value: '169.254.169.254,169.254.170.2,cognitiveservices.azure.com,internal.deutschebahn.com,db.de' }
|
||||
{ name: 'no_proxy', value: '169.254.169.254,169.254.170.2,cognitiveservices.azure.com,internal.deutschebahn.com,db.de' }
|
||||
{ name: 'STREAMABLE_HTTP', value: 'true' }
|
||||
{ name: 'REMOTE_AUTHORIZATION', value: 'true' }
|
||||
{ name: 'HOST', value: '0.0.0.0' }
|
||||
{
|
||||
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
|
||||
secretRef: 'appinsights-connection-string'
|
||||
}
|
||||
]
|
||||
probes: [
|
||||
{
|
||||
type: 'Readiness'
|
||||
httpGet: {
|
||||
path: '/health'
|
||||
port: 4000
|
||||
}
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 30
|
||||
}
|
||||
{
|
||||
type: 'Liveness'
|
||||
httpGet: {
|
||||
path: '/health'
|
||||
port: 4000
|
||||
}
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 60
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
scale: {
|
||||
minReplicas: 1
|
||||
maxReplicas: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
output containerAppName string = containerApp.name
|
||||
output containerAppId string = containerApp.id
|
||||
output containerAppFqdn string = containerApp.properties.configuration.ingress.fqdn
|
||||
output systemIdentityPrincipalId string = containerApp.identity.principalId
|
||||
output containerAppEnvironmentStaticIp string = containerAppEnvironment.properties.staticIp
|
||||
Reference in New Issue
Block a user