Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 33 additions & 39 deletions infra/main.bicep

Large diffs are not rendered by default.

3,724 changes: 2,333 additions & 1,391 deletions infra/main.json

Large diffs are not rendered by default.

15 changes: 0 additions & 15 deletions infra/main.parameters.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,6 @@
},
"vmAdminPassword": {
"value": "${AZURE_ENV_VM_ADMIN_PASSWORD}"
},
"aiModelDeployments": {
"value": [
{
"name": "${AZURE_ENV_GPT_MODEL_NAME}",
"model": {
"name": "${AZURE_ENV_GPT_MODEL_NAME}",
"version": "${AZURE_ENV_GPT_MODEL_VERSION}"
},
"sku": {
"name": "${AZURE_ENV_MODEL_DEPLOYMENT_TYPE}",
"capacity": "${AZURE_ENV_GPT_MODEL_CAPACITY}"
}
}
]
}
}
}
15 changes: 0 additions & 15 deletions infra/main.waf.parameters.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,21 +55,6 @@
},
"enableScalability": {
"value": true
},
"aiModelDeployments": {
"value": [
{
"name": "${AZURE_ENV_GPT_MODEL_NAME}",
"model": {
"name": "${AZURE_ENV_GPT_MODEL_NAME}",
"version": "${AZURE_ENV_GPT_MODEL_VERSION}"
},
"sku": {
"name": "${AZURE_ENV_MODEL_DEPLOYMENT_TYPE}",
"capacity": "${AZURE_ENV_GPT_MODEL_CAPACITY}"
}
}
]
}
}
}
74 changes: 31 additions & 43 deletions infra/main_custom.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -167,15 +167,15 @@ var resourceGroupTagsValue = union(
)

