Skip to content
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
16cbd9a
Bug Fixes #19515,#19278,#19330
Ravikirana-Microsoft Jul 2, 2025
b028c6e
commented code removed
Ravikirana-Microsoft Jul 2, 2025
a76c584
Merge remote-tracking branch 'origin/dev' into Bugs-fixing
Ravikirana-Microsoft Jul 2, 2025
c1c41ba
Merge pull request #296 from microsoft/Bugs-fixing
Roopan-Microsoft Jul 2, 2025
2c8f72f
DateFormat_backend
UtkarshMishra-Microsoft Jul 3, 2025
48c1809
Update utils_date.py
UtkarshMishra-Microsoft Jul 3, 2025
e827d52
Bugs fixes of 19597,19553,19524,19330,19278,19238
Ravikirana-Microsoft Jul 4, 2025
f555a83
Merge remote-tracking branch 'origin/dev' into Bugs-fixing
Ravikirana-Microsoft Jul 4, 2025
e3e229c
copilot comments resolved
Ravikirana-Microsoft Jul 4, 2025
ef5665d
missed file added
Ravikirana-Microsoft Jul 4, 2025
4089d85
crpto reverted
Ravikirana-Microsoft Jul 4, 2025
5dff284
Merge pull request #299 from microsoft/Bugs-fixing
Roopan-Microsoft Jul 4, 2025
095ee5b
Merge pull request #297 from microsoft/DateFormat-Bug
Roopan-Microsoft Jul 4, 2025
fb4827e
Reuse Ai Foundry for MACAE
NirajC-Microsoft Jul 4, 2025
39597cf
added missing parameter
VishalS-Microsoft Jul 4, 2025
d8a6806
Add AZURE_ENV_FOUNDRY_PROJECT_ID in CustomizingAzdParameters.md file
NirajC-Microsoft Jul 4, 2025
268e63d
Merge pull request #300 from microsoft/psl-reuse-aif
Roopan-Microsoft Jul 4, 2025
1ff08b3
Merge pull request #301 from microsoft/psl-missingparameter-macae
Roopan-Microsoft Jul 4, 2025
ff5b366
test: MACAE - updated script per new UX/UI
Ritesh-Microsoft Jul 8, 2025
560a356
test: MACAE - updated script per new UX/UI
Avijit-Microsoft Jul 8, 2025
6fe8692
Added condition for Azure openAI and Azure Ai Project name selection …
NirajC-Microsoft Jul 8, 2025
72f412e
remove type from existingAiFounryName
NirajC-Microsoft Jul 8, 2025
7a68739
Bug fix # 20359
Ravikirana-Microsoft Jul 8, 2025
503b983
Merge pull request #305 from microsoft/macae-bug-fixes-2.0
Roopan-Microsoft Jul 8, 2025
b566ffa
Private Connection should get used only for deployment which is creat…
NirajC-Microsoft Jul 8, 2025
2c63e5b
refactor: Code clean up for roleassignments
Prajwal-Microsoft Jul 9, 2025
678d77e
Merge pull request #304 from microsoft/psl-bug-20357
Prajwal-Microsoft Jul 9, 2025
da4380a
Bug fix of #20088
Ravikirana-Microsoft Jul 9, 2025
38f05fc
Merge branch 'macae-bug-fixes-2.0' of https://github.com/microsoft/Mu…
Ravikirana-Microsoft Jul 9, 2025
8b8c39b
Merge pull request #308 from microsoft/macae-bug-fixes-2.0
Roopan-Microsoft Jul 9, 2025
26dab82
added required azd version in azure.yml file and updated DeploymentGu…
NirajC-Microsoft Jul 10, 2025
c0051cc
Tooltip Issue fix
Ravikirana-Microsoft Jul 10, 2025
bb4e212
Merge branch 'main' into dev
Roopan-Microsoft Jul 10, 2025
13feee6
Merge pull request #312 from microsoft/macae-bug-fixes-2.0
Roopan-Microsoft Jul 10, 2025
2dbe915
Merge pull request #311 from microsoft/psl-macae-azdversion
Roopan-Microsoft Jul 10, 2025
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
2 changes: 2 additions & 0 deletions docs/CustomizingAzdParameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ By default this template will use the environment name as the prefix to prevent
| `AZURE_ENV_OPENAI_LOCATION` | string | `swedencentral` | Specifies the region for OpenAI resource deployment. |
| `AZURE_ENV_MODEL_DEPLOYMENT_TYPE` | string | `GlobalStandard` | Defines the deployment type for the AI model (e.g., Standard, GlobalStandard). |
| `AZURE_ENV_MODEL_NAME` | string | `gpt-4o` | Specifies the name of the GPT model to be deployed. |
| `AZURE_ENV_FOUNDRY_PROJECT_ID` | string | `<Existing Workspace Id>` | Set this if you want to reuse an AI Foundry Project instead of creating a new one. |
| `AZURE_ENV_MODEL_VERSION` | string | `2024-08-06` | Version of the GPT model to be used for deployment. |
| `AZURE_ENV_MODEL_CAPACITY` | int | `150` | Sets the GPT model capacity. |
| `AZURE_ENV_IMAGETAG` | string | `latest` | Docker image tag used for container deployments. |
| `AZURE_ENV_ENABLE_TELEMETRY` | bool | `true` | Enables telemetry for monitoring and diagnostics. |
| `AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID` | string | `<Existing Workspace Id>` | Set this if you want to reuse an existing Log Analytics Workspace instead of creating a new one. |
Expand Down
1 change: 1 addition & 0 deletions docs/DeploymentGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ When you start the deployment, most parameters will have **default values**, but
| **Model Deployment Type** | Defines the deployment type for the AI model (e.g., Standard, GlobalStandard). | GlobalStandard |
| **GPT Model Name** | Specifies the name of the GPT model to be deployed. | gpt-4o |
| **GPT Model Version** | Version of the GPT model to be used for deployment. | 2024-08-06 |
| **GPT Model Capacity** | Sets the GPT model capacity. | 150 |
| **Image Tag** | Docker image tag used for container deployments. | latest |
| **Enable Telemetry** | Enables telemetry for monitoring and diagnostics. | true |

