diff --git a/.github/workflows/avm.res.operations-management.solution.yml b/.github/workflows/avm.res.operations-management.solution.yml new file mode 100644 index 0000000000..6378665a69 --- /dev/null +++ b/.github/workflows/avm.res.operations-management.solution.yml @@ -0,0 +1,81 @@ +name: "avm.res.operations-management.solution" + +on: + schedule: + - cron: "0 12 1/15 * *" # Bi-Weekly Test (on 1st & 15th of month) + workflow_dispatch: + inputs: + staticValidation: + type: boolean + description: "Execute static validation" + required: false + default: true + deploymentValidation: + type: boolean + description: "Execute deployment validation" + required: false + default: true + removeDeployment: + type: boolean + description: "Remove deployed module" + required: false + default: true + + push: + branches: + - main + paths: + - ".github/actions/templates/avm-**" + - ".github/workflows/avm.template.module.yml" + - ".github/workflows/avm.res.operations-management.solution.yml" + - "avm/res/operations-management/solution/**" + - "avm/utilities/pipelines/**" + - "!*/**/README.md" + +env: + modulePath: "avm/res/operations-management/solution" + workflowPath: ".github/workflows/avm.res.operations-management.solution.yml" + +concurrency: + group: ${{ github.workflow }} + +jobs: + ########################### + # Initialize pipeline # + ########################### + job_initialize_pipeline: + runs-on: ubuntu-20.04 + name: "Initialize pipeline" + steps: + - name: "Checkout" + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: "Set input parameters to output variables" + id: get-workflow-param + uses: ./.github/actions/templates/avm-getWorkflowInput + with: + workflowPath: "${{ env.workflowPath}}" + - name: "Get parameter file paths" + id: get-module-test-file-paths + uses: ./.github/actions/templates/avm-getModuleTestFiles + with: + modulePath: "${{ env.modulePath }}" + outputs: + workflowInput: ${{ steps.get-workflow-param.outputs.workflowInput }} + moduleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.moduleTestFilePaths }} + modulePath: "${{ env.modulePath }}" + + ############################## + # Call reusable workflow # + ############################## + call-workflow-passing-data: + name: "Module" + needs: + - job_initialize_pipeline + uses: ./.github/workflows/avm.template.module.yml + with: + workflowInput: "${{ needs.job_initialize_pipeline.outputs.workflowInput }}" + moduleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.moduleTestFilePaths }}" + modulePath: "${{ needs.job_initialize_pipeline.outputs.modulePath}}" + secrets: inherit diff --git a/avm/res/operations-management/solution/README.md b/avm/res/operations-management/solution/README.md new file mode 100644 index 0000000000..badf475a35 --- /dev/null +++ b/avm/res/operations-management/solution/README.md @@ -0,0 +1,335 @@ +# Operations Management Solutions `[Microsoft.OperationsManagement/solutions]` + +This module deploys an Operations Management Solution. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Usage examples](#Usage-examples) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.OperationsManagement/solutions` | [2015-11-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.OperationsManagement/2015-11-01-preview/solutions) | + +## Usage examples + +The following section provides usage examples for the module, which were used to validate and deploy the module successfully. For a full reference, please review the module's test folder in its repository. + +>**Note**: Each example lists all the required parameters first, followed by the rest - each in alphabetical order. + +>**Note**: To reference the module, please use the following syntax `br/public:avm/res/operations-management/solution:`. + +- [Using only defaults](#example-1-using-only-defaults) +- [Microsoft solution](#example-2-microsoft-solution) +- [Non-Microsoft solution](#example-3-non-microsoft-solution) +- [WAF-aligned](#example-4-waf-aligned) + +### Example 1: _Using only defaults_ + +This instance deploys the module with the minimum set of required parameters. + + +
+ +via Bicep module + +```bicep +module solution 'br/public:avm/res/operations-management/solution:' = { + name: '${uniqueString(deployment().name, location)}-test-omsmin' + params: { + // Required parameters + logAnalyticsWorkspaceName: '' + name: 'Updates' + // Non-required parameters + location: '' + } +} +``` + +
+

