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,243 @@
|
||||
// DB Planet MCP Server Infrastructure
|
||||
// Deploys: Resource Group, Managed Identity, Key Vault,
|
||||
// Application Insights, Container App, Key Vault permissions
|
||||
|
||||
targetScope = 'subscription'
|
||||
|
||||
// ── Core parameters ──────────────────────────────────────────
|
||||
@description('Environment name')
|
||||
@allowed(['DEV', 'IAT', 'Prod'])
|
||||
param environment string
|
||||
|
||||
@description('Azure region')
|
||||
param location string = 'westeurope'
|
||||
|
||||
@description('Container image tag')
|
||||
param imageTag string = 'latest'
|
||||
|
||||
@description('Set to true on second deployment after infra + permissions are in place')
|
||||
param deployContainerApp bool = false
|
||||
|
||||
// ── Tags ─────────────────────────────────────────────────────
|
||||
@description('Tags applied to all resources')
|
||||
param tags object = {
|
||||
CostReference: 'H-450007-52-01'
|
||||
ReferenceID: 'A-113241'
|
||||
ReferenceName: 'DB Planet MCP Server'
|
||||
Environment: environment
|
||||
}
|
||||
|
||||
// ── Existing infrastructure references ───────────────────────
|
||||
@description('Central Key Vault name (shared secrets)')
|
||||
param centralKeyVaultName string
|
||||
|
||||
@description('Central Key Vault resource group')
|
||||
param centralKeyVaultResourceGroup string
|
||||
|
||||
@description('Container App Environment name')
|
||||
param containerAppEnvironmentName string
|
||||
|
||||
@description('Container App Environment resource group')
|
||||
param containerAppEnvironmentResourceGroup string
|
||||
|
||||
// ── Application configuration ────────────────────────────────
|
||||
@description('Artifactory server URL')
|
||||
param artifactoryServer string
|
||||
|
||||
@description('Registry username')
|
||||
param registryUsername string
|
||||
|
||||
@description('DB Planet base URL (staging vs production)')
|
||||
param dbplanetBaseUrl string
|
||||
|
||||
// ── Service Principal for Key Vault secrets management ───────
|
||||
#disable-next-line secure-secrets-in-params // Object ID, not a secret
|
||||
@description('Service Principal Object ID for Key Vault Secrets Officer role')
|
||||
param secretsOfficerPrincipalId string = ''
|
||||
|
||||
// ── Custom domain (optional) ─────────────────────────────────
|
||||
@description('Certificate name in Container App Environment')
|
||||
param certificateName string = ''
|
||||
|
||||
@description('DNS zone name for custom domain')
|
||||
param dnsZoneName string = ''
|
||||
|
||||
@description('DNS record name (subdomain)')
|
||||
param dnsRecordName string = ''
|
||||
|
||||
@description('Resource group containing the DNS zone')
|
||||
param dnsZoneResourceGroup string = 'Infrastructure'
|
||||
|
||||
// ── Derived values ───────────────────────────────────────────
|
||||
var resourceGroupName = 'rg-dbplanet-mcp-${toLower(environment)}'
|
||||
var resourceToken = toLower(uniqueString(subscription().id, resourceGroupName, location))
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
// 1. Resource Group
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
module rg 'modules/resource-group.bicep' = {
|
||||
name: 'deploy-rg'
|
||||
params: {
|
||||
resourceGroupName: resourceGroupName
|
||||
location: location
|
||||
tags: tags
|
||||
}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
// 2. Managed Identity
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
module identity 'modules/managed-identity.bicep' = {
|
||||
name: 'deploy-identity'
|
||||
scope: resourceGroup(resourceGroupName)
|
||||
dependsOn: [rg]
|
||||
params: {
|
||||
environment: environment
|
||||
location: location
|
||||
tags: tags
|
||||
resourceToken: resourceToken
|
||||
}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
// 3. Key Vault (app-specific, public access)
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
module keyVault 'modules/keyvault.bicep' = {
|
||||
name: 'deploy-keyvault'
|
||||
scope: resourceGroup(resourceGroupName)
|
||||
dependsOn: [rg]
|
||||
params: {
|
||||
environment: environment
|
||||
location: location
|
||||
tags: tags
|
||||
resourceToken: resourceToken
|
||||
}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
// 4. Application Insights + Log Analytics
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
module appInsights 'modules/application-insights.bicep' = {
|
||||
name: 'deploy-app-insights'
|
||||
scope: resourceGroup(resourceGroupName)
|
||||
params: {
|
||||
environment: environment
|
||||
location: location
|
||||
tags: tags
|
||||
resourceToken: resourceToken
|
||||
keyVaultName: keyVault.outputs.keyVaultName
|
||||
}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
// 5. Container App Certificate (existing, optional)
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
module certificate 'modules/container-app-certificate.bicep' = if (!empty(certificateName)) {
|
||||
name: 'deploy-certificate'
|
||||
scope: resourceGroup(containerAppEnvironmentResourceGroup)
|
||||
params: {
|
||||
containerAppEnvironmentName: containerAppEnvironmentName
|
||||
certificateName: certificateName
|
||||
}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
// 6. Container App
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
var customDomainName = !empty(dnsRecordName) && !empty(dnsZoneName) ? '${dnsRecordName}.${dnsZoneName}' : ''
|
||||
|
||||
module containerApp 'modules/container-app.bicep' = if (deployContainerApp) {
|
||||
name: 'deploy-container-app'
|
||||
scope: resourceGroup(resourceGroupName)
|
||||
dependsOn: [rg]
|
||||
params: {
|
||||
environment: environment
|
||||
location: location
|
||||
tags: tags
|
||||
resourceToken: resourceToken
|
||||
centralKeyVaultName: centralKeyVaultName
|
||||
centralKeyVaultResourceGroup: centralKeyVaultResourceGroup
|
||||
appKeyVaultUri: keyVault.outputs.keyVaultUri
|
||||
containerAppEnvironmentName: containerAppEnvironmentName
|
||||
containerAppEnvironmentResourceGroup: containerAppEnvironmentResourceGroup
|
||||
artifactoryServer: artifactoryServer
|
||||
registryUsername: registryUsername
|
||||
managedIdentityId: identity.outputs.managedIdentityId
|
||||
imageTag: imageTag
|
||||
dbplanetBaseUrl: dbplanetBaseUrl
|
||||
customDomainName: !empty(certificateName) ? customDomainName : ''
|
||||
containerAppCertificateId: !empty(certificateName) ? certificate.outputs.certificateId! : ''
|
||||
}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
// 7. DNS Record
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
module dnsRecord 'modules/dns-record.bicep' = if (deployContainerApp && !empty(dnsRecordName)) {
|
||||
name: 'deploy-dns-record'
|
||||
scope: resourceGroup(dnsZoneResourceGroup)
|
||||
params: {
|
||||
privateDnsZoneName: dnsZoneName
|
||||
aRecordName: dnsRecordName
|
||||
ipv4Address: containerApp.outputs.containerAppEnvironmentStaticIp!
|
||||
}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
// 8. Key Vault Permissions
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
|
||||
// 6a. Managed Identity → central Key Vault (read registry secrets)
|
||||
module centralKvPermissions 'modules/key-vault-permissions.bicep' = {
|
||||
name: 'deploy-central-kv-permissions'
|
||||
scope: resourceGroup(centralKeyVaultResourceGroup)
|
||||
params: {
|
||||
keyVaultName: centralKeyVaultName
|
||||
principalId: identity.outputs.managedIdentityPrincipalId
|
||||
roleName: 'Key Vault Secrets User'
|
||||
}
|
||||
}
|
||||
|
||||
// 6b. Managed Identity → app Key Vault (read app secrets)
|
||||
module appKvIdentityPermissions 'modules/key-vault-permissions.bicep' = {
|
||||
name: 'deploy-app-kv-identity-permissions'
|
||||
scope: resourceGroup(resourceGroupName)
|
||||
params: {
|
||||
keyVaultName: keyVault.outputs.keyVaultName
|
||||
principalId: identity.outputs.managedIdentityPrincipalId
|
||||
roleName: 'Key Vault Secrets User'
|
||||
}
|
||||
}
|
||||
|
||||
// 6c. Container App system identity → app Key Vault (read app secrets)
|
||||
module appKvContainerAppPermissions 'modules/key-vault-permissions.bicep' = if (deployContainerApp) {
|
||||
name: 'deploy-app-kv-ca-permissions'
|
||||
scope: resourceGroup(resourceGroupName)
|
||||
params: {
|
||||
keyVaultName: keyVault.outputs.keyVaultName
|
||||
principalId: containerApp.outputs.systemIdentityPrincipalId!
|
||||
roleName: 'Key Vault Secrets User'
|
||||
}
|
||||
}
|
||||
|
||||
// 6d. Service Principal → app Key Vault (read + write secrets for CI/CD)
|
||||
module appKvOfficerPermissions 'modules/key-vault-permissions.bicep' = if (!empty(secretsOfficerPrincipalId)) {
|
||||
name: 'deploy-app-kv-officer-permissions'
|
||||
scope: resourceGroup(resourceGroupName)
|
||||
params: {
|
||||
keyVaultName: keyVault.outputs.keyVaultName
|
||||
principalId: secretsOfficerPrincipalId
|
||||
roleName: 'Key Vault Secrets Officer'
|
||||
}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
// Outputs
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
output resourceGroupName string = rg.outputs.resourceGroupName
|
||||
output keyVaultName string = keyVault.outputs.keyVaultName
|
||||
output keyVaultUri string = keyVault.outputs.keyVaultUri
|
||||
output containerAppName string = deployContainerApp ? containerApp.outputs.containerAppName! : ''
|
||||
output containerAppFqdn string = deployContainerApp ? containerApp.outputs.containerAppFqdn! : ''
|
||||
output managedIdentityId string = identity.outputs.managedIdentityId
|
||||
output appInsightsName string = appInsights.outputs.applicationInsightsName
|
||||
Reference in New Issue
Block a user