Expand Down
178 changes: 32 additions & 146 deletions infra/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ metadata description = 'This module contains the resources required to deploy th
@description('Set to true if you want to deploy WAF-aligned infrastructure.')
param useWafAlignedArchitecture bool

@description('Use this parameter to use an existing AI project resource ID')
param existingFoundryProjectResourceId string = ''

@description('Optional. The prefix to add in the default names given to all deployed Azure resources.')
@maxLength(19)
param solutionPrefix string = 'macae${uniqueString(deployer().objectId, deployer().tenantId, subscription().subscriptionId, resourceGroup().id)}'
Expand Down Expand Up @@ -45,10 +48,6 @@ param gptModelCapacity int = 150
@description('Set the image tag for the container images used in the solution. Default is "latest".')
param imageTag string = 'latest'

// @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.')
// param AZURE_LOCATION string=''
// param solutionLocation string = empty(AZURE_LOCATION) ? resourceGroup().location

@description('Optional. The tags to apply to all deployed Azure resources.')
param tags object = {
app: solutionPrefix
Expand Down Expand Up @@ -233,32 +232,6 @@ param webSiteConfiguration webSiteConfigurationType = {
environmentResourceId: null //Default value set on module configuration
}

//
// Add your parameters here
//

// ============== //
// Resources //
// ============== //

/* #disable-next-line no-deployments-resources
resource avmTelemetry 'Microsoft.Resources/deployments@2024-03-01' = if (enableTelemetry) {
name: '46d3xbcp.[[REPLACE WITH TELEMETRY IDENTIFIER]].${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}'
properties: {
mode: 'Incremental'
template: {
'$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#'
contentVersion: '1.0.0.0'
resources: []
outputs: {
telemetry: {
type: 'String'
value: 'For more information, see https://aka.ms/avm/TelemetryInfo'
}
}
}
}
} */

// ========== Log Analytics Workspace ========== //
// WAF best practices for Log Analytics: https://learn.microsoft.com/en-us/azure/well-architected/service-guides/azure-log-analytics
Expand Down Expand Up @@ -595,8 +568,6 @@ module virtualNetwork 'br/public:avm/res/network/virtual-network:0.6.1' = if (vi
name: 'administration'
addressPrefix: '10.0.0.32/27'
networkSecurityGroupResourceId: networkSecurityGroupAdministration.outputs.resourceId
//defaultOutboundAccess: false TODO: check this configuration for a more restricted outbound access
//natGatewayResourceId: natGateway.outputs.resourceId
}
{
// For Azure Bastion resources deployed on or after November 2, 2021, the minimum AzureBastionSubnet size is /26 or larger (/25, /24, etc.).
Expand All @@ -610,7 +581,6 @@ module virtualNetwork 'br/public:avm/res/network/virtual-network:0.6.1' = if (vi
// https://learn.microsoft.com/en-us/azure/container-apps/networking?tabs=workload-profiles-env%2Cazure-cli#custom-vnw-configuration
name: 'containers'
addressPrefix: '10.0.2.0/23' //subnet of size /23 is required for container app
//defaultOutboundAccess: false TODO: check this configuration for a more restricted outbound access
delegation: 'Microsoft.App/environments'
networkSecurityGroupResourceId: networkSecurityGroupContainers.outputs.resourceId
privateEndpointNetworkPolicies: 'Disabled'
Expand Down Expand Up @@ -640,9 +610,7 @@ module bastionHost 'br/public:avm/res/network/bastion-host:0.6.1' = if (virtualN
disableCopyPaste: false
enableFileCopy: false
enableIpConnect: true
//enableKerberos: bastionConfiguration.?enableKerberos
enableShareableLink: true
//scaleUnits: bastionConfiguration.?scaleUnits
}
}

Expand All @@ -664,8 +632,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:0.13.0' = if (v
nicConfigurations: [
{
name: 'nic-${virtualMachineResourceName}'
//networkSecurityGroupResourceId: virtualMachineConfiguration.?nicConfigurationConfiguration.networkSecurityGroupResourceId
//nicSuffix: 'nic-${virtualMachineResourceName}'
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspaceId }]
ipConfigurations: [
{
Expand All @@ -691,18 +657,13 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:0.13.0' = if (v
diskSizeGB: 128
caching: 'ReadWrite'
}
//patchMode: virtualMachineConfiguration.?patchMode
osType: 'Windows'
encryptionAtHost: false //The property 'securityProfile.encryptionAtHost' is not valid because the 'Microsoft.Compute/EncryptionAtHost' feature is not enabled for this subscription.
zone: 0
extensionAadJoinConfig: {
enabled: true
typeHandlerVersion: '1.0'
}
// extensionMonitoringAgentConfig: {
// enabled: true
// }
// maintenanceConfigurationResourceId: virtualMachineConfiguration.?maintenanceConfigurationResourceId
}
}

Expand Down Expand Up @@ -736,7 +697,9 @@ module privateDnsZonesAiServices 'br/public:avm/res/network/private-dns-zone:0.7
]

