From d5bc11b6519661189dde1239d0db2e02dc72cdf1 Mon Sep 17 00:00:00 2001 From: Kris Baranek <20225789+krbar@users.noreply.github.com> Date: Thu, 7 Nov 2024 21:38:10 +0100 Subject: [PATCH] feat: Add onboardingStates extension resource to `avm/res/operational-insights/workspace` (#3667) ## Description - Adds new parameter `onboardWorkspaceToSentinel` controlling the onboardingStates extension resource, which onboards the workspace to Sentinel - Adds references to the AVM common types - Updated the cross-reference to the module `avm/res/operations-management/solution`. Now referencing the newest version 0.3.0, which offers more flexibility in the solution naming. This should resolve #3378. > Note: this is a breaking change. The format of the expected values of the `gallerySolutions` parameter has changed. Please refer to the updated documentation and parameter descriptions for more information. Resolves #3340 Resolves #3378 ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.operational-insights.workspace](https://github.com/krbar/bicep-registry-modules/actions/workflows/avm.res.operational-insights.workspace.yml/badge.svg?branch=users%2Fkrbar%2FlawOnboardingStates&event=workflow_dispatch)](https://github.com/krbar/bicep-registry-modules/actions/workflows/avm.res.operational-insights.workspace.yml) | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [x] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [x] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [x] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [x] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation ## Checklist - [x] I'm sure there are no other open Pull Requests for the same update/change - [x] I have run `Set-AVMModule` locally to generate the supporting module files. - [x] My corresponding pipelines / checks run clean and green without any errors or warnings --- .../operational-insights/workspace/README.md | 186 ++++- .../operational-insights/workspace/main.bicep | 91 +-- .../operational-insights/workspace/main.json | 756 ++++++++++-------- .../workspace/table/README.md | 9 + .../workspace/table/main.bicep | 29 +- .../workspace/table/main.json | 146 ++-- .../workspace/tests/e2e/adv/main.test.bicep | 7 +- .../workspace/tests/e2e/max/main.test.bicep | 23 +- .../tests/e2e/waf-aligned/main.test.bicep | 7 +- .../workspace/version.json | 10 +- 10 files changed, 752 insertions(+), 512 deletions(-) diff --git a/avm/res/operational-insights/workspace/README.md b/avm/res/operational-insights/workspace/README.md index 40a8d48755..5e62e5614e 100644 --- a/avm/res/operational-insights/workspace/README.md +++ b/avm/res/operational-insights/workspace/README.md @@ -27,6 +27,7 @@ This module deploys a Log Analytics Workspace. | `Microsoft.OperationalInsights/workspaces/storageInsightConfigs` | [2020-08-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2020-08-01/workspaces/storageInsightConfigs) | | `Microsoft.OperationalInsights/workspaces/tables` | [2022-10-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2022-10-01/workspaces/tables) | | `Microsoft.OperationsManagement/solutions` | [2015-11-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationsManagement/2015-11-01-preview/solutions) | +| `Microsoft.SecurityInsights/onboardingStates` | [2024-03-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.SecurityInsights/onboardingStates) | ## Usage examples @@ -199,9 +200,10 @@ module workspace 'br/public:avm/res/operational-insights/workspace:' = ] gallerySolutions: [ { - name: 'AzureAutomation' - product: 'OMSGallery' - publisher: 'Microsoft' + name: 'AzureAutomation(oiwadv001)' + plan: { + product: 'OMSGallery/AzureAutomation' + } } ] linkedServices: [ @@ -507,9 +509,10 @@ module workspace 'br/public:avm/res/operational-insights/workspace:' = "gallerySolutions": { "value": [ { - "name": "AzureAutomation", - "product": "OMSGallery", - "publisher": "Microsoft" + "name": "AzureAutomation(oiwadv001)", + "plan": { + "product": "OMSGallery/AzureAutomation" + } } ] }, @@ -825,9 +828,10 @@ param diagnosticSettings = [ ] param gallerySolutions = [ { - name: 'AzureAutomation' - product: 'OMSGallery' - publisher: 'Microsoft' + name: 'AzureAutomation(oiwadv001)' + plan: { + product: 'OMSGallery/AzureAutomation' + } } ] param linkedServices = [ @@ -1153,9 +1157,25 @@ module workspace 'br/public:avm/res/operational-insights/workspace:' = ] gallerySolutions: [ { - name: 'AzureAutomation' - product: 'OMSGallery' - publisher: 'Microsoft' + name: 'AzureAutomation(oiwmax001)' + plan: { + product: 'OMSGallery/AzureAutomation' + } + } + { + name: 'SecurityInsights(oiwmax001)' + plan: { + product: 'OMSGallery/SecurityInsights' + publisher: 'Microsoft' + } + } + { + name: 'SQLAuditing(oiwmax001)' + plan: { + name: 'SQLAuditing(oiwmax001)' + product: 'SQLAuditing' + publisher: 'Microsoft' + } } ] linkedServices: [ @@ -1178,6 +1198,7 @@ module workspace 'br/public:avm/res/operational-insights/workspace:' = managedIdentities: { systemAssigned: true } + onboardWorkspaceToSentinel: true publicNetworkAccessForIngestion: 'Disabled' publicNetworkAccessForQuery: 'Disabled' roleAssignments: [ @@ -1455,9 +1476,25 @@ module workspace 'br/public:avm/res/operational-insights/workspace:' = "gallerySolutions": { "value": [ { - "name": "AzureAutomation", - "product": "OMSGallery", - "publisher": "Microsoft" + "name": "AzureAutomation(oiwmax001)", + "plan": { + "product": "OMSGallery/AzureAutomation" + } + }, + { + "name": "SecurityInsights(oiwmax001)", + "plan": { + "product": "OMSGallery/SecurityInsights", + "publisher": "Microsoft" + } + }, + { + "name": "SQLAuditing(oiwmax001)", + "plan": { + "name": "SQLAuditing(oiwmax001)", + "product": "SQLAuditing", + "publisher": "Microsoft" + } } ] }, @@ -1491,6 +1528,9 @@ module workspace 'br/public:avm/res/operational-insights/workspace:' = "systemAssigned": true } }, + "onboardWorkspaceToSentinel": { + "value": true + }, "publicNetworkAccessForIngestion": { "value": "Disabled" }, @@ -1773,9 +1813,25 @@ param diagnosticSettings = [ ] param gallerySolutions = [ { - name: 'AzureAutomation' - product: 'OMSGallery' - publisher: 'Microsoft' + name: 'AzureAutomation(oiwmax001)' + plan: { + product: 'OMSGallery/AzureAutomation' + } + } + { + name: 'SecurityInsights(oiwmax001)' + plan: { + product: 'OMSGallery/SecurityInsights' + publisher: 'Microsoft' + } + } + { + name: 'SQLAuditing(oiwmax001)' + plan: { + name: 'SQLAuditing(oiwmax001)' + product: 'SQLAuditing' + publisher: 'Microsoft' + } } ] param linkedServices = [ @@ -1798,6 +1854,7 @@ param lock = { param managedIdentities = { systemAssigned: true } +param onboardWorkspaceToSentinel = true param publicNetworkAccessForIngestion = 'Disabled' param publicNetworkAccessForQuery = 'Disabled' param roleAssignments = [ @@ -2062,9 +2119,10 @@ module workspace 'br/public:avm/res/operational-insights/workspace:' = ] gallerySolutions: [ { - name: 'AzureAutomation' - product: 'OMSGallery' - publisher: 'Microsoft' + name: 'AzureAutomation(oiwwaf001)' + plan: { + product: 'OMSGallery/AzureAutomation' + } } ] linkedServices: [ @@ -2231,9 +2289,10 @@ module workspace 'br/public:avm/res/operational-insights/workspace:' = "gallerySolutions": { "value": [ { - "name": "AzureAutomation", - "product": "OMSGallery", - "publisher": "Microsoft" + "name": "AzureAutomation(oiwwaf001)", + "plan": { + "product": "OMSGallery/AzureAutomation" + } } ] }, @@ -2408,9 +2467,10 @@ param diagnosticSettings = [ ] param gallerySolutions = [ { - name: 'AzureAutomation' - product: 'OMSGallery' - publisher: 'Microsoft' + name: 'AzureAutomation(oiwwaf001)' + plan: { + product: 'OMSGallery/AzureAutomation' + } } ] param linkedServices = [ @@ -2483,6 +2543,7 @@ param useResourcePermissions = true | [`location`](#parameter-location) | string | Location for all resources. | | [`lock`](#parameter-lock) | object | The lock settings of the service. | | [`managedIdentities`](#parameter-managedidentities) | object | The managed identity definition for this resource. Only one type of identity is supported: system-assigned or user-assigned, but not both. | +| [`onboardWorkspaceToSentinel`](#parameter-onboardworkspacetosentinel) | bool | Onboard the Log Analytics Workspace to Sentinel. Requires 'SecurityInsights' solution to be in gallerySolutions. | | [`publicNetworkAccessForIngestion`](#parameter-publicnetworkaccessforingestion) | string | The network access type for accessing Log Analytics ingestion. | | [`publicNetworkAccessForQuery`](#parameter-publicnetworkaccessforquery) | string | The network access type for accessing Log Analytics query. | | [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | @@ -2717,7 +2778,61 @@ List of gallerySolutions to be created in the log analytics workspace. - Required: No - Type: array -- Default: `[]` + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-gallerysolutionsname) | string | Name of the solution.

For solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.

For solutions authored by third parties, the name should be in the pattern: `SolutionType[WorkspaceName]`, for example `MySolution[contoso-Logs]`.

The solution type is case-sensitive. | +| [`plan`](#parameter-gallerysolutionsplan) | object | Plan for solution object supported by the OperationsManagement resource provider. | + +### Parameter: `gallerySolutions.name` + +Name of the solution.

For solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.

For solutions authored by third parties, the name should be in the pattern: `SolutionType[WorkspaceName]`, for example `MySolution[contoso-Logs]`.

The solution type is case-sensitive. + +- Required: Yes +- Type: string + +### Parameter: `gallerySolutions.plan` + +Plan for solution object supported by the OperationsManagement resource provider. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`product`](#parameter-gallerysolutionsplanproduct) | string | The product name of the deployed solution.

For Microsoft published gallery solution it should be `OMSGallery/{solutionType}`, for example `OMSGallery/AntiMalware`.

For a third party solution, it can be anything.

This is case sensitive. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-gallerysolutionsplanname) | string | Name of the solution to be created.

For solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.

For solutions authored by third parties, it can be anything.

The solution type is case-sensitive.

If not provided, the value of the `name` parameter will be used. | +| [`publisher`](#parameter-gallerysolutionsplanpublisher) | string | The publisher name of the deployed solution. For Microsoft published gallery solution, it is `Microsoft`, which is the default value. | + +### Parameter: `gallerySolutions.plan.product` + +The product name of the deployed solution.

For Microsoft published gallery solution it should be `OMSGallery/{solutionType}`, for example `OMSGallery/AntiMalware`.

For a third party solution, it can be anything.

This is case sensitive. + +- Required: Yes +- Type: string + +### Parameter: `gallerySolutions.plan.name` + +Name of the solution to be created.

For solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.

For solutions authored by third parties, it can be anything.

The solution type is case-sensitive.

If not provided, the value of the `name` parameter will be used. + +- Required: No +- Type: string + +### Parameter: `gallerySolutions.plan.publisher` + +The publisher name of the deployed solution. For Microsoft published gallery solution, it is `Microsoft`, which is the default value. + +- Required: No +- Type: string ### Parameter: `linkedServices` @@ -2783,7 +2898,7 @@ The managed identity definition for this resource. Only one type of identity is | Parameter | Type | Description | | :-- | :-- | :-- | | [`systemAssigned`](#parameter-managedidentitiessystemassigned) | bool | Enables system assigned managed identity on the resource. | -| [`userAssignedResourceIds`](#parameter-managedidentitiesuserassignedresourceids) | array | The resource ID(s) to assign to the resource. | +| [`userAssignedResourceIds`](#parameter-managedidentitiesuserassignedresourceids) | array | The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption. | ### Parameter: `managedIdentities.systemAssigned` @@ -2794,11 +2909,19 @@ Enables system assigned managed identity on the resource. ### Parameter: `managedIdentities.userAssignedResourceIds` -The resource ID(s) to assign to the resource. +The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption. - Required: No - Type: array +### Parameter: `onboardWorkspaceToSentinel` + +Onboard the Log Analytics Workspace to Sentinel. Requires 'SecurityInsights' solution to be in gallerySolutions. + +- Required: No +- Type: bool +- Default: `False` + ### Parameter: `publicNetworkAccessForIngestion` The network access type for accessing Log Analytics ingestion. @@ -3023,7 +3146,8 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | -| `br/public:avm/res/operations-management/solution:0.1.0` | Remote reference | +| `br/public:avm/res/operations-management/solution:0.3.0` | Remote reference | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | ## Data Collection diff --git a/avm/res/operational-insights/workspace/main.bicep b/avm/res/operational-insights/workspace/main.bicep index b5be253202..22cfc7ffd3 100644 --- a/avm/res/operational-insights/workspace/main.bicep +++ b/avm/res/operational-insights/workspace/main.bicep @@ -48,7 +48,10 @@ param dataSources array = [] param tables array = [] @description('Optional. List of gallerySolutions to be created in the log analytics workspace.') -param gallerySolutions array = [] +param gallerySolutions gallerySolutionType[]? + +@description('Optional. Onboard the Log Analytics Workspace to Sentinel. Requires \'SecurityInsights\' solution to be in gallerySolutions.') +param onboardWorkspaceToSentinel bool = false @description('Optional. Number of days data will be retained for.') @minValue(0) @@ -73,23 +76,26 @@ param publicNetworkAccessForIngestion string = 'Enabled' ]) param publicNetworkAccessForQuery string = 'Enabled' +import { managedIdentityAllType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The managed identity definition for this resource. Only one type of identity is supported: system-assigned or user-assigned, but not both.') -param managedIdentities managedIdentitiesType +param managedIdentities managedIdentityAllType? @description('Optional. Set to \'true\' to use resource or workspace permissions and \'false\' (or leave empty) to require workspace permissions.') param useResourcePermissions bool = false @description('Optional. The diagnostic settings of the service.') -param diagnosticSettings diagnosticSettingType +param diagnosticSettings diagnosticSettingType[]? @description('Optional. Indicates whether customer managed storage is mandatory for query management.') param forceCmkForQuery bool = true +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. The lock settings of the service.') -param lock lockType +param lock lockType? +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? @description('Optional. Tags of the resource.') param tags object? @@ -342,20 +348,29 @@ module logAnalyticsWorkspace_tables 'table/main.bicep' = [ } ] -module logAnalyticsWorkspace_solutions 'br/public:avm/res/operations-management/solution:0.1.0' = [ - for (gallerySolution, index) in gallerySolutions: if (!empty(gallerySolutions)) { +module logAnalyticsWorkspace_solutions 'br/public:avm/res/operations-management/solution:0.3.0' = [ + for (gallerySolution, index) in gallerySolutions ?? []: if (!empty(gallerySolutions)) { name: '${uniqueString(deployment().name, location)}-LAW-Solution-${index}' params: { name: gallerySolution.name location: location logAnalyticsWorkspaceName: logAnalyticsWorkspace.name - product: gallerySolution.?product - publisher: gallerySolution.?publisher + plan: gallerySolution.plan enableTelemetry: gallerySolution.?enableTelemetry ?? enableTelemetry } } ] +// Onboard the Log Analytics Workspace to Sentinel if SecurityInsights is in gallerySolutions and onboardWorkspaceToSentinel is set to true +resource logAnalyticsWorkspace_sentinelOnboarding 'Microsoft.SecurityInsights/onboardingStates@2024-03-01' = if (!empty(filter( + gallerySolutions ?? [], + item => startsWith(item.name, 'SecurityInsights') +)) && onboardWorkspaceToSentinel) { + name: 'default' + scope: logAnalyticsWorkspace + properties: {} +} + resource logAnalyticsWorkspace_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock ?? {}) && lock.?kind != 'None') { name: lock.?name ?? 'lock-${name}' properties: { @@ -409,48 +424,6 @@ output systemAssignedMIPrincipalId string = logAnalyticsWorkspace.?identity.?pri // Definitions // // =============== // -type managedIdentitiesType = { - @description('Optional. Enables system assigned managed identity on the resource.') - systemAssigned: bool? - - @description('Optional. The resource ID(s) to assign to the resource.') - userAssignedResourceIds: string[]? -}? - -type lockType = { - @description('Optional. Specify the name of lock.') - name: string? - - @description('Optional. Specify the type of lock.') - kind: ('CanNotDelete' | 'ReadOnly' | 'None')? -}? - -type roleAssignmentType = { - @description('Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated.') - name: string? - - @description('Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') - roleDefinitionIdOrName: string - - @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') - principalId: string - - @description('Optional. The principal type of the assigned principal ID.') - principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? - - @description('Optional. The description of the role assignment.') - description: string? - - @description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container".') - condition: string? - - @description('Optional. Version of the condition.') - conditionVersion: '2.0'? - - @description('Optional. The Resource Id of the delegated managed identity resource.') - delegatedManagedIdentityResourceId: string? -}[]? - type diagnosticSettingType = { @description('Optional. The name of diagnostic setting.') name: string? @@ -496,4 +469,18 @@ type diagnosticSettingType = { @description('Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs.') marketplacePartnerResourceId: string? -}[]? +} + +import { solutionPlanType } from 'br/public:avm/res/operations-management/solution:0.3.0' + +@export() +type gallerySolutionType = { + @description('''Required. Name of the solution. + For solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`. + For solutions authored by third parties, the name should be in the pattern: `SolutionType[WorkspaceName]`, for example `MySolution[contoso-Logs]`. + The solution type is case-sensitive.''') + name: string + + @description('Required. Plan for solution object supported by the OperationsManagement resource provider.') + plan: solutionPlanType +} diff --git a/avm/res/operational-insights/workspace/main.json b/avm/res/operational-insights/workspace/main.json index f9386570de..f9283c7f7d 100644 --- a/avm/res/operational-insights/workspace/main.json +++ b/avm/res/operational-insights/workspace/main.json @@ -6,35 +6,155 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "2112385645205183034" + "templateHash": "15477650738706698985" }, "name": "Log Analytics Workspaces", "description": "This module deploys a Log Analytics Workspace.", "owner": "Azure/module-maintainers" }, "definitions": { - "managedIdentitiesType": { + "diagnosticSettingType": { "type": "object", "properties": { - "systemAssigned": { - "type": "bool", + "name": { + "type": "string", "nullable": true, "metadata": { - "description": "Optional. Enables system assigned managed identity on the resource." + "description": "Optional. The name of diagnostic setting." } }, - "userAssignedResourceIds": { + "logCategoriesAndGroups": { "type": "array", "items": { - "type": "string" + "type": "object", + "properties": { + "category": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." + } + }, + "categoryGroup": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." + } + }, + "metricCategories": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "metadata": { + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } }, "nullable": true, "metadata": { - "description": "Optional. The resource ID(s) to assign to the resource." + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." + } + }, + "logAnalyticsDestinationType": { + "type": "string", + "allowedValues": [ + "AzureDiagnostics", + "Dedicated" + ], + "nullable": true, + "metadata": { + "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type." + } + }, + "useThisWorkspace": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Instead of using an external reference, use the deployed instance as the target for its diagnostic settings. If set to `true`, the `workspaceResourceId` property is ignored." + } + }, + "workspaceResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "storageAccountResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "eventHubAuthorizationRuleResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." + } + }, + "eventHubName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "marketplacePartnerResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." + } + } + } + }, + "gallerySolutionType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the solution.\nFor solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.\nFor solutions authored by third parties, the name should be in the pattern: `SolutionType[WorkspaceName]`, for example `MySolution[contoso-Logs]`.\nThe solution type is case-sensitive." + } + }, + "plan": { + "$ref": "#/definitions/solutionPlanType", + "metadata": { + "description": "Required. Plan for solution object supported by the OperationsManagement resource provider." } } }, - "nullable": true + "metadata": { + "__bicep_export!": true + } }, "lockType": { "type": "object", @@ -59,207 +179,145 @@ } } }, - "nullable": true + "metadata": { + "description": "An AVM-aligned type for a lock.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } }, - "roleAssignmentType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." - } - }, - "principalId": { - "type": "string", - "metadata": { - "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." - } - }, - "principalType": { - "type": "string", - "allowedValues": [ - "Device", - "ForeignGroup", - "Group", - "ServicePrincipal", - "User" - ], - "nullable": true, - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." - } - }, - "conditionVersion": { - "type": "string", - "allowedValues": [ - "2.0" - ], - "nullable": true, - "metadata": { - "description": "Optional. Version of the condition." - } + "managedIdentityAllType": { + "type": "object", + "properties": { + "systemAssigned": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enables system assigned managed identity on the resource." + } + }, + "userAssignedResourceIds": { + "type": "array", + "items": { + "type": "string" }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } + "nullable": true, + "metadata": { + "description": "Optional. The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption." } } }, - "nullable": true + "metadata": { + "description": "An AVM-aligned type for a managed identity configuration. To be used if both a system-assigned & user-assigned identities are supported by the resource provider.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } }, - "diagnosticSettingType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name of diagnostic setting." - } - }, - "logCategoriesAndGroups": { - "type": "array", - "items": { - "type": "object", - "properties": { - "category": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." - } - }, - "categoryGroup": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." - } - }, - "enabled": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. Enable or disable the category explicitly. Default is `true`." - } - } - } - }, - "nullable": true, - "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." - } - }, - "metricCategories": { - "type": "array", - "items": { - "type": "object", - "properties": { - "category": { - "type": "string", - "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." - } - }, - "enabled": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. Enable or disable the category explicitly. Default is `true`." - } - } - } - }, - "nullable": true, - "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." - } - }, - "logAnalyticsDestinationType": { - "type": "string", - "allowedValues": [ - "AzureDiagnostics", - "Dedicated" - ], - "nullable": true, - "metadata": { - "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type." - } - }, - "useThisWorkspace": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. Instead of using an external reference, use the deployed instance as the target for its diagnostic settings. If set to `true`, the `workspaceResourceId` property is ignored." - } - }, - "workspaceResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." - } - }, - "storageAccountResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." - } - }, - "eventHubAuthorizationRuleResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." - } - }, - "eventHubName": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." - } - }, - "marketplacePartnerResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." - } + "roleAssignmentType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." } } }, - "nullable": true + "metadata": { + "description": "An AVM-aligned type for a role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } + }, + "solutionPlanType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the solution to be created.\nFor solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.\nFor solutions authored by third parties, it can be anything.\nThe solution type is case-sensitive.\nIf not provided, the value of the `name` parameter will be used." + } + }, + "product": { + "type": "string", + "metadata": { + "description": "Required. The product name of the deployed solution.\nFor Microsoft published gallery solution it should be `OMSGallery/{solutionType}`, for example `OMSGallery/AntiMalware`.\nFor a third party solution, it can be anything.\nThis is case sensitive." + } + }, + "publisher": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The publisher name of the deployed solution. For Microsoft published gallery solution, it is `Microsoft`, which is the default value." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/res/operations-management/solution:0.3.0" + } + } } }, "parameters": { @@ -353,11 +411,21 @@ }, "gallerySolutions": { "type": "array", - "defaultValue": [], + "items": { + "$ref": "#/definitions/gallerySolutionType" + }, + "nullable": true, "metadata": { "description": "Optional. List of gallerySolutions to be created in the log analytics workspace." } }, + "onboardWorkspaceToSentinel": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Onboard the Log Analytics Workspace to Sentinel. Requires 'SecurityInsights' solution to be in gallerySolutions." + } + }, "dataRetention": { "type": "int", "defaultValue": 365, @@ -398,7 +466,8 @@ } }, "managedIdentities": { - "$ref": "#/definitions/managedIdentitiesType", + "$ref": "#/definitions/managedIdentityAllType", + "nullable": true, "metadata": { "description": "Optional. The managed identity definition for this resource. Only one type of identity is supported: system-assigned or user-assigned, but not both." } @@ -411,7 +480,11 @@ } }, "diagnosticSettings": { - "$ref": "#/definitions/diagnosticSettingType", + "type": "array", + "items": { + "$ref": "#/definitions/diagnosticSettingType" + }, + "nullable": true, "metadata": { "description": "Optional. The diagnostic settings of the service." } @@ -425,12 +498,17 @@ }, "lock": { "$ref": "#/definitions/lockType", + "nullable": true, "metadata": { "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } @@ -561,6 +639,17 @@ "logAnalyticsWorkspace" ] }, + "logAnalyticsWorkspace_sentinelOnboarding": { + "condition": "[and(not(empty(filter(coalesce(parameters('gallerySolutions'), createArray()), lambda('item', startsWith(lambdaVariables('item').name, 'SecurityInsights'))))), parameters('onboardWorkspaceToSentinel'))]", + "type": "Microsoft.SecurityInsights/onboardingStates", + "apiVersion": "2024-03-01", + "scope": "[format('Microsoft.OperationalInsights/workspaces/{0}', parameters('name'))]", + "name": "default", + "properties": {}, + "dependsOn": [ + "logAnalyticsWorkspace" + ] + }, "logAnalyticsWorkspace_lock": { "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", @@ -1567,7 +1656,7 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "2417830359794202602" + "templateHash": "13749997754119668516" }, "name": "Log Analytics Workspace Tables", "description": "This module deploys a Log Analytics Workspace Table.", @@ -1575,77 +1664,79 @@ }, "definitions": { "roleAssignmentType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." - } - }, - "principalId": { - "type": "string", - "metadata": { - "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." - } - }, - "principalType": { - "type": "string", - "allowedValues": [ - "Device", - "ForeignGroup", - "Group", - "ServicePrincipal", - "User" - ], - "nullable": true, - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." - } - }, - "conditionVersion": { - "type": "string", - "allowedValues": [ - "2.0" - ], - "nullable": true, - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." } } }, - "nullable": true + "metadata": { + "description": "An AVM-aligned type for a role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } } }, "parameters": { @@ -1712,7 +1803,11 @@ } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } @@ -1816,7 +1911,7 @@ "logAnalyticsWorkspace_solutions": { "copy": { "name": "logAnalyticsWorkspace_solutions", - "count": "[length(parameters('gallerySolutions'))]" + "count": "[length(coalesce(parameters('gallerySolutions'), createArray()))]" }, "condition": "[not(empty(parameters('gallerySolutions')))]", "type": "Microsoft.Resources/deployments", @@ -1829,7 +1924,7 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[parameters('gallerySolutions')[copyIndex()].name]" + "value": "[coalesce(parameters('gallerySolutions'), createArray())[copyIndex()].name]" }, "location": { "value": "[parameters('location')]" @@ -1837,34 +1932,68 @@ "logAnalyticsWorkspaceName": { "value": "[parameters('name')]" }, - "product": { - "value": "[tryGet(parameters('gallerySolutions')[copyIndex()], 'product')]" - }, - "publisher": { - "value": "[tryGet(parameters('gallerySolutions')[copyIndex()], 'publisher')]" + "plan": { + "value": "[coalesce(parameters('gallerySolutions'), createArray())[copyIndex()].plan]" }, "enableTelemetry": { - "value": "[coalesce(tryGet(parameters('gallerySolutions')[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]" + "value": "[coalesce(tryGet(coalesce(parameters('gallerySolutions'), createArray())[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]" } }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "18444780972506374592" + "version": "0.30.23.60470", + "templateHash": "1867653058254938383" }, "name": "Operations Management Solutions", "description": "This module deploys an Operations Management Solution.", "owner": "Azure/module-maintainers" }, + "definitions": { + "solutionPlanType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the solution to be created.\nFor solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.\nFor solutions authored by third parties, it can be anything.\nThe solution type is case-sensitive.\nIf not provided, the value of the `name` parameter will be used." + } + }, + "product": { + "type": "string", + "metadata": { + "description": "Required. The product name of the deployed solution.\nFor Microsoft published gallery solution it should be `OMSGallery/{solutionType}`, for example `OMSGallery/AntiMalware`.\nFor a third party solution, it can be anything.\nThis is case sensitive." + } + }, + "publisher": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The publisher name of the deployed solution. For Microsoft published gallery solution, it is `Microsoft`, which is the default value." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, "parameters": { "name": { "type": "string", "metadata": { - "description": "Required. Name of the solution. For Microsoft published gallery solution the target solution resource name will be composed as `{name}({logAnalyticsWorkspaceName})`." + "description": "Required. Name of the solution.\nFor solutions authored by Microsoft, the name must be in the pattern: `SolutionType(WorkspaceName)`, for example: `AntiMalware(contoso-Logs)`.\nFor solutions authored by third parties, the name should be in the pattern: `SolutionType[WorkspaceName]`, for example `MySolution[contoso-Logs]`.\nThe solution type is case-sensitive." + } + }, + "plan": { + "$ref": "#/definitions/solutionPlanType", + "metadata": { + "description": "Required. Plan for solution object supported by the OperationsManagement resource provider." } }, "logAnalyticsWorkspaceName": { @@ -1880,20 +2009,6 @@ "description": "Optional. Location for all resources." } }, - "product": { - "type": "string", - "defaultValue": "OMSGallery", - "metadata": { - "description": "Optional. The product of the deployed solution. For Microsoft published gallery solution it should be `OMSGallery` and the target solution resource product will be composed as `OMSGallery/{name}`. For third party solution, it can be anything. This is case sensitive." - } - }, - "publisher": { - "type": "string", - "defaultValue": "Microsoft", - "metadata": { - "description": "Optional. The publisher name of the deployed solution. For Microsoft published gallery solution, it is `Microsoft`." - } - }, "enableTelemetry": { "type": "bool", "defaultValue": true, @@ -1902,16 +2017,12 @@ } } }, - "variables": { - "solutionName": "[if(equals(parameters('publisher'), 'Microsoft'), format('{0}({1})', parameters('name'), parameters('logAnalyticsWorkspaceName')), parameters('name'))]", - "solutionProduct": "[if(equals(parameters('publisher'), 'Microsoft'), format('OMSGallery/{0}', parameters('name')), parameters('product'))]" - }, - "resources": [ - { + "resources": { + "avmTelemetry": { "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", - "apiVersion": "2023-07-01", - "name": "[format('46d3xbcp.res.operationsmanagement-solution.{0}.{1}', replace('0.1.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.res.operationsmanagement-solution.{0}.{1}', replace('0.3.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -1927,36 +2038,45 @@ } } }, - { + "logAnalyticsWorkspace": { + "existing": true, + "type": "Microsoft.OperationalInsights/workspaces", + "apiVersion": "2021-06-01", + "name": "[parameters('logAnalyticsWorkspaceName')]" + }, + "solution": { "type": "Microsoft.OperationsManagement/solutions", "apiVersion": "2015-11-01-preview", - "name": "[variables('solutionName')]", + "name": "[parameters('name')]", "location": "[parameters('location')]", "properties": { "workspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('logAnalyticsWorkspaceName'))]" }, "plan": { - "name": "[variables('solutionName')]", + "name": "[coalesce(tryGet(parameters('plan'), 'name'), parameters('name'))]", "promotionCode": "", - "product": "[variables('solutionProduct')]", - "publisher": "[parameters('publisher')]" - } + "product": "[parameters('plan').product]", + "publisher": "[coalesce(tryGet(parameters('plan'), 'publisher'), 'Microsoft')]" + }, + "dependsOn": [ + "logAnalyticsWorkspace" + ] } - ], + }, "outputs": { "name": { "type": "string", "metadata": { "description": "The name of the deployed solution." }, - "value": "[variables('solutionName')]" + "value": "[parameters('name')]" }, "resourceId": { "type": "string", "metadata": { "description": "The resource ID of the deployed solution." }, - "value": "[resourceId('Microsoft.OperationsManagement/solutions', variables('solutionName'))]" + "value": "[resourceId('Microsoft.OperationsManagement/solutions', parameters('name'))]" }, "resourceGroupName": { "type": "string", @@ -1970,7 +2090,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.OperationsManagement/solutions', variables('solutionName')), '2015-11-01-preview', 'full').location]" + "value": "[reference('solution', '2015-11-01-preview', 'full').location]" } } } diff --git a/avm/res/operational-insights/workspace/table/README.md b/avm/res/operational-insights/workspace/table/README.md index dc20f643c0..4418b50f3b 100644 --- a/avm/res/operational-insights/workspace/table/README.md +++ b/avm/res/operational-insights/workspace/table/README.md @@ -7,6 +7,7 @@ This module deploys a Log Analytics Workspace Table. - [Resource Types](#Resource-Types) - [Parameters](#Parameters) - [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) ## Resource Types @@ -224,3 +225,11 @@ The table total retention in days, between 4 and 2555. Setting this property to | `name` | string | The name of the table. | | `resourceGroupName` | string | The name of the resource group the table was created in. | | `resourceId` | string | The resource ID of the table. | + +## Cross-referenced modules + +This section gives you an overview of all local-referenced module files (i.e., other modules that are referenced in this module) and all remote-referenced files (i.e., Bicep modules that are referenced from a Bicep Registry or Template Specs). + +| Reference | Type | +| :-- | :-- | +| `br/public:avm/utl/types/avm-common-types:0.2.1` | Remote reference | diff --git a/avm/res/operational-insights/workspace/table/main.bicep b/avm/res/operational-insights/workspace/table/main.bicep index b38ff9210f..ad3323e998 100644 --- a/avm/res/operational-insights/workspace/table/main.bicep +++ b/avm/res/operational-insights/workspace/table/main.bicep @@ -38,8 +38,9 @@ param searchResults object = {} @maxValue(2555) param totalRetentionInDays int = -1 +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.2.1' @description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') @@ -135,29 +136,3 @@ output resourceGroupName string = resourceGroup().name // =============== // // Definitions // // =============== // - -type roleAssignmentType = { - @description('Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated.') - name: string? - - @description('Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') - roleDefinitionIdOrName: string - - @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') - principalId: string - - @description('Optional. The principal type of the assigned principal ID.') - principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? - - @description('Optional. The description of the role assignment.') - description: string? - - @description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container".') - condition: string? - - @description('Optional. Version of the condition.') - conditionVersion: '2.0'? - - @description('Optional. The Resource Id of the delegated managed identity resource.') - delegatedManagedIdentityResourceId: string? -}[]? diff --git a/avm/res/operational-insights/workspace/table/main.json b/avm/res/operational-insights/workspace/table/main.json index 9c038008cd..62a5285595 100644 --- a/avm/res/operational-insights/workspace/table/main.json +++ b/avm/res/operational-insights/workspace/table/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "2417830359794202602" + "templateHash": "13749997754119668516" }, "name": "Log Analytics Workspace Tables", "description": "This module deploys a Log Analytics Workspace Table.", @@ -14,77 +14,79 @@ }, "definitions": { "roleAssignmentType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." - } - }, - "principalId": { - "type": "string", - "metadata": { - "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." - } - }, - "principalType": { - "type": "string", - "allowedValues": [ - "Device", - "ForeignGroup", - "Group", - "ServicePrincipal", - "User" - ], - "nullable": true, - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." - } - }, - "conditionVersion": { - "type": "string", - "allowedValues": [ - "2.0" - ], - "nullable": true, - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." } } }, - "nullable": true + "metadata": { + "description": "An AVM-aligned type for a role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.2.1" + } + } } }, "parameters": { @@ -151,7 +153,11 @@ } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } diff --git a/avm/res/operational-insights/workspace/tests/e2e/adv/main.test.bicep b/avm/res/operational-insights/workspace/tests/e2e/adv/main.test.bicep index 94d627e6a7..9fe570be9d 100644 --- a/avm/res/operational-insights/workspace/tests/e2e/adv/main.test.bicep +++ b/avm/res/operational-insights/workspace/tests/e2e/adv/main.test.bicep @@ -186,9 +186,10 @@ module testDeployment '../../../main.bicep' = [ ] gallerySolutions: [ { - name: 'AzureAutomation' - product: 'OMSGallery' - publisher: 'Microsoft' + name: 'AzureAutomation(${namePrefix}${serviceShort}001)' + plan: { + product: 'OMSGallery/AzureAutomation' + } } ] linkedServices: [ diff --git a/avm/res/operational-insights/workspace/tests/e2e/max/main.test.bicep b/avm/res/operational-insights/workspace/tests/e2e/max/main.test.bicep index 4b277bc3f5..1c9fde140b 100644 --- a/avm/res/operational-insights/workspace/tests/e2e/max/main.test.bicep +++ b/avm/res/operational-insights/workspace/tests/e2e/max/main.test.bicep @@ -175,11 +175,28 @@ module testDeployment '../../../main.bicep' = [ ] gallerySolutions: [ { - name: 'AzureAutomation' - product: 'OMSGallery' - publisher: 'Microsoft' + name: 'AzureAutomation(${namePrefix}${serviceShort}001)' + plan: { + product: 'OMSGallery/AzureAutomation' + } + } + { + name: 'SecurityInsights(${namePrefix}${serviceShort}001)' + plan: { + product: 'OMSGallery/SecurityInsights' + publisher: 'Microsoft' + } + } + { + name: 'SQLAuditing(${namePrefix}${serviceShort}001)' + plan: { + name: 'SQLAuditing(${namePrefix}${serviceShort}001)' + product: 'SQLAuditing' + publisher: 'Microsoft' + } } ] + onboardWorkspaceToSentinel: true linkedServices: [ { name: 'Automation' diff --git a/avm/res/operational-insights/workspace/tests/e2e/waf-aligned/main.test.bicep b/avm/res/operational-insights/workspace/tests/e2e/waf-aligned/main.test.bicep index 62e91d5492..9819017c8c 100644 --- a/avm/res/operational-insights/workspace/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/operational-insights/workspace/tests/e2e/waf-aligned/main.test.bicep @@ -168,9 +168,10 @@ module testDeployment '../../../main.bicep' = [ ] gallerySolutions: [ { - name: 'AzureAutomation' - product: 'OMSGallery' - publisher: 'Microsoft' + name: 'AzureAutomation(${namePrefix}${serviceShort}001)' + plan: { + product: 'OMSGallery/AzureAutomation' + } } ] linkedServices: [ diff --git a/avm/res/operational-insights/workspace/version.json b/avm/res/operational-insights/workspace/version.json index 7e1d3f4157..9a9a06e897 100644 --- a/avm/res/operational-insights/workspace/version.json +++ b/avm/res/operational-insights/workspace/version.json @@ -1,7 +1,7 @@ { - "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.7", - "pathFilters": [ - "./main.json" - ] + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.8", + "pathFilters": [ + "./main.json" + ] } \ No newline at end of file