// ========== Resource Group Tag ========== //
resource resourceGroupTags 'Microsoft.Resources/tags@2021-04-01' = {
resource resourceGroupTags 'Microsoft.Resources/tags@2025-04-01' = {
name: 'default'
properties: {
tags: resourceGroupTagsValue
}
}

#disable-next-line no-deployments-resources
resource avmTelemetry 'Microsoft.Resources/deployments@2024-03-01' = if (enableTelemetry) {
resource avmTelemetry 'Microsoft.Resources/deployments@2025-04-01' = if (enableTelemetry) {
name: take(
'46d3xbcp.ptn.sa-modernizeyourcode.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}',
64
Expand All @@ -196,7 +196,7 @@ resource avmTelemetry 'Microsoft.Resources/deployments@2024-03-01' = if (enableT
}
}

module appIdentity 'br/public:avm/res/managed-identity/user-assigned-identity:0.4.2' = {
module appIdentity 'br/public:avm/res/managed-identity/user-assigned-identity:0.5.0' = {
name: take('avm.res.managed-identity.user-assigned-identity.${solutionSuffix}', 64)
params: {
name: 'id-${solutionSuffix}'
Expand All @@ -212,13 +212,13 @@ var existingLawSubscription = useExistingLogAnalytics ? split(existingLogAnalyti
var existingLawResourceGroup = useExistingLogAnalytics ? split(existingLogAnalyticsWorkspaceId, '/')[4] : ''
var existingLawName = useExistingLogAnalytics ? split(existingLogAnalyticsWorkspaceId, '/')[8] : ''

resource existingLogAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2020-08-01' existing = if (useExistingLogAnalytics) {
resource existingLogAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2025-07-01' existing = if (useExistingLogAnalytics) {
name: existingLawName
scope: resourceGroup(existingLawSubscription, existingLawResourceGroup)
}

// Deploy new Log Analytics workspace only if required and not using existing
module logAnalyticsWorkspace 'br/public:avm/res/operational-insights/workspace:0.12.0' = if ((enableMonitoring || enablePrivateNetworking) && !useExistingLogAnalytics) {
module logAnalyticsWorkspace 'br/public:avm/res/operational-insights/workspace:0.15.0' = if ((enableMonitoring || enablePrivateNetworking) && !useExistingLogAnalytics) {
name: take('avm.res.operational-insights.workspace.${solutionSuffix}', 64)
params: {
name: 'log-${solutionSuffix}'
Expand All @@ -229,7 +229,7 @@ module logAnalyticsWorkspace 'br/public:avm/res/operational-insights/workspace:0
tags: allTags
enableTelemetry: enableTelemetry
// WAF aligned configuration for Redundancy
dailyQuotaGb: enableRedundancy ? 10 : null //WAF recommendation: 10 GB per day is a good starting point for most workloads
dailyQuotaGb: enableRedundancy ? '10' : null //WAF recommendation: 10 GB per day is a good starting point for most workloads
replication: enableRedundancy
? {
enabled: true
Expand Down Expand Up @@ -278,11 +278,9 @@ module logAnalyticsWorkspace 'br/public:avm/res/operational-insights/workspace:0

// Log Analytics workspace ID, customer ID, and shared key (existing or new)
var logAnalyticsWorkspaceResourceId = useExistingLogAnalytics ? existingLogAnalyticsWorkspaceId : logAnalyticsWorkspace!.outputs.resourceId
var LogAnalyticsPrimarySharedKey string = useExistingLogAnalytics? existingLogAnalyticsWorkspace.listKeys().primarySharedKey : logAnalyticsWorkspace.outputs.primarySharedKey
var LogAnalyticsWorkspaceId = useExistingLogAnalytics? existingLogAnalyticsWorkspace.properties.customerId : logAnalyticsWorkspace!.outputs.logAnalyticsWorkspaceId
var logAnalyticsWorkspaceName = useExistingLogAnalytics ? existingLawName : logAnalyticsWorkspace!.outputs.name

module applicationInsights 'br/public:avm/res/insights/component:0.7.0' = if (enableMonitoring) {
module applicationInsights 'br/public:avm/res/insights/component:0.7.1' = if (enableMonitoring) {
name: take('avm.res.insights.component.${solutionSuffix}', 64)
params: {
name: 'appi-${solutionSuffix}'
Expand Down Expand Up @@ -341,7 +339,7 @@ var dnsZoneIndex = {
// - Excludes AI-related zones when using with an existing Foundry project
// ===================================================
@batchSize(5)
module avmPrivateDnsZones 'br/public:avm/res/network/private-dns-zone:0.8.0' = [
module avmPrivateDnsZones 'br/public:avm/res/network/private-dns-zone:0.8.1' = [
for (zone, i) in privateDnsZones: if (enablePrivateNetworking) {
name: take('avm.res.network.private-dns-zone.${split(zone, '.')[1]}.${solutionSuffix}', 64)
params: {
Expand All @@ -360,7 +358,7 @@ module avmPrivateDnsZones 'br/public:avm/res/network/private-dns-zone:0.8.0' = [

// Azure Bastion Host
var bastionHostName = 'bas-${solutionSuffix}'
module bastionHost 'br/public:avm/res/network/bastion-host:0.8.0' = if (enablePrivateNetworking) {
module bastionHost 'br/public:avm/res/network/bastion-host:0.8.2' = if (enablePrivateNetworking) {
name: take('avm.res.network.bastion-host.${bastionHostName}', 64)
params: {
Comment thread
Pavan-Microsoft marked this conversation as resolved.
name: bastionHostName
Expand All @@ -383,14 +381,14 @@ module bastionHost 'br/public:avm/res/network/bastion-host:0.8.0' = if (enablePr
enableTelemetry: enableTelemetry
publicIPAddressObject: {
name: 'pip-${bastionHostName}'
zones: []
availabilityZones: []
}
}
}

// ========== Jumpbox Virtual machine ========== //
var maintenanceConfigurationResourceName = 'mc-${solutionSuffix}'
module maintenanceConfiguration 'br/public:avm/res/maintenance/maintenance-configuration:0.3.2' = if (enablePrivateNetworking) {
module maintenanceConfiguration 'br/public:avm/res/maintenance/maintenance-configuration:0.4.0' = if (enablePrivateNetworking) {
name: take('avm.res.compute.virtual-machine.${maintenanceConfigurationResourceName}', 64)
params: {
name: maintenanceConfigurationResourceName
Expand Down Expand Up @@ -430,7 +428,7 @@ var dataCollectionRulesResourceName = 'dcr-${solutionSuffix}'
var dataCollectionRulesLocation = useExistingLogAnalytics
? existingLogAnalyticsWorkspace!.location
: logAnalyticsWorkspace!.outputs.location
module windowsVmDataCollectionRules 'br/public:avm/res/insights/data-collection-rule:0.8.0' = if (enablePrivateNetworking && enableMonitoring) {
module windowsVmDataCollectionRules 'br/public:avm/res/insights/data-collection-rule:0.11.0' = if (enablePrivateNetworking && enableMonitoring) {
name: take('avm.res.insights.data-collection-rule.${dataCollectionRulesResourceName}', 64)
params: {
name: dataCollectionRulesResourceName
Expand Down Expand Up @@ -503,15 +501,6 @@ module windowsVmDataCollectionRules 'br/public:avm/res/insights/data-collection-
streams: [
'Microsoft-WindowsEvent'
]
eventLogName: 'Security'
eventTypes: [
{
eventType: 'Audit Success'
}
{
eventType: 'Audit Failure'
}
]
xPathQueries: [
'Security!*[System[(EventID=4624 or EventID=4625)]]'
]
Expand Down Expand Up @@ -556,7 +545,7 @@ module proximityPlacementGroup 'br/public:avm/res/compute/proximity-placement-gr


var virtualMachineResourceName = take('vm-jumpbox-${solutionSuffix}', 15)
module virtualMachine 'br/public:avm/res/compute/virtual-machine:0.20.0' = if (enablePrivateNetworking) {
module virtualMachine 'br/public:avm/res/compute/virtual-machine:0.22.0' = if (enablePrivateNetworking) {
name: take('avm.res.compute.virtual-machine.${virtualMachineResourceName}', 64)
params: {
name: virtualMachineResourceName
Expand All @@ -565,18 +554,18 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:0.20.0' = if (e
enableTelemetry: enableTelemetry
computerName: take(virtualMachineResourceName, 15)
osType: 'Windows'
vmSize: !empty(vmSize) ? vmSize : 'Standard_D2s_v5'
vmSize: !empty(vmSize) ? vmSize! : 'Standard_D2s_v5'
adminUsername: !empty(vmAdminUsername) ? vmAdminUsername : 'JumpboxAdminUser'
adminPassword: !empty(vmAdminPassword) ? vmAdminPassword : 'JumpboxAdminP@ssw0rd1234!'
managedIdentities: {
systemAssigned: true
}
patchMode: 'AutomaticByPlatform'
bypassPlatformSafetyChecksOnUserSchedule: true
maintenanceConfigurationResourceId: maintenanceConfiguration.outputs.resourceId
maintenanceConfigurationResourceId: maintenanceConfiguration!.outputs.resourceId
enableAutomaticUpdates: true
encryptionAtHost: false
proximityPlacementGroupResourceId: proximityPlacementGroup.outputs.resourceId
proximityPlacementGroupResourceId: proximityPlacementGroup!.outputs.resourceId
availabilityZone: enableRedundancy ? 1 : -1
imageReference: {
publisher: 'microsoft-dsvm'
Expand Down Expand Up @@ -642,7 +631,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:0.20.0' = if (e
? {
dataCollectionRuleAssociations: [
{
dataCollectionRuleResourceId: windowsVmDataCollectionRules.outputs.resourceId
dataCollectionRuleResourceId: windowsVmDataCollectionRules!.outputs.resourceId
name: 'send-${logAnalyticsWorkspaceName}'
}
]
Expand Down Expand Up @@ -673,11 +662,9 @@ module aiServices 'modules/ai-foundry/aifoundry.bicep' = {
privateNetworking: null // Private endpoint is handled by the standalone aiFoundryPrivateEndpoint module
existingFoundryProjectResourceId: existingFoundryProjectResourceId
disableLocalAuth: true //Should be set to true for WAF aligned configuration
customSubDomainName: 'aif-${solutionSuffix}'
apiProperties: {
//staticsEnabled: false
}
allowProjectManagement: true
managedIdentities: {
systemAssigned: true
}
Expand Down Expand Up @@ -712,7 +699,7 @@ module aiServices 'modules/ai-foundry/aifoundry.bicep' = {
var aiFoundryAiServicesResourceName = 'aif-${solutionSuffix}'
var useExistingAiFoundryAiProject = !empty(existingFoundryProjectResourceId)

module aiFoundryPrivateEndpoint 'br/public:avm/res/network/private-endpoint:0.8.1' = if (enablePrivateNetworking && !useExistingAiFoundryAiProject) {
module aiFoundryPrivateEndpoint 'br/public:avm/res/network/private-endpoint:0.12.0' = if (enablePrivateNetworking && !useExistingAiFoundryAiProject) {
name: take('pep-${aiFoundryAiServicesResourceName}-deployment', 64)
params: {
name: 'pep-${aiFoundryAiServicesResourceName}'
Expand Down Expand Up @@ -788,7 +775,7 @@ module storageAccount 'modules/storageAccount.bicep' = {
}

// Azure Container Registry for azd container deployments
resource containerRegistry 'Microsoft.ContainerRegistry/registries@2023-07-01' = {
resource containerRegistry 'Microsoft.ContainerRegistry/registries@2025-11-01' = {
name: take('acrreg${solutionSuffix}', 50)
location: location
sku: {
Expand Down Expand Up @@ -863,7 +850,7 @@ module cosmosDb 'modules/cosmosDb.bicep' = {

var containerAppsEnvironmentName = 'cae-${solutionSuffix}'

module containerAppsEnvironment 'br/public:avm/res/app/managed-environment:0.11.3' = {
module containerAppsEnvironment 'br/public:avm/res/app/managed-environment:0.13.1' = {
name: take('avm.res.app.managed-environment.${solutionSuffix}', 64)
#disable-next-line no-unnecessary-dependson
dependsOn: [applicationInsights, logAnalyticsWorkspace, virtualNetwork] // required due to optional flags that could change dependency
Expand All @@ -879,16 +866,17 @@ module containerAppsEnvironment 'br/public:avm/res/app/managed-environment:0.11.
appIdentity.outputs.resourceId
]
}
appInsightsConnectionString: enableMonitoring ? applicationInsights.outputs.connectionString : null
appInsightsConnectionString: enableMonitoring ? applicationInsights!.outputs.connectionString : null
appLogsConfiguration: enableMonitoring
? {
destination: 'log-analytics'
logAnalyticsConfiguration: {
customerId: LogAnalyticsWorkspaceId
sharedKey: LogAnalyticsPrimarySharedKey
customerId: useExistingLogAnalytics ? existingLogAnalyticsWorkspace.properties.customerId : logAnalyticsWorkspace.outputs.logAnalyticsWorkspaceId
sharedKey: useExistingLogAnalytics ? existingLogAnalyticsWorkspace.listKeys().primarySharedKey : logAnalyticsWorkspace.outputs.primarySharedKey
}
logAnalyticsWorkspaceResourceId: logAnalyticsWorkspaceResourceId
}
: {}
: null
workloadProfiles: enablePrivateNetworking
? [
// NOTE: workload profiles are required for private networking
Expand All @@ -903,7 +891,7 @@ module containerAppsEnvironment 'br/public:avm/res/app/managed-environment:0.11.
}
}

module containerAppBackend 'br/public:avm/res/app/container-app:0.19.0' = {
module containerAppBackend 'br/public:avm/res/app/container-app:0.22.0' = {
name: take('avm.res.app.container-app.backend.${solutionSuffix}', 64)
#disable-next-line no-unnecessary-dependson
dependsOn: [applicationInsights] // required due to optional flags that could change dependency
Expand Down Expand Up @@ -1034,11 +1022,11 @@ module containerAppBackend 'br/public:avm/res/app/container-app:0.19.0' = {
? [
{
name: 'APPLICATIONINSIGHTS_INSTRUMENTATION_KEY'
value: applicationInsights.outputs.instrumentationKey
value: applicationInsights!.outputs.instrumentationKey
}
{
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
value: applicationInsights.outputs.connectionString
value: applicationInsights!.outputs.connectionString
}
]
: []
Expand Down Expand Up @@ -1088,7 +1076,7 @@ module containerAppBackend 'br/public:avm/res/app/container-app:0.19.0' = {
}
}

module containerAppFrontend 'br/public:avm/res/app/container-app:0.19.0' = {
module containerAppFrontend 'br/public:avm/res/app/container-app:0.22.0' = {
name: take('avm.res.app.container-app.frontend.${solutionSuffix}', 64)
params: {
name: take('ca-frontend-${solutionSuffix}', 32)
Expand Down Expand Up @@ -1155,7 +1143,7 @@ output resourceGroupName string = resourceGroup().name
output WEB_APP_URL string = 'https://${containerAppFrontend.outputs.fqdn}'
output COSMOSDB_ENDPOINT string = cosmosDb.outputs.endpoint
output AZURE_BLOB_ACCOUNT_NAME string = storageAccount.outputs.name
output AZURE_BLOB_ENDPOINT string = 'https://${storageAccount.outputs.name}.blob.core.windows.net/'
output AZURE_BLOB_ENDPOINT string = 'https://${storageAccount.outputs.name}.blob.${environment().suffixes.storage}/'
output AZURE_CONTAINER_REGISTRY_ENDPOINT string = containerRegistry.properties.loginServer
output AZURE_AI_AGENT_PROJECT_NAME string = aiServices.outputs.aiProjectInfo.name
output AZURE_AI_AGENT_ENDPOINT string = aiServices.outputs.aiProjectInfo.apiEndpoint
Expand All @@ -1169,7 +1157,7 @@ output COSMOSDB_DATABASE string = cosmosDb.outputs.databaseName
output COSMOSDB_BATCH_CONTAINER string = cosmosDb.outputs.containerNames.batch
output COSMOSDB_FILE_CONTAINER string = cosmosDb.outputs.containerNames.file
output COSMOSDB_LOG_CONTAINER string = cosmosDb.outputs.containerNames.log
output APPLICATIONINSIGHTS_CONNECTION_STRING string = enableMonitoring ? applicationInsights.outputs.connectionString : ''
output APPLICATIONINSIGHTS_CONNECTION_STRING string = enableMonitoring ? applicationInsights!.outputs.connectionString : ''
output MIGRATOR_AGENT_MODEL_DEPLOY string = modelDeployment.name
output PICKER_AGENT_MODEL_DEPLOY string = modelDeployment.name
output FIXER_AGENT_MODEL_DEPLOY string = modelDeployment.name
Expand Down
16 changes: 8 additions & 8 deletions infra/modules/ai-foundry/ai-services.bicep
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// This module is here solely to provide network injection for Cognitive Services.
// The AVM Module 'br/public:avm/res/cognitive-services/account:0.11.0' does not support that feature as of version 0.11.0
// The AVM Module 'br/public:avm/res/cognitive-services/account:0.14.2' does not support that feature as of version 0.14.2
metadata name = 'Cognitive Services'
metadata description = 'This module deploys a Cognitive Service.'

Expand Down Expand Up @@ -60,7 +60,7 @@ param sku string = 'S0'
@description('Optional. Location for all Resources.')
param location string = resourceGroup().location

import { diagnosticSettingFullType } from 'br/public:avm/utl/types/avm-common-types:0.5.1'
import { diagnosticSettingFullType } from 'br/public:avm/utl/types/avm-common-types:0.7.0'
@description('Optional. The diagnostic settings of the service.')
param diagnosticSettings diagnosticSettingFullType[]?

Expand All @@ -80,11 +80,11 @@ param networkAcls object?
@description('Optional. The network injection subnet resource Id for the Cognitive Services account. This allows to use the AI Services account with a virtual network.')
param networkInjectionSubnetResourceId string?

import { privateEndpointSingleServiceType } from 'br/public:avm/utl/types/avm-common-types:0.5.1'
import { privateEndpointSingleServiceType } from 'br/public:avm/utl/types/avm-common-types:0.7.0'
@description('Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible.')
param privateEndpoints privateEndpointSingleServiceType[]?

import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.5.1'
import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.7.0'
@description('Optional. Array of role assignments to create.')
param roleAssignments roleAssignmentType[]?

Expand Down Expand Up @@ -116,7 +116,7 @@ param restrictOutboundNetworkAccess bool = true
@description('Optional. The storage accounts for this resource.')
param userOwnedStorage array?

import { managedIdentityAllType } from 'br/public:avm/utl/types/avm-common-types:0.5.1'
import { managedIdentityAllType } from 'br/public:avm/utl/types/avm-common-types:0.7.0'
@description('Optional. The managed identity definition for this resource.')
param managedIdentities managedIdentityAllType?

Expand Down Expand Up @@ -260,7 +260,7 @@ var formattedRoleAssignments = [
})
]

resource cognitiveService 'Microsoft.CognitiveServices/accounts@2025-07-01-preview' = {
resource cognitiveService 'Microsoft.CognitiveServices/accounts@2026-03-01' = {
name: name
kind: kind
identity: identity
Expand Down Expand Up @@ -306,7 +306,7 @@ resource cognitiveService 'Microsoft.CognitiveServices/accounts@2025-07-01-previ
}

@batchSize(1)
resource cognitiveService_deployments 'Microsoft.CognitiveServices/accounts/deployments@2024-10-01' = [
resource cognitiveService_deployments 'Microsoft.CognitiveServices/accounts/deployments@2026-03-01' = [
for (deployment, index) in (deployments ?? []): {
parent: cognitiveService
name: deployment.?name ?? '${name}-deployments'
Expand Down Expand Up @@ -355,7 +355,7 @@ resource cognitiveService_diagnosticSettings 'Microsoft.Insights/diagnosticSetti
}
]

module cognitiveService_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.11.1' = [
module cognitiveService_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.12.0' = [
for (privateEndpoint, index) in (privateEndpoints ?? []): {
name: take('${uniqueString(deployment().name, location)}-cognitiveService-PrivateEndpoint-${index}', 64)
scope: resourceGroup(
Expand Down
Loading
Loading