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
11 changes: 10 additions & 1 deletion documentation/DeploymentGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,16 @@ For **production deployments**, the repository also provides [`main.waf-aligned.
- For a WAF-aligned, production-ready deployment, copy the contents of [`main.waf-aligned.bicepparam`](../infra/main.waf-aligned.bicepparam) into `main.bicepparam` before running `azd up`.

> [!TIP]
> Always review and adjust parameter values (such as region, capacity, and security settings) to match your organization’s requirements before deploying. For production, ensure you have sufficient quota and follow the principle of least privilege for all identities and role assignments.
> Always review and adjust parameter values (such as region, capacity, security settings and log analytics workspace configuration) to match your organization’s requirements before deploying. For production, ensure you have sufficient quota and follow the principle of least privilege for all identities and role assignments.

> To reuse an existing Log Analytics workspace, update the existingWorkspaceResourceId field under the logAnalyticsWorkspaceConfiguration parameter in the bicepparam file with the resource ID of your existing workspace.
For example:
```
param logAnalyticsWorkspaceConfiguration = {
dataRetentionInDays: 30
existingWorkspaceResourceId: '/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.OperationalInsights/workspaces/<workspace-name>'
}
```

> [!IMPORTANT]
> The WAF-aligned configuration is under active development. More Azure Well-Architected recommendations will be added in future updates.
Expand Down
47 changes: 28 additions & 19 deletions infra/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ param logAnalyticsWorkspaceConfiguration logAnalyticsWorkspaceConfigurationType
sku: 'PerGB2018'
tags: tags
dataRetentionInDays: 365
existingWorkspaceResourceId: ''
}

@description('Optional. The configuration to apply for the Multi-Agent Custom Automation Engine Application Insights resource.')
Expand Down Expand Up @@ -255,7 +256,10 @@ resource avmTelemetry 'Microsoft.Resources/deployments@2024-03-01' = if (enableT
// Log Analytics configuration defaults
var logAnalyticsWorkspaceEnabled = logAnalyticsWorkspaceConfiguration.?enabled ?? true
var logAnalyticsWorkspaceResourceName = logAnalyticsWorkspaceConfiguration.?name ?? 'log-${solutionPrefix}'
module logAnalyticsWorkspace 'br/public:avm/res/operational-insights/workspace:0.11.2' = if (logAnalyticsWorkspaceEnabled) {
var existingWorkspaceResourceId = logAnalyticsWorkspaceConfiguration.?existingWorkspaceResourceId ?? ''
var useExistingWorkspace = existingWorkspaceResourceId != ''

module logAnalyticsWorkspace 'br/public:avm/res/operational-insights/workspace:0.11.2' = if (logAnalyticsWorkspaceEnabled && !useExistingWorkspace) {
name: take('avm.res.operational-insights.workspace.${logAnalyticsWorkspaceResourceName}', 64)
params: {
name: logAnalyticsWorkspaceResourceName
Expand All @@ -268,6 +272,8 @@ module logAnalyticsWorkspace 'br/public:avm/res/operational-insights/workspace:0
}
}

var logAnalyticsWorkspaceId = useExistingWorkspace ? existingWorkspaceResourceId : logAnalyticsWorkspace.outputs.resourceId

// ========== Application Insights ========== //
// WAF best practices for Application Insights: https://learn.microsoft.com/en-us/azure/well-architected/service-guides/application-insights
// Application Insights configuration defaults
Expand All @@ -277,12 +283,12 @@ module applicationInsights 'br/public:avm/res/insights/component:0.6.0' = if (ap
name: take('avm.res.insights.component.${applicationInsightsResourceName}', 64)
params: {
name: applicationInsightsResourceName
workspaceResourceId: logAnalyticsWorkspace.outputs.resourceId
workspaceResourceId: logAnalyticsWorkspaceId
location: applicationInsightsConfiguration.?location ?? solutionLocation
enableTelemetry: enableTelemetry
tags: applicationInsightsConfiguration.?tags ?? tags
retentionInDays: applicationInsightsConfiguration.?retentionInDays ?? 365
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspace.outputs.resourceId }]
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspaceId }]
kind: 'web'
disableIpMasking: false
flowType: 'Bluefield'
Expand Down Expand Up @@ -315,7 +321,7 @@ module networkSecurityGroupBackend 'br/public:avm/res/network/network-security-g
location: networkSecurityGroupBackendConfiguration.?location ?? solutionLocation
tags: networkSecurityGroupBackendConfiguration.?tags ?? tags
enableTelemetry: enableTelemetry
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspace.outputs.resourceId }]
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspaceId }]
securityRules: networkSecurityGroupBackendConfiguration.?securityRules ?? [
// {
// name: 'DenySshRdpOutbound' //Azure Bastion
Expand Down Expand Up @@ -346,7 +352,7 @@ module networkSecurityGroupContainers 'br/public:avm/res/network/network-securit
location: networkSecurityGroupContainersConfiguration.?location ?? solutionLocation
tags: networkSecurityGroupContainersConfiguration.?tags ?? tags
enableTelemetry: enableTelemetry
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspace.outputs.resourceId }]
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspaceId }]
securityRules: networkSecurityGroupContainersConfiguration.?securityRules ?? [
// {
// name: 'DenySshRdpOutbound' //Azure Bastion
Expand Down Expand Up @@ -377,7 +383,7 @@ module networkSecurityGroupBastion 'br/public:avm/res/network/network-security-g
location: networkSecurityGroupBastionConfiguration.?location ?? solutionLocation
tags: networkSecurityGroupBastionConfiguration.?tags ?? tags
enableTelemetry: enableTelemetry
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspace.outputs.resourceId }]
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspaceId }]
securityRules: networkSecurityGroupBastionConfiguration.?securityRules ?? [
{
name: 'AllowHttpsInBound'
Expand Down Expand Up @@ -534,7 +540,7 @@ module networkSecurityGroupAdministration 'br/public:avm/res/network/network-sec
location: networkSecurityGroupAdministrationConfiguration.?location ?? solutionLocation
tags: networkSecurityGroupAdministrationConfiguration.?tags ?? tags
enableTelemetry: enableTelemetry
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspace.outputs.resourceId }]
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspaceId }]
securityRules: networkSecurityGroupAdministrationConfiguration.?securityRules ?? [
// {
// name: 'DenySshRdpOutbound' //Azure Bastion
Expand Down Expand Up @@ -651,12 +657,12 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:0.13.0' = if (v
name: 'nic-${virtualMachineResourceName}'
//networkSecurityGroupResourceId: virtualMachineConfiguration.?nicConfigurationConfiguration.networkSecurityGroupResourceId
//nicSuffix: 'nic-${virtualMachineResourceName}'
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspace.outputs.resourceId }]
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspaceId }]
ipConfigurations: [
{
name: '${virtualMachineResourceName}-nic01-ipconfig01'
subnetResourceId: virtualMachineConfiguration.?subnetResourceId ?? virtualNetwork.outputs.subnetResourceIds[1]
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspace.outputs.resourceId }]
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspaceId }]
}
]
}
Expand Down Expand Up @@ -730,7 +736,7 @@ var aiFoundryAiServicesModelDeployment = {
sku: {
name: 'GlobalStandard'
//Curently the capacity is set to 140 for opinanal performance.
capacity: aiFoundryAiServicesConfiguration.?modelCapcity ?? 140
capacity: aiFoundryAiServicesConfiguration.?modelCapacity ?? 140
}
raiPolicyName: 'Microsoft.Default'
}
Expand All @@ -742,7 +748,7 @@ module aiFoundryAiServices 'br/public:avm/res/cognitive-services/account:0.10.2'
tags: aiFoundryAiServicesConfiguration.?tags ?? tags
location: aiFoundryAiServicesConfiguration.?location ?? azureOpenAILocation
enableTelemetry: enableTelemetry
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspace.outputs.resourceId }]
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspaceId }]
sku: aiFoundryAiServicesConfiguration.?sku ?? 'S0'
kind: 'AIServices'
disableLocalAuth: false //Should be set to true for WAF aligned configuration
Expand Down Expand Up @@ -841,7 +847,7 @@ module aiFoundryStorageAccount 'br/public:avm/res/storage/storage-account:0.18.2
location: aiFoundryStorageAccountConfiguration.?location ?? azureOpenAILocation
tags: aiFoundryStorageAccountConfiguration.?tags ?? tags
enableTelemetry: enableTelemetry
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspace.outputs.resourceId }]
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspaceId }]
skuName: aiFoundryStorageAccountConfiguration.?sku ?? 'Standard_ZRS'
allowSharedKeyAccess: false
networkAcls: {
Expand All @@ -852,7 +858,7 @@ module aiFoundryStorageAccount 'br/public:avm/res/storage/storage-account:0.18.2
deleteRetentionPolicyEnabled: false
containerDeleteRetentionPolicyDays: 7
containerDeleteRetentionPolicyEnabled: false
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspace.outputs.resourceId }]
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspaceId }]
}
publicNetworkAccess: virtualNetworkEnabled ? 'Disabled' : 'Enabled'
allowBlobPublicAccess: virtualNetworkEnabled ? false : true
Expand Down Expand Up @@ -912,7 +918,7 @@ module aiFoundryAiHub 'modules/ai-hub.bicep' = if (aiFoundryAiHubEnabled) {
aiFoundryAiServicesName: aiFoundryAiServices.outputs.name
applicationInsightsResourceId: applicationInsights.outputs.resourceId
enableTelemetry: enableTelemetry
logAnalyticsWorkspaceResourceId: logAnalyticsWorkspace.outputs.resourceId
logAnalyticsWorkspaceResourceId: logAnalyticsWorkspaceId
storageAccountResourceId: aiFoundryStorageAccount.outputs.resourceId
virtualNetworkEnabled: virtualNetworkEnabled
privateEndpoints: virtualNetworkEnabled
Expand Down Expand Up @@ -948,7 +954,7 @@ module aiFoundryAiProject 'br/public:avm/res/machine-learning-services/workspace
location: aiFoundryAiProjectConfiguration.?location ?? azureOpenAILocation
tags: aiFoundryAiProjectConfiguration.?tags ?? tags
enableTelemetry: enableTelemetry
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspace.outputs.resourceId }]
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspaceId }]
sku: aiFoundryAiProjectConfiguration.?sku ?? 'Basic'
kind: 'Project'
hubResourceId: aiFoundryAiHub.outputs.resourceId
Expand Down Expand Up @@ -991,7 +997,7 @@ module cosmosDb 'br/public:avm/res/document-db/database-account:0.12.0' = if (co
location: cosmosDbAccountConfiguration.?location ?? solutionLocation
tags: cosmosDbAccountConfiguration.?tags ?? tags
enableTelemetry: enableTelemetry
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspace.outputs.resourceId }]
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspaceId }]
databaseAccountOfferType: 'Standard'
enableFreeTier: false
networkRestrictions: {
Expand Down Expand Up @@ -1065,7 +1071,7 @@ module containerAppEnvironment 'modules/container-app-environment.bicep' = if (c
name: containerAppEnvironmentResourceName
tags: containerAppEnvironmentConfiguration.?tags ?? tags
location: containerAppEnvironmentConfiguration.?location ?? solutionLocation
logAnalyticsResourceName: logAnalyticsWorkspace.outputs.name
logAnalyticsResourceId: logAnalyticsWorkspaceId
publicNetworkAccess: 'Enabled'
zoneRedundant: virtualNetworkEnabled ? true : false
applicationInsightsConnectionString: applicationInsights.outputs.connectionString
Expand Down Expand Up @@ -1210,7 +1216,7 @@ module webServerFarm 'br/public:avm/res/web/serverfarm:0.4.1' = if (webServerFar
skuName: webServerFarmConfiguration.?skuName ?? 'P1v3'
skuCapacity: webServerFarmConfiguration.?skuCapacity ?? 3
reserved: true
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspace.outputs.resourceId }]
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspaceId }]
kind: 'linux'
zoneRedundant: false //TODO: make it zone redundant for waf aligned
}
Expand All @@ -1231,7 +1237,7 @@ module webSite 'br/public:avm/res/web/site:0.15.1' = if (webSiteEnabled) {
enableTelemetry: enableTelemetry
serverFarmResourceId: webSiteConfiguration.?environmentResourceId ?? webServerFarm.?outputs.resourceId
appInsightResourceId: applicationInsights.outputs.resourceId
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspace.outputs.resourceId }]
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspaceId }]
publicNetworkAccess: 'Enabled' //TODO: use Azure Front Door WAF or Application Gateway WAF instead
siteConfig: {
linuxFxVersion: 'DOCKER|${webSiteConfiguration.?containerImageRegistryDomain ?? 'biabcontainerreg.azurecr.io'}/${webSiteConfiguration.?containerImageName ?? 'macaefrontend'}:${webSiteConfiguration.?containerImageTag ?? 'latest'}'
Expand Down Expand Up @@ -1292,6 +1298,9 @@ type logAnalyticsWorkspaceConfigurationType = {
@description('Optional. The number of days to retain the data in the Log Analytics Workspace. If empty, it will be set to 365 days.')
@maxValue(730)
dataRetentionInDays: int?

@description('Optional: Existing Log Analytics Workspace Resource ID')
existingWorkspaceResourceId: string?
}

@export()
Expand Down
1 change: 1 addition & 0 deletions infra/main.bicepparam
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ param solutionLocation = readEnvironmentVariable('AZURE_LOCATION', 'swedencentra
param azureOpenAILocation = readEnvironmentVariable('AZURE_ENV_OPENAI_LOCATION', 'swedencentral')
param logAnalyticsWorkspaceConfiguration = {
dataRetentionInDays: 30
existingWorkspaceResourceId: ''
}
param applicationInsightsConfiguration = {
retentionInDays: 30
Expand Down
4 changes: 4 additions & 0 deletions infra/main.waf-aligned.bicepparam
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@ param virtualMachineConfiguration = {
adminUsername: 'adminuser'
adminPassword: 'P@ssw0rd1234'
}

param logAnalyticsWorkspaceConfiguration = {
existingWorkspaceResourceId: ''
}
10 changes: 7 additions & 3 deletions infra/modules/container-app-environment.bicep
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
param name string
param location string
param logAnalyticsResourceName string
param logAnalyticsResourceId string
param tags object
param publicNetworkAccess string
//param vnetConfiguration object
Expand All @@ -10,8 +10,12 @@ param enableTelemetry bool
param subnetResourceId string
param applicationInsightsConnectionString string

resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2023-09-01' existing = {
name: logAnalyticsResourceName
var logAnalyticsResourceGroup = split(logAnalyticsResourceId, '/')[4]
var logAnalyticsName = split(logAnalyticsResourceId, '/')[8]

resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2020-08-01' existing = {
name: logAnalyticsName
scope: resourceGroup(logAnalyticsResourceGroup)
}

// resource containerAppEnvironment 'Microsoft.App/managedEnvironments@2024-08-02-preview' = {
Expand Down
Loading