// NOTE: Required version 'Microsoft.CognitiveServices/accounts@2024-04-01-preview' not available in AVM
var aiFoundryAiServicesResourceName = aiFoundryAiServicesConfiguration.?name ?? 'aisa-${solutionPrefix}'
var useExistingFoundryProject = !empty(existingFoundryProjectResourceId)
var existingAiFoundryName = useExistingFoundryProject?split( existingFoundryProjectResourceId,'/')[8]:''
var aiFoundryAiServicesResourceName = useExistingFoundryProject? existingAiFoundryName : aiFoundryAiServicesConfiguration.?name ?? 'aisa-${solutionPrefix}'
var aiFoundryAIservicesEnabled = aiFoundryAiServicesConfiguration.?enabled ?? true
var aiFoundryAiServicesModelDeployment = {
format: 'OpenAI'
Expand All @@ -750,17 +713,20 @@ var aiFoundryAiServicesModelDeployment = {
raiPolicyName: 'Microsoft.Default'
}

module aiFoundryAiServices 'br/public:avm/res/cognitive-services/account:0.11.0' = if (aiFoundryAIservicesEnabled) {
module aiFoundryAiServices 'modules/account/main.bicep' = if (aiFoundryAIservicesEnabled) {
name: take('avm.res.cognitive-services.account.${aiFoundryAiServicesResourceName}', 64)
params: {
name: aiFoundryAiServicesResourceName
tags: aiFoundryAiServicesConfiguration.?tags ?? tags
location: aiFoundryAiServicesConfiguration.?location ?? aiDeploymentsLocation
enableTelemetry: enableTelemetry
projectName: 'aifp-${solutionPrefix}'
projectDescription: 'aifp-${solutionPrefix}'
existingFoundryProjectResourceId: existingFoundryProjectResourceId
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspaceId }]
sku: aiFoundryAiServicesConfiguration.?sku ?? 'S0'
kind: 'AIServices'
disableLocalAuth: false //Should be set to true for WAF aligned configuration
disableLocalAuth: true //Should be set to true for WAF aligned configuration
customSubDomainName: aiFoundryAiServicesResourceName
apiProperties: {
//staticsEnabled: false
Expand All @@ -769,10 +735,12 @@ module aiFoundryAiServices 'br/public:avm/res/cognitive-services/account:0.11.0'
managedIdentities: {
systemAssigned: true
}
//publicNetworkAccess: virtualNetworkEnabled ? 'Disabled' : 'Enabled'
//publicNetworkAccess: virtualNetworkEnabled ? 'Disabled' : 'Enabled'
publicNetworkAccess: 'Enabled' //TODO: connection via private endpoint is not working from containers network. Change this when fixed
privateEndpoints: virtualNetworkEnabled
publicNetworkAccess: virtualNetworkEnabled ? 'Disabled' : 'Enabled'
networkAcls: {
bypass: 'AzureServices'
defaultAction: (virtualNetworkEnabled) ? 'Deny' : 'Allow'
}
privateEndpoints: virtualNetworkEnabled && !useExistingFoundryProject
? ([
{
name: 'pep-${aiFoundryAiServicesResourceName}'
Expand All @@ -786,19 +754,7 @@ module aiFoundryAiServices 'br/public:avm/res/cognitive-services/account:0.11.0'
}
}
])
: []
// roleAssignments: [
// // {
// // principalId: userAssignedIdentity.outputs.principalId
// // principalType: 'ServicePrincipal'
// // roleDefinitionIdOrName: 'Cognitive Services OpenAI User'
// // }
// {
// principalId: containerApp.outputs.?systemAssignedMIPrincipalId!
// principalType: 'ServicePrincipal'
// roleDefinitionIdOrName: 'Cognitive Services OpenAI User'
// }
// ]
: []
deployments: aiFoundryAiServicesConfiguration.?deployments ?? [
{
name: aiFoundryAiServicesModelDeployment.name
Expand All @@ -819,76 +775,27 @@ module aiFoundryAiServices 'br/public:avm/res/cognitive-services/account:0.11.0'

// AI Foundry: AI Project
// WAF best practices for Open AI: https://learn.microsoft.com/en-us/azure/well-architected/service-guides/azure-openai
// var aiFoundryAiProjectEnabled = aiFoundryAiProjectConfiguration.?enabled ?? true
var aiFoundryAiProjectName = aiFoundryAiProjectConfiguration.?name ?? 'aifp-${solutionPrefix}'
var aiProjectDescription = 'AI Foundry Project'

resource aiServices 'Microsoft.CognitiveServices/accounts@2025-04-01-preview' existing = {
name: aiFoundryAiServicesResourceName
dependsOn:[
aiFoundryAiServices
]
}
var existingAiFounryProjectName = useExistingFoundryProject ? last(split( existingFoundryProjectResourceId,'/')) : ''
var aiFoundryAiProjectName = useExistingFoundryProject ? existingAiFounryProjectName : aiFoundryAiProjectConfiguration.?name ?? 'aifp-${solutionPrefix}'

resource aiFoundryProject 'Microsoft.CognitiveServices/accounts/projects@2025-04-01-preview' = {
parent: aiServices
name: aiFoundryAiProjectName
location: aiFoundryAiProjectConfiguration.?location ?? aiDeploymentsLocation
identity: {
type: 'SystemAssigned'
}
properties: {
description: aiProjectDescription
displayName: aiFoundryAiProjectName
}
}

resource aiUser 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = {
name: '53ca6127-db72-4b80-b1b0-d745d6d5456d'
}
var useExistingResourceId = !empty(existingFoundryProjectResourceId)

resource aiUserAccessProj 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(containerApp.name, aiFoundryProject.id, aiUser.id)
scope: aiFoundryProject
properties: {
roleDefinitionId: aiUser.id
principalId: containerApp.outputs.?systemAssignedMIPrincipalId!
}
}

resource aiUserAccessFoundry 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(containerApp.name, aiServices.id, aiUser.id)
scope: aiServices
properties: {
roleDefinitionId: aiUser.id
principalId: containerApp.outputs.?systemAssignedMIPrincipalId!
}
}

resource aiDeveloper 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = {
name: '64702f94-c441-49e6-a78b-ef80e0188fee'
}

resource aiDeveloperAccessFoundry 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(containerApp.name, aiServices.id, aiDeveloper.id)
scope: aiFoundryProject
properties: {
roleDefinitionId: aiDeveloper.id
module cogServiceRoleAssignmentsNew './modules/role.bicep' = if(!useExistingResourceId) {
params: {
name: 'new-${guid(containerApp.name, aiFoundryAiServices.outputs.resourceId)}'
principalId: containerApp.outputs.?systemAssignedMIPrincipalId!
aiServiceName: aiFoundryAiServices.outputs.name
}
scope: resourceGroup(subscription().subscriptionId, resourceGroup().name)
}

resource cognitiveServiceOpenAIUser 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = {
name: '5e0bd9bd-7b93-4f28-af87-19fc36ad61bd'
}

resource cognitiveServiceOpenAIUserAccessFoundry 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(containerApp.name, aiServices.id, cognitiveServiceOpenAIUser.id)
scope: aiServices
properties: {
roleDefinitionId: cognitiveServiceOpenAIUser.id
module cogServiceRoleAssignmentsExisting './modules/role.bicep' = if(useExistingResourceId) {
params: {
name: 'reuse-${guid(containerApp.name, aiFoundryAiServices.outputs.aiProjectInfo.resourceId)}'
principalId: containerApp.outputs.?systemAssignedMIPrincipalId!
aiServiceName: aiFoundryAiServices.outputs.name
}
scope: resourceGroup( split(existingFoundryProjectResourceId, '/')[2], split(existingFoundryProjectResourceId, '/')[4])
}

// ========== Cosmos DB ========== //
Expand Down Expand Up @@ -966,7 +873,6 @@ module cosmosDb 'br/public:avm/res/document-db/database-account:0.12.0' = if (co
'EnableServerless'
]
sqlRoleAssignmentsPrincipalIds: [
//userAssignedIdentity.outputs.principalId
containerApp.outputs.?systemAssignedMIPrincipalId
]
sqlRoleDefinitions: [
Expand Down Expand Up @@ -1003,13 +909,6 @@ module containerAppEnvironment 'modules/container-app-environment.bicep' = if (c
subnetResourceId: virtualNetworkEnabled
? containerAppEnvironmentConfiguration.?subnetResourceId ?? virtualNetwork.?outputs.?subnetResourceIds[3] ?? ''
: ''
//aspireDashboardEnabled: !virtualNetworkEnabled
// vnetConfiguration: virtualNetworkEnabled
// ? {
// internal: false
// infrastructureSubnetId: containerAppEnvironmentConfiguration.?subnetResourceId ?? virtualNetwork.?outputs.?subnetResourceIds[3] ?? ''
// }
// : {}
}
}

Expand Down Expand Up @@ -1117,7 +1016,7 @@ module containerApp 'br/public:avm/res/app/container-app:0.14.2' = if (container
}
{
name: 'AZURE_AI_AGENT_ENDPOINT'
value: aiFoundryProject.properties.endpoints['AI Foundry API']
value: aiFoundryAiServices.outputs.aiProjectInfo.apiEndpoint
}
{
name: 'AZURE_AI_AGENT_MODEL_DEPLOYMENT_NAME'
Expand Down Expand Up @@ -1189,19 +1088,6 @@ module webSite 'br/public:avm/res/web/site:0.15.1' = if (webSiteEnabled) {
@description('The default url of the website to connect to the Multi-Agent Custom Automation Engine solution.')
output webSiteDefaultHostname string = webSite.outputs.defaultHostname

// @description('The name of the resource.')
// output name string = <Resource>.name

// @description('The location the resource was deployed into.')
// output location string = <Resource>.location

// ================ //
// Definitions //
// ================ //
//
// Add your User-defined-types here, if any
//

@export()
@description('The type for the Multi-Agent Custom Automation Engine Log Analytics Workspace resource configuration.')
type logAnalyticsWorkspaceConfigurationType = {
Expand Down
3 changes: 3 additions & 0 deletions infra/main.parameters.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@
"gptModelCapacity": {
"value": "${AZURE_ENV_MODEL_CAPACITY}"
},
"existingFoundryProjectResourceId": {
"value": "${AZURE_ENV_FOUNDRY_PROJECT_ID}"
},
"imageTag": {
"value": "${AZURE_ENV_IMAGE_TAG}"
},
Expand Down
Loading
Loading