+ +

+ +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "logAnalyticsWorkspaceName": { + "value": "" + }, + "name": { + "value": "Updates" + }, + // Non-required parameters + "location": { + "value": "" + } + } +} +``` + +
+

+ +### Example 2: _Microsoft solution_ + +This instance deploys the module with a Microsoft solution. + + +

+ +via Bicep module + +```bicep +module solution 'br/public:avm/res/operations-management/solution:' = { + name: '${uniqueString(deployment().name, location)}-test-omsms' + params: { + // Required parameters + logAnalyticsWorkspaceName: '' + name: 'AzureAutomation' + // Non-required parameters + location: '' + product: 'OMSGallery' + publisher: 'Microsoft' + } +} +``` + +
+

+ +

+ +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "logAnalyticsWorkspaceName": { + "value": "" + }, + "name": { + "value": "AzureAutomation" + }, + // Non-required parameters + "location": { + "value": "" + }, + "product": { + "value": "OMSGallery" + }, + "publisher": { + "value": "Microsoft" + } + } +} +``` + +
+

+ +### Example 3: _Non-Microsoft solution_ + +This instance deploys the module with a third party (Non-Microsoft) solution. + + +

+ +via Bicep module + +```bicep +module solution 'br/public:avm/res/operations-management/solution:' = { + name: '${uniqueString(deployment().name, location)}-test-omsnonms' + params: { + // Required parameters + logAnalyticsWorkspaceName: '' + name: 'omsnonms001' + // Non-required parameters + location: '' + product: 'nonmsTestSolutionProduct' + publisher: 'nonmsTestSolutionPublisher' + } +} +``` + +
+

+ +

+ +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "logAnalyticsWorkspaceName": { + "value": "" + }, + "name": { + "value": "omsnonms001" + }, + // Non-required parameters + "location": { + "value": "" + }, + "product": { + "value": "nonmsTestSolutionProduct" + }, + "publisher": { + "value": "nonmsTestSolutionPublisher" + } + } +} +``` + +
+

+ +### Example 4: _WAF-aligned_ + +This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework. + + +

+ +via Bicep module + +```bicep +module solution 'br/public:avm/res/operations-management/solution:' = { + name: '${uniqueString(deployment().name, location)}-test-omswaf' + params: { + // Required parameters + logAnalyticsWorkspaceName: '' + name: 'AzureAutomation' + // Non-required parameters + location: '' + product: 'OMSGallery' + publisher: 'Microsoft' + } +} +``` + +
+

+ +

+ +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "logAnalyticsWorkspaceName": { + "value": "" + }, + "name": { + "value": "AzureAutomation" + }, + // Non-required parameters + "location": { + "value": "" + }, + "product": { + "value": "OMSGallery" + }, + "publisher": { + "value": "Microsoft" + } + } +} +``` + +
+

+ + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`logAnalyticsWorkspaceName`](#parameter-loganalyticsworkspacename) | string | Name of the Log Analytics workspace where the solution will be deployed/enabled. | +| [`name`](#parameter-name) | string | Name of the solution. For Microsoft published gallery solution the target solution resource name will be composed as `{name}({logAnalyticsWorkspaceName})`. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | +| [`location`](#parameter-location) | string | Location for all resources. | +| [`product`](#parameter-product) | string | 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`](#parameter-publisher) | string | The publisher name of the deployed solution. For Microsoft published gallery solution, it is `Microsoft`. | + +### Parameter: `enableTelemetry` + +Enable/Disable usage telemetry for module. +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `location` + +Location for all resources. +- Required: No +- Type: string +- Default: `[resourceGroup().location]` + +### Parameter: `logAnalyticsWorkspaceName` + +Name of the Log Analytics workspace where the solution will be deployed/enabled. +- Required: Yes +- Type: string + +### Parameter: `name` + +Name of the solution. For Microsoft published gallery solution the target solution resource name will be composed as `{name}({logAnalyticsWorkspaceName})`. +- Required: Yes +- Type: string + +### Parameter: `product` + +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. +- Required: No +- Type: string +- Default: `'OMSGallery'` + +### Parameter: `publisher` + +The publisher name of the deployed solution. For Microsoft published gallery solution, it is `Microsoft`. +- Required: No +- Type: string +- Default: `'Microsoft'` + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `location` | string | The location the resource was deployed into. | +| `name` | string | The name of the deployed solution. | +| `resourceGroupName` | string | The resource group where the solution is deployed. | +| `resourceId` | string | The resource ID of the deployed solution. | + +## Cross-referenced modules + +_None_ diff --git a/avm/res/operations-management/solution/main.bicep b/avm/res/operations-management/solution/main.bicep new file mode 100644 index 0000000000..5b5a475ae2 --- /dev/null +++ b/avm/res/operations-management/solution/main.bicep @@ -0,0 +1,73 @@ +metadata name = 'Operations Management Solutions' +metadata description = 'This module deploys an Operations Management Solution.' +metadata owner = 'Azure/module-maintainers' + +@description('Required. Name of the solution. For Microsoft published gallery solution the target solution resource name will be composed as `{name}({logAnalyticsWorkspaceName})`.') +param name string + +@description('Required. Name of the Log Analytics workspace where the solution will be deployed/enabled.') +param logAnalyticsWorkspaceName string + +@description('Optional. Location for all resources.') +param location string = resourceGroup().location + +@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.') +param product string = 'OMSGallery' + +@description('Optional. The publisher name of the deployed solution. For Microsoft published gallery solution, it is `Microsoft`.') +param publisher string = 'Microsoft' + +@description('Optional. Enable/Disable usage telemetry for module.') +param enableTelemetry bool = true + +resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { + name: '46d3xbcp.res.operationsmanagement-solution.${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' + } + } + } + } +} + +resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2021-06-01' existing = { + name: logAnalyticsWorkspaceName +} + +var solutionName = publisher == 'Microsoft' ? '${name}(${logAnalyticsWorkspace.name})' : name + +var solutionProduct = publisher == 'Microsoft' ? 'OMSGallery/${name}' : product + +resource solution 'Microsoft.OperationsManagement/solutions@2015-11-01-preview' = { + name: solutionName + location: location + properties: { + workspaceResourceId: logAnalyticsWorkspace.id + } + plan: { + name: solutionName + promotionCode: '' + product: solutionProduct + publisher: publisher + } +} + +@description('The name of the deployed solution.') +output name string = solution.name + +@description('The resource ID of the deployed solution.') +output resourceId string = solution.id + +@description('The resource group where the solution is deployed.') +output resourceGroupName string = resourceGroup().name + +@description('The location the resource was deployed into.') +output location string = solution.location diff --git a/avm/res/operations-management/solution/main.json b/avm/res/operations-management/solution/main.json new file mode 100644 index 0000000000..3aaa024230 --- /dev/null +++ b/avm/res/operations-management/solution/main.json @@ -0,0 +1,127 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.23.1.45101", + "templateHash": "18444780972506374592" + }, + "name": "Operations Management Solutions", + "description": "This module deploys an Operations Management Solution.", + "owner": "Azure/module-maintainers" + }, + "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})`." + } + }, + "logAnalyticsWorkspaceName": { + "type": "string", + "metadata": { + "description": "Required. Name of the Log Analytics workspace where the solution will be deployed/enabled." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "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, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "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": [ + { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.operationsmanagement-solution.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('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" + } + } + } + } + }, + { + "type": "Microsoft.OperationsManagement/solutions", + "apiVersion": "2015-11-01-preview", + "name": "[variables('solutionName')]", + "location": "[parameters('location')]", + "properties": { + "workspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('logAnalyticsWorkspaceName'))]" + }, + "plan": { + "name": "[variables('solutionName')]", + "promotionCode": "", + "product": "[variables('solutionProduct')]", + "publisher": "[parameters('publisher')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed solution." + }, + "value": "[variables('solutionName')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed solution." + }, + "value": "[resourceId('Microsoft.OperationsManagement/solutions', variables('solutionName'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group where the solution is deployed." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference(resourceId('Microsoft.OperationsManagement/solutions', variables('solutionName')), '2015-11-01-preview', 'full').location]" + } + } +} \ No newline at end of file diff --git a/avm/res/operations-management/solution/tests/e2e/defaults/dependencies.bicep b/avm/res/operations-management/solution/tests/e2e/defaults/dependencies.bicep new file mode 100644 index 0000000000..ef3592fb5f --- /dev/null +++ b/avm/res/operations-management/solution/tests/e2e/defaults/dependencies.bicep @@ -0,0 +1,13 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Log Analytics Workspace to create.') +param logAnalyticsWorkspaceName string + +resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2021-06-01' = { + name: logAnalyticsWorkspaceName + location: location +} + +@description('The name of the created Log Analytics Workspace.') +output logAnalyticsWorkspaceName string = logAnalytics.name diff --git a/avm/res/operations-management/solution/tests/e2e/defaults/main.test.bicep b/avm/res/operations-management/solution/tests/e2e/defaults/main.test.bicep new file mode 100644 index 0000000000..937829c24f --- /dev/null +++ b/avm/res/operations-management/solution/tests/e2e/defaults/main.test.bicep @@ -0,0 +1,55 @@ +targetScope = 'subscription' + +metadata name = 'Using only defaults' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-operationsmanagement.solutions-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param location string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'omsmin' + +@description('Optional. A token to inject into the name of each resource. This value can be automatically injected by the CI.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: location +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-nestedDependencies' + params: { + logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' + location: location + } +} + +// ============== // +// Test Execution // +// ============== // + +module testDeployment '../../../main.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}' + params: { + name: 'Updates' + location: location + logAnalyticsWorkspaceName: nestedDependencies.outputs.logAnalyticsWorkspaceName + } +} diff --git a/avm/res/operations-management/solution/tests/e2e/ms/dependencies.bicep b/avm/res/operations-management/solution/tests/e2e/ms/dependencies.bicep new file mode 100644 index 0000000000..ef3592fb5f --- /dev/null +++ b/avm/res/operations-management/solution/tests/e2e/ms/dependencies.bicep @@ -0,0 +1,13 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Log Analytics Workspace to create.') +param logAnalyticsWorkspaceName string + +resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2021-06-01' = { + name: logAnalyticsWorkspaceName + location: location +} + +@description('The name of the created Log Analytics Workspace.') +output logAnalyticsWorkspaceName string = logAnalytics.name diff --git a/avm/res/operations-management/solution/tests/e2e/ms/main.test.bicep b/avm/res/operations-management/solution/tests/e2e/ms/main.test.bicep new file mode 100644 index 0000000000..aa5fbbde0b --- /dev/null +++ b/avm/res/operations-management/solution/tests/e2e/ms/main.test.bicep @@ -0,0 +1,57 @@ +targetScope = 'subscription' + +metadata name = 'Microsoft solution' +metadata description = 'This instance deploys the module with a Microsoft solution.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-operationsmanagement.solutions-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param location string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'omsms' + +@description('Optional. A token to inject into the name of each resource. This value can be automatically injected by the CI.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: location +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-nestedDependencies' + params: { + logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' + location: location + } +} + +// ============== // +// Test Execution // +// ============== // + +module testDeployment '../../../main.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}' + params: { + name: 'AzureAutomation' + location: location + logAnalyticsWorkspaceName: nestedDependencies.outputs.logAnalyticsWorkspaceName + product: 'OMSGallery' + publisher: 'Microsoft' + } +} diff --git a/avm/res/operations-management/solution/tests/e2e/nonms/dependencies.bicep b/avm/res/operations-management/solution/tests/e2e/nonms/dependencies.bicep new file mode 100644 index 0000000000..ef3592fb5f --- /dev/null +++ b/avm/res/operations-management/solution/tests/e2e/nonms/dependencies.bicep @@ -0,0 +1,13 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Log Analytics Workspace to create.') +param logAnalyticsWorkspaceName string + +resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2021-06-01' = { + name: logAnalyticsWorkspaceName + location: location +} + +@description('The name of the created Log Analytics Workspace.') +output logAnalyticsWorkspaceName string = logAnalytics.name diff --git a/avm/res/operations-management/solution/tests/e2e/nonms/main.test.bicep b/avm/res/operations-management/solution/tests/e2e/nonms/main.test.bicep new file mode 100644 index 0000000000..2153dc3d75 --- /dev/null +++ b/avm/res/operations-management/solution/tests/e2e/nonms/main.test.bicep @@ -0,0 +1,57 @@ +targetScope = 'subscription' + +metadata name = 'Non-Microsoft solution' +metadata description = 'This instance deploys the module with a third party (Non-Microsoft) solution.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-operationsmanagement.solutions-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param location string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'omsnonms' + +@description('Optional. A token to inject into the name of each resource. This value can be automatically injected by the CI.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: location +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-nestedDependencies' + params: { + logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' + location: location + } +} + +// ============== // +// Test Execution // +// ============== // + +module testDeployment '../../../main.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}' + params: { + name: '${namePrefix}${serviceShort}001' + location: location + logAnalyticsWorkspaceName: nestedDependencies.outputs.logAnalyticsWorkspaceName + product: 'nonmsTestSolutionProduct' + publisher: 'nonmsTestSolutionPublisher' + } +} diff --git a/avm/res/operations-management/solution/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/operations-management/solution/tests/e2e/waf-aligned/dependencies.bicep new file mode 100644 index 0000000000..ef3592fb5f --- /dev/null +++ b/avm/res/operations-management/solution/tests/e2e/waf-aligned/dependencies.bicep @@ -0,0 +1,13 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Log Analytics Workspace to create.') +param logAnalyticsWorkspaceName string + +resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2021-06-01' = { + name: logAnalyticsWorkspaceName + location: location +} + +@description('The name of the created Log Analytics Workspace.') +output logAnalyticsWorkspaceName string = logAnalytics.name diff --git a/avm/res/operations-management/solution/tests/e2e/waf-aligned/main.test.bicep b/avm/res/operations-management/solution/tests/e2e/waf-aligned/main.test.bicep new file mode 100644 index 0000000000..9e7f561694 --- /dev/null +++ b/avm/res/operations-management/solution/tests/e2e/waf-aligned/main.test.bicep @@ -0,0 +1,58 @@ +targetScope = 'subscription' + +metadata name = 'WAF-aligned' +metadata description = 'This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-operationsmanagement.solutions-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param location string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'omswaf' + +@description('Optional. A token to inject into the name of each resource. This value can be automatically injected by the CI.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: location +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-nestedDependencies' + params: { + logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' + location: location + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' + params: { + name: 'AzureAutomation' + location: location + logAnalyticsWorkspaceName: nestedDependencies.outputs.logAnalyticsWorkspaceName + product: 'OMSGallery' + publisher: 'Microsoft' + } +}] diff --git a/avm/res/operations-management/solution/version.json b/avm/res/operations-management/solution/version.json new file mode 100644 index 0000000000..83083db694 --- /dev/null +++ b/avm/res/operations-management/solution/version.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.1", + "pathFilters": [ + "./main.json" + ] +} \ No newline at end of file