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:
2026-06-30 20:39:52 +02:00
parent 2f2b295531
commit a5f8fb49ab
1717 changed files with 447332 additions and 0 deletions
@@ -0,0 +1,71 @@
// Application Insights module
@description('The environment name (DEV, IAT, Prod)')
param environment string
@description('The location for Application Insights')
param location string
@description('Tags to apply to resources')
param tags object
@description('Unique token for resource naming')
param resourceToken string
@description('Key Vault name for storing connection string')
param keyVaultName string
var appInsightsName = 'appi-dbp-${toLower(environment)}-${resourceToken}'
var logAnalyticsWorkspaceName = 'log-dbp-${toLower(environment)}-${resourceToken}'
resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2025-02-01' = {
name: logAnalyticsWorkspaceName
location: location
tags: tags
properties: {
sku: {
name: 'PerGB2018'
}
retentionInDays: environment == 'Prod' ? 90 : 30
features: {
enableLogAccessUsingOnlyResourcePermissions: true
}
}
}
resource applicationInsights 'Microsoft.Insights/components@2020-02-02' = {
name: appInsightsName
location: location
tags: tags
kind: 'web'
properties: {
Application_Type: 'web'
WorkspaceResourceId: logAnalyticsWorkspace.id
IngestionMode: 'LogAnalytics'
publicNetworkAccessForIngestion: 'Enabled'
publicNetworkAccessForQuery: 'Enabled'
}
}
resource keyVault 'Microsoft.KeyVault/vaults@2024-11-01' existing = {
name: keyVaultName
}
resource connectionStringSecret 'Microsoft.KeyVault/vaults/secrets@2024-11-01' = {
parent: keyVault
name: 'applicationinsights-connection-string'
properties: {
value: applicationInsights.properties.ConnectionString
attributes: {
enabled: true
}
}
}
output applicationInsightsName string = applicationInsights.name
output applicationInsightsId string = applicationInsights.id
output connectionString string = applicationInsights.properties.ConnectionString
output instrumentationKey string = applicationInsights.properties.InstrumentationKey
output logAnalyticsWorkspaceId string = logAnalyticsWorkspace.id
output logAnalyticsWorkspaceName string = logAnalyticsWorkspace.name
@@ -0,0 +1,18 @@
// Container App Environment Certificate module (existing)
@description('Container App Environment name')
param containerAppEnvironmentName string
@description('Certificate name in the Container App Environment')
param certificateName string
resource containerAppEnvironment 'Microsoft.App/managedEnvironments@2025-01-01' existing = {
name: containerAppEnvironmentName
}
resource containerAppCertificate 'Microsoft.App/managedEnvironments/certificates@2025-01-01' existing = {
name: certificateName
parent: containerAppEnvironment
}
output certificateId string = containerAppCertificate.id
@@ -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
@@ -0,0 +1,30 @@
// DNS A Record module for Container App access
@description('Private DNS Zone name')
param privateDnsZoneName string
@description('A Record name (subdomain)')
param aRecordName string
@description('IPv4 address to point to')
param ipv4Address string
resource privateDnsZone 'Microsoft.Network/privateDnsZones@2020-06-01' existing = {
name: privateDnsZoneName
}
resource aRecord 'Microsoft.Network/privateDnsZones/A@2020-06-01' = {
name: aRecordName
parent: privateDnsZone
properties: {
ttl: 3600
aRecords: [
{
ipv4Address: ipv4Address
}
]
}
}
output recordName string = aRecord.name
output fqdn string = '${aRecordName}.${privateDnsZoneName}'
@@ -0,0 +1,59 @@
// Key Vault permissions module - reusable for different roles and principals
@description('Key Vault name')
param keyVaultName string
@description('Principal ID for Key Vault access')
param principalId string
@description('Principal type (User, Group, ServicePrincipal)')
@allowed(['User', 'Group', 'ServicePrincipal'])
param principalType string = 'ServicePrincipal'
@description('Key Vault role to assign')
@allowed([
'Key Vault Administrator'
'Key Vault Certificates Officer'
'Key Vault Crypto Officer'
'Key Vault Crypto Service Encryption User'
'Key Vault Crypto User'
'Key Vault Reader'
'Key Vault Secrets Officer'
'Key Vault Secrets User'
])
param roleName string = 'Key Vault Secrets User'
var roleDefinitions = {
// gitleaks:allow
'Key Vault Administrator': '00482a5a-887f-4fb3-b363-3b7fe8e74483'
'Key Vault Certificates Officer': 'a4417e6f-fecd-4de8-b567-7b0420556985'
'Key Vault Crypto Officer': '14b46e9e-c2b7-41b4-b07b-48a6ebf60603'
'Key Vault Crypto Service Encryption User': 'e147488a-f6f5-4113-8e2d-b22465e65bf6'
// gitleaks:allow
'Key Vault Crypto User': '12338af0-0e69-4776-bea7-57ae8d297424'
// gitleaks:allow
'Key Vault Reader': '21090545-7ca7-4776-b22c-e363652d74d2'
// gitleaks:allow
'Key Vault Secrets Officer': 'b86a8fe4-44ce-4948-aee5-eccb2c155cd7'
// gitleaks:allow
'Key Vault Secrets User': '4633458b-17de-408a-b874-0445c86b69e6'
}
var roleDefinitionId = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleDefinitions[roleName])
resource keyVault 'Microsoft.KeyVault/vaults@2024-11-01' existing = {
name: keyVaultName
}
resource keyVaultRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(keyVault.id, principalId, roleName)
scope: keyVault
properties: {
roleDefinitionId: roleDefinitionId
principalId: principalId
principalType: principalType
}
}
output roleAssignmentId string = keyVaultRoleAssignment.id
output roleAssignmentName string = keyVaultRoleAssignment.name
@@ -0,0 +1,47 @@
// Azure Key Vault module (public access, no Private Endpoint)
@description('The environment name (DEV, IAT, Prod)')
param environment string
@description('The location for the Key Vault')
param location string
@description('Tags to apply to resources')
param tags object
@description('Unique token for resource naming')
param resourceToken string
@description('The tenant ID for Key Vault access')
param tenantId string = subscription().tenantId
var keyVaultName = 'kv-dbp-${toLower(environment)}-${take(resourceToken, 8)}'
resource keyVault 'Microsoft.KeyVault/vaults@2024-11-01' = {
name: keyVaultName
location: location
tags: tags
properties: {
sku: {
family: 'A'
name: 'standard'
}
tenantId: tenantId
enabledForDeployment: false
enabledForDiskEncryption: true
enabledForTemplateDeployment: true
enableSoftDelete: true
softDeleteRetentionInDays: 7
enablePurgeProtection: true
enableRbacAuthorization: true
publicNetworkAccess: 'Enabled'
networkAcls: {
defaultAction: 'Allow'
bypass: 'AzureServices'
}
}
}
output keyVaultName string = keyVault.name
output keyVaultId string = keyVault.id
output keyVaultUri string = keyVault.properties.vaultUri
@@ -0,0 +1,26 @@
// User Managed Identity module
@description('The environment name (DEV, IAT, Prod)')
param environment string
@description('The location for the managed identity')
param location string
@description('Tags to apply to resources')
param tags object
@description('Unique token for resource naming')
param resourceToken string
var managedIdentityName = 'id-dbplanet-${toLower(environment)}-${resourceToken}'
resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2024-11-30' = {
name: managedIdentityName
location: location
tags: tags
}
output managedIdentityName string = managedIdentity.name
output managedIdentityId string = managedIdentity.id
output managedIdentityPrincipalId string = managedIdentity.properties.principalId
output managedIdentityClientId string = managedIdentity.properties.clientId
@@ -0,0 +1,21 @@
// Resource Group module
targetScope = 'subscription'
@description('The resource group name')
param resourceGroupName string
@description('The location for the resource group')
param location string
@description('Tags to apply to the resource group')
param tags object
resource resourceGroup 'Microsoft.Resources/resourceGroups@2025-04-01' = {
name: resourceGroupName
location: location
tags: tags
}
output resourceGroupName string = resourceGroup.name
output resourceGroupId string = resourceGroup.id