@@ -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
@@ -736,7 +697,9 @@ module privateDnsZonesAiServices 'br/public:avm/res/network/private-dns-zone:0.7
736697]
737698
738699// NOTE: Required version 'Microsoft.CognitiveServices/accounts@2024-04-01-preview' not available in AVM
739- var aiFoundryAiServicesResourceName = aiFoundryAiServicesConfiguration .?name ?? 'aisa-${solutionPrefix }'
700+ var useExistingFoundryProject = !empty (existingFoundryProjectResourceId )
701+ var existingAiFoundryName = useExistingFoundryProject ?split ( existingFoundryProjectResourceId ,'/' )[8 ]:''
702+ var aiFoundryAiServicesResourceName = useExistingFoundryProject ? existingAiFoundryName : aiFoundryAiServicesConfiguration .?name ?? 'aisa-${solutionPrefix }'
740703var aiFoundryAIservicesEnabled = aiFoundryAiServicesConfiguration .?enabled ?? true
741704var aiFoundryAiServicesModelDeployment = {
742705 format : 'OpenAI'
@@ -750,17 +713,20 @@ var aiFoundryAiServicesModelDeployment = {
750713 raiPolicyName : 'Microsoft.Default'
751714}
752715
753- module aiFoundryAiServices 'br/public:avm/res/cognitive-services/ account:0.11.0 ' = if (aiFoundryAIservicesEnabled ) {
716+ module aiFoundryAiServices 'modules/ account/main.bicep ' = if (aiFoundryAIservicesEnabled ) {
754717 name : take ('avm.res.cognitive-services.account.${aiFoundryAiServicesResourceName }' , 64 )
755718 params : {
756719 name : aiFoundryAiServicesResourceName
757720 tags : aiFoundryAiServicesConfiguration .?tags ?? tags
758721 location : aiFoundryAiServicesConfiguration .?location ?? aiDeploymentsLocation
759722 enableTelemetry : enableTelemetry
723+ projectName : 'aifp-${solutionPrefix }'
724+ projectDescription : 'aifp-${solutionPrefix }'
725+ existingFoundryProjectResourceId : existingFoundryProjectResourceId
760726 diagnosticSettings : [{ workspaceResourceId : logAnalyticsWorkspaceId }]
761727 sku : aiFoundryAiServicesConfiguration .?sku ?? 'S0'
762728 kind : 'AIServices'
763- disableLocalAuth : false //Should be set to true for WAF aligned configuration
729+ disableLocalAuth : true //Should be set to true for WAF aligned configuration
764730 customSubDomainName : aiFoundryAiServicesResourceName
765731 apiProperties : {
766732 //staticsEnabled: false
@@ -769,10 +735,12 @@ module aiFoundryAiServices 'br/public:avm/res/cognitive-services/account:0.11.0'
769735 managedIdentities : {
770736 systemAssigned : true
771737 }
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
775- privateEndpoints : virtualNetworkEnabled
738+ publicNetworkAccess : virtualNetworkEnabled ? 'Disabled' : 'Enabled'
739+ networkAcls : {
740+ bypass : 'AzureServices'
741+ defaultAction : (virtualNetworkEnabled ) ? 'Deny' : 'Allow'
742+ }
743+ privateEndpoints : virtualNetworkEnabled && !useExistingFoundryProject
776744 ? ([
777745 {
778746 name : 'pep-${aiFoundryAiServicesResourceName }'
@@ -786,19 +754,7 @@ module aiFoundryAiServices 'br/public:avm/res/cognitive-services/account:0.11.0'
786754 }
787755 }
788756 ])
789- : []
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- // ]
757+ : []
802758 deployments : aiFoundryAiServicesConfiguration .?deployments ?? [
803759 {
804760 name : aiFoundryAiServicesModelDeployment .name
@@ -819,76 +775,27 @@ 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
823- var 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- }
778+ var existingAiFounryProjectName = useExistingFoundryProject ? last (split ( existingFoundryProjectResourceId ,'/' )) : ''
779+ var aiFoundryAiProjectName = useExistingFoundryProject ? existingAiFounryProjectName : aiFoundryAiProjectConfiguration .?name ?? 'aifp-${solutionPrefix }'
832780
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- }
845-
846- resource aiUser 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = {
847- name : '53ca6127-db72-4b80-b1b0-d745d6d5456d'
848- }
781+ var useExistingResourceId = !empty (existingFoundryProjectResourceId )
849782
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- }
858-
859- resource aiUserAccessFoundry 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
860- name : guid (containerApp .name , aiServices .id , aiUser .id )
861- scope : aiServices
862- properties : {
863- roleDefinitionId : aiUser .id
864- principalId : containerApp .outputs .?systemAssignedMIPrincipalId !
865- }
866- }
867-
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
783+ module cogServiceRoleAssignmentsNew './modules/role.bicep' = if (!useExistingResourceId ) {
784+ params : {
785+ name : 'new-${guid (containerApp .name , aiFoundryAiServices .outputs .resourceId )}'
877786 principalId : containerApp .outputs .?systemAssignedMIPrincipalId !
787+ aiServiceName : aiFoundryAiServices .outputs .name
878788 }
789+ scope : resourceGroup (subscription ().subscriptionId , resourceGroup ().name )
879790}
880791
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
792+ module cogServiceRoleAssignmentsExisting './modules/role.bicep' = if (useExistingResourceId ) {
793+ params : {
794+ name : 'reuse-${guid (containerApp .name , aiFoundryAiServices .outputs .aiProjectInfo .resourceId )}'
890795 principalId : containerApp .outputs .?systemAssignedMIPrincipalId !
796+ aiServiceName : aiFoundryAiServices .outputs .name
891797 }
798+ scope : resourceGroup ( split (existingFoundryProjectResourceId , '/' )[2 ], split (existingFoundryProjectResourceId , '/' )[4 ])
892799}
893800
894801// ========== Cosmos DB ========== //
@@ -966,7 +873,6 @@ module cosmosDb 'br/public:avm/res/document-db/database-account:0.12.0' = if (co
966873 'EnableServerless'
967874 ]
968875 sqlRoleAssignmentsPrincipalIds : [
969- //userAssignedIdentity.outputs.principalId
970876 containerApp .outputs .?systemAssignedMIPrincipalId
971877 ]
972878 sqlRoleDefinitions : [
@@ -1003,13 +909,6 @@ module containerAppEnvironment 'modules/container-app-environment.bicep' = if (c
1003909 subnetResourceId : virtualNetworkEnabled
1004910 ? containerAppEnvironmentConfiguration .?subnetResourceId ?? virtualNetwork .?outputs .?subnetResourceIds [3 ] ?? ''
1005911 : ''
1006- //aspireDashboardEnabled: !virtualNetworkEnabled
1007- // vnetConfiguration: virtualNetworkEnabled
1008- // ? {
1009- // internal: false
1010- // infrastructureSubnetId: containerAppEnvironmentConfiguration.?subnetResourceId ?? virtualNetwork.?outputs.?subnetResourceIds[3] ?? ''
1011- // }
1012- // : {}
1013912 }
1014913}
1015914
@@ -1117,7 +1016,7 @@ module containerApp 'br/public:avm/res/app/container-app:0.14.2' = if (container
11171016 }
11181017 {
11191018 name : 'AZURE_AI_AGENT_ENDPOINT'
1120- value : aiFoundryProject . properties . endpoints [ 'AI Foundry API' ]
1019+ value : aiFoundryAiServices . outputs . aiProjectInfo . apiEndpoint
11211020 }
11221021 {
11231022 name : 'AZURE_AI_AGENT_MODEL_DEPLOYMENT_NAME'
@@ -1189,19 +1088,6 @@ module webSite 'br/public:avm/res/web/site:0.15.1' = if (webSiteEnabled) {
11891088@description ('The default url of the website to connect to the Multi-Agent Custom Automation Engine solution.' )
11901089output webSiteDefaultHostname string = webSite .outputs .defaultHostname
11911090
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-
12051091@export ()
12061092@description ('The type for the Multi-Agent Custom Automation Engine Log Analytics Workspace resource configuration.' )
12071093type logAnalyticsWorkspaceConfigurationType = {
0 commit comments