@@ -4,6 +4,9 @@ metadata description = 'This module contains the resources required to deploy th
44@description ('Set to true if you want to deploy WAF-aligned infrastructure.' )
55param useWafAlignedArchitecture bool
66
7+ @description ('Use this parameter to use an existing AI project resource ID' )
8+ param existingFoundryProjectResourceId string = ''
9+
710@description ('Optional. The prefix to add in the default names given to all deployed Azure resources.' )
811@maxLength (19 )
912param solutionPrefix string = 'macae${uniqueString (deployer ().objectId , deployer ().tenantId , subscription ().subscriptionId , resourceGroup ().id )}'
@@ -45,10 +48,6 @@ param gptModelCapacity int = 150
4548@description ('Set the image tag for the container images used in the solution. Default is "latest".' )
4649param imageTag string = 'latest'
4750
48- // @description('Set this if you want to deploy to a different region than the resource group. Otherwise, it will use the resource group location by default.')
49- // param AZURE_LOCATION string=''
50- // param solutionLocation string = empty(AZURE_LOCATION) ? resourceGroup().location
51-
5251@description ('Optional. The tags to apply to all deployed Azure resources.' )
5352param tags object = {
5453 app : solutionPrefix
@@ -233,32 +232,6 @@ param webSiteConfiguration webSiteConfigurationType = {
233232 environmentResourceId : null //Default value set on module configuration
234233}
235234
236- //
237- // Add your parameters here
238- //
239-
240- // ============== //
241- // Resources //
242- // ============== //
243-
244- /* #disable-next-line no-deployments-resources
245- resource avmTelemetry 'Microsoft.Resources/deployments@2024-03-01' = if (enableTelemetry) {
246- name: '46d3xbcp.[[REPLACE WITH TELEMETRY IDENTIFIER]].${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}'
247- properties: {
248- mode: 'Incremental'
249- template: {
250- '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#'
251- contentVersion: '1.0.0.0'
252- resources: []
253- outputs: {
254- telemetry: {
255- type: 'String'
256- value: 'For more information, see https://aka.ms/avm/TelemetryInfo'
257- }
258- }
259- }
260- }
261- } */
262235
263236// ========== Log Analytics Workspace ========== //
264237// WAF best practices for Log Analytics: https://learn.microsoft.com/en-us/azure/well-architected/service-guides/azure-log-analytics
@@ -595,8 +568,6 @@ module virtualNetwork 'br/public:avm/res/network/virtual-network:0.6.1' = if (vi
595568 name : 'administration'
596569 addressPrefix : '10.0.0.32/27'
597570 networkSecurityGroupResourceId : networkSecurityGroupAdministration .outputs .resourceId
598- //defaultOutboundAccess: false TODO: check this configuration for a more restricted outbound access
599- //natGatewayResourceId: natGateway.outputs.resourceId
600571 }
601572 {
602573 // For Azure Bastion resources deployed on or after November 2, 2021, the minimum AzureBastionSubnet size is /26 or larger (/25, /24, etc.).
@@ -610,7 +581,6 @@ module virtualNetwork 'br/public:avm/res/network/virtual-network:0.6.1' = if (vi
610581 // https://learn.microsoft.com/en-us/azure/container-apps/networking?tabs=workload-profiles-env%2Cazure-cli#custom-vnw-configuration
611582 name : 'containers'
612583 addressPrefix : '10.0.2.0/23' //subnet of size /23 is required for container app
613- //defaultOutboundAccess: false TODO: check this configuration for a more restricted outbound access
614584 delegation : 'Microsoft.App/environments'
615585 networkSecurityGroupResourceId : networkSecurityGroupContainers .outputs .resourceId
616586 privateEndpointNetworkPolicies : 'Disabled'
@@ -640,9 +610,7 @@ module bastionHost 'br/public:avm/res/network/bastion-host:0.6.1' = if (virtualN
640610 disableCopyPaste : false
641611 enableFileCopy : false
642612 enableIpConnect : true
643- //enableKerberos: bastionConfiguration.?enableKerberos
644613 enableShareableLink : true
645- //scaleUnits: bastionConfiguration.?scaleUnits
646614 }
647615}
648616
@@ -664,8 +632,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:0.13.0' = if (v
664632 nicConfigurations : [
665633 {
666634 name : 'nic-${virtualMachineResourceName }'
667- //networkSecurityGroupResourceId: virtualMachineConfiguration.?nicConfigurationConfiguration.networkSecurityGroupResourceId
668- //nicSuffix: 'nic-${virtualMachineResourceName}'
669635 diagnosticSettings : [{ workspaceResourceId : logAnalyticsWorkspaceId }]
670636 ipConfigurations : [
671637 {
@@ -691,18 +657,13 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:0.13.0' = if (v
691657 diskSizeGB : 128
692658 caching : 'ReadWrite'
693659 }
694- //patchMode: virtualMachineConfiguration.?patchMode
695660 osType : 'Windows'
696661 encryptionAtHost : false //The property 'securityProfile.encryptionAtHost' is not valid because the 'Microsoft.Compute/EncryptionAtHost' feature is not enabled for this subscription.
697662 zone : 0
698663 extensionAadJoinConfig : {
699664 enabled : true
700665 typeHandlerVersion : '1.0'
701666 }
702- // extensionMonitoringAgentConfig: {
703- // enabled: true
704- // }
705- // maintenanceConfigurationResourceId: virtualMachineConfiguration.?maintenanceConfigurationResourceId
706667 }
707668}
708669
@@ -750,17 +711,20 @@ var aiFoundryAiServicesModelDeployment = {
750711 raiPolicyName : 'Microsoft.Default'
751712}
752713
753- module aiFoundryAiServices 'br/public:avm/res/cognitive-services/ account:0.11.0 ' = if (aiFoundryAIservicesEnabled ) {
714+ module aiFoundryAiServices 'modules/ account/main.bicep ' = if (aiFoundryAIservicesEnabled ) {
754715 name : take ('avm.res.cognitive-services.account.${aiFoundryAiServicesResourceName }' , 64 )
755716 params : {
756717 name : aiFoundryAiServicesResourceName
757718 tags : aiFoundryAiServicesConfiguration .?tags ?? tags
758719 location : aiFoundryAiServicesConfiguration .?location ?? aiDeploymentsLocation
759720 enableTelemetry : enableTelemetry
721+ projectName : 'aifp-${solutionPrefix }'
722+ projectDescription : 'aifp-${solutionPrefix }'
723+ existingFoundryProjectResourceId : existingFoundryProjectResourceId
760724 diagnosticSettings : [{ workspaceResourceId : logAnalyticsWorkspaceId }]
761725 sku : aiFoundryAiServicesConfiguration .?sku ?? 'S0'
762726 kind : 'AIServices'
763- disableLocalAuth : false //Should be set to true for WAF aligned configuration
727+ disableLocalAuth : true //Should be set to true for WAF aligned configuration
764728 customSubDomainName : aiFoundryAiServicesResourceName
765729 apiProperties : {
766730 //staticsEnabled: false
@@ -769,9 +733,13 @@ module aiFoundryAiServices 'br/public:avm/res/cognitive-services/account:0.11.0'
769733 managedIdentities : {
770734 systemAssigned : true
771735 }
772- //publicNetworkAccess: virtualNetworkEnabled ? 'Disabled' : 'Enabled'
773- //publicNetworkAccess: virtualNetworkEnabled ? 'Disabled' : 'Enabled'
774- publicNetworkAccess : 'Enabled' //TODO: connection via private endpoint is not working from containers network. Change this when fixed
736+ publicNetworkAccess : virtualNetworkEnabled ? 'Disabled' : 'Enabled'
737+ networkAcls : {
738+ bypass : 'AzureServices'
739+ defaultAction : (virtualNetworkEnabled ) ? 'Deny' : 'Allow'
740+ }
741+
742+
775743 privateEndpoints : virtualNetworkEnabled
776744 ? ([
777745 {
@@ -787,18 +755,6 @@ module aiFoundryAiServices 'br/public:avm/res/cognitive-services/account:0.11.0'
787755 }
788756 ])
789757 : []
790- // roleAssignments: [
791- // // {
792- // // principalId: userAssignedIdentity.outputs.principalId
793- // // principalType: 'ServicePrincipal'
794- // // roleDefinitionIdOrName: 'Cognitive Services OpenAI User'
795- // // }
796- // {
797- // principalId: containerApp.outputs.?systemAssignedMIPrincipalId!
798- // principalType: 'ServicePrincipal'
799- // roleDefinitionIdOrName: 'Cognitive Services OpenAI User'
800- // }
801- // ]
802758 deployments : aiFoundryAiServicesConfiguration .?deployments ?? [
803759 {
804760 name : aiFoundryAiServicesModelDeployment .name
@@ -819,76 +775,34 @@ module aiFoundryAiServices 'br/public:avm/res/cognitive-services/account:0.11.0'
819775
820776// AI Foundry: AI Project
821777// WAF best practices for Open AI: https://learn.microsoft.com/en-us/azure/well-architected/service-guides/azure-openai
822- // var aiFoundryAiProjectEnabled = aiFoundryAiProjectConfiguration.?enabled ?? true
823778var aiFoundryAiProjectName = aiFoundryAiProjectConfiguration .?name ?? 'aifp-${solutionPrefix }'
824- var aiProjectDescription = 'AI Foundry Project'
825-
826- resource aiServices 'Microsoft.CognitiveServices/accounts@2025-04-01-preview' existing = {
827- name : aiFoundryAiServicesResourceName
828- dependsOn :[
829- aiFoundryAiServices
830- ]
831- }
832-
833- resource aiFoundryProject 'Microsoft.CognitiveServices/accounts/projects@2025-04-01-preview' = {
834- parent : aiServices
835- name : aiFoundryAiProjectName
836- location : aiFoundryAiProjectConfiguration .?location ?? aiDeploymentsLocation
837- identity : {
838- type : 'SystemAssigned'
839- }
840- properties : {
841- description : aiProjectDescription
842- displayName : aiFoundryAiProjectName
843- }
844- }
845779
846780resource aiUser 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = {
847781 name : '53ca6127-db72-4b80-b1b0-d745d6d5456d'
848782}
849783
850- resource aiUserAccessProj 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
851- name : guid (containerApp .name , aiFoundryProject .id , aiUser .id )
852- scope : aiFoundryProject
853- properties : {
854- roleDefinitionId : aiUser .id
855- principalId : containerApp .outputs .?systemAssignedMIPrincipalId !
856- }
857- }
784+ var useExistingResourceId = !empty (existingFoundryProjectResourceId )
858785
859- resource aiUserAccessFoundry 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
860- name : guid (containerApp .name , aiServices .id , aiUser .id )
861- scope : aiServices
862- properties : {
786+ module Newroles './modules/role.bicep' = if (!useExistingResourceId ){
787+ params : {
788+ name : 'new-${guid (containerApp .name , aiFoundryAiServices .outputs .resourceId , aiUser .id )}'
863789 roleDefinitionId : aiUser .id
864790 principalId : containerApp .outputs .?systemAssignedMIPrincipalId !
791+ aiUserid : aiUser .id
792+ aiServiceName : aiFoundryAiServices .outputs .name
865793 }
794+ scope : resourceGroup (subscription ().subscriptionId , resourceGroup ().name )
866795}
867796
868- resource aiDeveloper 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = {
869- name : '64702f94-c441-49e6-a78b-ef80e0188fee'
870- }
871-
872- resource aiDeveloperAccessFoundry 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
873- name : guid (containerApp .name , aiServices .id , aiDeveloper .id )
874- scope : aiFoundryProject
875- properties : {
876- roleDefinitionId : aiDeveloper .id
877- principalId : containerApp .outputs .?systemAssignedMIPrincipalId !
878- }
879- }
880-
881- resource cognitiveServiceOpenAIUser 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = {
882- name : '5e0bd9bd-7b93-4f28-af87-19fc36ad61bd'
883- }
884-
885- resource cognitiveServiceOpenAIUserAccessFoundry 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
886- name : guid (containerApp .name , aiServices .id , cognitiveServiceOpenAIUser .id )
887- scope : aiServices
888- properties : {
889- roleDefinitionId : cognitiveServiceOpenAIUser .id
797+ module Existingroles './modules/role.bicep' = if (useExistingResourceId ){
798+ params : {
799+ name : 'reuse-${guid (containerApp .name , aiFoundryAiServices .outputs .aiProjectInfo .resourceId , aiUser .id )}'
800+ roleDefinitionId : aiUser .id
890801 principalId : containerApp .outputs .?systemAssignedMIPrincipalId !
802+ aiUserid : aiUser .id
803+ aiServiceName : aiFoundryAiServices .outputs .name
891804 }
805+ scope : resourceGroup ( split (existingFoundryProjectResourceId , '/' )[2 ], split (existingFoundryProjectResourceId , '/' )[4 ])
892806}
893807
894808// ========== Cosmos DB ========== //
@@ -966,7 +880,6 @@ module cosmosDb 'br/public:avm/res/document-db/database-account:0.12.0' = if (co
966880 'EnableServerless'
967881 ]
968882 sqlRoleAssignmentsPrincipalIds : [
969- //userAssignedIdentity.outputs.principalId
970883 containerApp .outputs .?systemAssignedMIPrincipalId
971884 ]
972885 sqlRoleDefinitions : [
@@ -1003,13 +916,6 @@ module containerAppEnvironment 'modules/container-app-environment.bicep' = if (c
1003916 subnetResourceId : virtualNetworkEnabled
1004917 ? containerAppEnvironmentConfiguration .?subnetResourceId ?? virtualNetwork .?outputs .?subnetResourceIds [3 ] ?? ''
1005918 : ''
1006- //aspireDashboardEnabled: !virtualNetworkEnabled
1007- // vnetConfiguration: virtualNetworkEnabled
1008- // ? {
1009- // internal: false
1010- // infrastructureSubnetId: containerAppEnvironmentConfiguration.?subnetResourceId ?? virtualNetwork.?outputs.?subnetResourceIds[3] ?? ''
1011- // }
1012- // : {}
1013919 }
1014920}
1015921
@@ -1117,7 +1023,7 @@ module containerApp 'br/public:avm/res/app/container-app:0.14.2' = if (container
11171023 }
11181024 {
11191025 name : 'AZURE_AI_AGENT_ENDPOINT'
1120- value : aiFoundryProject . properties . endpoints [ 'AI Foundry API' ]
1026+ value : aiFoundryAiServices . outputs . aiProjectInfo . apiEndpoint
11211027 }
11221028 {
11231029 name : 'AZURE_AI_AGENT_MODEL_DEPLOYMENT_NAME'
@@ -1189,19 +1095,6 @@ module webSite 'br/public:avm/res/web/site:0.15.1' = if (webSiteEnabled) {
11891095@description ('The default url of the website to connect to the Multi-Agent Custom Automation Engine solution.' )
11901096output webSiteDefaultHostname string = webSite .outputs .defaultHostname
11911097
1192- // @description('The name of the resource.')
1193- // output name string = <Resource>.name
1194-
1195- // @description('The location the resource was deployed into.')
1196- // output location string = <Resource>.location
1197-
1198- // ================ //
1199- // Definitions //
1200- // ================ //
1201- //
1202- // Add your User-defined-types here, if any
1203- //
1204-
12051098@export ()
12061099@description ('The type for the Multi-Agent Custom Automation Engine Log Analytics Workspace resource configuration.' )
12071100type logAnalyticsWorkspaceConfigurationType = {
0 commit comments