From 0f5cc4532f7520c9f943fbe8b9d08d86c6d58cd6 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Wed, 6 Dec 2023 10:31:11 +0100 Subject: [PATCH 01/96] uncomment VM in code owners file --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 78390b5d90..b35e987043 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -28,7 +28,7 @@ #/avm/res/compute/image/ @Azure/avm-res-compute-image-module-owners-bicep @Azure/avm-core-team-technical-bicep #/avm/res/compute/proximity-placement-group/ @Azure/avm-res-compute-proximityplacementgroup-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/compute/ssh-public-key/ @Azure/avm-res-compute-sshpublickey-module-owners-bicep @Azure/avm-core-team-technical-bicep -#/avm/res/compute/virtual-machine/ @Azure/avm-res-compute-virtualmachine-module-owners-bicep @Azure/avm-core-team-technical-bicep +/avm/res/compute/virtual-machine/ @Azure/avm-res-compute-virtualmachine-module-owners-bicep @Azure/avm-core-team-technical-bicep #/avm/res/compute/virtual-machine-scale-set/ @Azure/avm-res-compute-virtualmachinescaleset-module-owners-bicep @Azure/avm-core-team-technical-bicep #/avm/res/consumption/budget/ @Azure/avm-res-consumption-budget-module-owners-bicep @Azure/avm-core-team-technical-bicep #/avm/res/container-instance/container-group/ @Azure/avm-res-containerinstance-containergroup-module-owners-bicep @Azure/avm-core-team-technical-bicep From dc3a4e027f83e1447bb66d1f3ad4ff67a1900980 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Wed, 6 Dec 2023 10:33:13 +0100 Subject: [PATCH 02/96] initial import of CARML module --- modules/compute/virtual-machine/README.md | 3552 +++++++++++++ .../virtual-machine/extension/README.md | 165 + .../virtual-machine/extension/main.bicep | 92 + .../virtual-machine/extension/main.json | 181 + .../virtual-machine/extension/version.json | 7 + modules/compute/virtual-machine/main.bicep | 771 +++ modules/compute/virtual-machine/main.json | 4524 +++++++++++++++++ .../modules/nested_networkInterface.bicep | 147 + .../tests/e2e/linux.atmg/dependencies.bicep | 86 + .../tests/e2e/linux.atmg/main.test.bicep | 123 + .../tests/e2e/linux.min/dependencies.bicep | 86 + .../tests/e2e/linux.min/main.test.bicep | 102 + .../tests/e2e/linux/dependencies.bicep | 337 ++ .../tests/e2e/linux/main.test.bicep | 314 ++ .../tests/e2e/windows.atmg/dependencies.bicep | 30 + .../tests/e2e/windows.atmg/main.test.bicep | 92 + .../tests/e2e/windows.min/dependencies.bicep | 30 + .../tests/e2e/windows.min/main.test.bicep | 85 + .../e2e/windows.ssecmk/dependencies.bicep | 92 + .../tests/e2e/windows.ssecmk/main.test.bicep | 110 + .../tests/e2e/windows/dependencies.bicep | 310 ++ .../tests/e2e/windows/main.test.bicep | 332 ++ modules/compute/virtual-machine/version.json | 7 + 23 files changed, 11575 insertions(+) create mode 100644 modules/compute/virtual-machine/README.md create mode 100644 modules/compute/virtual-machine/extension/README.md create mode 100644 modules/compute/virtual-machine/extension/main.bicep create mode 100644 modules/compute/virtual-machine/extension/main.json create mode 100644 modules/compute/virtual-machine/extension/version.json create mode 100644 modules/compute/virtual-machine/main.bicep create mode 100644 modules/compute/virtual-machine/main.json create mode 100644 modules/compute/virtual-machine/modules/nested_networkInterface.bicep create mode 100644 modules/compute/virtual-machine/tests/e2e/linux.atmg/dependencies.bicep create mode 100644 modules/compute/virtual-machine/tests/e2e/linux.atmg/main.test.bicep create mode 100644 modules/compute/virtual-machine/tests/e2e/linux.min/dependencies.bicep create mode 100644 modules/compute/virtual-machine/tests/e2e/linux.min/main.test.bicep create mode 100644 modules/compute/virtual-machine/tests/e2e/linux/dependencies.bicep create mode 100644 modules/compute/virtual-machine/tests/e2e/linux/main.test.bicep create mode 100644 modules/compute/virtual-machine/tests/e2e/windows.atmg/dependencies.bicep create mode 100644 modules/compute/virtual-machine/tests/e2e/windows.atmg/main.test.bicep create mode 100644 modules/compute/virtual-machine/tests/e2e/windows.min/dependencies.bicep create mode 100644 modules/compute/virtual-machine/tests/e2e/windows.min/main.test.bicep create mode 100644 modules/compute/virtual-machine/tests/e2e/windows.ssecmk/dependencies.bicep create mode 100644 modules/compute/virtual-machine/tests/e2e/windows.ssecmk/main.test.bicep create mode 100644 modules/compute/virtual-machine/tests/e2e/windows/dependencies.bicep create mode 100644 modules/compute/virtual-machine/tests/e2e/windows/main.test.bicep create mode 100644 modules/compute/virtual-machine/version.json diff --git a/modules/compute/virtual-machine/README.md b/modules/compute/virtual-machine/README.md new file mode 100644 index 0000000000..b92ce4549a --- /dev/null +++ b/modules/compute/virtual-machine/README.md @@ -0,0 +1,3552 @@ +# Virtual Machines `[Microsoft.Compute/virtualMachines]` + +This module deploys a Virtual Machine with one or multiple NICs and optionally one or multiple public IPs. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Usage examples](#Usage-examples) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Notes](#Notes) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | +| `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | +| `Microsoft.Automanage/configurationProfileAssignments` | [2021-04-30-preview](https://learn.microsoft.com/en-us/azure/templates) | +| `Microsoft.Compute/virtualMachines` | [2022-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Compute/2022-11-01/virtualMachines) | +| `Microsoft.Compute/virtualMachines/extensions` | [2022-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Compute/2022-11-01/virtualMachines/extensions) | +| `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | +| `Microsoft.Network/networkInterfaces` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/networkInterfaces) | +| `Microsoft.Network/publicIPAddresses` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/publicIPAddresses) | +| `Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems` | [2023-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.RecoveryServices/2023-01-01/vaults/backupFabrics/protectionContainers/protectedItems) | + +## 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:bicep/modules/compute.virtual-machine:1.0.0`. + +- [Linux.Atmg](#example-1-linuxatmg) +- [Linux.Min](#example-2-linuxmin) +- [Linux](#example-3-linux) +- [Windows.Atmg](#example-4-windowsatmg) +- [Windows.Min](#example-5-windowsmin) +- [Windows.Ssecmk](#example-6-windowsssecmk) +- [Windows](#example-7-windows) + +### Example 1: _Linux.Atmg_ + +
+ +via Bicep module + +```bicep +module virtualMachine 'br:bicep/modules/compute.virtual-machine:1.0.0' = { + name: '${uniqueString(deployment().name, location)}-test-cvmlinatmg' + params: { + // Required parameters + adminUsername: 'localAdminUser' + imageReference: { + offer: '0001-com-ubuntu-server-jammy' + publisher: 'Canonical' + sku: '22_04-lts-gen2' + version: 'latest' + } + nicConfigurations: [ + { + ipConfigurations: [ + { + name: 'ipconfig01' + pipConfiguration: { + publicIpNameSuffix: '-pip-01' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + subnetResourceId: '' + zones: [ + '1' + '2' + '3' + ] + } + ] + nicSuffix: '-nic-01' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + ] + osDisk: { + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + osType: 'Linux' + vmSize: 'Standard_DS2_v2' + // Non-required parameters + configurationProfile: '/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesProduction' + disablePasswordAuthentication: true + enableDefaultTelemetry: '' + location: '' + name: 'cvmlinatmg' + publicKeys: [ + { + keyData: '' + path: '/home/localAdminUser/.ssh/authorized_keys' + } + ] + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } +} +``` + +
+

+ +

+ +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 + "adminUsername": { + "value": "localAdminUser" + }, + "imageReference": { + "value": { + "offer": "0001-com-ubuntu-server-jammy", + "publisher": "Canonical", + "sku": "22_04-lts-gen2", + "version": "latest" + } + }, + "nicConfigurations": { + "value": [ + { + "ipConfigurations": [ + { + "name": "ipconfig01", + "pipConfiguration": { + "publicIpNameSuffix": "-pip-01", + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + }, + "subnetResourceId": "", + "zones": [ + "1", + "2", + "3" + ] + } + ], + "nicSuffix": "-nic-01", + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + ] + }, + "osDisk": { + "value": { + "diskSizeGB": "128", + "managedDisk": { + "storageAccountType": "Premium_LRS" + } + } + }, + "osType": { + "value": "Linux" + }, + "vmSize": { + "value": "Standard_DS2_v2" + }, + // Non-required parameters + "configurationProfile": { + "value": "/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesProduction" + }, + "disablePasswordAuthentication": { + "value": true + }, + "enableDefaultTelemetry": { + "value": "" + }, + "location": { + "value": "" + }, + "name": { + "value": "cvmlinatmg" + }, + "publicKeys": { + "value": [ + { + "keyData": "", + "path": "/home/localAdminUser/.ssh/authorized_keys" + } + ] + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + } +} +``` + +
+

+ +### Example 2: _Linux.Min_ + +

+ +via Bicep module + +```bicep +module virtualMachine 'br:bicep/modules/compute.virtual-machine:1.0.0' = { + name: '${uniqueString(deployment().name, location)}-test-cvmlinmin' + params: { + // Required parameters + adminUsername: 'localAdminUser' + imageReference: { + offer: '0001-com-ubuntu-server-jammy' + publisher: 'Canonical' + sku: '22_04-lts-gen2' + version: 'latest' + } + nicConfigurations: [ + { + ipConfigurations: [ + { + name: 'ipconfig01' + pipConfiguration: { + publicIpNameSuffix: '-pip-01' + } + subnetResourceId: '' + } + ] + nicSuffix: '-nic-01' + } + ] + osDisk: { + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + osType: 'Linux' + vmSize: 'Standard_DS2_v2' + // Non-required parameters + disablePasswordAuthentication: true + enableDefaultTelemetry: '' + location: '' + name: 'cvmlinmin' + publicKeys: [ + { + keyData: '' + path: '/home/localAdminUser/.ssh/authorized_keys' + } + ] + } +} +``` + +
+

+ +

+ +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 + "adminUsername": { + "value": "localAdminUser" + }, + "imageReference": { + "value": { + "offer": "0001-com-ubuntu-server-jammy", + "publisher": "Canonical", + "sku": "22_04-lts-gen2", + "version": "latest" + } + }, + "nicConfigurations": { + "value": [ + { + "ipConfigurations": [ + { + "name": "ipconfig01", + "pipConfiguration": { + "publicIpNameSuffix": "-pip-01" + }, + "subnetResourceId": "" + } + ], + "nicSuffix": "-nic-01" + } + ] + }, + "osDisk": { + "value": { + "diskSizeGB": "128", + "managedDisk": { + "storageAccountType": "Premium_LRS" + } + } + }, + "osType": { + "value": "Linux" + }, + "vmSize": { + "value": "Standard_DS2_v2" + }, + // Non-required parameters + "disablePasswordAuthentication": { + "value": true + }, + "enableDefaultTelemetry": { + "value": "" + }, + "location": { + "value": "" + }, + "name": { + "value": "cvmlinmin" + }, + "publicKeys": { + "value": [ + { + "keyData": "", + "path": "/home/localAdminUser/.ssh/authorized_keys" + } + ] + } + } +} +``` + +
+

+ +### Example 3: _Linux_ + +

+ +via Bicep module + +```bicep +module virtualMachine 'br:bicep/modules/compute.virtual-machine:1.0.0' = { + name: '${uniqueString(deployment().name, location)}-test-cvmlincom' + params: { + // Required parameters + adminUsername: 'localAdministrator' + imageReference: { + offer: '0001-com-ubuntu-server-focal' + publisher: 'Canonical' + sku: '' + version: 'latest' + } + nicConfigurations: [ + { + deleteOption: 'Delete' + diagnosticSettings: [ + { + eventHubAuthorizationRuleResourceId: '' + eventHubName: '' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + name: 'customSetting' + storageAccountResourceId: '' + workspaceResourceId: '' + } + ] + ipConfigurations: [ + { + applicationSecurityGroups: [ + { + id: '' + } + ] + diagnosticSettings: [ + { + eventHubAuthorizationRuleResourceId: '' + eventHubName: '' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + name: 'customSetting' + storageAccountResourceId: '' + workspaceResourceId: '' + } + ] + loadBalancerBackendAddressPools: [ + { + id: '' + } + ] + name: 'ipconfig01' + pipConfiguration: { + publicIpNameSuffix: '-pip-01' + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Reader' + } + ] + } + subnetResourceId: '' + zones: [ + '1' + '2' + '3' + ] + } + ] + nicSuffix: '-nic-01' + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Reader' + } + ] + } + ] + osDisk: { + caching: 'ReadOnly' + createOption: 'fromImage' + deleteOption: 'Delete' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + osType: 'Linux' + vmSize: 'Standard_DS2_v2' + // Non-required parameters + availabilityZone: 1 + backupPolicyName: '' + backupVaultName: '' + backupVaultResourceGroup: '' + computerName: 'linvm1' + dataDisks: [ + { + caching: 'ReadWrite' + createOption: 'Empty' + deleteOption: 'Delete' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + { + caching: 'ReadWrite' + createOption: 'Empty' + deleteOption: 'Delete' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + ] + disablePasswordAuthentication: true + enableAutomaticUpdates: true + enableDefaultTelemetry: '' + encryptionAtHost: false + extensionAadJoinConfig: { + enabled: true + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionAzureDiskEncryptionConfig: { + enabled: true + settings: { + EncryptionOperation: 'EnableEncryption' + KekVaultResourceId: '' + KeyEncryptionAlgorithm: 'RSA-OAEP' + KeyEncryptionKeyURL: '' + KeyVaultResourceId: '' + KeyVaultURL: '' + ResizeOSDisk: 'false' + VolumeType: 'All' + } + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionCustomScriptConfig: { + enabled: true + fileData: [ + { + storageAccountId: '' + uri: '' + } + ] + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionCustomScriptProtectedSetting: { + commandToExecute: '' + } + extensionDependencyAgentConfig: { + enabled: true + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionDSCConfig: { + enabled: false + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionMonitoringAgentConfig: { + enabled: true + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionNetworkWatcherAgentConfig: { + enabled: true + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + location: '' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + '' + ] + } + monitoringWorkspaceId: '' + name: 'cvmlincom' + patchMode: 'AutomaticByPlatform' + publicKeys: [ + { + keyData: '' + path: '/home/localAdministrator/.ssh/authorized_keys' + } + ] + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Owner' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: '' + } + ] + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } +} +``` + +
+

+ +

+ +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 + "adminUsername": { + "value": "localAdministrator" + }, + "imageReference": { + "value": { + "offer": "0001-com-ubuntu-server-focal", + "publisher": "Canonical", + "sku": "", + "version": "latest" + } + }, + "nicConfigurations": { + "value": [ + { + "deleteOption": "Delete", + "diagnosticSettings": [ + { + "eventHubAuthorizationRuleResourceId": "", + "eventHubName": "", + "metricCategories": [ + { + "category": "AllMetrics" + } + ], + "name": "customSetting", + "storageAccountResourceId": "", + "workspaceResourceId": "" + } + ], + "ipConfigurations": [ + { + "applicationSecurityGroups": [ + { + "id": "" + } + ], + "diagnosticSettings": [ + { + "eventHubAuthorizationRuleResourceId": "", + "eventHubName": "", + "metricCategories": [ + { + "category": "AllMetrics" + } + ], + "name": "customSetting", + "storageAccountResourceId": "", + "workspaceResourceId": "" + } + ], + "loadBalancerBackendAddressPools": [ + { + "id": "" + } + ], + "name": "ipconfig01", + "pipConfiguration": { + "publicIpNameSuffix": "-pip-01", + "roleAssignments": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Reader" + } + ] + }, + "subnetResourceId": "", + "zones": [ + "1", + "2", + "3" + ] + } + ], + "nicSuffix": "-nic-01", + "roleAssignments": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Reader" + } + ] + } + ] + }, + "osDisk": { + "value": { + "caching": "ReadOnly", + "createOption": "fromImage", + "deleteOption": "Delete", + "diskSizeGB": "128", + "managedDisk": { + "storageAccountType": "Premium_LRS" + } + } + }, + "osType": { + "value": "Linux" + }, + "vmSize": { + "value": "Standard_DS2_v2" + }, + // Non-required parameters + "availabilityZone": { + "value": 1 + }, + "backupPolicyName": { + "value": "" + }, + "backupVaultName": { + "value": "" + }, + "backupVaultResourceGroup": { + "value": "" + }, + "computerName": { + "value": "linvm1" + }, + "dataDisks": { + "value": [ + { + "caching": "ReadWrite", + "createOption": "Empty", + "deleteOption": "Delete", + "diskSizeGB": "128", + "managedDisk": { + "storageAccountType": "Premium_LRS" + } + }, + { + "caching": "ReadWrite", + "createOption": "Empty", + "deleteOption": "Delete", + "diskSizeGB": "128", + "managedDisk": { + "storageAccountType": "Premium_LRS" + } + } + ] + }, + "disablePasswordAuthentication": { + "value": true + }, + "enableAutomaticUpdates": { + "value": true + }, + "enableDefaultTelemetry": { + "value": "" + }, + "encryptionAtHost": { + "value": false + }, + "extensionAadJoinConfig": { + "value": { + "enabled": true, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionAzureDiskEncryptionConfig": { + "value": { + "enabled": true, + "settings": { + "EncryptionOperation": "EnableEncryption", + "KekVaultResourceId": "", + "KeyEncryptionAlgorithm": "RSA-OAEP", + "KeyEncryptionKeyURL": "", + "KeyVaultResourceId": "", + "KeyVaultURL": "", + "ResizeOSDisk": "false", + "VolumeType": "All" + }, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionCustomScriptConfig": { + "value": { + "enabled": true, + "fileData": [ + { + "storageAccountId": "", + "uri": "" + } + ], + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionCustomScriptProtectedSetting": { + "value": { + "commandToExecute": "" + } + }, + "extensionDependencyAgentConfig": { + "value": { + "enabled": true, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionDSCConfig": { + "value": { + "enabled": false, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionMonitoringAgentConfig": { + "value": { + "enabled": true, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionNetworkWatcherAgentConfig": { + "value": { + "enabled": true, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "location": { + "value": "" + }, + "lock": { + "value": { + "kind": "CanNotDelete", + "name": "myCustomLockName" + } + }, + "managedIdentities": { + "value": { + "systemAssigned": true, + "userAssignedResourceIds": [ + "" + ] + } + }, + "monitoringWorkspaceId": { + "value": "" + }, + "name": { + "value": "cvmlincom" + }, + "patchMode": { + "value": "AutomaticByPlatform" + }, + "publicKeys": { + "value": [ + { + "keyData": "", + "path": "/home/localAdministrator/.ssh/authorized_keys" + } + ] + }, + "roleAssignments": { + "value": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Owner" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "" + } + ] + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + } +} +``` + +
+

+ +### Example 4: _Windows.Atmg_ + +

+ +via Bicep module + +```bicep +module virtualMachine 'br:bicep/modules/compute.virtual-machine:1.0.0' = { + name: '${uniqueString(deployment().name, location)}-test-cvmwinatmg' + params: { + // Required parameters + adminUsername: 'localAdministrator' + imageReference: { + offer: 'WindowsServer' + publisher: 'MicrosoftWindowsServer' + sku: '2022-datacenter-azure-edition' + version: 'latest' + } + nicConfigurations: [ + { + ipConfigurations: [ + { + name: 'ipconfig01' + subnetResourceId: '' + } + ] + nicSuffix: '-nic-01' + } + ] + osDisk: { + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + osType: 'Windows' + vmSize: 'Standard_DS2_v2' + // Non-required parameters + adminPassword: '' + configurationProfile: '/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesProduction' + enableDefaultTelemetry: '' + location: '' + name: 'cvmwinatmg' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } +} +``` + +
+

+ +

+ +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 + "adminUsername": { + "value": "localAdministrator" + }, + "imageReference": { + "value": { + "offer": "WindowsServer", + "publisher": "MicrosoftWindowsServer", + "sku": "2022-datacenter-azure-edition", + "version": "latest" + } + }, + "nicConfigurations": { + "value": [ + { + "ipConfigurations": [ + { + "name": "ipconfig01", + "subnetResourceId": "" + } + ], + "nicSuffix": "-nic-01" + } + ] + }, + "osDisk": { + "value": { + "diskSizeGB": "128", + "managedDisk": { + "storageAccountType": "Premium_LRS" + } + } + }, + "osType": { + "value": "Windows" + }, + "vmSize": { + "value": "Standard_DS2_v2" + }, + // Non-required parameters + "adminPassword": { + "value": "" + }, + "configurationProfile": { + "value": "/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesProduction" + }, + "enableDefaultTelemetry": { + "value": "" + }, + "location": { + "value": "" + }, + "name": { + "value": "cvmwinatmg" + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + } +} +``` + +
+

+ +### Example 5: _Windows.Min_ + +

+ +via Bicep module + +```bicep +module virtualMachine 'br:bicep/modules/compute.virtual-machine:1.0.0' = { + name: '${uniqueString(deployment().name, location)}-test-cvmwinmin' + params: { + // Required parameters + adminUsername: 'localAdminUser' + imageReference: { + offer: 'WindowsServer' + publisher: 'MicrosoftWindowsServer' + sku: '2022-datacenter-azure-edition' + version: 'latest' + } + nicConfigurations: [ + { + ipConfigurations: [ + { + name: 'ipconfig01' + subnetResourceId: '' + } + ] + nicSuffix: '-nic-01' + } + ] + osDisk: { + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + osType: 'Windows' + vmSize: 'Standard_DS2_v2' + // Non-required parameters + adminPassword: '' + enableDefaultTelemetry: '' + location: '' + name: 'cvmwinmin' + } +} +``` + +
+

+ +

+ +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 + "adminUsername": { + "value": "localAdminUser" + }, + "imageReference": { + "value": { + "offer": "WindowsServer", + "publisher": "MicrosoftWindowsServer", + "sku": "2022-datacenter-azure-edition", + "version": "latest" + } + }, + "nicConfigurations": { + "value": [ + { + "ipConfigurations": [ + { + "name": "ipconfig01", + "subnetResourceId": "" + } + ], + "nicSuffix": "-nic-01" + } + ] + }, + "osDisk": { + "value": { + "diskSizeGB": "128", + "managedDisk": { + "storageAccountType": "Premium_LRS" + } + } + }, + "osType": { + "value": "Windows" + }, + "vmSize": { + "value": "Standard_DS2_v2" + }, + // Non-required parameters + "adminPassword": { + "value": "" + }, + "enableDefaultTelemetry": { + "value": "" + }, + "location": { + "value": "" + }, + "name": { + "value": "cvmwinmin" + } + } +} +``` + +
+

+ +### Example 6: _Windows.Ssecmk_ + +

+ +via Bicep module + +```bicep +module virtualMachine 'br:bicep/modules/compute.virtual-machine:1.0.0' = { + name: '${uniqueString(deployment().name, location)}-test-cvmwincmk' + params: { + // Required parameters + adminUsername: 'VMAdministrator' + imageReference: { + offer: 'WindowsServer' + publisher: 'MicrosoftWindowsServer' + sku: '2019-datacenter' + version: 'latest' + } + nicConfigurations: [ + { + ipConfigurations: [ + { + name: 'ipconfig01' + subnetResourceId: '' + } + ] + nicSuffix: '-nic-01' + } + ] + osDisk: { + diskSizeGB: '128' + managedDisk: { + diskEncryptionSet: { + id: '' + } + storageAccountType: 'Premium_LRS' + } + } + osType: 'Windows' + vmSize: 'Standard_DS2_v2' + // Non-required parameters + adminPassword: '' + dataDisks: [ + { + diskSizeGB: '128' + managedDisk: { + diskEncryptionSet: { + id: '' + } + storageAccountType: 'Premium_LRS' + } + } + ] + enableDefaultTelemetry: '' + location: '' + name: 'cvmwincmk' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } +} +``` + +
+

+ +

+ +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 + "adminUsername": { + "value": "VMAdministrator" + }, + "imageReference": { + "value": { + "offer": "WindowsServer", + "publisher": "MicrosoftWindowsServer", + "sku": "2019-datacenter", + "version": "latest" + } + }, + "nicConfigurations": { + "value": [ + { + "ipConfigurations": [ + { + "name": "ipconfig01", + "subnetResourceId": "" + } + ], + "nicSuffix": "-nic-01" + } + ] + }, + "osDisk": { + "value": { + "diskSizeGB": "128", + "managedDisk": { + "diskEncryptionSet": { + "id": "" + }, + "storageAccountType": "Premium_LRS" + } + } + }, + "osType": { + "value": "Windows" + }, + "vmSize": { + "value": "Standard_DS2_v2" + }, + // Non-required parameters + "adminPassword": { + "value": "" + }, + "dataDisks": { + "value": [ + { + "diskSizeGB": "128", + "managedDisk": { + "diskEncryptionSet": { + "id": "" + }, + "storageAccountType": "Premium_LRS" + } + } + ] + }, + "enableDefaultTelemetry": { + "value": "" + }, + "location": { + "value": "" + }, + "name": { + "value": "cvmwincmk" + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + } +} +``` + +
+

+ +### Example 7: _Windows_ + +

+ +via Bicep module + +```bicep +module virtualMachine 'br:bicep/modules/compute.virtual-machine:1.0.0' = { + name: '${uniqueString(deployment().name, location)}-test-cvmwincom' + params: { + // Required parameters + adminUsername: 'VMAdmin' + imageReference: { + offer: 'WindowsServer' + publisher: 'MicrosoftWindowsServer' + sku: '2019-datacenter' + version: 'latest' + } + nicConfigurations: [ + { + deleteOption: 'Delete' + diagnosticSettings: [ + { + eventHubAuthorizationRuleResourceId: '' + eventHubName: '' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + name: 'customSetting' + storageAccountResourceId: '' + workspaceResourceId: '' + } + ] + ipConfigurations: [ + { + applicationSecurityGroups: [ + { + id: '' + } + ] + diagnosticSettings: [ + { + eventHubAuthorizationRuleResourceId: '' + eventHubName: '' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + name: 'customSetting' + storageAccountResourceId: '' + workspaceResourceId: '' + } + ] + loadBalancerBackendAddressPools: [ + { + id: '' + } + ] + name: 'ipconfig01' + pipConfiguration: { + publicIpNameSuffix: '-pip-01' + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Reader' + } + ] + } + subnetResourceId: '' + zones: [ + '1' + '2' + '3' + ] + } + ] + nicSuffix: '-nic-01' + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Reader' + } + ] + } + ] + osDisk: { + caching: 'None' + createOption: 'fromImage' + deleteOption: 'Delete' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + osType: 'Windows' + vmSize: 'Standard_DS2_v2' + // Non-required parameters + adminPassword: '' + availabilityZone: 2 + backupPolicyName: '' + backupVaultName: '' + backupVaultResourceGroup: '' + computerName: 'winvm1' + dataDisks: [ + { + caching: 'None' + createOption: 'Empty' + deleteOption: 'Delete' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + { + caching: 'None' + createOption: 'Empty' + deleteOption: 'Delete' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + ] + enableAutomaticUpdates: true + enableDefaultTelemetry: '' + encryptionAtHost: false + extensionAadJoinConfig: { + enabled: true + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionAntiMalwareConfig: { + enabled: true + settings: { + AntimalwareEnabled: 'true' + Exclusions: { + Extensions: '.ext1;.ext2' + Paths: 'c:\\excluded-path-1;c:\\excluded-path-2' + Processes: 'excludedproc1.exe;excludedproc2.exe' + } + RealtimeProtectionEnabled: 'true' + ScheduledScanSettings: { + day: '7' + isEnabled: 'true' + scanType: 'Quick' + time: '120' + } + } + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionAzureDiskEncryptionConfig: { + enabled: true + settings: { + EncryptionOperation: 'EnableEncryption' + KekVaultResourceId: '' + KeyEncryptionAlgorithm: 'RSA-OAEP' + KeyEncryptionKeyURL: '' + KeyVaultResourceId: '' + KeyVaultURL: '' + ResizeOSDisk: 'false' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + VolumeType: 'All' + } + } + extensionCustomScriptConfig: { + enabled: true + fileData: [ + { + storageAccountId: '' + uri: '' + } + ] + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionCustomScriptProtectedSetting: { + commandToExecute: '' + } + extensionDependencyAgentConfig: { + enabled: true + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionDSCConfig: { + enabled: true + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionMonitoringAgentConfig: { + enabled: true + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionNetworkWatcherAgentConfig: { + enabled: true + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + location: '' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + '' + ] + } + monitoringWorkspaceId: '' + name: 'cvmwincom' + patchMode: 'AutomaticByPlatform' + proximityPlacementGroupResourceId: '' + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Owner' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: '' + } + ] + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } +} +``` + +
+

+ +

+ +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 + "adminUsername": { + "value": "VMAdmin" + }, + "imageReference": { + "value": { + "offer": "WindowsServer", + "publisher": "MicrosoftWindowsServer", + "sku": "2019-datacenter", + "version": "latest" + } + }, + "nicConfigurations": { + "value": [ + { + "deleteOption": "Delete", + "diagnosticSettings": [ + { + "eventHubAuthorizationRuleResourceId": "", + "eventHubName": "", + "metricCategories": [ + { + "category": "AllMetrics" + } + ], + "name": "customSetting", + "storageAccountResourceId": "", + "workspaceResourceId": "" + } + ], + "ipConfigurations": [ + { + "applicationSecurityGroups": [ + { + "id": "" + } + ], + "diagnosticSettings": [ + { + "eventHubAuthorizationRuleResourceId": "", + "eventHubName": "", + "metricCategories": [ + { + "category": "AllMetrics" + } + ], + "name": "customSetting", + "storageAccountResourceId": "", + "workspaceResourceId": "" + } + ], + "loadBalancerBackendAddressPools": [ + { + "id": "" + } + ], + "name": "ipconfig01", + "pipConfiguration": { + "publicIpNameSuffix": "-pip-01", + "roleAssignments": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Reader" + } + ] + }, + "subnetResourceId": "", + "zones": [ + "1", + "2", + "3" + ] + } + ], + "nicSuffix": "-nic-01", + "roleAssignments": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Reader" + } + ] + } + ] + }, + "osDisk": { + "value": { + "caching": "None", + "createOption": "fromImage", + "deleteOption": "Delete", + "diskSizeGB": "128", + "managedDisk": { + "storageAccountType": "Premium_LRS" + } + } + }, + "osType": { + "value": "Windows" + }, + "vmSize": { + "value": "Standard_DS2_v2" + }, + // Non-required parameters + "adminPassword": { + "value": "" + }, + "availabilityZone": { + "value": 2 + }, + "backupPolicyName": { + "value": "" + }, + "backupVaultName": { + "value": "" + }, + "backupVaultResourceGroup": { + "value": "" + }, + "computerName": { + "value": "winvm1" + }, + "dataDisks": { + "value": [ + { + "caching": "None", + "createOption": "Empty", + "deleteOption": "Delete", + "diskSizeGB": "128", + "managedDisk": { + "storageAccountType": "Premium_LRS" + } + }, + { + "caching": "None", + "createOption": "Empty", + "deleteOption": "Delete", + "diskSizeGB": "128", + "managedDisk": { + "storageAccountType": "Premium_LRS" + } + } + ] + }, + "enableAutomaticUpdates": { + "value": true + }, + "enableDefaultTelemetry": { + "value": "" + }, + "encryptionAtHost": { + "value": false + }, + "extensionAadJoinConfig": { + "value": { + "enabled": true, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionAntiMalwareConfig": { + "value": { + "enabled": true, + "settings": { + "AntimalwareEnabled": "true", + "Exclusions": { + "Extensions": ".ext1;.ext2", + "Paths": "c:\\excluded-path-1;c:\\excluded-path-2", + "Processes": "excludedproc1.exe;excludedproc2.exe" + }, + "RealtimeProtectionEnabled": "true", + "ScheduledScanSettings": { + "day": "7", + "isEnabled": "true", + "scanType": "Quick", + "time": "120" + } + }, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionAzureDiskEncryptionConfig": { + "value": { + "enabled": true, + "settings": { + "EncryptionOperation": "EnableEncryption", + "KekVaultResourceId": "", + "KeyEncryptionAlgorithm": "RSA-OAEP", + "KeyEncryptionKeyURL": "", + "KeyVaultResourceId": "", + "KeyVaultURL": "", + "ResizeOSDisk": "false", + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + }, + "VolumeType": "All" + } + } + }, + "extensionCustomScriptConfig": { + "value": { + "enabled": true, + "fileData": [ + { + "storageAccountId": "", + "uri": "" + } + ], + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionCustomScriptProtectedSetting": { + "value": { + "commandToExecute": "" + } + }, + "extensionDependencyAgentConfig": { + "value": { + "enabled": true, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionDSCConfig": { + "value": { + "enabled": true, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionMonitoringAgentConfig": { + "value": { + "enabled": true, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionNetworkWatcherAgentConfig": { + "value": { + "enabled": true, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "location": { + "value": "" + }, + "lock": { + "value": { + "kind": "CanNotDelete", + "name": "myCustomLockName" + } + }, + "managedIdentities": { + "value": { + "systemAssigned": true, + "userAssignedResourceIds": [ + "" + ] + } + }, + "monitoringWorkspaceId": { + "value": "" + }, + "name": { + "value": "cvmwincom" + }, + "patchMode": { + "value": "AutomaticByPlatform" + }, + "proximityPlacementGroupResourceId": { + "value": "" + }, + "roleAssignments": { + "value": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Owner" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "" + } + ] + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + } +} +``` + +
+

+ + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`adminUsername`](#parameter-adminusername) | securestring | Administrator username. | +| [`configurationProfile`](#parameter-configurationprofile) | string | The configuration profile of automanage. | +| [`imageReference`](#parameter-imagereference) | object | OS image reference. In case of marketplace images, it's the combination of the publisher, offer, sku, version attributes. In case of custom images it's the resource ID of the custom image. | +| [`nicConfigurations`](#parameter-nicconfigurations) | array | Configures NICs and PIPs. | +| [`osDisk`](#parameter-osdisk) | object | Specifies the OS disk. For security reasons, it is recommended to specify DiskEncryptionSet into the osDisk object. Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. | +| [`osType`](#parameter-ostype) | string | The chosen OS type. | +| [`vmSize`](#parameter-vmsize) | string | Specifies the size for the VMs. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`additionalUnattendContent`](#parameter-additionalunattendcontent) | array | Specifies additional base-64 encoded XML formatted information that can be included in the Unattend.xml file, which is used by Windows Setup. - AdditionalUnattendContent object. | +| [`adminPassword`](#parameter-adminpassword) | securestring | When specifying a Windows Virtual Machine, this value should be passed. | +| [`allowExtensionOperations`](#parameter-allowextensionoperations) | bool | Specifies whether extension operations should be allowed on the virtual machine. This may only be set to False when no extensions are present on the virtual machine. | +| [`availabilitySetResourceId`](#parameter-availabilitysetresourceid) | string | Resource ID of an availability set. Cannot be used in combination with availability zone nor scale set. | +| [`availabilityZone`](#parameter-availabilityzone) | int | If set to 1, 2 or 3, the availability zone for all VMs is hardcoded to that value. If zero, then availability zones is not used. Cannot be used in combination with availability set nor scale set. | +| [`backupPolicyName`](#parameter-backuppolicyname) | string | Backup policy the VMs should be using for backup. If not provided, it will use the DefaultPolicy from the backup recovery service vault. | +| [`backupVaultName`](#parameter-backupvaultname) | string | Recovery service vault name to add VMs to backup. | +| [`backupVaultResourceGroup`](#parameter-backupvaultresourcegroup) | string | Resource group of the backup recovery service vault. If not provided the current resource group name is considered by default. | +| [`bootDiagnostics`](#parameter-bootdiagnostics) | bool | Whether boot diagnostics should be enabled on the Virtual Machine. Boot diagnostics will be enabled with a managed storage account if no bootDiagnosticsStorageAccountName value is provided. If bootDiagnostics and bootDiagnosticsStorageAccountName values are not provided, boot diagnostics will be disabled. | +| [`bootDiagnosticStorageAccountName`](#parameter-bootdiagnosticstorageaccountname) | string | Custom storage account used to store boot diagnostic information. Boot diagnostics will be enabled with a custom storage account if a value is provided. | +| [`bootDiagnosticStorageAccountUri`](#parameter-bootdiagnosticstorageaccounturi) | string | Storage account boot diagnostic base URI. | +| [`certificatesToBeInstalled`](#parameter-certificatestobeinstalled) | array | Specifies set of certificates that should be installed onto the virtual machine. | +| [`computerName`](#parameter-computername) | string | Can be used if the computer name needs to be different from the Azure VM resource name. If not used, the resource name will be used as computer name. | +| [`customData`](#parameter-customdata) | string | Custom data associated to the VM, this value will be automatically converted into base64 to account for the expected VM format. | +| [`dataDisks`](#parameter-datadisks) | array | Specifies the data disks. For security reasons, it is recommended to specify DiskEncryptionSet into the dataDisk object. Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. | +| [`dedicatedHostId`](#parameter-dedicatedhostid) | string | Specifies resource ID about the dedicated host that the virtual machine resides in. | +| [`disablePasswordAuthentication`](#parameter-disablepasswordauthentication) | bool | Specifies whether password authentication should be disabled. | +| [`enableAutomaticUpdates`](#parameter-enableautomaticupdates) | bool | Indicates whether Automatic Updates is enabled for the Windows virtual machine. Default value is true. When patchMode is set to Manual, this parameter must be set to false. For virtual machine scale sets, this property can be updated and updates will take effect on OS reprovisioning. | +| [`enableDefaultTelemetry`](#parameter-enabledefaulttelemetry) | bool | Enable telemetry via a Globally Unique Identifier (GUID). | +| [`enableEvictionPolicy`](#parameter-enableevictionpolicy) | bool | Specifies the eviction policy for the low priority virtual machine. Will result in 'Deallocate' eviction policy. | +| [`encryptionAtHost`](#parameter-encryptionathost) | bool | This property can be used by user in the request to enable or disable the Host Encryption for the virtual machine. This will enable the encryption for all the disks including Resource/Temp disk at host itself. For security reasons, it is recommended to set encryptionAtHost to True. Restrictions: Cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. | +| [`extensionAadJoinConfig`](#parameter-extensionaadjoinconfig) | object | The configuration for the [AAD Join] extension. Must at least contain the ["enabled": true] property to be executed. | +| [`extensionAntiMalwareConfig`](#parameter-extensionantimalwareconfig) | object | The configuration for the [Anti Malware] extension. Must at least contain the ["enabled": true] property to be executed. | +| [`extensionAzureDiskEncryptionConfig`](#parameter-extensionazurediskencryptionconfig) | object | The configuration for the [Azure Disk Encryption] extension. Must at least contain the ["enabled": true] property to be executed. Restrictions: Cannot be enabled on disks that have encryption at host enabled. Managed disks encrypted using Azure Disk Encryption cannot be encrypted using customer-managed keys. | +| [`extensionCustomScriptConfig`](#parameter-extensioncustomscriptconfig) | object | The configuration for the [Custom Script] extension. Must at least contain the ["enabled": true] property to be executed. | +| [`extensionCustomScriptProtectedSetting`](#parameter-extensioncustomscriptprotectedsetting) | secureObject | Any object that contains the extension specific protected settings. | +| [`extensionDependencyAgentConfig`](#parameter-extensiondependencyagentconfig) | object | The configuration for the [Dependency Agent] extension. Must at least contain the ["enabled": true] property to be executed. | +| [`extensionDomainJoinConfig`](#parameter-extensiondomainjoinconfig) | object | The configuration for the [Domain Join] extension. Must at least contain the ["enabled": true] property to be executed. | +| [`extensionDomainJoinPassword`](#parameter-extensiondomainjoinpassword) | securestring | Required if name is specified. Password of the user specified in user parameter. | +| [`extensionDSCConfig`](#parameter-extensiondscconfig) | object | The configuration for the [Desired State Configuration] extension. Must at least contain the ["enabled": true] property to be executed. | +| [`extensionMonitoringAgentConfig`](#parameter-extensionmonitoringagentconfig) | object | The configuration for the [Monitoring Agent] extension. Must at least contain the ["enabled": true] property to be executed. | +| [`extensionNetworkWatcherAgentConfig`](#parameter-extensionnetworkwatcheragentconfig) | object | The configuration for the [Network Watcher Agent] extension. Must at least contain the ["enabled": true] property to be executed. | +| [`licenseType`](#parameter-licensetype) | string | Specifies that the image or disk that is being used was licensed on-premises. This element is only used for images that contain the Windows Server operating system. | +| [`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. The system-assigned managed identity will automatically be enabled if extensionAadJoinConfig.enabled = "True". | +| [`maxPriceForLowPriorityVm`](#parameter-maxpriceforlowpriorityvm) | string | Specifies the maximum price you are willing to pay for a low priority VM/VMSS. This price is in US Dollars. | +| [`monitoringWorkspaceId`](#parameter-monitoringworkspaceid) | string | Resource ID of the monitoring log analytics workspace. Must be set when extensionMonitoringAgentConfig is set to true. | +| [`name`](#parameter-name) | string | The name of the virtual machine to be created. You should use a unique prefix to reduce name collisions in Active Directory. If no value is provided, a 10 character long unique string will be generated based on the Resource Group's name. | +| [`patchAssessmentMode`](#parameter-patchassessmentmode) | string | VM guest patching assessment mode. Set it to 'AutomaticByPlatform' to enable automatically check for updates every 24 hours. | +| [`patchMode`](#parameter-patchmode) | string | VM guest patching orchestration mode. 'AutomaticByOS' & 'Manual' are for Windows only, 'ImageDefault' for Linux only. Refer to 'https://learn.microsoft.com/en-us/azure/virtual-machines/automatic-vm-guest-patching'. | +| [`plan`](#parameter-plan) | object | Specifies information about the marketplace image used to create the virtual machine. This element is only used for marketplace images. Before you can use a marketplace image from an API, you must enable the image for programmatic use. | +| [`priority`](#parameter-priority) | string | Specifies the priority for the virtual machine. | +| [`provisionVMAgent`](#parameter-provisionvmagent) | bool | Indicates whether virtual machine agent should be provisioned on the virtual machine. When this property is not specified in the request body, default behavior is to set it to true. This will ensure that VM Agent is installed on the VM so that extensions can be added to the VM later. | +| [`proximityPlacementGroupResourceId`](#parameter-proximityplacementgroupresourceid) | string | Resource ID of a proximity placement group. | +| [`publicKeys`](#parameter-publickeys) | array | The list of SSH public keys used to authenticate with linux based VMs. | +| [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | +| [`sasTokenValidityLength`](#parameter-sastokenvaliditylength) | string | SAS token validity length to use to download files from storage accounts. Usage: 'PT8H' - valid for 8 hours; 'P5D' - valid for 5 days; 'P1Y' - valid for 1 year. When not provided, the SAS token will be valid for 8 hours. | +| [`secureBootEnabled`](#parameter-securebootenabled) | bool | Specifies whether secure boot should be enabled on the virtual machine. This parameter is part of the UefiSettings. SecurityType should be set to TrustedLaunch to enable UefiSettings. | +| [`securityType`](#parameter-securitytype) | string | Specifies the SecurityType of the virtual machine. It is set as TrustedLaunch to enable UefiSettings. | +| [`tags`](#parameter-tags) | object | Tags of the resource. | +| [`timeZone`](#parameter-timezone) | string | Specifies the time zone of the virtual machine. e.g. 'Pacific Standard Time'. Possible values can be `TimeZoneInfo.id` value from time zones returned by `TimeZoneInfo.GetSystemTimeZones`. | +| [`ultraSSDEnabled`](#parameter-ultrassdenabled) | bool | The flag that enables or disables a capability to have one or more managed data disks with UltraSSD_LRS storage account type on the VM or VMSS. Managed disks with storage account type UltraSSD_LRS can be added to a virtual machine or virtual machine scale set only if this property is enabled. | +| [`vTpmEnabled`](#parameter-vtpmenabled) | bool | Specifies whether vTPM should be enabled on the virtual machine. This parameter is part of the UefiSettings. SecurityType should be set to TrustedLaunch to enable UefiSettings. | +| [`winRM`](#parameter-winrm) | object | Specifies the Windows Remote Management listeners. This enables remote Windows PowerShell. - WinRMConfiguration object. | + +**Generated parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`baseTime`](#parameter-basetime) | string | Do not provide a value! This date value is used to generate a registration token. | + +### Parameter: `adminUsername` + +Administrator username. + +- Required: Yes +- Type: securestring + +### Parameter: `configurationProfile` + +The configuration profile of automanage. + +- Required: No +- Type: string +- Default: `''` +- Allowed: + ```Bicep + [ + '' + '/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesDevTest' + '/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesProduction' + ] + ``` + +### Parameter: `imageReference` + +OS image reference. In case of marketplace images, it's the combination of the publisher, offer, sku, version attributes. In case of custom images it's the resource ID of the custom image. + +- Required: Yes +- Type: object + +### Parameter: `nicConfigurations` + +Configures NICs and PIPs. + +- Required: Yes +- Type: array + +### Parameter: `osDisk` + +Specifies the OS disk. For security reasons, it is recommended to specify DiskEncryptionSet into the osDisk object. Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. + +- Required: Yes +- Type: object + +### Parameter: `osType` + +The chosen OS type. + +- Required: Yes +- Type: string +- Allowed: + ```Bicep + [ + 'Linux' + 'Windows' + ] + ``` + +### Parameter: `vmSize` + +Specifies the size for the VMs. + +- Required: Yes +- Type: string + +### Parameter: `additionalUnattendContent` + +Specifies additional base-64 encoded XML formatted information that can be included in the Unattend.xml file, which is used by Windows Setup. - AdditionalUnattendContent object. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `adminPassword` + +When specifying a Windows Virtual Machine, this value should be passed. + +- Required: No +- Type: securestring +- Default: `''` + +### Parameter: `allowExtensionOperations` + +Specifies whether extension operations should be allowed on the virtual machine. This may only be set to False when no extensions are present on the virtual machine. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `availabilitySetResourceId` + +Resource ID of an availability set. Cannot be used in combination with availability zone nor scale set. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `availabilityZone` + +If set to 1, 2 or 3, the availability zone for all VMs is hardcoded to that value. If zero, then availability zones is not used. Cannot be used in combination with availability set nor scale set. + +- Required: No +- Type: int +- Default: `0` +- Allowed: + ```Bicep + [ + 0 + 1 + 2 + 3 + ] + ``` + +### Parameter: `backupPolicyName` + +Backup policy the VMs should be using for backup. If not provided, it will use the DefaultPolicy from the backup recovery service vault. + +- Required: No +- Type: string +- Default: `'DefaultPolicy'` + +### Parameter: `backupVaultName` + +Recovery service vault name to add VMs to backup. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `backupVaultResourceGroup` + +Resource group of the backup recovery service vault. If not provided the current resource group name is considered by default. + +- Required: No +- Type: string +- Default: `[resourceGroup().name]` + +### Parameter: `bootDiagnostics` + +Whether boot diagnostics should be enabled on the Virtual Machine. Boot diagnostics will be enabled with a managed storage account if no bootDiagnosticsStorageAccountName value is provided. If bootDiagnostics and bootDiagnosticsStorageAccountName values are not provided, boot diagnostics will be disabled. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `bootDiagnosticStorageAccountName` + +Custom storage account used to store boot diagnostic information. Boot diagnostics will be enabled with a custom storage account if a value is provided. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `bootDiagnosticStorageAccountUri` + +Storage account boot diagnostic base URI. + +- Required: No +- Type: string +- Default: `[format('.blob.{0}/', environment().suffixes.storage)]` + +### Parameter: `certificatesToBeInstalled` + +Specifies set of certificates that should be installed onto the virtual machine. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `computerName` + +Can be used if the computer name needs to be different from the Azure VM resource name. If not used, the resource name will be used as computer name. + +- Required: No +- Type: string +- Default: `[parameters('name')]` + +### Parameter: `customData` + +Custom data associated to the VM, this value will be automatically converted into base64 to account for the expected VM format. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `dataDisks` + +Specifies the data disks. For security reasons, it is recommended to specify DiskEncryptionSet into the dataDisk object. Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `dedicatedHostId` + +Specifies resource ID about the dedicated host that the virtual machine resides in. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `disablePasswordAuthentication` + +Specifies whether password authentication should be disabled. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `enableAutomaticUpdates` + +Indicates whether Automatic Updates is enabled for the Windows virtual machine. Default value is true. When patchMode is set to Manual, this parameter must be set to false. For virtual machine scale sets, this property can be updated and updates will take effect on OS reprovisioning. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `enableDefaultTelemetry` + +Enable telemetry via a Globally Unique Identifier (GUID). + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `enableEvictionPolicy` + +Specifies the eviction policy for the low priority virtual machine. Will result in 'Deallocate' eviction policy. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `encryptionAtHost` + +This property can be used by user in the request to enable or disable the Host Encryption for the virtual machine. This will enable the encryption for all the disks including Resource/Temp disk at host itself. For security reasons, it is recommended to set encryptionAtHost to True. Restrictions: Cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `extensionAadJoinConfig` + +The configuration for the [AAD Join] extension. Must at least contain the ["enabled": true] property to be executed. + +- Required: No +- Type: object +- Default: + ```Bicep + { + enabled: false + } + ``` + +### Parameter: `extensionAntiMalwareConfig` + +The configuration for the [Anti Malware] extension. Must at least contain the ["enabled": true] property to be executed. + +- Required: No +- Type: object +- Default: + ```Bicep + { + enabled: false + } + ``` + +### Parameter: `extensionAzureDiskEncryptionConfig` + +The configuration for the [Azure Disk Encryption] extension. Must at least contain the ["enabled": true] property to be executed. Restrictions: Cannot be enabled on disks that have encryption at host enabled. Managed disks encrypted using Azure Disk Encryption cannot be encrypted using customer-managed keys. + +- Required: No +- Type: object +- Default: + ```Bicep + { + enabled: false + } + ``` + +### Parameter: `extensionCustomScriptConfig` + +The configuration for the [Custom Script] extension. Must at least contain the ["enabled": true] property to be executed. + +- Required: No +- Type: object +- Default: + ```Bicep + { + enabled: false + fileData: [] + } + ``` + +### Parameter: `extensionCustomScriptProtectedSetting` + +Any object that contains the extension specific protected settings. + +- Required: No +- Type: secureObject +- Default: `{}` + +### Parameter: `extensionDependencyAgentConfig` + +The configuration for the [Dependency Agent] extension. Must at least contain the ["enabled": true] property to be executed. + +- Required: No +- Type: object +- Default: + ```Bicep + { + enabled: false + } + ``` + +### Parameter: `extensionDomainJoinConfig` + +The configuration for the [Domain Join] extension. Must at least contain the ["enabled": true] property to be executed. + +- Required: No +- Type: object +- Default: + ```Bicep + { + enabled: false + } + ``` + +### Parameter: `extensionDomainJoinPassword` + +Required if name is specified. Password of the user specified in user parameter. + +- Required: No +- Type: securestring +- Default: `''` + +### Parameter: `extensionDSCConfig` + +The configuration for the [Desired State Configuration] extension. Must at least contain the ["enabled": true] property to be executed. + +- Required: No +- Type: object +- Default: + ```Bicep + { + enabled: false + } + ``` + +### Parameter: `extensionMonitoringAgentConfig` + +The configuration for the [Monitoring Agent] extension. Must at least contain the ["enabled": true] property to be executed. + +- Required: No +- Type: object +- Default: + ```Bicep + { + enabled: false + } + ``` + +### Parameter: `extensionNetworkWatcherAgentConfig` + +The configuration for the [Network Watcher Agent] extension. Must at least contain the ["enabled": true] property to be executed. + +- Required: No +- Type: object +- Default: + ```Bicep + { + enabled: false + } + ``` + +### Parameter: `licenseType` + +Specifies that the image or disk that is being used was licensed on-premises. This element is only used for images that contain the Windows Server operating system. + +- Required: No +- Type: string +- Default: `''` +- Allowed: + ```Bicep + [ + '' + 'Windows_Client' + 'Windows_Server' + ] + ``` + +### Parameter: `location` + +Location for all resources. + +- Required: No +- Type: string +- Default: `[resourceGroup().location]` + +### Parameter: `lock` + +The lock settings of the service. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`kind`](#parameter-lockkind) | string | Specify the type of lock. | +| [`name`](#parameter-lockname) | string | Specify the name of lock. | + +### Parameter: `lock.kind` + +Specify the type of lock. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'CanNotDelete' + 'None' + 'ReadOnly' + ] + ``` + +### Parameter: `lock.name` + +Specify the name of lock. + +- Required: No +- Type: string + +### Parameter: `managedIdentities` + +The managed identity definition for this resource. The system-assigned managed identity will automatically be enabled if extensionAadJoinConfig.enabled = "True". + +- Required: No +- Type: object + +**Optional parameters** + +| 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. | + +### Parameter: `managedIdentities.systemAssigned` + +Enables system assigned managed identity on the resource. + +- Required: No +- Type: bool + +### Parameter: `managedIdentities.userAssignedResourceIds` + +The resource ID(s) to assign to the resource. + +- Required: No +- Type: array + +### Parameter: `maxPriceForLowPriorityVm` + +Specifies the maximum price you are willing to pay for a low priority VM/VMSS. This price is in US Dollars. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `monitoringWorkspaceId` + +Resource ID of the monitoring log analytics workspace. Must be set when extensionMonitoringAgentConfig is set to true. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `name` + +The name of the virtual machine to be created. You should use a unique prefix to reduce name collisions in Active Directory. If no value is provided, a 10 character long unique string will be generated based on the Resource Group's name. + +- Required: No +- Type: string +- Default: `[take(toLower(uniqueString(resourceGroup().name)), 10)]` + +### Parameter: `patchAssessmentMode` + +VM guest patching assessment mode. Set it to 'AutomaticByPlatform' to enable automatically check for updates every 24 hours. + +- Required: No +- Type: string +- Default: `'ImageDefault'` +- Allowed: + ```Bicep + [ + 'AutomaticByPlatform' + 'ImageDefault' + ] + ``` + +### Parameter: `patchMode` + +VM guest patching orchestration mode. 'AutomaticByOS' & 'Manual' are for Windows only, 'ImageDefault' for Linux only. Refer to 'https://learn.microsoft.com/en-us/azure/virtual-machines/automatic-vm-guest-patching'. + +- Required: No +- Type: string +- Default: `''` +- Allowed: + ```Bicep + [ + '' + 'AutomaticByOS' + 'AutomaticByPlatform' + 'ImageDefault' + 'Manual' + ] + ``` + +### Parameter: `plan` + +Specifies information about the marketplace image used to create the virtual machine. This element is only used for marketplace images. Before you can use a marketplace image from an API, you must enable the image for programmatic use. + +- Required: No +- Type: object +- Default: `{}` + +### Parameter: `priority` + +Specifies the priority for the virtual machine. + +- Required: No +- Type: string +- Default: `'Regular'` +- Allowed: + ```Bicep + [ + 'Low' + 'Regular' + 'Spot' + ] + ``` + +### Parameter: `provisionVMAgent` + +Indicates whether virtual machine agent should be provisioned on the virtual machine. When this property is not specified in the request body, default behavior is to set it to true. This will ensure that VM Agent is installed on the VM so that extensions can be added to the VM later. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `proximityPlacementGroupResourceId` + +Resource ID of a proximity placement group. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `publicKeys` + +The list of SSH public keys used to authenticate with linux based VMs. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `roleAssignments` + +Array of role assignments to create. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`principalId`](#parameter-roleassignmentsprincipalid) | string | The principal ID of the principal (user/group/identity) to assign the role to. | +| [`roleDefinitionIdOrName`](#parameter-roleassignmentsroledefinitionidorname) | string | 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'. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`condition`](#parameter-roleassignmentscondition) | string | 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`](#parameter-roleassignmentsconditionversion) | string | Version of the condition. | +| [`delegatedManagedIdentityResourceId`](#parameter-roleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | +| [`description`](#parameter-roleassignmentsdescription) | string | The description of the role assignment. | +| [`principalType`](#parameter-roleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. | + +### Parameter: `roleAssignments.principalId` + +The principal ID of the principal (user/group/identity) to assign the role to. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.roleDefinitionIdOrName` + +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'. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.condition` + +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" + +- Required: No +- Type: string + +### Parameter: `roleAssignments.conditionVersion` + +Version of the condition. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + '2.0' + ] + ``` + +### Parameter: `roleAssignments.delegatedManagedIdentityResourceId` + +The Resource Id of the delegated managed identity resource. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.description` + +The description of the role assignment. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.principalType` + +The principal type of the assigned principal ID. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Device' + 'ForeignGroup' + 'Group' + 'ServicePrincipal' + 'User' + ] + ``` + +### Parameter: `sasTokenValidityLength` + +SAS token validity length to use to download files from storage accounts. Usage: 'PT8H' - valid for 8 hours; 'P5D' - valid for 5 days; 'P1Y' - valid for 1 year. When not provided, the SAS token will be valid for 8 hours. + +- Required: No +- Type: string +- Default: `'PT8H'` + +### Parameter: `secureBootEnabled` + +Specifies whether secure boot should be enabled on the virtual machine. This parameter is part of the UefiSettings. SecurityType should be set to TrustedLaunch to enable UefiSettings. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `securityType` + +Specifies the SecurityType of the virtual machine. It is set as TrustedLaunch to enable UefiSettings. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `tags` + +Tags of the resource. + +- Required: No +- Type: object + +### Parameter: `timeZone` + +Specifies the time zone of the virtual machine. e.g. 'Pacific Standard Time'. Possible values can be `TimeZoneInfo.id` value from time zones returned by `TimeZoneInfo.GetSystemTimeZones`. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `ultraSSDEnabled` + +The flag that enables or disables a capability to have one or more managed data disks with UltraSSD_LRS storage account type on the VM or VMSS. Managed disks with storage account type UltraSSD_LRS can be added to a virtual machine or virtual machine scale set only if this property is enabled. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `vTpmEnabled` + +Specifies whether vTPM should be enabled on the virtual machine. This parameter is part of the UefiSettings. SecurityType should be set to TrustedLaunch to enable UefiSettings. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `winRM` + +Specifies the Windows Remote Management listeners. This enables remote Windows PowerShell. - WinRMConfiguration object. + +- Required: No +- Type: object +- Default: `{}` + +### Parameter: `baseTime` + +Do not provide a value! This date value is used to generate a registration token. + +- Required: No +- Type: string +- Default: `[utcNow('u')]` + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `location` | string | The location the resource was deployed into. | +| `name` | string | The name of the VM. | +| `resourceGroupName` | string | The name of the resource group the VM was created in. | +| `resourceId` | string | The resource ID of the VM. | +| `systemAssignedMIPrincipalId` | string | The principal ID of the system assigned identity. | + +## Cross-referenced modules + +This section gives you an overview of all local-referenced module files (i.e., other CARML 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 | +| :-- | :-- | +| `modules/network/network-interface` | Local reference | +| `modules/network/public-ip-address` | Local reference | +| `modules/recovery-services/vault/backup-fabric/protection-container/protected-item` | Local reference | + +## Notes + +### Automanage considerations + +Enabling automanage triggers the creation of additional resources outside of the specific virtual machine deployment, such as: +- an `Automanage-Automate-` in the same Virtual Machine Resource Group and linking to the log analytics workspace leveraged by Azure Security Center. +- a `DefaultResourceGroup-` resource group hosting a recovery services vault `DefaultBackupVault-` where virtual machine backups are stored +For further details on automanage please refer to [Automanage virtual machines](https://learn.microsoft.com/en-us/azure/automanage/automanage-virtual-machines). + +### Parameter Usage: `imageReference` + +#### Marketplace images + +

+ +Parameter JSON format + +```json +"imageReference": { + "value": { + "publisher": "MicrosoftWindowsServer", + "offer": "WindowsServer", + "sku": "2022-datacenter-azure-edition", + "version": "latest" + } +} +``` + +
+
+ +Bicep format + +```bicep +imageReference: { + publisher: 'MicrosoftWindowsServer' + offer: 'WindowsServer' + sku: '2022-datacenter-azure-edition' + version: 'latest' +} +``` + +
+

+ +#### Custom images + +

+ +Parameter JSON format + +```json +"imageReference": { + "value": { + "id": "/subscriptions/12345-6789-1011-1213-15161718/resourceGroups/rg-name/providers/Microsoft.Compute/images/imagename" + } +} +``` + +
+ +
+ +Bicep format + +```bicep +imageReference: { + id: '/subscriptions/12345-6789-1011-1213-15161718/resourceGroups/rg-name/providers/Microsoft.Compute/images/imagename' +} +``` + +
+

+ +### Parameter Usage: `plan` + +

+ +Parameter JSON format + +```json +"plan": { + "value": { + "name": "qvsa-25", + "product": "qualys-virtual-scanner", + "publisher": "qualysguard" + } +} +``` + +
+ +
+ +Bicep format + +```bicep +plan: { + name: 'qvsa-25' + product: 'qualys-virtual-scanner' + publisher: 'qualysguard' +} +``` + +
+

+ +### Parameter Usage: `osDisk` + +

+ +Parameter JSON format + +```json +"osDisk": { + "value": { + "createOption": "fromImage", + "deleteOption": "Delete", // Optional. Can be 'Delete' or 'Detach' + "diskSizeGB": "128", + "managedDisk": { + "storageAccountType": "Premium_LRS", + "diskEncryptionSet": { // Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. + "id": "/subscriptions//resourceGroups//providers/Microsoft.Compute/diskEncryptionSets/" + } + } + } +} +``` + +
+ +
+ +Bicep format + +```bicep +osDisk: { + createOption: 'fromImage' + deleteOption: 'Delete' // Optional. Can be 'Delete' or 'Detach' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + diskEncryptionSet: { // Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. + id: '/subscriptions//resourceGroups//providers/Microsoft.Compute/diskEncryptionSets/' + } + } +} +``` + +
+

+ +### Parameter Usage: `dataDisks` + +

+ +Parameter JSON format + +```json +"dataDisks": { + "value": [ + { + "caching": "ReadOnly", + "createOption": "Empty", + "deleteOption": "Delete", // Optional. Can be 'Delete' or 'Detach' + "diskSizeGB": "256", + "managedDisk": { + "storageAccountType": "Premium_LRS", + "diskEncryptionSet": { // Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. + "id": "/subscriptions//resourceGroups//providers/Microsoft.Compute/diskEncryptionSets/" + } + } + }, + { + "caching": "ReadOnly", + "createOption": "Empty", + "diskSizeGB": "128", + "managedDisk": { + "storageAccountType": "Premium_LRS", + "diskEncryptionSet": { // Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. + "id": "/subscriptions//resourceGroups//providers/Microsoft.Compute/diskEncryptionSets/" + } + } + } + ] +} +``` + +
+ +
+ +Bicep format + +```bicep +dataDisks: [ + { + caching: 'ReadOnly' + createOption: 'Empty' + deleteOption: 'Delete' // Optional. Can be 'Delete' or 'Detach' + diskSizeGB: '256' + managedDisk: { + storageAccountType: 'Premium_LRS' + diskEncryptionSet: { // Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. + id: '/subscriptions//resourceGroups//providers/Microsoft.Compute/diskEncryptionSets/' + } + } + } + { + caching: 'ReadOnly' + createOption: 'Empty' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + diskEncryptionSet: { // Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. + id: '/subscriptions//resourceGroups//providers/Microsoft.Compute/diskEncryptionSets/' + } + } + } +] +``` + +
+

+ +### Parameter Usage: `nicConfigurations` + +Comments: +- The field `nicSuffix` and `subnetResourceId` are mandatory. +- If `enablePublicIP` is set to true, then `publicIpNameSuffix` is also mandatory. +- Each IP config needs to have the mandatory field `name`. +- If not disabled, `enableAcceleratedNetworking` is considered `true` by default and requires the VM to be deployed with a supported OS and VM size. + +

+ +Parameter JSON format + +```json +"nicConfigurations": { + "value": [ + { + "nicSuffix": "-nic-01", + "deleteOption": "Delete", // Optional. Can be 'Delete' or 'Detach' + "ipConfigurations": [ + { + "name": "ipconfig1", + "subnetResourceId": "/subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/", + "pipConfiguration": { + "publicIpNameSuffix": "-pip-01", + "roleAssignments": [ + { + "roleDefinitionIdOrName": "Reader", + "principalIds": [ + "" + ] + } + ] + } + }, + { + "name": "ipconfig2", + "subnetResourceId": "/subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/", + } + ], + "nsgId": "/subscriptions//resourceGroups//providers/Microsoft.Network/networkSecurityGroups/", + "roleAssignments": [ + { + "roleDefinitionIdOrName": "Reader", + "principalIds": [ + "" + ] + } + ] + }, + { + "nicSuffix": "-nic-02", + "ipConfigurations": [ + { + "name": "ipconfig1", + "subnetResourceId": "/subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/", + "pipConfiguration": { + "publicIpNameSuffix": "-pip-02" + } + }, + { + "name": "ipconfig2", + "subnetResourceId": "/subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/", + "privateIPAllocationMethod": "Static", + "privateIPAddress": "10.0.0.9" + } + ] + } + ] +} +``` + +
+ +
+ +Bicep format + +```bicep +nicConfigurations: { + value: [ + { + nicSuffix: '-nic-01' + deleteOption: 'Delete' // Optional. Can be 'Delete' or 'Detach' + ipConfigurations: [ + { + name: 'ipconfig1' + subnetResourceId: '/subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/' + pipConfiguration: { + publicIpNameSuffix: '-pip-01' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalIds: [ + '' + ] + } + ] + } + } + { + name: 'ipconfig2' + subnetResourceId: '/subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/' + } + ] + nsgId: '/subscriptions//resourceGroups//providers/Microsoft.Network/networkSecurityGroups/' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalIds: [ + '' + ] + } + ] + } + { + nicSuffix: '-nic-02' + ipConfigurations: [ + { + name: 'ipconfig1' + subnetResourceId: '/subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/' + pipConfiguration: { + publicIpNameSuffix: '-pip-02' + } + } + { + name: 'ipconfig2' + subnetResourceId: '/subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/' + privateIPAllocationMethod: 'Static' + privateIPAddress: '10.0.0.9' + } + ] + } + ] +} +``` + +
+

+ +### Parameter Usage: `configurationProfileAssignments` + +

+ +Parameter JSON format + +```json +"configurationProfileAssignments": { + "value": [ + "/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesProduction", + "/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesDevTest" + ] +} +``` + +
+ +
+ +Bicep format + +```bicep +configurationProfileAssignments: [ + '/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesProduction' + '/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesDevTest' +] +``` + +
+

+ +### Parameter Usage: `extensionDomainJoinConfig` + +

+ +Parameter JSON format + +```json +"extensionDomainJoinConfig": { + "value": { + "enabled": true, + "settings": { + "name": "contoso.com", + "user": "test.user@testcompany.com", + "ouPath": "OU=testOU; DC=contoso; DC=com", + "restart": true, + "options": 3 + } + } +}, +"extensionDomainJoinPassword": { + "reference": { + "keyVault": { + "id": "/subscriptions/</resourceGroups/myRG/providers/Microsoft.KeyVault/vaults/myKvlt" + }, + "secretName": "domainJoinUser02-Password" + } +} +``` + +
+ +
+ +Bicep format + +```bicep +extensionDomainJoinConfig: { + enabled: true + settings: { + name: 'contoso.com' + user: 'test.user@testcompany.com' + ouPath: 'OU=testOU; DC=contoso; DC=com' + restart: true + options: 3 + } +} + +resource kv1 'Microsoft.KeyVault/vaults@2019-09-01' existing = { + name: 'adp-[[namePrefix]]-az-kv-x-001' + scope: resourceGroup('[[subscriptionId]]','validation-rg') +} + +extensionDomainJoinPassword: kv1.getSecret('domainJoinUser02-Password') +``` + +
+

+ +### Parameter Usage: `extensionAntiMalwareConfig` + +Only for OSType Windows + +

+ +Parameter JSON format + +```json +"extensionAntiMalwareConfig": { + "value": { + "enabled": true, + "settings": { + "AntimalwareEnabled": true, + "Exclusions": { + "Extensions": ".log;.ldf", + "Paths": "D:\\IISlogs;D:\\DatabaseLogs", + "Processes": "mssence.svc" + }, + "RealtimeProtectionEnabled": true, + "ScheduledScanSettings": { + "isEnabled": "true", + "scanType": "Quick", + "day": "7", + "time": "120" + } + } + } +} +``` + +
+ +
+ +Bicep format + +```bicep +extensionAntiMalwareConfig: { + enabled: true + settings: { + AntimalwareEnabled: true + Exclusions: { + Extensions: '.log;.ldf' + Paths: 'D:\\IISlogs;D:\\DatabaseLogs' + Processes: 'mssence.svc' + } + RealtimeProtectionEnabled: true + ScheduledScanSettings: { + isEnabled: 'true' + scanType: 'Quick' + day: '7' + time: '120' + } + } +} +``` + +
+

+ +### Parameter Usage: `extensionAzureDiskEncryptionConfig` + +

+ +Parameter JSON format + +```json +"extensionAzureDiskEncryptionConfig": { + // Restrictions: Cannot be enabled on disks that have encryption at host enabled. Managed disks encrypted using Azure Disk Encryption cannot be encrypted using customer-managed keys. + "value": { + "enabled": true, + "settings": { + "EncryptionOperation": "EnableEncryption", + "KeyVaultURL": "https://mykeyvault.vault.azure.net/", + "KeyVaultResourceId": "/subscriptions/[[subscriptionId]]/resourceGroups/validation-rg/providers/Microsoft.KeyVault/vaults/adp-sxx-az-kv-x-001", + "KeyEncryptionKeyURL": "https://mykeyvault.vault.azure.net/keys/keyEncryptionKey/bc3bb46d95c64367975d722f473eeae5", // ID must be updated for new keys + "KekVaultResourceId": "/subscriptions/[[subscriptionId]]/resourceGroups/validation-rg/providers/Microsoft.KeyVault/vaults/adp-sxx-az-kv-x-001", + "KeyEncryptionAlgorithm": "RSA-OAEP", //'RSA-OAEP'/'RSA-OAEP-256'/'RSA1_5' + "VolumeType": "All", //'OS'/'Data'/'All' + "ResizeOSDisk": "false" + } + } +} +``` + +
+ +
+ +Bicep format + +```bicep +extensionAzureDiskEncryptionConfig: { + // Restrictions: Cannot be enabled on disks that have encryption at host enabled. Managed disks encrypted using Azure Disk Encryption cannot be encrypted using customer-managed keys. + enabled: true + settings: { + EncryptionOperation: 'EnableEncryption' + KeyVaultURL: 'https://mykeyvault.vault.azure.net/' + KeyVaultResourceId: '/subscriptions/[[subscriptionId]]/resourceGroups/validation-rg/providers/Microsoft.KeyVault/vaults/adp-sxx-az-kv-x-001' + KeyEncryptionKeyURL: 'https://mykeyvault.vault.azure.net/keys/keyEncryptionKey/bc3bb46d95c64367975d722f473eeae5' // ID must be updated for new keys + KekVaultResourceId: '/subscriptions/[[subscriptionId]]/resourceGroups/validation-rg/providers/Microsoft.KeyVault/vaults/adp-sxx-az-kv-x-001' + KeyEncryptionAlgorithm: 'RSA-OAEP' //'RSA-OAEP'/'RSA-OAEP-256'/'RSA1_5' + VolumeType: 'All' //'OS'/'Data'/'All' + ResizeOSDisk: 'false' + } +} +``` + +
+

+ +### Parameter Usage: `extensionDSCConfig` + +

+ +Parameter JSON format + +```json +"extensionDSCConfig": { + "value": { + { + "enabled": true, + "settings": { + "wmfVersion": "latest", + "configuration": { + "url": "http://validURLToConfigLocation", + "script": "ConfigurationScript.ps1", + "function": "ConfigurationFunction" + }, + "configurationArguments": { + "argument1": "Value1", + "argument2": "Value2" + }, + "configurationData": { + "url": "https://foo.psd1" + }, + "privacy": { + "dataCollection": "enable" + }, + "advancedOptions": { + "forcePullAndApply": false, + "downloadMappings": { + "specificDependencyKey": "https://myCustomDependencyLocation" + } + } + }, + "protectedSettings": { + "configurationArguments": { + "mySecret": "MyPlaceholder" + }, + "configurationUrlSasToken": "MyPlaceholder", + "configurationDataUrlSasToken": "MyPlaceholder" + } + } + } +} +``` + +
+ +
+ +Bicep format + +```bicep +extensionDSCConfig: { + { + enabled: true + settings: { + wmfVersion: 'latest' + configuration: { + url: 'http://validURLToConfigLocation' + script: 'ConfigurationScript.ps1' + function: 'ConfigurationFunction' + } + configurationArguments: { + argument1: 'Value1' + argument2: 'Value2' + } + configurationData: { + url: 'https://foo.psd1' + } + privacy: { + dataCollection: 'enable' + } + advancedOptions: { + forcePullAndApply: false + downloadMappings: { + specificDependencyKey: 'https://myCustomDependencyLocation' + } + } + } + protectedSettings: { + configurationArguments: { + mySecret: 'MyPlaceholder' + } + configurationUrlSasToken: 'MyPlaceholder' + configurationDataUrlSasToken: 'MyPlaceholder' + } + } +} +``` + +
+

+ +### Parameter Usage: `extensionCustomScriptConfig` + +

+ +Parameter JSON format + +```json +"extensionCustomScriptConfig": { + "value": { + "enabled": true, + "fileData": [ + //storage accounts with SAS token requirement + { + "uri": "https://mystorageaccount.blob.core.windows.net/avdscripts/File1.ps1", + "storageAccountId": "/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/rgName/providers/Microsoft.Storage/storageAccounts/storageAccountName" + }, + { + "uri": "https://mystorageaccount.blob.core.windows.net/avdscripts/File2.ps1", + "storageAccountId": "/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/rgName/providers/Microsoft.Storage/storageAccounts/storageAccountName" + }, + //storage account with public container (no SAS token is required) OR other public URL (not a storage account) + { + "uri": "https://github.com/myProject/File3.ps1", + "storageAccountId": "" + } + ], + "settings": { + "commandToExecute": "powershell -ExecutionPolicy Unrestricted -File testscript.ps1" + } + } +} +``` + +
+ +
+ +Bicep format + +```bicep +extensionCustomScriptConfig: { + enabled: true + fileData: [ + //storage accounts with SAS token requirement + { + uri: 'https://mystorageaccount.blob.core.windows.net/avdscripts/File1.ps1' + storageAccountId: '/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/rgName/providers/Microsoft.Storage/storageAccounts/storageAccountName' + } + { + uri: 'https://mystorageaccount.blob.core.windows.net/avdscripts/File2.ps1' + storageAccountId: '/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/rgName/providers/Microsoft.Storage/storageAccounts/storageAccountName' + } + //storage account with public container (no SAS token is required) OR other public URL (not a storage account) + { + uri: 'https://github.com/myProject/File3.ps1' + storageAccountId: '' + } + ] + settings: { + commandToExecute: 'powershell -ExecutionPolicy Unrestricted -File testscript.ps1' + } +} +``` + +
+

+ +### Parameter Usage: `extensionCustomScriptProtectedSetting` + +This is used if you are going to use secrets or other sensitive information that you don't want to be visible in the deployment and logs. + +

+ +Parameter JSON format + +```json +"extensionCustomScriptProtectedSetting": { + "value": [ + { + "commandToExecute": "mycommandToRun -someParam MYSECRET" + } + ] +} +``` + +
+ +
+ +Bicep format + +```bicep +extensionCustomScriptProtectedSetting: [ + { + commandToExecute: 'mycommandToRun -someParam MYSECRET' + } +] +``` + +
+

diff --git a/modules/compute/virtual-machine/extension/README.md b/modules/compute/virtual-machine/extension/README.md new file mode 100644 index 0000000000..324ebc8179 --- /dev/null +++ b/modules/compute/virtual-machine/extension/README.md @@ -0,0 +1,165 @@ +# Virtual Machine Extensions `[Microsoft.Compute/virtualMachines/extensions]` + +This module deploys a Virtual Machine Extension. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Compute/virtualMachines/extensions` | [2022-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Compute/2022-11-01/virtualMachines/extensions) | + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`autoUpgradeMinorVersion`](#parameter-autoupgrademinorversion) | bool | Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true. | +| [`enableAutomaticUpgrade`](#parameter-enableautomaticupgrade) | bool | Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available. | +| [`name`](#parameter-name) | string | The name of the virtual machine extension. | +| [`publisher`](#parameter-publisher) | string | The name of the extension handler publisher. | +| [`type`](#parameter-type) | string | Specifies the type of the extension; an example is "CustomScriptExtension". | +| [`typeHandlerVersion`](#parameter-typehandlerversion) | string | Specifies the version of the script handler. | + +**Conditional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`virtualMachineName`](#parameter-virtualmachinename) | string | The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enableDefaultTelemetry`](#parameter-enabledefaulttelemetry) | bool | Enable telemetry via a Globally Unique Identifier (GUID). | +| [`forceUpdateTag`](#parameter-forceupdatetag) | string | How the extension handler should be forced to update even if the extension configuration has not changed. | +| [`location`](#parameter-location) | string | The location the extension is deployed to. | +| [`protectedSettings`](#parameter-protectedsettings) | secureObject | Any object that contains the extension specific protected settings. | +| [`settings`](#parameter-settings) | object | Any object that contains the extension specific settings. | +| [`supressFailures`](#parameter-supressfailures) | bool | Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false. | +| [`tags`](#parameter-tags) | object | Tags of the resource. | + +### Parameter: `autoUpgradeMinorVersion` + +Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true. + +- Required: Yes +- Type: bool + +### Parameter: `enableAutomaticUpgrade` + +Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available. + +- Required: Yes +- Type: bool + +### Parameter: `name` + +The name of the virtual machine extension. + +- Required: Yes +- Type: string + +### Parameter: `publisher` + +The name of the extension handler publisher. + +- Required: Yes +- Type: string + +### Parameter: `type` + +Specifies the type of the extension; an example is "CustomScriptExtension". + +- Required: Yes +- Type: string + +### Parameter: `typeHandlerVersion` + +Specifies the version of the script handler. + +- Required: Yes +- Type: string + +### Parameter: `virtualMachineName` + +The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment. + +- Required: Yes +- Type: string + +### Parameter: `enableDefaultTelemetry` + +Enable telemetry via a Globally Unique Identifier (GUID). + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `forceUpdateTag` + +How the extension handler should be forced to update even if the extension configuration has not changed. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `location` + +The location the extension is deployed to. + +- Required: No +- Type: string +- Default: `[resourceGroup().location]` + +### Parameter: `protectedSettings` + +Any object that contains the extension specific protected settings. + +- Required: No +- Type: secureObject +- Default: `{}` + +### Parameter: `settings` + +Any object that contains the extension specific settings. + +- Required: No +- Type: object +- Default: `{}` + +### Parameter: `supressFailures` + +Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `tags` + +Tags of the resource. + +- Required: No +- Type: object + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `location` | string | The location the resource was deployed into. | +| `name` | string | The name of the extension. | +| `resourceGroupName` | string | The name of the Resource Group the extension was created in. | +| `resourceId` | string | The resource ID of the extension. | + +## Cross-referenced modules + +_None_ diff --git a/modules/compute/virtual-machine/extension/main.bicep b/modules/compute/virtual-machine/extension/main.bicep new file mode 100644 index 0000000000..909805fe1c --- /dev/null +++ b/modules/compute/virtual-machine/extension/main.bicep @@ -0,0 +1,92 @@ +metadata name = 'Virtual Machine Extensions' +metadata description = 'This module deploys a Virtual Machine Extension.' +metadata owner = 'Azure/module-maintainers' + +@description('Conditional. The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment.') +param virtualMachineName string + +@description('Required. The name of the virtual machine extension.') +param name string + +@description('Optional. The location the extension is deployed to.') +param location string = resourceGroup().location + +@description('Required. The name of the extension handler publisher.') +param publisher string + +@description('Required. Specifies the type of the extension; an example is "CustomScriptExtension".') +param type string + +@description('Required. Specifies the version of the script handler.') +param typeHandlerVersion string + +@description('Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true.') +param autoUpgradeMinorVersion bool + +@description('Optional. How the extension handler should be forced to update even if the extension configuration has not changed.') +param forceUpdateTag string = '' + +@description('Optional. Any object that contains the extension specific settings.') +param settings object = {} + +@description('Optional. Any object that contains the extension specific protected settings.') +@secure() +param protectedSettings object = {} + +@description('Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false.') +param supressFailures bool = false + +@description('Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available.') +param enableAutomaticUpgrade bool + +@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') +param enableDefaultTelemetry bool = true + +@description('Optional. Tags of the resource.') +param tags object? + +resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (enableDefaultTelemetry) { + name: 'pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-${uniqueString(deployment().name, location)}' + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + } + } +} + +resource virtualMachine 'Microsoft.Compute/virtualMachines@2022-11-01' existing = { + name: virtualMachineName +} + +resource extension 'Microsoft.Compute/virtualMachines/extensions@2022-11-01' = { + name: name + parent: virtualMachine + location: location + tags: tags + properties: { + publisher: publisher + type: type + typeHandlerVersion: typeHandlerVersion + autoUpgradeMinorVersion: autoUpgradeMinorVersion + enableAutomaticUpgrade: enableAutomaticUpgrade + forceUpdateTag: !empty(forceUpdateTag) ? forceUpdateTag : null + settings: !empty(settings) ? settings : null + protectedSettings: !empty(protectedSettings) ? protectedSettings : null + suppressFailures: supressFailures + } +} + +@description('The name of the extension.') +output name string = extension.name + +@description('The resource ID of the extension.') +output resourceId string = extension.id + +@description('The name of the Resource Group the extension was created in.') +output resourceGroupName string = resourceGroup().name + +@description('The location the resource was deployed into.') +output location string = extension.location diff --git a/modules/compute/virtual-machine/extension/main.json b/modules/compute/virtual-machine/extension/main.json new file mode 100644 index 0000000000..50534220f0 --- /dev/null +++ b/modules/compute/virtual-machine/extension/main.json @@ -0,0 +1,181 @@ +{ + "$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.22.6.54827", + "templateHash": "9638144716839375831" + }, + "name": "Virtual Machine Extensions", + "description": "This module deploys a Virtual Machine Extension.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "virtualMachineName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the virtual machine extension." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. The location the extension is deployed to." + } + }, + "publisher": { + "type": "string", + "metadata": { + "description": "Required. The name of the extension handler publisher." + } + }, + "type": { + "type": "string", + "metadata": { + "description": "Required. Specifies the type of the extension; an example is \"CustomScriptExtension\"." + } + }, + "typeHandlerVersion": { + "type": "string", + "metadata": { + "description": "Required. Specifies the version of the script handler." + } + }, + "autoUpgradeMinorVersion": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true." + } + }, + "forceUpdateTag": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." + } + }, + "settings": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific settings." + } + }, + "protectedSettings": { + "type": "secureObject", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific protected settings." + } + }, + "supressFailures": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false." + } + }, + "enableAutomaticUpgrade": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + } + }, + "resources": { + "defaultTelemetry": { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + "virtualMachine": { + "existing": true, + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2022-11-01", + "name": "[parameters('virtualMachineName')]" + }, + "extension": { + "type": "Microsoft.Compute/virtualMachines/extensions", + "apiVersion": "2022-11-01", + "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "publisher": "[parameters('publisher')]", + "type": "[parameters('type')]", + "typeHandlerVersion": "[parameters('typeHandlerVersion')]", + "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", + "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", + "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", + "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", + "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", + "suppressFailures": "[parameters('supressFailures')]" + }, + "dependsOn": [ + "virtualMachine" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the extension." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the extension." + }, + "value": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the extension was created in." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('extension', '2022-11-01', 'full').location]" + } + } +} \ No newline at end of file diff --git a/modules/compute/virtual-machine/extension/version.json b/modules/compute/virtual-machine/extension/version.json new file mode 100644 index 0000000000..96236a61ba --- /dev/null +++ b/modules/compute/virtual-machine/extension/version.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.4", + "pathFilters": [ + "./main.json" + ] +} diff --git a/modules/compute/virtual-machine/main.bicep b/modules/compute/virtual-machine/main.bicep new file mode 100644 index 0000000000..f908e4b473 --- /dev/null +++ b/modules/compute/virtual-machine/main.bicep @@ -0,0 +1,771 @@ +metadata name = 'Virtual Machines' +metadata description = 'This module deploys a Virtual Machine with one or multiple NICs and optionally one or multiple public IPs.' +metadata owner = 'Azure/module-maintainers' + +// Main resource +@description('Optional. The name of the virtual machine to be created. You should use a unique prefix to reduce name collisions in Active Directory. If no value is provided, a 10 character long unique string will be generated based on the Resource Group\'s name.') +param name string = take(toLower(uniqueString(resourceGroup().name)), 10) + +@description('Optional. Can be used if the computer name needs to be different from the Azure VM resource name. If not used, the resource name will be used as computer name.') +param computerName string = name + +@description('Required. Specifies the size for the VMs.') +param vmSize string + +@description('Optional. This property can be used by user in the request to enable or disable the Host Encryption for the virtual machine. This will enable the encryption for all the disks including Resource/Temp disk at host itself. For security reasons, it is recommended to set encryptionAtHost to True. Restrictions: Cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs.') +param encryptionAtHost bool = true + +@description('Optional. Specifies the SecurityType of the virtual machine. It is set as TrustedLaunch to enable UefiSettings.') +param securityType string = '' + +@description('Optional. Specifies whether secure boot should be enabled on the virtual machine. This parameter is part of the UefiSettings. SecurityType should be set to TrustedLaunch to enable UefiSettings.') +param secureBootEnabled bool = false + +@description('Optional. Specifies whether vTPM should be enabled on the virtual machine. This parameter is part of the UefiSettings. SecurityType should be set to TrustedLaunch to enable UefiSettings.') +param vTpmEnabled bool = false + +@description('Required. OS image reference. In case of marketplace images, it\'s the combination of the publisher, offer, sku, version attributes. In case of custom images it\'s the resource ID of the custom image.') +param imageReference object + +@description('Optional. Specifies information about the marketplace image used to create the virtual machine. This element is only used for marketplace images. Before you can use a marketplace image from an API, you must enable the image for programmatic use.') +param plan object = {} + +@description('Required. Specifies the OS disk. For security reasons, it is recommended to specify DiskEncryptionSet into the osDisk object. Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs.') +param osDisk object + +@description('Optional. Specifies the data disks. For security reasons, it is recommended to specify DiskEncryptionSet into the dataDisk object. Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs.') +param dataDisks array = [] + +@description('Optional. The flag that enables or disables a capability to have one or more managed data disks with UltraSSD_LRS storage account type on the VM or VMSS. Managed disks with storage account type UltraSSD_LRS can be added to a virtual machine or virtual machine scale set only if this property is enabled.') +param ultraSSDEnabled bool = false + +@description('Required. Administrator username.') +@secure() +param adminUsername string + +@description('Optional. When specifying a Windows Virtual Machine, this value should be passed.') +@secure() +param adminPassword string = '' + +@description('Optional. Custom data associated to the VM, this value will be automatically converted into base64 to account for the expected VM format.') +param customData string = '' + +@description('Optional. Specifies set of certificates that should be installed onto the virtual machine.') +param certificatesToBeInstalled array = [] + +@description('Optional. Specifies the priority for the virtual machine.') +@allowed([ + 'Regular' + 'Low' + 'Spot' +]) +param priority string = 'Regular' + +@description('Optional. Specifies the eviction policy for the low priority virtual machine. Will result in \'Deallocate\' eviction policy.') +param enableEvictionPolicy bool = false + +@description('Optional. Specifies the maximum price you are willing to pay for a low priority VM/VMSS. This price is in US Dollars.') +param maxPriceForLowPriorityVm string = '' + +@description('Optional. Specifies resource ID about the dedicated host that the virtual machine resides in.') +param dedicatedHostId string = '' + +@description('Optional. Specifies that the image or disk that is being used was licensed on-premises. This element is only used for images that contain the Windows Server operating system.') +@allowed([ + 'Windows_Client' + 'Windows_Server' + '' +]) +param licenseType string = '' + +@description('Optional. The list of SSH public keys used to authenticate with linux based VMs.') +param publicKeys array = [] + +@description('Optional. The managed identity definition for this resource. The system-assigned managed identity will automatically be enabled if extensionAadJoinConfig.enabled = "True".') +param managedIdentities managedIdentitiesType + +@description('Optional. Whether boot diagnostics should be enabled on the Virtual Machine. Boot diagnostics will be enabled with a managed storage account if no bootDiagnosticsStorageAccountName value is provided. If bootDiagnostics and bootDiagnosticsStorageAccountName values are not provided, boot diagnostics will be disabled.') +param bootDiagnostics bool = false + +@description('Optional. Custom storage account used to store boot diagnostic information. Boot diagnostics will be enabled with a custom storage account if a value is provided.') +param bootDiagnosticStorageAccountName string = '' + +@description('Optional. Storage account boot diagnostic base URI.') +param bootDiagnosticStorageAccountUri string = '.blob.${environment().suffixes.storage}/' + +@description('Optional. Resource ID of a proximity placement group.') +param proximityPlacementGroupResourceId string = '' + +@description('Optional. Resource ID of an availability set. Cannot be used in combination with availability zone nor scale set.') +param availabilitySetResourceId string = '' + +@description('Optional. If set to 1, 2 or 3, the availability zone for all VMs is hardcoded to that value. If zero, then availability zones is not used. Cannot be used in combination with availability set nor scale set.') +@allowed([ + 0 + 1 + 2 + 3 +]) +param availabilityZone int = 0 + +// External resources +@description('Required. Configures NICs and PIPs.') +param nicConfigurations array + +@description('Optional. Recovery service vault name to add VMs to backup.') +param backupVaultName string = '' + +@description('Optional. Resource group of the backup recovery service vault. If not provided the current resource group name is considered by default.') +param backupVaultResourceGroup string = resourceGroup().name + +@description('Optional. Backup policy the VMs should be using for backup. If not provided, it will use the DefaultPolicy from the backup recovery service vault.') +param backupPolicyName string = 'DefaultPolicy' + +// Child resources +@description('Optional. Specifies whether extension operations should be allowed on the virtual machine. This may only be set to False when no extensions are present on the virtual machine.') +param allowExtensionOperations bool = true + +@description('Optional. Required if name is specified. Password of the user specified in user parameter.') +@secure() +param extensionDomainJoinPassword string = '' + +@description('Optional. The configuration for the [Domain Join] extension. Must at least contain the ["enabled": true] property to be executed.') +param extensionDomainJoinConfig object = { + enabled: false +} + +@description('Optional. The configuration for the [AAD Join] extension. Must at least contain the ["enabled": true] property to be executed.') +param extensionAadJoinConfig object = { + enabled: false +} + +@description('Optional. The configuration for the [Anti Malware] extension. Must at least contain the ["enabled": true] property to be executed.') +param extensionAntiMalwareConfig object = { + enabled: false +} + +@description('Optional. The configuration for the [Monitoring Agent] extension. Must at least contain the ["enabled": true] property to be executed.') +param extensionMonitoringAgentConfig object = { + enabled: false +} + +@description('Optional. Resource ID of the monitoring log analytics workspace. Must be set when extensionMonitoringAgentConfig is set to true.') +param monitoringWorkspaceId string = '' + +@description('Optional. The configuration for the [Dependency Agent] extension. Must at least contain the ["enabled": true] property to be executed.') +param extensionDependencyAgentConfig object = { + enabled: false +} + +@description('Optional. The configuration for the [Network Watcher Agent] extension. Must at least contain the ["enabled": true] property to be executed.') +param extensionNetworkWatcherAgentConfig object = { + enabled: false +} + +@description('Optional. The configuration for the [Azure Disk Encryption] extension. Must at least contain the ["enabled": true] property to be executed. Restrictions: Cannot be enabled on disks that have encryption at host enabled. Managed disks encrypted using Azure Disk Encryption cannot be encrypted using customer-managed keys.') +param extensionAzureDiskEncryptionConfig object = { + enabled: false +} + +@description('Optional. The configuration for the [Desired State Configuration] extension. Must at least contain the ["enabled": true] property to be executed.') +param extensionDSCConfig object = { + enabled: false +} + +@description('Optional. The configuration for the [Custom Script] extension. Must at least contain the ["enabled": true] property to be executed.') +param extensionCustomScriptConfig object = { + enabled: false + fileData: [] +} + +@description('Optional. Any object that contains the extension specific protected settings.') +@secure() +param extensionCustomScriptProtectedSetting object = {} + +// Shared parameters +@description('Optional. Location for all resources.') +param location string = resourceGroup().location + +@description('Optional. The lock settings of the service.') +param lock lockType + +@description('Optional. Array of role assignments to create.') +param roleAssignments roleAssignmentType + +@description('Optional. Tags of the resource.') +param tags object? + +@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') +param enableDefaultTelemetry bool = true + +@description('Generated. Do not provide a value! This date value is used to generate a registration token.') +param baseTime string = utcNow('u') + +@description('Optional. SAS token validity length to use to download files from storage accounts. Usage: \'PT8H\' - valid for 8 hours; \'P5D\' - valid for 5 days; \'P1Y\' - valid for 1 year. When not provided, the SAS token will be valid for 8 hours.') +param sasTokenValidityLength string = 'PT8H' + +@description('Required. The chosen OS type.') +@allowed([ + 'Windows' + 'Linux' +]) +param osType string + +@description('Optional. Specifies whether password authentication should be disabled.') +#disable-next-line secure-secrets-in-params // Not a secret +param disablePasswordAuthentication bool = false + +@description('Optional. Indicates whether virtual machine agent should be provisioned on the virtual machine. When this property is not specified in the request body, default behavior is to set it to true. This will ensure that VM Agent is installed on the VM so that extensions can be added to the VM later.') +param provisionVMAgent bool = true + +@description('Optional. Indicates whether Automatic Updates is enabled for the Windows virtual machine. Default value is true. When patchMode is set to Manual, this parameter must be set to false. For virtual machine scale sets, this property can be updated and updates will take effect on OS reprovisioning.') +param enableAutomaticUpdates bool = true + +@description('Optional. VM guest patching orchestration mode. \'AutomaticByOS\' & \'Manual\' are for Windows only, \'ImageDefault\' for Linux only. Refer to \'https://learn.microsoft.com/en-us/azure/virtual-machines/automatic-vm-guest-patching\'.') +@allowed([ + 'AutomaticByPlatform' + 'AutomaticByOS' + 'Manual' + 'ImageDefault' + '' +]) +param patchMode string = '' + +@description('Optional. VM guest patching assessment mode. Set it to \'AutomaticByPlatform\' to enable automatically check for updates every 24 hours.') +@allowed([ + 'AutomaticByPlatform' + 'ImageDefault' +]) +param patchAssessmentMode string = 'ImageDefault' + +@description('Optional. Specifies the time zone of the virtual machine. e.g. \'Pacific Standard Time\'. Possible values can be `TimeZoneInfo.id` value from time zones returned by `TimeZoneInfo.GetSystemTimeZones`.') +param timeZone string = '' + +@description('Optional. Specifies additional base-64 encoded XML formatted information that can be included in the Unattend.xml file, which is used by Windows Setup. - AdditionalUnattendContent object.') +param additionalUnattendContent array = [] + +@description('Optional. Specifies the Windows Remote Management listeners. This enables remote Windows PowerShell. - WinRMConfiguration object.') +param winRM object = {} + +@description('Required. The configuration profile of automanage.') +@allowed([ + '/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesProduction' + '/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesDevTest' + '' +]) +param configurationProfile string = '' + +var publicKeysFormatted = [for publicKey in publicKeys: { + path: publicKey.path + keyData: publicKey.keyData +}] + +var linuxConfiguration = { + disablePasswordAuthentication: disablePasswordAuthentication + ssh: { + publicKeys: publicKeysFormatted + } + provisionVMAgent: provisionVMAgent + patchSettings: (provisionVMAgent && (patchMode =~ 'AutomaticByPlatform' || patchMode =~ 'ImageDefault')) ? { + patchMode: patchMode + assessmentMode: patchAssessmentMode + } : null +} + +var windowsConfiguration = { + provisionVMAgent: provisionVMAgent + enableAutomaticUpdates: enableAutomaticUpdates + patchSettings: (provisionVMAgent && (patchMode =~ 'AutomaticByPlatform' || patchMode =~ 'AutomaticByOS' || patchMode =~ 'Manual')) ? { + patchMode: patchMode + assessmentMode: patchAssessmentMode + } : null + timeZone: empty(timeZone) ? null : timeZone + additionalUnattendContent: empty(additionalUnattendContent) ? null : additionalUnattendContent + winRM: !empty(winRM) ? { + listeners: winRM + } : null +} + +var accountSasProperties = { + signedServices: 'b' + signedPermission: 'r' + signedExpiry: dateTimeAdd(baseTime, sasTokenValidityLength) + signedResourceTypes: 'o' + signedProtocol: 'https' +} + +var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +// If AADJoin Extension is enabled then we automatically enable SystemAssigned (required by AADJoin), otherwise we follow the usual logic. +var identity = !empty(managedIdentities) ? { + type: (extensionAadJoinConfig.enabled ? true : (managedIdentities.?systemAssigned ?? false)) ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : null) + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null +} : null + +var enableReferencedModulesTelemetry = false + +var builtInRoleNames = { + Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') + 'Data Operator for Managed Disks': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '959f8984-c045-4866-89c7-12bf9737be2e') + 'Desktop Virtualization Power On Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '489581de-a3bd-480d-9518-53dea7416b33') + 'Desktop Virtualization Power On Off Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '40c5ff49-9181-41f8-ae61-143b0e78555e') + 'Desktop Virtualization Virtual Machine Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c') + 'DevTest Labs User': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64') + 'Disk Backup Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3e5e47e6-65f7-47ef-90b5-e5dd4d455f24') + 'Disk Pool Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '60fc6e62-5479-42d4-8bf4-67625fcc2840') + 'Disk Restore Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b50d9833-a0cb-478e-945f-707fcc997c13') + 'Disk Snapshot Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7efff54f-a5b4-42b5-a1c5-5411624893ce') + Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') + Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168') + 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') + 'Virtual Machine Administrator Login': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4') + 'Virtual Machine Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c') + 'Virtual Machine User Login': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52') + 'VM Scanner Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'd24ecba3-c1f4-40fa-a7bb-4588a071e8fd') +} + +resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (enableDefaultTelemetry) { + name: 'pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-${uniqueString(deployment().name, location)}' + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + } + } +} + +module vm_nic 'modules/nested_networkInterface.bicep' = [for (nicConfiguration, index) in nicConfigurations: { + name: '${uniqueString(deployment().name, location)}-VM-Nic-${index}' + params: { + networkInterfaceName: '${name}${nicConfiguration.nicSuffix}' + virtualMachineName: name + location: location + enableIPForwarding: contains(nicConfiguration, 'enableIPForwarding') ? (!empty(nicConfiguration.enableIPForwarding) ? nicConfiguration.enableIPForwarding : false) : false + enableAcceleratedNetworking: contains(nicConfiguration, 'enableAcceleratedNetworking') ? nicConfiguration.enableAcceleratedNetworking : true + dnsServers: contains(nicConfiguration, 'dnsServers') ? (!empty(nicConfiguration.dnsServers) ? nicConfiguration.dnsServers : []) : [] + networkSecurityGroupResourceId: contains(nicConfiguration, 'networkSecurityGroupResourceId') ? nicConfiguration.networkSecurityGroupResourceId : '' + ipConfigurations: nicConfiguration.ipConfigurations + lock: nicConfiguration.?lock ?? lock + tags: nicConfiguration.?tags ?? tags + diagnosticSettings: nicConfiguration.?diagnosticSettings + roleAssignments: nicConfiguration.?roleAssignments + } +}] + +resource vm 'Microsoft.Compute/virtualMachines@2022-11-01' = { + name: name + location: location + identity: identity + tags: tags + zones: availabilityZone != 0 ? array(availabilityZone) : null + plan: !empty(plan) ? plan : null + properties: { + hardwareProfile: { + vmSize: vmSize + } + securityProfile: { + encryptionAtHost: encryptionAtHost ? encryptionAtHost : null + securityType: securityType + uefiSettings: securityType == 'TrustedLaunch' ? { + secureBootEnabled: secureBootEnabled + vTpmEnabled: vTpmEnabled + } : null + } + storageProfile: { + imageReference: imageReference + osDisk: { + name: '${name}-disk-os-01' + createOption: contains(osDisk, 'createOption') ? osDisk.createOption : 'FromImage' + deleteOption: contains(osDisk, 'deleteOption') ? osDisk.deleteOption : 'Delete' + diskSizeGB: osDisk.diskSizeGB + caching: contains(osDisk, 'caching') ? osDisk.caching : 'ReadOnly' + managedDisk: { + storageAccountType: osDisk.managedDisk.storageAccountType + diskEncryptionSet: contains(osDisk.managedDisk, 'diskEncryptionSet') ? { + id: osDisk.managedDisk.diskEncryptionSet.id + } : null + } + } + dataDisks: [for (dataDisk, index) in dataDisks: { + lun: index + name: '${name}-disk-data-${padLeft((index + 1), 2, '0')}' + diskSizeGB: dataDisk.diskSizeGB + createOption: contains(dataDisk, 'createOption') ? dataDisk.createOption : 'Empty' + deleteOption: contains(dataDisk, 'deleteOption') ? dataDisk.deleteOption : 'Delete' + caching: contains(dataDisk, 'caching') ? dataDisk.caching : 'ReadOnly' + managedDisk: { + storageAccountType: dataDisk.managedDisk.storageAccountType + diskEncryptionSet: contains(dataDisk.managedDisk, 'diskEncryptionSet') ? { + id: dataDisk.managedDisk.diskEncryptionSet.id + } : null + } + }] + } + additionalCapabilities: { + ultraSSDEnabled: ultraSSDEnabled + } + osProfile: { + computerName: computerName + adminUsername: adminUsername + adminPassword: adminPassword + customData: !empty(customData) ? base64(customData) : null + windowsConfiguration: osType == 'Windows' ? windowsConfiguration : null + linuxConfiguration: osType == 'Linux' ? linuxConfiguration : null + secrets: certificatesToBeInstalled + allowExtensionOperations: allowExtensionOperations + } + networkProfile: { + networkInterfaces: [for (nicConfiguration, index) in nicConfigurations: { + properties: { + deleteOption: contains(nicConfiguration, 'deleteOption') ? nicConfiguration.deleteOption : 'Delete' + primary: index == 0 ? true : false + } + id: az.resourceId('Microsoft.Network/networkInterfaces', '${name}${nicConfiguration.nicSuffix}') + }] + } + diagnosticsProfile: { + bootDiagnostics: { + enabled: !empty(bootDiagnosticStorageAccountName) ? true : bootDiagnostics + storageUri: !empty(bootDiagnosticStorageAccountName) ? 'https://${bootDiagnosticStorageAccountName}${bootDiagnosticStorageAccountUri}' : null + } + } + availabilitySet: !empty(availabilitySetResourceId) ? { + id: availabilitySetResourceId + } : null + proximityPlacementGroup: !empty(proximityPlacementGroupResourceId) ? { + id: proximityPlacementGroupResourceId + } : null + priority: priority + evictionPolicy: enableEvictionPolicy ? 'Deallocate' : null + billingProfile: !empty(priority) && !empty(maxPriceForLowPriorityVm) ? { + maxPrice: maxPriceForLowPriorityVm + } : null + host: !empty(dedicatedHostId) ? { + id: dedicatedHostId + } : null + licenseType: !empty(licenseType) ? licenseType : null + } + dependsOn: [ + vm_nic + ] +} + +resource vm_configurationProfileAssignment 'Microsoft.Automanage/configurationProfileAssignments@2021-04-30-preview' = if (!empty(configurationProfile)) { + name: 'default' + properties: { + configurationProfile: configurationProfile + } + scope: vm +} + +module vm_aadJoinExtension 'extension/main.bicep' = if (extensionAadJoinConfig.enabled) { + name: '${uniqueString(deployment().name, location)}-VM-AADLogin' + params: { + virtualMachineName: vm.name + name: 'AADLogin' + publisher: 'Microsoft.Azure.ActiveDirectory' + type: osType == 'Windows' ? 'AADLoginForWindows' : 'AADSSHLoginforLinux' + typeHandlerVersion: contains(extensionAadJoinConfig, 'typeHandlerVersion') ? extensionAadJoinConfig.typeHandlerVersion : '1.0' + autoUpgradeMinorVersion: contains(extensionAadJoinConfig, 'autoUpgradeMinorVersion') ? extensionAadJoinConfig.autoUpgradeMinorVersion : true + enableAutomaticUpgrade: contains(extensionAadJoinConfig, 'enableAutomaticUpgrade') ? extensionAadJoinConfig.enableAutomaticUpgrade : false + settings: contains(extensionAadJoinConfig, 'settings') ? extensionAadJoinConfig.settings : {} + tags: extensionAadJoinConfig.?tags ?? tags + } +} + +module vm_domainJoinExtension 'extension/main.bicep' = if (extensionDomainJoinConfig.enabled) { + name: '${uniqueString(deployment().name, location)}-VM-DomainJoin' + params: { + virtualMachineName: vm.name + name: 'DomainJoin' + publisher: 'Microsoft.Compute' + type: 'JsonADDomainExtension' + typeHandlerVersion: contains(extensionDomainJoinConfig, 'typeHandlerVersion') ? extensionDomainJoinConfig.typeHandlerVersion : '1.3' + autoUpgradeMinorVersion: contains(extensionDomainJoinConfig, 'autoUpgradeMinorVersion') ? extensionDomainJoinConfig.autoUpgradeMinorVersion : true + enableAutomaticUpgrade: contains(extensionDomainJoinConfig, 'enableAutomaticUpgrade') ? extensionDomainJoinConfig.enableAutomaticUpgrade : false + settings: extensionDomainJoinConfig.settings + tags: extensionDomainJoinConfig.?tags ?? tags + protectedSettings: { + Password: extensionDomainJoinPassword + } + enableDefaultTelemetry: enableReferencedModulesTelemetry + } +} + +module vm_microsoftAntiMalwareExtension 'extension/main.bicep' = if (extensionAntiMalwareConfig.enabled) { + name: '${uniqueString(deployment().name, location)}-VM-MicrosoftAntiMalware' + params: { + virtualMachineName: vm.name + name: 'MicrosoftAntiMalware' + publisher: 'Microsoft.Azure.Security' + type: 'IaaSAntimalware' + typeHandlerVersion: contains(extensionAntiMalwareConfig, 'typeHandlerVersion') ? extensionAntiMalwareConfig.typeHandlerVersion : '1.3' + autoUpgradeMinorVersion: contains(extensionAntiMalwareConfig, 'autoUpgradeMinorVersion') ? extensionAntiMalwareConfig.autoUpgradeMinorVersion : true + enableAutomaticUpgrade: contains(extensionAntiMalwareConfig, 'enableAutomaticUpgrade') ? extensionAntiMalwareConfig.enableAutomaticUpgrade : false + settings: extensionAntiMalwareConfig.settings + tags: extensionAntiMalwareConfig.?tags ?? tags + enableDefaultTelemetry: enableReferencedModulesTelemetry + } +} + +resource vm_logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2021-06-01' existing = if (!empty(monitoringWorkspaceId)) { + name: last(split((!empty(monitoringWorkspaceId) ? monitoringWorkspaceId : 'law'), '/'))! + scope: az.resourceGroup(split((!empty(monitoringWorkspaceId) ? monitoringWorkspaceId : '//'), '/')[2], split((!empty(monitoringWorkspaceId) ? monitoringWorkspaceId : '////'), '/')[4]) +} + +module vm_microsoftMonitoringAgentExtension 'extension/main.bicep' = if (extensionMonitoringAgentConfig.enabled) { + name: '${uniqueString(deployment().name, location)}-VM-MicrosoftMonitoringAgent' + params: { + virtualMachineName: vm.name + name: 'MicrosoftMonitoringAgent' + publisher: 'Microsoft.EnterpriseCloud.Monitoring' + type: osType == 'Windows' ? 'MicrosoftMonitoringAgent' : 'OmsAgentForLinux' + typeHandlerVersion: contains(extensionMonitoringAgentConfig, 'typeHandlerVersion') ? extensionMonitoringAgentConfig.typeHandlerVersion : (osType == 'Windows' ? '1.0' : '1.7') + autoUpgradeMinorVersion: contains(extensionMonitoringAgentConfig, 'autoUpgradeMinorVersion') ? extensionMonitoringAgentConfig.autoUpgradeMinorVersion : true + enableAutomaticUpgrade: contains(extensionMonitoringAgentConfig, 'enableAutomaticUpgrade') ? extensionMonitoringAgentConfig.enableAutomaticUpgrade : false + settings: { + workspaceId: !empty(monitoringWorkspaceId) ? vm_logAnalyticsWorkspace.properties.customerId : '' + } + tags: extensionMonitoringAgentConfig.?tags ?? tags + protectedSettings: { + workspaceKey: !empty(monitoringWorkspaceId) ? vm_logAnalyticsWorkspace.listKeys().primarySharedKey : '' + } + enableDefaultTelemetry: enableReferencedModulesTelemetry + } +} + +module vm_dependencyAgentExtension 'extension/main.bicep' = if (extensionDependencyAgentConfig.enabled) { + name: '${uniqueString(deployment().name, location)}-VM-DependencyAgent' + params: { + virtualMachineName: vm.name + name: 'DependencyAgent' + publisher: 'Microsoft.Azure.Monitoring.DependencyAgent' + type: osType == 'Windows' ? 'DependencyAgentWindows' : 'DependencyAgentLinux' + typeHandlerVersion: contains(extensionDependencyAgentConfig, 'typeHandlerVersion') ? extensionDependencyAgentConfig.typeHandlerVersion : '9.5' + autoUpgradeMinorVersion: contains(extensionDependencyAgentConfig, 'autoUpgradeMinorVersion') ? extensionDependencyAgentConfig.autoUpgradeMinorVersion : true + enableAutomaticUpgrade: contains(extensionDependencyAgentConfig, 'enableAutomaticUpgrade') ? extensionDependencyAgentConfig.enableAutomaticUpgrade : true + enableDefaultTelemetry: enableReferencedModulesTelemetry + tags: extensionDependencyAgentConfig.?tags ?? tags + } +} + +module vm_networkWatcherAgentExtension 'extension/main.bicep' = if (extensionNetworkWatcherAgentConfig.enabled) { + name: '${uniqueString(deployment().name, location)}-VM-NetworkWatcherAgent' + params: { + virtualMachineName: vm.name + name: 'NetworkWatcherAgent' + publisher: 'Microsoft.Azure.NetworkWatcher' + type: osType == 'Windows' ? 'NetworkWatcherAgentWindows' : 'NetworkWatcherAgentLinux' + typeHandlerVersion: contains(extensionNetworkWatcherAgentConfig, 'typeHandlerVersion') ? extensionNetworkWatcherAgentConfig.typeHandlerVersion : '1.4' + autoUpgradeMinorVersion: contains(extensionNetworkWatcherAgentConfig, 'autoUpgradeMinorVersion') ? extensionNetworkWatcherAgentConfig.autoUpgradeMinorVersion : true + enableAutomaticUpgrade: contains(extensionNetworkWatcherAgentConfig, 'enableAutomaticUpgrade') ? extensionNetworkWatcherAgentConfig.enableAutomaticUpgrade : false + enableDefaultTelemetry: enableReferencedModulesTelemetry + tags: extensionNetworkWatcherAgentConfig.?tags ?? tags + } +} + +module vm_desiredStateConfigurationExtension 'extension/main.bicep' = if (extensionDSCConfig.enabled) { + name: '${uniqueString(deployment().name, location)}-VM-DesiredStateConfiguration' + params: { + virtualMachineName: vm.name + name: 'DesiredStateConfiguration' + publisher: 'Microsoft.Powershell' + type: 'DSC' + typeHandlerVersion: contains(extensionDSCConfig, 'typeHandlerVersion') ? extensionDSCConfig.typeHandlerVersion : '2.77' + autoUpgradeMinorVersion: contains(extensionDSCConfig, 'autoUpgradeMinorVersion') ? extensionDSCConfig.autoUpgradeMinorVersion : true + enableAutomaticUpgrade: contains(extensionDSCConfig, 'enableAutomaticUpgrade') ? extensionDSCConfig.enableAutomaticUpgrade : false + settings: contains(extensionDSCConfig, 'settings') ? extensionDSCConfig.settings : {} + tags: extensionDSCConfig.?tags ?? tags + protectedSettings: contains(extensionDSCConfig, 'protectedSettings') ? extensionDSCConfig.protectedSettings : {} + enableDefaultTelemetry: enableReferencedModulesTelemetry + } +} + +module vm_customScriptExtension 'extension/main.bicep' = if (extensionCustomScriptConfig.enabled) { + name: '${uniqueString(deployment().name, location)}-VM-CustomScriptExtension' + params: { + virtualMachineName: vm.name + name: 'CustomScriptExtension' + publisher: osType == 'Windows' ? 'Microsoft.Compute' : 'Microsoft.Azure.Extensions' + type: osType == 'Windows' ? 'CustomScriptExtension' : 'CustomScript' + typeHandlerVersion: contains(extensionCustomScriptConfig, 'typeHandlerVersion') ? extensionCustomScriptConfig.typeHandlerVersion : (osType == 'Windows' ? '1.10' : '2.1') + autoUpgradeMinorVersion: contains(extensionCustomScriptConfig, 'autoUpgradeMinorVersion') ? extensionCustomScriptConfig.autoUpgradeMinorVersion : true + enableAutomaticUpgrade: contains(extensionCustomScriptConfig, 'enableAutomaticUpgrade') ? extensionCustomScriptConfig.enableAutomaticUpgrade : false + settings: { + fileUris: [for fileData in extensionCustomScriptConfig.fileData: contains(fileData, 'storageAccountId') ? '${fileData.uri}?${listAccountSas(fileData.storageAccountId, '2019-04-01', accountSasProperties).accountSasToken}' : fileData.uri] + } + tags: extensionCustomScriptConfig.?tags ?? tags + protectedSettings: extensionCustomScriptProtectedSetting + enableDefaultTelemetry: enableReferencedModulesTelemetry + } + dependsOn: [ + vm_desiredStateConfigurationExtension + ] +} + +module vm_azureDiskEncryptionExtension 'extension/main.bicep' = if (extensionAzureDiskEncryptionConfig.enabled) { + name: '${uniqueString(deployment().name, location)}-VM-AzureDiskEncryption' + params: { + virtualMachineName: vm.name + name: 'AzureDiskEncryption' + publisher: 'Microsoft.Azure.Security' + type: osType == 'Windows' ? 'AzureDiskEncryption' : 'AzureDiskEncryptionForLinux' + typeHandlerVersion: contains(extensionAzureDiskEncryptionConfig, 'typeHandlerVersion') ? extensionAzureDiskEncryptionConfig.typeHandlerVersion : (osType == 'Windows' ? '2.2' : '1.1') + autoUpgradeMinorVersion: contains(extensionAzureDiskEncryptionConfig, 'autoUpgradeMinorVersion') ? extensionAzureDiskEncryptionConfig.autoUpgradeMinorVersion : true + enableAutomaticUpgrade: contains(extensionAzureDiskEncryptionConfig, 'enableAutomaticUpgrade') ? extensionAzureDiskEncryptionConfig.enableAutomaticUpgrade : false + forceUpdateTag: contains(extensionAzureDiskEncryptionConfig, 'forceUpdateTag') ? extensionAzureDiskEncryptionConfig.forceUpdateTag : '1.0' + settings: extensionAzureDiskEncryptionConfig.settings + tags: extensionAzureDiskEncryptionConfig.?tags ?? tags + enableDefaultTelemetry: enableReferencedModulesTelemetry + } + dependsOn: [ + vm_customScriptExtension + vm_microsoftMonitoringAgentExtension + ] +} + +module vm_backup '../../recovery-services/vault/backup-fabric/protection-container/protected-item/main.bicep' = if (!empty(backupVaultName)) { + name: '${uniqueString(deployment().name, location)}-VM-Backup' + params: { + name: 'vm;iaasvmcontainerv2;${resourceGroup().name};${vm.name}' + policyId: az.resourceId('Microsoft.RecoveryServices/vaults/backupPolicies', backupVaultName, backupPolicyName) + protectedItemType: 'Microsoft.Compute/virtualMachines' + protectionContainerName: 'iaasvmcontainer;iaasvmcontainerv2;${resourceGroup().name};${vm.name}' + recoveryVaultName: backupVaultName + sourceResourceId: vm.id + enableDefaultTelemetry: enableReferencedModulesTelemetry + } + scope: az.resourceGroup(backupVaultResourceGroup) + dependsOn: [ + vm_aadJoinExtension + vm_domainJoinExtension + vm_microsoftMonitoringAgentExtension + vm_microsoftAntiMalwareExtension + vm_networkWatcherAgentExtension + vm_dependencyAgentExtension + vm_desiredStateConfigurationExtension + vm_customScriptExtension + ] +} + +resource vm_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock ?? {}) && lock.?kind != 'None') { + name: lock.?name ?? 'lock-${name}' + properties: { + level: lock.?kind ?? '' + notes: lock.?kind == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot delete or modify the resource or child resources.' + } + scope: vm +} + +resource vm_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(vm.id, roleAssignment.principalId, roleAssignment.roleDefinitionIdOrName) + properties: { + roleDefinitionId: contains(builtInRoleNames, roleAssignment.roleDefinitionIdOrName) ? builtInRoleNames[roleAssignment.roleDefinitionIdOrName] : contains(roleAssignment.roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/') ? roleAssignment.roleDefinitionIdOrName : subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleAssignment.roleDefinitionIdOrName) + principalId: roleAssignment.principalId + description: roleAssignment.?description + principalType: roleAssignment.?principalType + condition: roleAssignment.?condition + conditionVersion: !empty(roleAssignment.?condition) ? (roleAssignment.?conditionVersion ?? '2.0') : null // Must only be set if condtion is set + delegatedManagedIdentityResourceId: roleAssignment.?delegatedManagedIdentityResourceId + } + scope: vm +}] + +@description('The name of the VM.') +output name string = vm.name + +@description('The resource ID of the VM.') +output resourceId string = vm.id + +@description('The name of the resource group the VM was created in.') +output resourceGroupName string = resourceGroup().name + +@description('The principal ID of the system assigned identity.') +output systemAssignedMIPrincipalId string = (managedIdentities.?systemAssigned ?? false) && contains(vm.identity, 'principalId') ? vm.identity.principalId : '' + +@description('The location the resource was deployed into.') +output location string = vm.location + +// =============== // +// 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('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? + + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + logCategoriesAndGroups: { + @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') + category: string? + + @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.') + categoryGroup: string? + }[]? + + @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: { + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') + category: string + }[]? + + @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.') + logAnalyticsDestinationType: ('Dedicated' | 'AzureDiagnostics')? + + @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.') + workspaceResourceId: string? + + @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.') + storageAccountResourceId: string? + + @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.') + eventHubAuthorizationRuleResourceId: string? + + @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.') + eventHubName: string? + + @description('Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs.') + marketplacePartnerResourceId: string? +}[]? diff --git a/modules/compute/virtual-machine/main.json b/modules/compute/virtual-machine/main.json new file mode 100644 index 0000000000..cb696cbdcc --- /dev/null +++ b/modules/compute/virtual-machine/main.json @@ -0,0 +1,4524 @@ +{ + "$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": "89939038941992549" + }, + "name": "Virtual Machines", + "description": "This module deploys a Virtual Machine with one or multiple NICs and optionally one or multiple public IPs.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "managedIdentitiesType": { + "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" + }, + "nullable": true, + "metadata": { + "description": "Optional. The resource ID(s) to assign to the resource." + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "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 + }, + "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." + } + } + } + }, + "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." + } + } + } + }, + "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." + } + }, + "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." + } + }, + "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." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "defaultValue": "[take(toLower(uniqueString(resourceGroup().name)), 10)]", + "metadata": { + "description": "Optional. The name of the virtual machine to be created. You should use a unique prefix to reduce name collisions in Active Directory. If no value is provided, a 10 character long unique string will be generated based on the Resource Group's name." + } + }, + "computerName": { + "type": "string", + "defaultValue": "[parameters('name')]", + "metadata": { + "description": "Optional. Can be used if the computer name needs to be different from the Azure VM resource name. If not used, the resource name will be used as computer name." + } + }, + "vmSize": { + "type": "string", + "metadata": { + "description": "Required. Specifies the size for the VMs." + } + }, + "encryptionAtHost": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. This property can be used by user in the request to enable or disable the Host Encryption for the virtual machine. This will enable the encryption for all the disks including Resource/Temp disk at host itself. For security reasons, it is recommended to set encryptionAtHost to True. Restrictions: Cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs." + } + }, + "securityType": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Specifies the SecurityType of the virtual machine. It is set as TrustedLaunch to enable UefiSettings." + } + }, + "secureBootEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Specifies whether secure boot should be enabled on the virtual machine. This parameter is part of the UefiSettings. SecurityType should be set to TrustedLaunch to enable UefiSettings." + } + }, + "vTpmEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Specifies whether vTPM should be enabled on the virtual machine. This parameter is part of the UefiSettings. SecurityType should be set to TrustedLaunch to enable UefiSettings." + } + }, + "imageReference": { + "type": "object", + "metadata": { + "description": "Required. OS image reference. In case of marketplace images, it's the combination of the publisher, offer, sku, version attributes. In case of custom images it's the resource ID of the custom image." + } + }, + "plan": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Specifies information about the marketplace image used to create the virtual machine. This element is only used for marketplace images. Before you can use a marketplace image from an API, you must enable the image for programmatic use." + } + }, + "osDisk": { + "type": "object", + "metadata": { + "description": "Required. Specifies the OS disk. For security reasons, it is recommended to specify DiskEncryptionSet into the osDisk object. Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs." + } + }, + "dataDisks": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Specifies the data disks. For security reasons, it is recommended to specify DiskEncryptionSet into the dataDisk object. Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs." + } + }, + "ultraSSDEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. The flag that enables or disables a capability to have one or more managed data disks with UltraSSD_LRS storage account type on the VM or VMSS. Managed disks with storage account type UltraSSD_LRS can be added to a virtual machine or virtual machine scale set only if this property is enabled." + } + }, + "adminUsername": { + "type": "securestring", + "metadata": { + "description": "Required. Administrator username." + } + }, + "adminPassword": { + "type": "securestring", + "defaultValue": "", + "metadata": { + "description": "Optional. When specifying a Windows Virtual Machine, this value should be passed." + } + }, + "customData": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Custom data associated to the VM, this value will be automatically converted into base64 to account for the expected VM format." + } + }, + "certificatesToBeInstalled": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Specifies set of certificates that should be installed onto the virtual machine." + } + }, + "priority": { + "type": "string", + "defaultValue": "Regular", + "allowedValues": [ + "Regular", + "Low", + "Spot" + ], + "metadata": { + "description": "Optional. Specifies the priority for the virtual machine." + } + }, + "enableEvictionPolicy": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Specifies the eviction policy for the low priority virtual machine. Will result in 'Deallocate' eviction policy." + } + }, + "maxPriceForLowPriorityVm": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Specifies the maximum price you are willing to pay for a low priority VM/VMSS. This price is in US Dollars." + } + }, + "dedicatedHostId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Specifies resource ID about the dedicated host that the virtual machine resides in." + } + }, + "licenseType": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "Windows_Client", + "Windows_Server", + "" + ], + "metadata": { + "description": "Optional. Specifies that the image or disk that is being used was licensed on-premises. This element is only used for images that contain the Windows Server operating system." + } + }, + "publicKeys": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. The list of SSH public keys used to authenticate with linux based VMs." + } + }, + "managedIdentities": { + "$ref": "#/definitions/managedIdentitiesType", + "metadata": { + "description": "Optional. The managed identity definition for this resource. The system-assigned managed identity will automatically be enabled if extensionAadJoinConfig.enabled = \"True\"." + } + }, + "bootDiagnostics": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Whether boot diagnostics should be enabled on the Virtual Machine. Boot diagnostics will be enabled with a managed storage account if no bootDiagnosticsStorageAccountName value is provided. If bootDiagnostics and bootDiagnosticsStorageAccountName values are not provided, boot diagnostics will be disabled." + } + }, + "bootDiagnosticStorageAccountName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Custom storage account used to store boot diagnostic information. Boot diagnostics will be enabled with a custom storage account if a value is provided." + } + }, + "bootDiagnosticStorageAccountUri": { + "type": "string", + "defaultValue": "[format('.blob.{0}/', environment().suffixes.storage)]", + "metadata": { + "description": "Optional. Storage account boot diagnostic base URI." + } + }, + "proximityPlacementGroupResourceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of a proximity placement group." + } + }, + "availabilitySetResourceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of an availability set. Cannot be used in combination with availability zone nor scale set." + } + }, + "availabilityZone": { + "type": "int", + "defaultValue": 0, + "allowedValues": [ + 0, + 1, + 2, + 3 + ], + "metadata": { + "description": "Optional. If set to 1, 2 or 3, the availability zone for all VMs is hardcoded to that value. If zero, then availability zones is not used. Cannot be used in combination with availability set nor scale set." + } + }, + "nicConfigurations": { + "type": "array", + "metadata": { + "description": "Required. Configures NICs and PIPs." + } + }, + "backupVaultName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Recovery service vault name to add VMs to backup." + } + }, + "backupVaultResourceGroup": { + "type": "string", + "defaultValue": "[resourceGroup().name]", + "metadata": { + "description": "Optional. Resource group of the backup recovery service vault. If not provided the current resource group name is considered by default." + } + }, + "backupPolicyName": { + "type": "string", + "defaultValue": "DefaultPolicy", + "metadata": { + "description": "Optional. Backup policy the VMs should be using for backup. If not provided, it will use the DefaultPolicy from the backup recovery service vault." + } + }, + "allowExtensionOperations": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Specifies whether extension operations should be allowed on the virtual machine. This may only be set to False when no extensions are present on the virtual machine." + } + }, + "extensionDomainJoinPassword": { + "type": "securestring", + "defaultValue": "", + "metadata": { + "description": "Optional. Required if name is specified. Password of the user specified in user parameter." + } + }, + "extensionDomainJoinConfig": { + "type": "object", + "defaultValue": { + "enabled": false + }, + "metadata": { + "description": "Optional. The configuration for the [Domain Join] extension. Must at least contain the [\"enabled\": true] property to be executed." + } + }, + "extensionAadJoinConfig": { + "type": "object", + "defaultValue": { + "enabled": false + }, + "metadata": { + "description": "Optional. The configuration for the [AAD Join] extension. Must at least contain the [\"enabled\": true] property to be executed." + } + }, + "extensionAntiMalwareConfig": { + "type": "object", + "defaultValue": { + "enabled": false + }, + "metadata": { + "description": "Optional. The configuration for the [Anti Malware] extension. Must at least contain the [\"enabled\": true] property to be executed." + } + }, + "extensionMonitoringAgentConfig": { + "type": "object", + "defaultValue": { + "enabled": false + }, + "metadata": { + "description": "Optional. The configuration for the [Monitoring Agent] extension. Must at least contain the [\"enabled\": true] property to be executed." + } + }, + "monitoringWorkspaceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of the monitoring log analytics workspace. Must be set when extensionMonitoringAgentConfig is set to true." + } + }, + "extensionDependencyAgentConfig": { + "type": "object", + "defaultValue": { + "enabled": false + }, + "metadata": { + "description": "Optional. The configuration for the [Dependency Agent] extension. Must at least contain the [\"enabled\": true] property to be executed." + } + }, + "extensionNetworkWatcherAgentConfig": { + "type": "object", + "defaultValue": { + "enabled": false + }, + "metadata": { + "description": "Optional. The configuration for the [Network Watcher Agent] extension. Must at least contain the [\"enabled\": true] property to be executed." + } + }, + "extensionAzureDiskEncryptionConfig": { + "type": "object", + "defaultValue": { + "enabled": false + }, + "metadata": { + "description": "Optional. The configuration for the [Azure Disk Encryption] extension. Must at least contain the [\"enabled\": true] property to be executed. Restrictions: Cannot be enabled on disks that have encryption at host enabled. Managed disks encrypted using Azure Disk Encryption cannot be encrypted using customer-managed keys." + } + }, + "extensionDSCConfig": { + "type": "object", + "defaultValue": { + "enabled": false + }, + "metadata": { + "description": "Optional. The configuration for the [Desired State Configuration] extension. Must at least contain the [\"enabled\": true] property to be executed." + } + }, + "extensionCustomScriptConfig": { + "type": "object", + "defaultValue": { + "enabled": false, + "fileData": [] + }, + "metadata": { + "description": "Optional. The configuration for the [Custom Script] extension. Must at least contain the [\"enabled\": true] property to be executed." + } + }, + "extensionCustomScriptProtectedSetting": { + "type": "secureObject", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific protected settings." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + }, + "baseTime": { + "type": "string", + "defaultValue": "[utcNow('u')]", + "metadata": { + "description": "Generated. Do not provide a value! This date value is used to generate a registration token." + } + }, + "sasTokenValidityLength": { + "type": "string", + "defaultValue": "PT8H", + "metadata": { + "description": "Optional. SAS token validity length to use to download files from storage accounts. Usage: 'PT8H' - valid for 8 hours; 'P5D' - valid for 5 days; 'P1Y' - valid for 1 year. When not provided, the SAS token will be valid for 8 hours." + } + }, + "osType": { + "type": "string", + "allowedValues": [ + "Windows", + "Linux" + ], + "metadata": { + "description": "Required. The chosen OS type." + } + }, + "disablePasswordAuthentication": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Specifies whether password authentication should be disabled." + } + }, + "provisionVMAgent": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Indicates whether virtual machine agent should be provisioned on the virtual machine. When this property is not specified in the request body, default behavior is to set it to true. This will ensure that VM Agent is installed on the VM so that extensions can be added to the VM later." + } + }, + "enableAutomaticUpdates": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Indicates whether Automatic Updates is enabled for the Windows virtual machine. Default value is true. When patchMode is set to Manual, this parameter must be set to false. For virtual machine scale sets, this property can be updated and updates will take effect on OS reprovisioning." + } + }, + "patchMode": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "AutomaticByPlatform", + "AutomaticByOS", + "Manual", + "ImageDefault", + "" + ], + "metadata": { + "description": "Optional. VM guest patching orchestration mode. 'AutomaticByOS' & 'Manual' are for Windows only, 'ImageDefault' for Linux only. Refer to 'https://learn.microsoft.com/en-us/azure/virtual-machines/automatic-vm-guest-patching'." + } + }, + "patchAssessmentMode": { + "type": "string", + "defaultValue": "ImageDefault", + "allowedValues": [ + "AutomaticByPlatform", + "ImageDefault" + ], + "metadata": { + "description": "Optional. VM guest patching assessment mode. Set it to 'AutomaticByPlatform' to enable automatically check for updates every 24 hours." + } + }, + "timeZone": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Specifies the time zone of the virtual machine. e.g. 'Pacific Standard Time'. Possible values can be `TimeZoneInfo.id` value from time zones returned by `TimeZoneInfo.GetSystemTimeZones`." + } + }, + "additionalUnattendContent": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Specifies additional base-64 encoded XML formatted information that can be included in the Unattend.xml file, which is used by Windows Setup. - AdditionalUnattendContent object." + } + }, + "winRM": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Specifies the Windows Remote Management listeners. This enables remote Windows PowerShell. - WinRMConfiguration object." + } + }, + "configurationProfile": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesProduction", + "/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesDevTest", + "" + ], + "metadata": { + "description": "Required. The configuration profile of automanage." + } + } + }, + "variables": { + "copy": [ + { + "name": "publicKeysFormatted", + "count": "[length(parameters('publicKeys'))]", + "input": { + "path": "[parameters('publicKeys')[copyIndex('publicKeysFormatted')].path]", + "keyData": "[parameters('publicKeys')[copyIndex('publicKeysFormatted')].keyData]" + } + } + ], + "linuxConfiguration": { + "disablePasswordAuthentication": "[parameters('disablePasswordAuthentication')]", + "ssh": { + "publicKeys": "[variables('publicKeysFormatted')]" + }, + "provisionVMAgent": "[parameters('provisionVMAgent')]", + "patchSettings": "[if(and(parameters('provisionVMAgent'), or(equals(toLower(parameters('patchMode')), toLower('AutomaticByPlatform')), equals(toLower(parameters('patchMode')), toLower('ImageDefault')))), createObject('patchMode', parameters('patchMode'), 'assessmentMode', parameters('patchAssessmentMode')), null())]" + }, + "windowsConfiguration": { + "provisionVMAgent": "[parameters('provisionVMAgent')]", + "enableAutomaticUpdates": "[parameters('enableAutomaticUpdates')]", + "patchSettings": "[if(and(parameters('provisionVMAgent'), or(or(equals(toLower(parameters('patchMode')), toLower('AutomaticByPlatform')), equals(toLower(parameters('patchMode')), toLower('AutomaticByOS'))), equals(toLower(parameters('patchMode')), toLower('Manual')))), createObject('patchMode', parameters('patchMode'), 'assessmentMode', parameters('patchAssessmentMode')), null())]", + "timeZone": "[if(empty(parameters('timeZone')), null(), parameters('timeZone'))]", + "additionalUnattendContent": "[if(empty(parameters('additionalUnattendContent')), null(), parameters('additionalUnattendContent'))]", + "winRM": "[if(not(empty(parameters('winRM'))), createObject('listeners', parameters('winRM')), null())]" + }, + "accountSasProperties": { + "signedServices": "b", + "signedPermission": "r", + "signedExpiry": "[dateTimeAdd(parameters('baseTime'), parameters('sasTokenValidityLength'))]", + "signedResourceTypes": "o", + "signedProtocol": "https" + }, + "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]", + "identity": "[if(not(empty(parameters('managedIdentities'))), createObject('type', if(if(parameters('extensionAadJoinConfig').enabled, true(), coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false())), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'SystemAssigned,UserAssigned', 'SystemAssigned'), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'UserAssigned', null())), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]", + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Data Operator for Managed Disks": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '959f8984-c045-4866-89c7-12bf9737be2e')]", + "Desktop Virtualization Power On Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '489581de-a3bd-480d-9518-53dea7416b33')]", + "Desktop Virtualization Power On Off Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '40c5ff49-9181-41f8-ae61-143b0e78555e')]", + "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", + "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", + "Disk Backup Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3e5e47e6-65f7-47ef-90b5-e5dd4d455f24')]", + "Disk Pool Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '60fc6e62-5479-42d4-8bf4-67625fcc2840')]", + "Disk Restore Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b50d9833-a0cb-478e-945f-707fcc997c13')]", + "Disk Snapshot Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7efff54f-a5b4-42b5-a1c5-5411624893ce')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", + "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", + "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", + "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", + "VM Scanner Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'd24ecba3-c1f4-40fa-a7bb-4588a071e8fd')]" + } + }, + "resources": { + "defaultTelemetry": { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + "vm": { + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2022-11-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "identity": "[variables('identity')]", + "tags": "[parameters('tags')]", + "zones": "[if(not(equals(parameters('availabilityZone'), 0)), array(parameters('availabilityZone')), null())]", + "plan": "[if(not(empty(parameters('plan'))), parameters('plan'), null())]", + "properties": { + "hardwareProfile": { + "vmSize": "[parameters('vmSize')]" + }, + "securityProfile": { + "encryptionAtHost": "[if(parameters('encryptionAtHost'), parameters('encryptionAtHost'), null())]", + "securityType": "[parameters('securityType')]", + "uefiSettings": "[if(equals(parameters('securityType'), 'TrustedLaunch'), createObject('secureBootEnabled', parameters('secureBootEnabled'), 'vTpmEnabled', parameters('vTpmEnabled')), null())]" + }, + "storageProfile": { + "copy": [ + { + "name": "dataDisks", + "count": "[length(parameters('dataDisks'))]", + "input": { + "lun": "[copyIndex('dataDisks')]", + "name": "[format('{0}-disk-data-{1}', parameters('name'), padLeft(add(copyIndex('dataDisks'), 1), 2, '0'))]", + "diskSizeGB": "[parameters('dataDisks')[copyIndex('dataDisks')].diskSizeGB]", + "createOption": "[if(contains(parameters('dataDisks')[copyIndex('dataDisks')], 'createOption'), parameters('dataDisks')[copyIndex('dataDisks')].createOption, 'Empty')]", + "deleteOption": "[if(contains(parameters('dataDisks')[copyIndex('dataDisks')], 'deleteOption'), parameters('dataDisks')[copyIndex('dataDisks')].deleteOption, 'Delete')]", + "caching": "[if(contains(parameters('dataDisks')[copyIndex('dataDisks')], 'caching'), parameters('dataDisks')[copyIndex('dataDisks')].caching, 'ReadOnly')]", + "managedDisk": { + "storageAccountType": "[parameters('dataDisks')[copyIndex('dataDisks')].managedDisk.storageAccountType]", + "diskEncryptionSet": "[if(contains(parameters('dataDisks')[copyIndex('dataDisks')].managedDisk, 'diskEncryptionSet'), createObject('id', parameters('dataDisks')[copyIndex('dataDisks')].managedDisk.diskEncryptionSet.id), null())]" + } + } + } + ], + "imageReference": "[parameters('imageReference')]", + "osDisk": { + "name": "[format('{0}-disk-os-01', parameters('name'))]", + "createOption": "[if(contains(parameters('osDisk'), 'createOption'), parameters('osDisk').createOption, 'FromImage')]", + "deleteOption": "[if(contains(parameters('osDisk'), 'deleteOption'), parameters('osDisk').deleteOption, 'Delete')]", + "diskSizeGB": "[parameters('osDisk').diskSizeGB]", + "caching": "[if(contains(parameters('osDisk'), 'caching'), parameters('osDisk').caching, 'ReadOnly')]", + "managedDisk": { + "storageAccountType": "[parameters('osDisk').managedDisk.storageAccountType]", + "diskEncryptionSet": "[if(contains(parameters('osDisk').managedDisk, 'diskEncryptionSet'), createObject('id', parameters('osDisk').managedDisk.diskEncryptionSet.id), null())]" + } + } + }, + "additionalCapabilities": { + "ultraSSDEnabled": "[parameters('ultraSSDEnabled')]" + }, + "osProfile": { + "computerName": "[parameters('computerName')]", + "adminUsername": "[parameters('adminUsername')]", + "adminPassword": "[parameters('adminPassword')]", + "customData": "[if(not(empty(parameters('customData'))), base64(parameters('customData')), null())]", + "windowsConfiguration": "[if(equals(parameters('osType'), 'Windows'), variables('windowsConfiguration'), null())]", + "linuxConfiguration": "[if(equals(parameters('osType'), 'Linux'), variables('linuxConfiguration'), null())]", + "secrets": "[parameters('certificatesToBeInstalled')]", + "allowExtensionOperations": "[parameters('allowExtensionOperations')]" + }, + "networkProfile": { + "copy": [ + { + "name": "networkInterfaces", + "count": "[length(parameters('nicConfigurations'))]", + "input": { + "properties": { + "deleteOption": "[if(contains(parameters('nicConfigurations')[copyIndex('networkInterfaces')], 'deleteOption'), parameters('nicConfigurations')[copyIndex('networkInterfaces')].deleteOption, 'Delete')]", + "primary": "[if(equals(copyIndex('networkInterfaces'), 0), true(), false())]" + }, + "id": "[resourceId('Microsoft.Network/networkInterfaces', format('{0}{1}', parameters('name'), parameters('nicConfigurations')[copyIndex('networkInterfaces')].nicSuffix))]" + } + } + ] + }, + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": "[if(not(empty(parameters('bootDiagnosticStorageAccountName'))), true(), parameters('bootDiagnostics'))]", + "storageUri": "[if(not(empty(parameters('bootDiagnosticStorageAccountName'))), format('https://{0}{1}', parameters('bootDiagnosticStorageAccountName'), parameters('bootDiagnosticStorageAccountUri')), null())]" + } + }, + "availabilitySet": "[if(not(empty(parameters('availabilitySetResourceId'))), createObject('id', parameters('availabilitySetResourceId')), null())]", + "proximityPlacementGroup": "[if(not(empty(parameters('proximityPlacementGroupResourceId'))), createObject('id', parameters('proximityPlacementGroupResourceId')), null())]", + "priority": "[parameters('priority')]", + "evictionPolicy": "[if(parameters('enableEvictionPolicy'), 'Deallocate', null())]", + "billingProfile": "[if(and(not(empty(parameters('priority'))), not(empty(parameters('maxPriceForLowPriorityVm')))), createObject('maxPrice', parameters('maxPriceForLowPriorityVm')), null())]", + "host": "[if(not(empty(parameters('dedicatedHostId'))), createObject('id', parameters('dedicatedHostId')), null())]", + "licenseType": "[if(not(empty(parameters('licenseType'))), parameters('licenseType'), null())]" + }, + "dependsOn": [ + "vm_nic" + ] + }, + "vm_configurationProfileAssignment": { + "condition": "[not(empty(parameters('configurationProfile')))]", + "type": "Microsoft.Automanage/configurationProfileAssignments", + "apiVersion": "2021-04-30-preview", + "scope": "[format('Microsoft.Compute/virtualMachines/{0}', parameters('name'))]", + "name": "default", + "properties": { + "configurationProfile": "[parameters('configurationProfile')]" + }, + "dependsOn": [ + "vm" + ] + }, + "vm_logAnalyticsWorkspace": { + "condition": "[not(empty(parameters('monitoringWorkspaceId')))]", + "existing": true, + "type": "Microsoft.OperationalInsights/workspaces", + "apiVersion": "2021-06-01", + "subscriptionId": "[split(if(not(empty(parameters('monitoringWorkspaceId'))), parameters('monitoringWorkspaceId'), '//'), '/')[2]]", + "resourceGroup": "[split(if(not(empty(parameters('monitoringWorkspaceId'))), parameters('monitoringWorkspaceId'), '////'), '/')[4]]", + "name": "[last(split(if(not(empty(parameters('monitoringWorkspaceId'))), parameters('monitoringWorkspaceId'), 'law'), '/'))]" + }, + "vm_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Compute/virtualMachines/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "vm" + ] + }, + "vm_roleAssignments": { + "copy": { + "name": "vm_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Compute/virtualMachines/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Compute/virtualMachines', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "vm" + ] + }, + "vm_nic": { + "copy": { + "name": "vm_nic", + "count": "[length(parameters('nicConfigurations'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-VM-Nic-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "networkInterfaceName": { + "value": "[format('{0}{1}', parameters('name'), parameters('nicConfigurations')[copyIndex()].nicSuffix)]" + }, + "virtualMachineName": { + "value": "[parameters('name')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "enableIPForwarding": "[if(contains(parameters('nicConfigurations')[copyIndex()], 'enableIPForwarding'), if(not(empty(parameters('nicConfigurations')[copyIndex()].enableIPForwarding)), createObject('value', parameters('nicConfigurations')[copyIndex()].enableIPForwarding), createObject('value', false())), createObject('value', false()))]", + "enableAcceleratedNetworking": "[if(contains(parameters('nicConfigurations')[copyIndex()], 'enableAcceleratedNetworking'), createObject('value', parameters('nicConfigurations')[copyIndex()].enableAcceleratedNetworking), createObject('value', true()))]", + "dnsServers": "[if(contains(parameters('nicConfigurations')[copyIndex()], 'dnsServers'), if(not(empty(parameters('nicConfigurations')[copyIndex()].dnsServers)), createObject('value', parameters('nicConfigurations')[copyIndex()].dnsServers), createObject('value', createArray())), createObject('value', createArray()))]", + "networkSecurityGroupResourceId": "[if(contains(parameters('nicConfigurations')[copyIndex()], 'networkSecurityGroupResourceId'), createObject('value', parameters('nicConfigurations')[copyIndex()].networkSecurityGroupResourceId), createObject('value', ''))]", + "ipConfigurations": { + "value": "[parameters('nicConfigurations')[copyIndex()].ipConfigurations]" + }, + "lock": { + "value": "[coalesce(tryGet(parameters('nicConfigurations')[copyIndex()], 'lock'), parameters('lock'))]" + }, + "tags": { + "value": "[coalesce(tryGet(parameters('nicConfigurations')[copyIndex()], 'tags'), parameters('tags'))]" + }, + "diagnosticSettings": { + "value": "[tryGet(parameters('nicConfigurations')[copyIndex()], 'diagnosticSettings')]" + }, + "roleAssignments": { + "value": "[tryGet(parameters('nicConfigurations')[copyIndex()], 'roleAssignments')]" + } + }, + "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": "11123708724712871468" + } + }, + "definitions": { + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "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 \u0007llLogs to collect all logs." + } + } + } + }, + "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." + } + } + } + }, + "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." + } + }, + "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." + } + }, + "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." + } + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "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 + } + }, + "parameters": { + "networkInterfaceName": { + "type": "string" + }, + "virtualMachineName": { + "type": "string" + }, + "location": { + "type": "string" + }, + "tags": { + "type": "object", + "nullable": true + }, + "enableIPForwarding": { + "type": "bool", + "defaultValue": false + }, + "enableAcceleratedNetworking": { + "type": "bool", + "defaultValue": false + }, + "dnsServers": { + "type": "array", + "defaultValue": [] + }, + "networkSecurityGroupResourceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The network security group (NSG) to attach to the network interface." + } + }, + "ipConfigurations": { + "type": "array" + }, + "lock": { + "$ref": "#/definitions/lockType" + }, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", + "metadata": { + "description": "Optional. The diagnostic settings of the Network Interface." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + } + }, + "variables": { + "enableReferencedModulesTelemetry": false + }, + "resources": { + "networkInterface_publicIPAddresses": { + "copy": { + "name": "networkInterface_publicIPAddresses", + "count": "[length(parameters('ipConfigurations'))]" + }, + "condition": "[contains(parameters('ipConfigurations')[copyIndex()], 'pipconfiguration')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-publicIP-{1}', deployment().name, copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[format('{0}{1}', parameters('virtualMachineName'), parameters('ipConfigurations')[copyIndex()].pipconfiguration.publicIpNameSuffix)]" + }, + "diagnosticSettings": { + "value": "[tryGet(parameters('ipConfigurations')[copyIndex()], 'diagnosticSettings')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "lock": { + "value": "[parameters('lock')]" + }, + "publicIPAddressVersion": "[if(contains(parameters('ipConfigurations')[copyIndex()], 'publicIPAddressVersion'), createObject('value', parameters('ipConfigurations')[copyIndex()].publicIPAddressVersion), createObject('value', 'IPv4'))]", + "publicIPAllocationMethod": "[if(contains(parameters('ipConfigurations')[copyIndex()], 'publicIPAllocationMethod'), createObject('value', parameters('ipConfigurations')[copyIndex()].publicIPAllocationMethod), createObject('value', 'Static'))]", + "publicIPPrefixResourceId": "[if(contains(parameters('ipConfigurations')[copyIndex()], 'publicIPPrefixResourceId'), createObject('value', parameters('ipConfigurations')[copyIndex()].publicIPPrefixResourceId), createObject('value', ''))]", + "roleAssignments": "[if(contains(parameters('ipConfigurations')[copyIndex()], 'roleAssignments'), createObject('value', parameters('ipConfigurations')[copyIndex()].roleAssignments), createObject('value', createArray()))]", + "skuName": "[if(contains(parameters('ipConfigurations')[copyIndex()], 'skuName'), createObject('value', parameters('ipConfigurations')[copyIndex()].skuName), createObject('value', 'Standard'))]", + "skuTier": "[if(contains(parameters('ipConfigurations')[copyIndex()], 'skuTier'), createObject('value', parameters('ipConfigurations')[copyIndex()].skuTier), createObject('value', 'Regional'))]", + "tags": { + "value": "[coalesce(tryGet(parameters('ipConfigurations')[copyIndex()], 'tags'), parameters('tags'))]" + }, + "zones": "[if(contains(parameters('ipConfigurations')[copyIndex()], 'zones'), createObject('value', parameters('ipConfigurations')[copyIndex()].zones), createObject('value', createArray()))]" + }, + "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": "15536304828480480757" + }, + "name": "Public IP Addresses", + "description": "This module deploys a Public IP Address.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "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 + }, + "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." + } + } + } + }, + "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." + } + } + } + }, + "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." + } + }, + "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." + } + }, + "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." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the Public IP Address." + } + }, + "publicIPPrefixResourceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of the Public IP Prefix object. This is only needed if you want your Public IPs created in a PIP Prefix." + } + }, + "publicIPAllocationMethod": { + "type": "string", + "defaultValue": "Static", + "allowedValues": [ + "Dynamic", + "Static" + ], + "metadata": { + "description": "Optional. The public IP address allocation method." + } + }, + "skuName": { + "type": "string", + "defaultValue": "Standard", + "allowedValues": [ + "Basic", + "Standard" + ], + "metadata": { + "description": "Optional. Name of a public IP address SKU." + } + }, + "skuTier": { + "type": "string", + "defaultValue": "Regional", + "allowedValues": [ + "Global", + "Regional" + ], + "metadata": { + "description": "Optional. Tier of a public IP address SKU." + } + }, + "zones": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. A list of availability zones denoting the IP allocated for the resource needs to come from." + } + }, + "publicIPAddressVersion": { + "type": "string", + "defaultValue": "IPv4", + "allowedValues": [ + "IPv4", + "IPv6" + ], + "metadata": { + "description": "Optional. IP address version." + } + }, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + }, + "domainNameLabel": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The domain name label. The concatenation of the domain name label and the regionalized DNS zone make up the fully qualified domain name associated with the public IP address. If a domain name label is specified, an A DNS record is created for the public IP in the Microsoft Azure DNS system." + } + }, + "domainNameLabelScope": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "", + "NoReuse", + "ResourceGroupReuse", + "SubscriptionReuse", + "TenantReuse" + ], + "metadata": { + "description": "Optional. The domain name label scope. If a domain name label and a domain name label scope are specified, an A DNS record is created for the public IP in the Microsoft Azure DNS system with a hashed value includes in FQDN." + } + }, + "fqdn": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The Fully Qualified Domain Name of the A DNS record associated with the public IP. This is the concatenation of the domainNameLabel and the regionalized DNS zone." + } + }, + "reverseFqdn": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The reverse FQDN. A user-visible, fully qualified domain name that resolves to this public IP address. If the reverseFqdn is specified, then a PTR DNS record is created pointing from the IP address in the in-addr.arpa domain to the reverse FQDN." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "defaultTelemetry": { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + "publicIpAddress": { + "type": "Microsoft.Network/publicIPAddresses", + "apiVersion": "2023-04-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "sku": { + "name": "[parameters('skuName')]", + "tier": "[parameters('skuTier')]" + }, + "zones": "[parameters('zones')]", + "properties": { + "dnsSettings": "[if(not(empty(parameters('domainNameLabel'))), createObject('domainNameLabel', parameters('domainNameLabel'), 'domainNameLabelScope', parameters('domainNameLabelScope'), 'fqdn', parameters('fqdn'), 'reverseFqdn', parameters('reverseFqdn')), null())]", + "publicIPAddressVersion": "[parameters('publicIPAddressVersion')]", + "publicIPAllocationMethod": "[parameters('publicIPAllocationMethod')]", + "publicIPPrefix": "[if(not(empty(parameters('publicIPPrefixResourceId'))), createObject('id', parameters('publicIPPrefixResourceId')), null())]", + "idleTimeoutInMinutes": 4, + "ipTags": [] + } + }, + "publicIpAddress_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Network/publicIPAddresses/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "publicIpAddress" + ] + }, + "publicIpAddress_diagnosticSettings": { + "copy": { + "name": "publicIpAddress_diagnosticSettings", + "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + }, + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.Network/publicIPAddresses/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", + "properties": { + "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", + "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", + "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", + "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", + "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", + "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", + "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", + "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + }, + "dependsOn": [ + "publicIpAddress" + ] + }, + "publicIpAddress_roleAssignments": { + "copy": { + "name": "publicIpAddress_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "name": "[guid(resourceId('Microsoft.Network/publicIPAddresses', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "publicIpAddress" + ] + } + }, + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the public IP address was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the public IP address." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the public IP address." + }, + "value": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('name'))]" + }, + "ipAddress": { + "type": "string", + "metadata": { + "description": "The public IP address of the public IP address resource." + }, + "value": "[if(contains(reference('publicIpAddress'), 'ipAddress'), reference('publicIpAddress').ipAddress, '')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('publicIpAddress', '2023-04-01', 'full').location]" + } + } + } + } + }, + "networkInterface": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-NetworkInterface', deployment().name)]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[parameters('networkInterfaceName')]" + }, + "ipConfigurations": { + "copy": [ + { + "name": "value", + "count": "[length(parameters('ipConfigurations'))]", + "input": "[createObject('name', if(not(empty(parameters('ipConfigurations')[copyIndex('value')].name)), parameters('ipConfigurations')[copyIndex('value')].name, null()), 'primary', equals(copyIndex('value'), 0), 'privateIPAllocationMethod', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'privateIPAllocationMethod'), if(not(empty(parameters('ipConfigurations')[copyIndex('value')].privateIPAllocationMethod)), parameters('ipConfigurations')[copyIndex('value')].privateIPAllocationMethod, null()), null()), 'privateIPAddress', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'privateIPAddress'), if(not(empty(parameters('ipConfigurations')[copyIndex('value')].privateIPAddress)), parameters('ipConfigurations')[copyIndex('value')].privateIPAddress, null()), null()), 'publicIPAddressResourceId', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'pipconfiguration'), resourceId('Microsoft.Network/publicIPAddresses', format('{0}{1}', parameters('virtualMachineName'), parameters('ipConfigurations')[copyIndex('value')].pipconfiguration.publicIpNameSuffix)), null()), 'subnetResourceId', parameters('ipConfigurations')[copyIndex('value')].subnetResourceId, 'loadBalancerBackendAddressPools', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'loadBalancerBackendAddressPools'), parameters('ipConfigurations')[copyIndex('value')].loadBalancerBackendAddressPools, null()), 'applicationSecurityGroups', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'applicationSecurityGroups'), parameters('ipConfigurations')[copyIndex('value')].applicationSecurityGroups, null()), 'applicationGatewayBackendAddressPools', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'applicationGatewayBackendAddressPools'), parameters('ipConfigurations')[copyIndex('value')].applicationGatewayBackendAddressPools, null()), 'gatewayLoadBalancer', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'gatewayLoadBalancer'), parameters('ipConfigurations')[copyIndex('value')].gatewayLoadBalancer, null()), 'loadBalancerInboundNatRules', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'loadBalancerInboundNatRules'), parameters('ipConfigurations')[copyIndex('value')].loadBalancerInboundNatRules, null()), 'privateIPAddressVersion', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'privateIPAddressVersion'), parameters('ipConfigurations')[copyIndex('value')].privateIPAddressVersion, null()), 'virtualNetworkTaps', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'virtualNetworkTaps'), parameters('ipConfigurations')[copyIndex('value')].virtualNetworkTaps, null()))]" + } + ] + }, + "location": { + "value": "[parameters('location')]" + }, + "tags": { + "value": "[parameters('tags')]" + }, + "diagnosticSettings": { + "value": "[parameters('diagnosticSettings')]" + }, + "dnsServers": "[if(not(empty(parameters('dnsServers'))), createObject('value', parameters('dnsServers')), createObject('value', createArray()))]", + "enableAcceleratedNetworking": { + "value": "[parameters('enableAcceleratedNetworking')]" + }, + "enableDefaultTelemetry": { + "value": "[variables('enableReferencedModulesTelemetry')]" + }, + "enableIPForwarding": { + "value": "[parameters('enableIPForwarding')]" + }, + "lock": { + "value": "[parameters('lock')]" + }, + "networkSecurityGroupResourceId": "[if(not(empty(parameters('networkSecurityGroupResourceId'))), createObject('value', parameters('networkSecurityGroupResourceId')), createObject('value', ''))]", + "roleAssignments": "[if(not(empty(parameters('roleAssignments'))), createObject('value', parameters('roleAssignments')), createObject('value', createArray()))]" + }, + "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": "2750011165297287068" + }, + "name": "Network Interface", + "description": "This module deploys a Network Interface.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "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 + }, + "diagnosticSettingType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of diagnostic setting." + } + }, + "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." + } + } + } + }, + "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." + } + }, + "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." + } + }, + "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." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the network interface." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + }, + "enableIPForwarding": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether IP forwarding is enabled on this network interface." + } + }, + "enableAcceleratedNetworking": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. If the network interface is accelerated networking enabled." + } + }, + "dnsServers": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. List of DNS servers IP addresses. Use 'AzureProvidedDNS' to switch to azure provided DNS resolution. 'AzureProvidedDNS' value cannot be combined with other IPs, it must be the only value in dnsServers collection." + } + }, + "networkSecurityGroupResourceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The network security group (NSG) to attach to the network interface." + } + }, + "auxiliaryMode": { + "type": "string", + "defaultValue": "None", + "allowedValues": [ + "Floating", + "MaxConnections", + "None" + ], + "metadata": { + "description": "Optional. Auxiliary mode of Network Interface resource. Not all regions are enabled for Auxiliary Mode Nic." + } + }, + "auxiliarySku": { + "type": "string", + "defaultValue": "None", + "allowedValues": [ + "A1", + "A2", + "A4", + "A8", + "None" + ], + "metadata": { + "description": "Optional. Auxiliary sku of Network Interface resource. Not all regions are enabled for Auxiliary Mode Nic." + } + }, + "disableTcpStateTracking": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether to disable tcp state tracking. Subscription must be registered for the Microsoft.Network/AllowDisableTcpStateTracking feature before this property can be set to true." + } + }, + "ipConfigurations": { + "type": "array", + "metadata": { + "description": "Required. A list of IPConfigurations of the network interface." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "defaultTelemetry": { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + "networkInterface": { + "type": "Microsoft.Network/networkInterfaces", + "apiVersion": "2023-04-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "copy": [ + { + "name": "ipConfigurations", + "count": "[length(parameters('ipConfigurations'))]", + "input": { + "name": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'name'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].name, format('ipconfig0{0}', add(copyIndex('ipConfigurations'), 1)))]", + "properties": { + "primary": "[if(equals(copyIndex('ipConfigurations'), 0), true(), false())]", + "privateIPAllocationMethod": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'privateIPAllocationMethod'), if(not(empty(parameters('ipConfigurations')[copyIndex('ipConfigurations')].privateIPAllocationMethod)), parameters('ipConfigurations')[copyIndex('ipConfigurations')].privateIPAllocationMethod, null()), null())]", + "privateIPAddress": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'privateIPAddress'), if(not(empty(parameters('ipConfigurations')[copyIndex('ipConfigurations')].privateIPAddress)), parameters('ipConfigurations')[copyIndex('ipConfigurations')].privateIPAddress, null()), null())]", + "publicIPAddress": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'publicIPAddressResourceId'), if(not(equals(parameters('ipConfigurations')[copyIndex('ipConfigurations')].publicIPAddressResourceId, null())), createObject('id', parameters('ipConfigurations')[copyIndex('ipConfigurations')].publicIPAddressResourceId), null()), null())]", + "subnet": { + "id": "[parameters('ipConfigurations')[copyIndex('ipConfigurations')].subnetResourceId]" + }, + "loadBalancerBackendAddressPools": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'loadBalancerBackendAddressPools'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].loadBalancerBackendAddressPools, null())]", + "applicationSecurityGroups": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'applicationSecurityGroups'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].applicationSecurityGroups, null())]", + "applicationGatewayBackendAddressPools": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'applicationGatewayBackendAddressPools'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].applicationGatewayBackendAddressPools, null())]", + "gatewayLoadBalancer": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'gatewayLoadBalancer'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].gatewayLoadBalancer, null())]", + "loadBalancerInboundNatRules": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'loadBalancerInboundNatRules'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].loadBalancerInboundNatRules, null())]", + "privateIPAddressVersion": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'privateIPAddressVersion'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].privateIPAddressVersion, null())]", + "virtualNetworkTaps": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'virtualNetworkTaps'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].virtualNetworkTaps, null())]" + } + } + } + ], + "auxiliaryMode": "[parameters('auxiliaryMode')]", + "auxiliarySku": "[parameters('auxiliarySku')]", + "disableTcpStateTracking": "[parameters('disableTcpStateTracking')]", + "dnsSettings": "[if(not(empty(parameters('dnsServers'))), createObject('dnsServers', parameters('dnsServers')), null())]", + "enableAcceleratedNetworking": "[parameters('enableAcceleratedNetworking')]", + "enableIPForwarding": "[parameters('enableIPForwarding')]", + "networkSecurityGroup": "[if(not(empty(parameters('networkSecurityGroupResourceId'))), createObject('id', parameters('networkSecurityGroupResourceId')), null())]" + } + }, + "networkInterface_diagnosticSettings": { + "copy": { + "name": "networkInterface_diagnosticSettings", + "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + }, + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.Network/networkInterfaces/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", + "properties": { + "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", + "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", + "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", + "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", + "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", + "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", + "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + }, + "dependsOn": [ + "networkInterface" + ] + }, + "networkInterface_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Network/networkInterfaces/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "networkInterface" + ] + }, + "networkInterface_roleAssignments": { + "copy": { + "name": "networkInterface_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "name": "[guid(resourceId('Microsoft.Network/networkInterfaces', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "networkInterface" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed resource." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed resource." + }, + "value": "[resourceId('Microsoft.Network/networkInterfaces', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed resource." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('networkInterface', '2023-04-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "networkInterface_publicIPAddresses" + ] + } + } + } + } + }, + "vm_aadJoinExtension": { + "condition": "[parameters('extensionAadJoinConfig').enabled]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-VM-AADLogin', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "virtualMachineName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "AADLogin" + }, + "publisher": { + "value": "Microsoft.Azure.ActiveDirectory" + }, + "type": "[if(equals(parameters('osType'), 'Windows'), createObject('value', 'AADLoginForWindows'), createObject('value', 'AADSSHLoginforLinux'))]", + "typeHandlerVersion": "[if(contains(parameters('extensionAadJoinConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionAadJoinConfig').typeHandlerVersion), createObject('value', '1.0'))]", + "autoUpgradeMinorVersion": "[if(contains(parameters('extensionAadJoinConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionAadJoinConfig').autoUpgradeMinorVersion), createObject('value', true()))]", + "enableAutomaticUpgrade": "[if(contains(parameters('extensionAadJoinConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionAadJoinConfig').enableAutomaticUpgrade), createObject('value', false()))]", + "settings": "[if(contains(parameters('extensionAadJoinConfig'), 'settings'), createObject('value', parameters('extensionAadJoinConfig').settings), createObject('value', createObject()))]", + "tags": { + "value": "[coalesce(tryGet(parameters('extensionAadJoinConfig'), 'tags'), parameters('tags'))]" + } + }, + "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": "5421737065579119324" + }, + "name": "Virtual Machine Extensions", + "description": "This module deploys a Virtual Machine Extension.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "virtualMachineName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the virtual machine extension." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. The location the extension is deployed to." + } + }, + "publisher": { + "type": "string", + "metadata": { + "description": "Required. The name of the extension handler publisher." + } + }, + "type": { + "type": "string", + "metadata": { + "description": "Required. Specifies the type of the extension; an example is \"CustomScriptExtension\"." + } + }, + "typeHandlerVersion": { + "type": "string", + "metadata": { + "description": "Required. Specifies the version of the script handler." + } + }, + "autoUpgradeMinorVersion": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true." + } + }, + "forceUpdateTag": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." + } + }, + "settings": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific settings." + } + }, + "protectedSettings": { + "type": "secureObject", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific protected settings." + } + }, + "supressFailures": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false." + } + }, + "enableAutomaticUpgrade": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + } + }, + "resources": { + "defaultTelemetry": { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + "virtualMachine": { + "existing": true, + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2022-11-01", + "name": "[parameters('virtualMachineName')]" + }, + "extension": { + "type": "Microsoft.Compute/virtualMachines/extensions", + "apiVersion": "2022-11-01", + "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "publisher": "[parameters('publisher')]", + "type": "[parameters('type')]", + "typeHandlerVersion": "[parameters('typeHandlerVersion')]", + "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", + "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", + "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", + "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", + "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", + "suppressFailures": "[parameters('supressFailures')]" + }, + "dependsOn": [ + "virtualMachine" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the extension." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the extension." + }, + "value": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the extension was created in." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('extension', '2022-11-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "vm" + ] + }, + "vm_domainJoinExtension": { + "condition": "[parameters('extensionDomainJoinConfig').enabled]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-VM-DomainJoin', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "virtualMachineName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "DomainJoin" + }, + "publisher": { + "value": "Microsoft.Compute" + }, + "type": { + "value": "JsonADDomainExtension" + }, + "typeHandlerVersion": "[if(contains(parameters('extensionDomainJoinConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionDomainJoinConfig').typeHandlerVersion), createObject('value', '1.3'))]", + "autoUpgradeMinorVersion": "[if(contains(parameters('extensionDomainJoinConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionDomainJoinConfig').autoUpgradeMinorVersion), createObject('value', true()))]", + "enableAutomaticUpgrade": "[if(contains(parameters('extensionDomainJoinConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionDomainJoinConfig').enableAutomaticUpgrade), createObject('value', false()))]", + "settings": { + "value": "[parameters('extensionDomainJoinConfig').settings]" + }, + "tags": { + "value": "[coalesce(tryGet(parameters('extensionDomainJoinConfig'), 'tags'), parameters('tags'))]" + }, + "protectedSettings": { + "value": { + "Password": "[parameters('extensionDomainJoinPassword')]" + } + }, + "enableDefaultTelemetry": { + "value": "[variables('enableReferencedModulesTelemetry')]" + } + }, + "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": "5421737065579119324" + }, + "name": "Virtual Machine Extensions", + "description": "This module deploys a Virtual Machine Extension.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "virtualMachineName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the virtual machine extension." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. The location the extension is deployed to." + } + }, + "publisher": { + "type": "string", + "metadata": { + "description": "Required. The name of the extension handler publisher." + } + }, + "type": { + "type": "string", + "metadata": { + "description": "Required. Specifies the type of the extension; an example is \"CustomScriptExtension\"." + } + }, + "typeHandlerVersion": { + "type": "string", + "metadata": { + "description": "Required. Specifies the version of the script handler." + } + }, + "autoUpgradeMinorVersion": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true." + } + }, + "forceUpdateTag": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." + } + }, + "settings": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific settings." + } + }, + "protectedSettings": { + "type": "secureObject", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific protected settings." + } + }, + "supressFailures": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false." + } + }, + "enableAutomaticUpgrade": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + } + }, + "resources": { + "defaultTelemetry": { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + "virtualMachine": { + "existing": true, + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2022-11-01", + "name": "[parameters('virtualMachineName')]" + }, + "extension": { + "type": "Microsoft.Compute/virtualMachines/extensions", + "apiVersion": "2022-11-01", + "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "publisher": "[parameters('publisher')]", + "type": "[parameters('type')]", + "typeHandlerVersion": "[parameters('typeHandlerVersion')]", + "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", + "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", + "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", + "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", + "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", + "suppressFailures": "[parameters('supressFailures')]" + }, + "dependsOn": [ + "virtualMachine" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the extension." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the extension." + }, + "value": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the extension was created in." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('extension', '2022-11-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "vm" + ] + }, + "vm_microsoftAntiMalwareExtension": { + "condition": "[parameters('extensionAntiMalwareConfig').enabled]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-VM-MicrosoftAntiMalware', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "virtualMachineName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "MicrosoftAntiMalware" + }, + "publisher": { + "value": "Microsoft.Azure.Security" + }, + "type": { + "value": "IaaSAntimalware" + }, + "typeHandlerVersion": "[if(contains(parameters('extensionAntiMalwareConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionAntiMalwareConfig').typeHandlerVersion), createObject('value', '1.3'))]", + "autoUpgradeMinorVersion": "[if(contains(parameters('extensionAntiMalwareConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionAntiMalwareConfig').autoUpgradeMinorVersion), createObject('value', true()))]", + "enableAutomaticUpgrade": "[if(contains(parameters('extensionAntiMalwareConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionAntiMalwareConfig').enableAutomaticUpgrade), createObject('value', false()))]", + "settings": { + "value": "[parameters('extensionAntiMalwareConfig').settings]" + }, + "tags": { + "value": "[coalesce(tryGet(parameters('extensionAntiMalwareConfig'), 'tags'), parameters('tags'))]" + }, + "enableDefaultTelemetry": { + "value": "[variables('enableReferencedModulesTelemetry')]" + } + }, + "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": "5421737065579119324" + }, + "name": "Virtual Machine Extensions", + "description": "This module deploys a Virtual Machine Extension.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "virtualMachineName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the virtual machine extension." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. The location the extension is deployed to." + } + }, + "publisher": { + "type": "string", + "metadata": { + "description": "Required. The name of the extension handler publisher." + } + }, + "type": { + "type": "string", + "metadata": { + "description": "Required. Specifies the type of the extension; an example is \"CustomScriptExtension\"." + } + }, + "typeHandlerVersion": { + "type": "string", + "metadata": { + "description": "Required. Specifies the version of the script handler." + } + }, + "autoUpgradeMinorVersion": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true." + } + }, + "forceUpdateTag": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." + } + }, + "settings": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific settings." + } + }, + "protectedSettings": { + "type": "secureObject", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific protected settings." + } + }, + "supressFailures": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false." + } + }, + "enableAutomaticUpgrade": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + } + }, + "resources": { + "defaultTelemetry": { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + "virtualMachine": { + "existing": true, + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2022-11-01", + "name": "[parameters('virtualMachineName')]" + }, + "extension": { + "type": "Microsoft.Compute/virtualMachines/extensions", + "apiVersion": "2022-11-01", + "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "publisher": "[parameters('publisher')]", + "type": "[parameters('type')]", + "typeHandlerVersion": "[parameters('typeHandlerVersion')]", + "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", + "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", + "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", + "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", + "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", + "suppressFailures": "[parameters('supressFailures')]" + }, + "dependsOn": [ + "virtualMachine" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the extension." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the extension." + }, + "value": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the extension was created in." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('extension', '2022-11-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "vm" + ] + }, + "vm_microsoftMonitoringAgentExtension": { + "condition": "[parameters('extensionMonitoringAgentConfig').enabled]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-VM-MicrosoftMonitoringAgent', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "virtualMachineName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "MicrosoftMonitoringAgent" + }, + "publisher": { + "value": "Microsoft.EnterpriseCloud.Monitoring" + }, + "type": "[if(equals(parameters('osType'), 'Windows'), createObject('value', 'MicrosoftMonitoringAgent'), createObject('value', 'OmsAgentForLinux'))]", + "typeHandlerVersion": "[if(contains(parameters('extensionMonitoringAgentConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionMonitoringAgentConfig').typeHandlerVersion), if(equals(parameters('osType'), 'Windows'), createObject('value', '1.0'), createObject('value', '1.7')))]", + "autoUpgradeMinorVersion": "[if(contains(parameters('extensionMonitoringAgentConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionMonitoringAgentConfig').autoUpgradeMinorVersion), createObject('value', true()))]", + "enableAutomaticUpgrade": "[if(contains(parameters('extensionMonitoringAgentConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionMonitoringAgentConfig').enableAutomaticUpgrade), createObject('value', false()))]", + "settings": { + "value": { + "workspaceId": "[if(not(empty(parameters('monitoringWorkspaceId'))), reference('vm_logAnalyticsWorkspace').customerId, '')]" + } + }, + "tags": { + "value": "[coalesce(tryGet(parameters('extensionMonitoringAgentConfig'), 'tags'), parameters('tags'))]" + }, + "protectedSettings": { + "value": { + "workspaceKey": "[if(not(empty(parameters('monitoringWorkspaceId'))), listKeys(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(if(not(empty(parameters('monitoringWorkspaceId'))), parameters('monitoringWorkspaceId'), '//'), '/')[2], split(if(not(empty(parameters('monitoringWorkspaceId'))), parameters('monitoringWorkspaceId'), '////'), '/')[4]), 'Microsoft.OperationalInsights/workspaces', last(split(if(not(empty(parameters('monitoringWorkspaceId'))), parameters('monitoringWorkspaceId'), 'law'), '/'))), '2021-06-01').primarySharedKey, '')]" + } + }, + "enableDefaultTelemetry": { + "value": "[variables('enableReferencedModulesTelemetry')]" + } + }, + "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": "5421737065579119324" + }, + "name": "Virtual Machine Extensions", + "description": "This module deploys a Virtual Machine Extension.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "virtualMachineName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the virtual machine extension." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. The location the extension is deployed to." + } + }, + "publisher": { + "type": "string", + "metadata": { + "description": "Required. The name of the extension handler publisher." + } + }, + "type": { + "type": "string", + "metadata": { + "description": "Required. Specifies the type of the extension; an example is \"CustomScriptExtension\"." + } + }, + "typeHandlerVersion": { + "type": "string", + "metadata": { + "description": "Required. Specifies the version of the script handler." + } + }, + "autoUpgradeMinorVersion": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true." + } + }, + "forceUpdateTag": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." + } + }, + "settings": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific settings." + } + }, + "protectedSettings": { + "type": "secureObject", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific protected settings." + } + }, + "supressFailures": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false." + } + }, + "enableAutomaticUpgrade": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + } + }, + "resources": { + "defaultTelemetry": { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + "virtualMachine": { + "existing": true, + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2022-11-01", + "name": "[parameters('virtualMachineName')]" + }, + "extension": { + "type": "Microsoft.Compute/virtualMachines/extensions", + "apiVersion": "2022-11-01", + "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "publisher": "[parameters('publisher')]", + "type": "[parameters('type')]", + "typeHandlerVersion": "[parameters('typeHandlerVersion')]", + "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", + "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", + "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", + "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", + "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", + "suppressFailures": "[parameters('supressFailures')]" + }, + "dependsOn": [ + "virtualMachine" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the extension." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the extension." + }, + "value": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the extension was created in." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('extension', '2022-11-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "vm", + "vm_logAnalyticsWorkspace" + ] + }, + "vm_dependencyAgentExtension": { + "condition": "[parameters('extensionDependencyAgentConfig').enabled]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-VM-DependencyAgent', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "virtualMachineName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "DependencyAgent" + }, + "publisher": { + "value": "Microsoft.Azure.Monitoring.DependencyAgent" + }, + "type": "[if(equals(parameters('osType'), 'Windows'), createObject('value', 'DependencyAgentWindows'), createObject('value', 'DependencyAgentLinux'))]", + "typeHandlerVersion": "[if(contains(parameters('extensionDependencyAgentConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionDependencyAgentConfig').typeHandlerVersion), createObject('value', '9.5'))]", + "autoUpgradeMinorVersion": "[if(contains(parameters('extensionDependencyAgentConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionDependencyAgentConfig').autoUpgradeMinorVersion), createObject('value', true()))]", + "enableAutomaticUpgrade": "[if(contains(parameters('extensionDependencyAgentConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionDependencyAgentConfig').enableAutomaticUpgrade), createObject('value', true()))]", + "enableDefaultTelemetry": { + "value": "[variables('enableReferencedModulesTelemetry')]" + }, + "tags": { + "value": "[coalesce(tryGet(parameters('extensionDependencyAgentConfig'), 'tags'), parameters('tags'))]" + } + }, + "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": "5421737065579119324" + }, + "name": "Virtual Machine Extensions", + "description": "This module deploys a Virtual Machine Extension.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "virtualMachineName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the virtual machine extension." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. The location the extension is deployed to." + } + }, + "publisher": { + "type": "string", + "metadata": { + "description": "Required. The name of the extension handler publisher." + } + }, + "type": { + "type": "string", + "metadata": { + "description": "Required. Specifies the type of the extension; an example is \"CustomScriptExtension\"." + } + }, + "typeHandlerVersion": { + "type": "string", + "metadata": { + "description": "Required. Specifies the version of the script handler." + } + }, + "autoUpgradeMinorVersion": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true." + } + }, + "forceUpdateTag": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." + } + }, + "settings": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific settings." + } + }, + "protectedSettings": { + "type": "secureObject", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific protected settings." + } + }, + "supressFailures": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false." + } + }, + "enableAutomaticUpgrade": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + } + }, + "resources": { + "defaultTelemetry": { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + "virtualMachine": { + "existing": true, + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2022-11-01", + "name": "[parameters('virtualMachineName')]" + }, + "extension": { + "type": "Microsoft.Compute/virtualMachines/extensions", + "apiVersion": "2022-11-01", + "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "publisher": "[parameters('publisher')]", + "type": "[parameters('type')]", + "typeHandlerVersion": "[parameters('typeHandlerVersion')]", + "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", + "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", + "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", + "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", + "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", + "suppressFailures": "[parameters('supressFailures')]" + }, + "dependsOn": [ + "virtualMachine" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the extension." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the extension." + }, + "value": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the extension was created in." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('extension', '2022-11-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "vm" + ] + }, + "vm_networkWatcherAgentExtension": { + "condition": "[parameters('extensionNetworkWatcherAgentConfig').enabled]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-VM-NetworkWatcherAgent', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "virtualMachineName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "NetworkWatcherAgent" + }, + "publisher": { + "value": "Microsoft.Azure.NetworkWatcher" + }, + "type": "[if(equals(parameters('osType'), 'Windows'), createObject('value', 'NetworkWatcherAgentWindows'), createObject('value', 'NetworkWatcherAgentLinux'))]", + "typeHandlerVersion": "[if(contains(parameters('extensionNetworkWatcherAgentConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionNetworkWatcherAgentConfig').typeHandlerVersion), createObject('value', '1.4'))]", + "autoUpgradeMinorVersion": "[if(contains(parameters('extensionNetworkWatcherAgentConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionNetworkWatcherAgentConfig').autoUpgradeMinorVersion), createObject('value', true()))]", + "enableAutomaticUpgrade": "[if(contains(parameters('extensionNetworkWatcherAgentConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionNetworkWatcherAgentConfig').enableAutomaticUpgrade), createObject('value', false()))]", + "enableDefaultTelemetry": { + "value": "[variables('enableReferencedModulesTelemetry')]" + }, + "tags": { + "value": "[coalesce(tryGet(parameters('extensionNetworkWatcherAgentConfig'), 'tags'), parameters('tags'))]" + } + }, + "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": "5421737065579119324" + }, + "name": "Virtual Machine Extensions", + "description": "This module deploys a Virtual Machine Extension.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "virtualMachineName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the virtual machine extension." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. The location the extension is deployed to." + } + }, + "publisher": { + "type": "string", + "metadata": { + "description": "Required. The name of the extension handler publisher." + } + }, + "type": { + "type": "string", + "metadata": { + "description": "Required. Specifies the type of the extension; an example is \"CustomScriptExtension\"." + } + }, + "typeHandlerVersion": { + "type": "string", + "metadata": { + "description": "Required. Specifies the version of the script handler." + } + }, + "autoUpgradeMinorVersion": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true." + } + }, + "forceUpdateTag": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." + } + }, + "settings": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific settings." + } + }, + "protectedSettings": { + "type": "secureObject", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific protected settings." + } + }, + "supressFailures": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false." + } + }, + "enableAutomaticUpgrade": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + } + }, + "resources": { + "defaultTelemetry": { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + "virtualMachine": { + "existing": true, + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2022-11-01", + "name": "[parameters('virtualMachineName')]" + }, + "extension": { + "type": "Microsoft.Compute/virtualMachines/extensions", + "apiVersion": "2022-11-01", + "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "publisher": "[parameters('publisher')]", + "type": "[parameters('type')]", + "typeHandlerVersion": "[parameters('typeHandlerVersion')]", + "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", + "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", + "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", + "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", + "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", + "suppressFailures": "[parameters('supressFailures')]" + }, + "dependsOn": [ + "virtualMachine" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the extension." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the extension." + }, + "value": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the extension was created in." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('extension', '2022-11-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "vm" + ] + }, + "vm_desiredStateConfigurationExtension": { + "condition": "[parameters('extensionDSCConfig').enabled]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-VM-DesiredStateConfiguration', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "virtualMachineName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "DesiredStateConfiguration" + }, + "publisher": { + "value": "Microsoft.Powershell" + }, + "type": { + "value": "DSC" + }, + "typeHandlerVersion": "[if(contains(parameters('extensionDSCConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionDSCConfig').typeHandlerVersion), createObject('value', '2.77'))]", + "autoUpgradeMinorVersion": "[if(contains(parameters('extensionDSCConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionDSCConfig').autoUpgradeMinorVersion), createObject('value', true()))]", + "enableAutomaticUpgrade": "[if(contains(parameters('extensionDSCConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionDSCConfig').enableAutomaticUpgrade), createObject('value', false()))]", + "settings": "[if(contains(parameters('extensionDSCConfig'), 'settings'), createObject('value', parameters('extensionDSCConfig').settings), createObject('value', createObject()))]", + "tags": { + "value": "[coalesce(tryGet(parameters('extensionDSCConfig'), 'tags'), parameters('tags'))]" + }, + "protectedSettings": "[if(contains(parameters('extensionDSCConfig'), 'protectedSettings'), createObject('value', parameters('extensionDSCConfig').protectedSettings), createObject('value', createObject()))]", + "enableDefaultTelemetry": { + "value": "[variables('enableReferencedModulesTelemetry')]" + } + }, + "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": "5421737065579119324" + }, + "name": "Virtual Machine Extensions", + "description": "This module deploys a Virtual Machine Extension.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "virtualMachineName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the virtual machine extension." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. The location the extension is deployed to." + } + }, + "publisher": { + "type": "string", + "metadata": { + "description": "Required. The name of the extension handler publisher." + } + }, + "type": { + "type": "string", + "metadata": { + "description": "Required. Specifies the type of the extension; an example is \"CustomScriptExtension\"." + } + }, + "typeHandlerVersion": { + "type": "string", + "metadata": { + "description": "Required. Specifies the version of the script handler." + } + }, + "autoUpgradeMinorVersion": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true." + } + }, + "forceUpdateTag": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." + } + }, + "settings": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific settings." + } + }, + "protectedSettings": { + "type": "secureObject", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific protected settings." + } + }, + "supressFailures": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false." + } + }, + "enableAutomaticUpgrade": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + } + }, + "resources": { + "defaultTelemetry": { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + "virtualMachine": { + "existing": true, + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2022-11-01", + "name": "[parameters('virtualMachineName')]" + }, + "extension": { + "type": "Microsoft.Compute/virtualMachines/extensions", + "apiVersion": "2022-11-01", + "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "publisher": "[parameters('publisher')]", + "type": "[parameters('type')]", + "typeHandlerVersion": "[parameters('typeHandlerVersion')]", + "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", + "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", + "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", + "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", + "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", + "suppressFailures": "[parameters('supressFailures')]" + }, + "dependsOn": [ + "virtualMachine" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the extension." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the extension." + }, + "value": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the extension was created in." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('extension', '2022-11-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "vm" + ] + }, + "vm_customScriptExtension": { + "condition": "[parameters('extensionCustomScriptConfig').enabled]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-VM-CustomScriptExtension', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "virtualMachineName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "CustomScriptExtension" + }, + "publisher": "[if(equals(parameters('osType'), 'Windows'), createObject('value', 'Microsoft.Compute'), createObject('value', 'Microsoft.Azure.Extensions'))]", + "type": "[if(equals(parameters('osType'), 'Windows'), createObject('value', 'CustomScriptExtension'), createObject('value', 'CustomScript'))]", + "typeHandlerVersion": "[if(contains(parameters('extensionCustomScriptConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionCustomScriptConfig').typeHandlerVersion), if(equals(parameters('osType'), 'Windows'), createObject('value', '1.10'), createObject('value', '2.1')))]", + "autoUpgradeMinorVersion": "[if(contains(parameters('extensionCustomScriptConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionCustomScriptConfig').autoUpgradeMinorVersion), createObject('value', true()))]", + "enableAutomaticUpgrade": "[if(contains(parameters('extensionCustomScriptConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionCustomScriptConfig').enableAutomaticUpgrade), createObject('value', false()))]", + "settings": { + "value": { + "copy": [ + { + "name": "fileUris", + "count": "[length(parameters('extensionCustomScriptConfig').fileData)]", + "input": "[if(contains(parameters('extensionCustomScriptConfig').fileData[copyIndex('fileUris')], 'storageAccountId'), format('{0}?{1}', parameters('extensionCustomScriptConfig').fileData[copyIndex('fileUris')].uri, listAccountSas(parameters('extensionCustomScriptConfig').fileData[copyIndex('fileUris')].storageAccountId, '2019-04-01', variables('accountSasProperties')).accountSasToken), parameters('extensionCustomScriptConfig').fileData[copyIndex('fileUris')].uri)]" + } + ] + } + }, + "tags": { + "value": "[coalesce(tryGet(parameters('extensionCustomScriptConfig'), 'tags'), parameters('tags'))]" + }, + "protectedSettings": { + "value": "[parameters('extensionCustomScriptProtectedSetting')]" + }, + "enableDefaultTelemetry": { + "value": "[variables('enableReferencedModulesTelemetry')]" + } + }, + "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": "5421737065579119324" + }, + "name": "Virtual Machine Extensions", + "description": "This module deploys a Virtual Machine Extension.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "virtualMachineName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the virtual machine extension." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. The location the extension is deployed to." + } + }, + "publisher": { + "type": "string", + "metadata": { + "description": "Required. The name of the extension handler publisher." + } + }, + "type": { + "type": "string", + "metadata": { + "description": "Required. Specifies the type of the extension; an example is \"CustomScriptExtension\"." + } + }, + "typeHandlerVersion": { + "type": "string", + "metadata": { + "description": "Required. Specifies the version of the script handler." + } + }, + "autoUpgradeMinorVersion": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true." + } + }, + "forceUpdateTag": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." + } + }, + "settings": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific settings." + } + }, + "protectedSettings": { + "type": "secureObject", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific protected settings." + } + }, + "supressFailures": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false." + } + }, + "enableAutomaticUpgrade": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + } + }, + "resources": { + "defaultTelemetry": { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + "virtualMachine": { + "existing": true, + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2022-11-01", + "name": "[parameters('virtualMachineName')]" + }, + "extension": { + "type": "Microsoft.Compute/virtualMachines/extensions", + "apiVersion": "2022-11-01", + "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "publisher": "[parameters('publisher')]", + "type": "[parameters('type')]", + "typeHandlerVersion": "[parameters('typeHandlerVersion')]", + "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", + "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", + "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", + "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", + "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", + "suppressFailures": "[parameters('supressFailures')]" + }, + "dependsOn": [ + "virtualMachine" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the extension." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the extension." + }, + "value": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the extension was created in." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('extension', '2022-11-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "vm", + "vm_desiredStateConfigurationExtension" + ] + }, + "vm_azureDiskEncryptionExtension": { + "condition": "[parameters('extensionAzureDiskEncryptionConfig').enabled]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-VM-AzureDiskEncryption', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "virtualMachineName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "AzureDiskEncryption" + }, + "publisher": { + "value": "Microsoft.Azure.Security" + }, + "type": "[if(equals(parameters('osType'), 'Windows'), createObject('value', 'AzureDiskEncryption'), createObject('value', 'AzureDiskEncryptionForLinux'))]", + "typeHandlerVersion": "[if(contains(parameters('extensionAzureDiskEncryptionConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionAzureDiskEncryptionConfig').typeHandlerVersion), if(equals(parameters('osType'), 'Windows'), createObject('value', '2.2'), createObject('value', '1.1')))]", + "autoUpgradeMinorVersion": "[if(contains(parameters('extensionAzureDiskEncryptionConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionAzureDiskEncryptionConfig').autoUpgradeMinorVersion), createObject('value', true()))]", + "enableAutomaticUpgrade": "[if(contains(parameters('extensionAzureDiskEncryptionConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionAzureDiskEncryptionConfig').enableAutomaticUpgrade), createObject('value', false()))]", + "forceUpdateTag": "[if(contains(parameters('extensionAzureDiskEncryptionConfig'), 'forceUpdateTag'), createObject('value', parameters('extensionAzureDiskEncryptionConfig').forceUpdateTag), createObject('value', '1.0'))]", + "settings": { + "value": "[parameters('extensionAzureDiskEncryptionConfig').settings]" + }, + "tags": { + "value": "[coalesce(tryGet(parameters('extensionAzureDiskEncryptionConfig'), 'tags'), parameters('tags'))]" + }, + "enableDefaultTelemetry": { + "value": "[variables('enableReferencedModulesTelemetry')]" + } + }, + "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": "5421737065579119324" + }, + "name": "Virtual Machine Extensions", + "description": "This module deploys a Virtual Machine Extension.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "virtualMachineName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the virtual machine extension." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. The location the extension is deployed to." + } + }, + "publisher": { + "type": "string", + "metadata": { + "description": "Required. The name of the extension handler publisher." + } + }, + "type": { + "type": "string", + "metadata": { + "description": "Required. Specifies the type of the extension; an example is \"CustomScriptExtension\"." + } + }, + "typeHandlerVersion": { + "type": "string", + "metadata": { + "description": "Required. Specifies the version of the script handler." + } + }, + "autoUpgradeMinorVersion": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true." + } + }, + "forceUpdateTag": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." + } + }, + "settings": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific settings." + } + }, + "protectedSettings": { + "type": "secureObject", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific protected settings." + } + }, + "supressFailures": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false." + } + }, + "enableAutomaticUpgrade": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + } + }, + "resources": { + "defaultTelemetry": { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + "virtualMachine": { + "existing": true, + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2022-11-01", + "name": "[parameters('virtualMachineName')]" + }, + "extension": { + "type": "Microsoft.Compute/virtualMachines/extensions", + "apiVersion": "2022-11-01", + "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "publisher": "[parameters('publisher')]", + "type": "[parameters('type')]", + "typeHandlerVersion": "[parameters('typeHandlerVersion')]", + "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", + "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", + "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", + "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", + "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", + "suppressFailures": "[parameters('supressFailures')]" + }, + "dependsOn": [ + "virtualMachine" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the extension." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the extension." + }, + "value": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the extension was created in." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('extension', '2022-11-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "vm", + "vm_customScriptExtension", + "vm_microsoftMonitoringAgentExtension" + ] + }, + "vm_backup": { + "condition": "[not(empty(parameters('backupVaultName')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-VM-Backup', uniqueString(deployment().name, parameters('location')))]", + "resourceGroup": "[parameters('backupVaultResourceGroup')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[format('vm;iaasvmcontainerv2;{0};{1}', resourceGroup().name, parameters('name'))]" + }, + "policyId": { + "value": "[resourceId('Microsoft.RecoveryServices/vaults/backupPolicies', parameters('backupVaultName'), parameters('backupPolicyName'))]" + }, + "protectedItemType": { + "value": "Microsoft.Compute/virtualMachines" + }, + "protectionContainerName": { + "value": "[format('iaasvmcontainer;iaasvmcontainerv2;{0};{1}', resourceGroup().name, parameters('name'))]" + }, + "recoveryVaultName": { + "value": "[parameters('backupVaultName')]" + }, + "sourceResourceId": { + "value": "[resourceId('Microsoft.Compute/virtualMachines', parameters('name'))]" + }, + "enableDefaultTelemetry": { + "value": "[variables('enableReferencedModulesTelemetry')]" + } + }, + "template": { + "$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": "9921011786088905122" + }, + "name": "Recovery Service Vaults Protection Container Protected Item", + "description": "This module deploys a Recovery Services Vault Protection Container Protected Item.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the resource." + } + }, + "protectionContainerName": { + "type": "string", + "metadata": { + "description": "Conditional. Name of the Azure Recovery Service Vault Protection Container. Required if the template is used in a standalone deployment." + } + }, + "recoveryVaultName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Azure Recovery Service Vault. Required if the template is used in a standalone deployment." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "protectedItemType": { + "type": "string", + "allowedValues": [ + "AzureFileShareProtectedItem", + "AzureVmWorkloadSAPAseDatabase", + "AzureVmWorkloadSAPHanaDatabase", + "AzureVmWorkloadSQLDatabase", + "DPMProtectedItem", + "GenericProtectedItem", + "MabFileFolderProtectedItem", + "Microsoft.ClassicCompute/virtualMachines", + "Microsoft.Compute/virtualMachines", + "Microsoft.Sql/servers/databases" + ], + "metadata": { + "description": "Required. The backup item type." + } + }, + "policyId": { + "type": "string", + "metadata": { + "description": "Required. ID of the backup policy with which this item is backed up." + } + }, + "sourceResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the resource to back up." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + } + }, + "resources": [ + { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + { + "type": "Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems", + "apiVersion": "2023-01-01", + "name": "[format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name'))]", + "location": "[parameters('location')]", + "properties": { + "protectedItemType": "[parameters('protectedItemType')]", + "policyId": "[parameters('policyId')]", + "sourceResourceId": "[parameters('sourceResourceId')]" + } + } + ], + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the protected item was created in." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the protected item." + }, + "value": "[resourceId('Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems', split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[0], split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[1], split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[2], split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[3])]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The Name of the protected item." + }, + "value": "[format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name'))]" + } + } + } + }, + "dependsOn": [ + "vm", + "vm_aadJoinExtension", + "vm_customScriptExtension", + "vm_dependencyAgentExtension", + "vm_desiredStateConfigurationExtension", + "vm_domainJoinExtension", + "vm_microsoftAntiMalwareExtension", + "vm_microsoftMonitoringAgentExtension", + "vm_networkWatcherAgentExtension" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the VM." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the VM." + }, + "value": "[resourceId('Microsoft.Compute/virtualMachines', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the VM was created in." + }, + "value": "[resourceGroup().name]" + }, + "systemAssignedMIPrincipalId": { + "type": "string", + "metadata": { + "description": "The principal ID of the system assigned identity." + }, + "value": "[if(and(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), contains(reference('vm', '2022-11-01', 'full').identity, 'principalId')), reference('vm', '2022-11-01', 'full').identity.principalId, '')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('vm', '2022-11-01', 'full').location]" + } + } +} \ No newline at end of file diff --git a/modules/compute/virtual-machine/modules/nested_networkInterface.bicep b/modules/compute/virtual-machine/modules/nested_networkInterface.bicep new file mode 100644 index 0000000000..a7e44aaf79 --- /dev/null +++ b/modules/compute/virtual-machine/modules/nested_networkInterface.bicep @@ -0,0 +1,147 @@ +param networkInterfaceName string +param virtualMachineName string +param location string +param tags object? +param enableIPForwarding bool = false +param enableAcceleratedNetworking bool = false +param dnsServers array = [] + +@description('Optional. The network security group (NSG) to attach to the network interface.') +param networkSecurityGroupResourceId string = '' + +param ipConfigurations array +param lock lockType + +@description('Optional. The diagnostic settings of the Network Interface.') +param diagnosticSettings diagnosticSettingType + +@description('Optional. Array of role assignments to create.') +param roleAssignments roleAssignmentType + +var enableReferencedModulesTelemetry = false + +module networkInterface_publicIPAddresses '../../../network/public-ip-address/main.bicep' = [for (ipConfiguration, index) in ipConfigurations: if (contains(ipConfiguration, 'pipconfiguration')) { + name: '${deployment().name}-publicIP-${index}' + params: { + name: '${virtualMachineName}${ipConfiguration.pipconfiguration.publicIpNameSuffix}' + diagnosticSettings: ipConfiguration.?diagnosticSettings + location: location + lock: lock + publicIPAddressVersion: contains(ipConfiguration, 'publicIPAddressVersion') ? ipConfiguration.publicIPAddressVersion : 'IPv4' + publicIPAllocationMethod: contains(ipConfiguration, 'publicIPAllocationMethod') ? ipConfiguration.publicIPAllocationMethod : 'Static' + publicIPPrefixResourceId: contains(ipConfiguration, 'publicIPPrefixResourceId') ? ipConfiguration.publicIPPrefixResourceId : '' + roleAssignments: contains(ipConfiguration, 'roleAssignments') ? ipConfiguration.roleAssignments : [] + skuName: contains(ipConfiguration, 'skuName') ? ipConfiguration.skuName : 'Standard' + skuTier: contains(ipConfiguration, 'skuTier') ? ipConfiguration.skuTier : 'Regional' + tags: ipConfiguration.?tags ?? tags + zones: contains(ipConfiguration, 'zones') ? ipConfiguration.zones : [] + } +}] + +module networkInterface '../../../network/network-interface/main.bicep' = { + name: '${deployment().name}-NetworkInterface' + params: { + name: networkInterfaceName + ipConfigurations: [for (ipConfiguration, index) in ipConfigurations: { + name: !empty(ipConfiguration.name) ? ipConfiguration.name : null + primary: index == 0 + privateIPAllocationMethod: contains(ipConfiguration, 'privateIPAllocationMethod') ? (!empty(ipConfiguration.privateIPAllocationMethod) ? ipConfiguration.privateIPAllocationMethod : null) : null + privateIPAddress: contains(ipConfiguration, 'privateIPAddress') ? (!empty(ipConfiguration.privateIPAddress) ? ipConfiguration.privateIPAddress : null) : null + publicIPAddressResourceId: contains(ipConfiguration, 'pipconfiguration') ? resourceId('Microsoft.Network/publicIPAddresses', '${virtualMachineName}${ipConfiguration.pipconfiguration.publicIpNameSuffix}') : null + subnetResourceId: ipConfiguration.subnetResourceId + loadBalancerBackendAddressPools: contains(ipConfiguration, 'loadBalancerBackendAddressPools') ? ipConfiguration.loadBalancerBackendAddressPools : null + applicationSecurityGroups: contains(ipConfiguration, 'applicationSecurityGroups') ? ipConfiguration.applicationSecurityGroups : null + applicationGatewayBackendAddressPools: contains(ipConfiguration, 'applicationGatewayBackendAddressPools') ? ipConfiguration.applicationGatewayBackendAddressPools : null + gatewayLoadBalancer: contains(ipConfiguration, 'gatewayLoadBalancer') ? ipConfiguration.gatewayLoadBalancer : null + loadBalancerInboundNatRules: contains(ipConfiguration, 'loadBalancerInboundNatRules') ? ipConfiguration.loadBalancerInboundNatRules : null + privateIPAddressVersion: contains(ipConfiguration, 'privateIPAddressVersion') ? ipConfiguration.privateIPAddressVersion : null + virtualNetworkTaps: contains(ipConfiguration, 'virtualNetworkTaps') ? ipConfiguration.virtualNetworkTaps : null + }] + location: location + tags: tags + diagnosticSettings: diagnosticSettings + dnsServers: !empty(dnsServers) ? dnsServers : [] + enableAcceleratedNetworking: enableAcceleratedNetworking + enableDefaultTelemetry: enableReferencedModulesTelemetry + enableIPForwarding: enableIPForwarding + lock: lock + networkSecurityGroupResourceId: !empty(networkSecurityGroupResourceId) ? networkSecurityGroupResourceId : '' + roleAssignments: !empty(roleAssignments) ? roleAssignments : [] + } + dependsOn: [ + networkInterface_publicIPAddresses + ] +} + +// =============== // +// Definitions // +// =============== // + +type lockType = { + @description('Optional. Specify the name of lock.') + name: string? + + @description('Optional. Specify the type of lock.') + kind: ('CanNotDelete' | 'ReadOnly' | 'None')? +}? + +type diagnosticSettingType = { + @description('Optional. The name of diagnostic setting.') + name: string? + + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + logCategoriesAndGroups: { + @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') + category: string? + + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to llLogs to collect all logs.') + categoryGroup: string? + }[]? + + @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: { + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to AllMetrics to collect all metrics.') + category: string + }[]? + + @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.') + logAnalyticsDestinationType: ('Dedicated' | 'AzureDiagnostics')? + + @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.') + workspaceResourceId: string? + + @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.') + storageAccountResourceId: string? + + @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.') + eventHubAuthorizationRuleResourceId: string? + + @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.') + eventHubName: string? + + @description('Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs.') + marketplacePartnerResourceId: string? +}[]? + +type roleAssignmentType = { + @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/modules/compute/virtual-machine/tests/e2e/linux.atmg/dependencies.bicep b/modules/compute/virtual-machine/tests/e2e/linux.atmg/dependencies.bicep new file mode 100644 index 0000000000..d8b2e100e0 --- /dev/null +++ b/modules/compute/virtual-machine/tests/e2e/linux.atmg/dependencies.bicep @@ -0,0 +1,86 @@ +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +@description('Required. The name of the Managed Identity to create.') +param managedIdentityName string + +@description('Required. The name of the Deployment Script to create for the SSH Key generation.') +param sshDeploymentScriptName string + +@description('Required. The name of the SSH Key to create.') +param sshKeyName string + +@description('Optional. The location to deploy resources to.') +param location string = resourceGroup().location + +var addressPrefix = '10.0.0.0/16' + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + } + } + ] + } +} + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: location +} + +resource msiRGContrRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(resourceGroup().id, 'Contributor', managedIdentity.id) + scope: resourceGroup() + properties: { + principalId: managedIdentity.properties.principalId + roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor + principalType: 'ServicePrincipal' + } +} + +resource sshDeploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = { + name: sshDeploymentScriptName + location: location + kind: 'AzurePowerShell' + identity: { + type: 'UserAssigned' + userAssignedIdentities: { + '${managedIdentity.id}': {} + } + } + properties: { + azPowerShellVersion: '9.0' + retentionInterval: 'P1D' + arguments: ' -SSHKeyName "${sshKeyName}" -ResourceGroupName "${resourceGroup().name}"' + scriptContent: loadTextContent('../../../../../.shared/.scripts/New-SSHKey.ps1') + } + dependsOn: [ + msiRGContrRoleAssignment + ] +} + +resource sshKey 'Microsoft.Compute/sshPublicKeys@2022-03-01' = { + name: sshKeyName + location: location + properties: { + publicKey: sshDeploymentScript.properties.outputs.publicKey + } +} + +@description('The resource ID of the created Virtual Network Subnet.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id + +@description('The Public Key of the created SSH Key.') +output SSHKeyPublicKey string = sshKey.properties.publicKey diff --git a/modules/compute/virtual-machine/tests/e2e/linux.atmg/main.test.bicep b/modules/compute/virtual-machine/tests/e2e/linux.atmg/main.test.bicep new file mode 100644 index 0000000000..4e53732a23 --- /dev/null +++ b/modules/compute/virtual-machine/tests/e2e/linux.atmg/main.test.bicep @@ -0,0 +1,123 @@ +targetScope = 'subscription' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-compute.virtualMachines-${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 = 'cvmlinatmg' + +@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') +param enableDefaultTelemetry bool = true + +@description('Optional. A token to inject into the name of each resource.') +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: { + location: location + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + sshDeploymentScriptName: 'dep-${namePrefix}-ds-${serviceShort}' + sshKeyName: 'dep-${namePrefix}-ssh-${serviceShort}' + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + } +} + +// ============== // +// Test Execution // +// ============== // + +// resource sshKey 'Microsoft.Compute/sshPublicKeys@2022-03-01' existing = { +// name: sshKeyName +// scope: resourceGroup +// } + +module testDeployment '../../../main.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}' + params: { + enableDefaultTelemetry: enableDefaultTelemetry + location: location + name: '${namePrefix}${serviceShort}' + adminUsername: 'localAdminUser' + imageReference: { + publisher: 'Canonical' + offer: '0001-com-ubuntu-server-jammy' + sku: '22_04-lts-gen2' + version: 'latest' + } + nicConfigurations: [ + { + ipConfigurations: [ + { + name: 'ipconfig01' + pipConfiguration: { + publicIpNameSuffix: '-pip-01' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + zones: [ + '1' + '2' + '3' + ] + subnetResourceId: nestedDependencies.outputs.subnetResourceId + } + ] + nicSuffix: '-nic-01' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + ] + osDisk: { + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + osType: 'Linux' + vmSize: 'Standard_DS2_v2' + configurationProfile: '/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesProduction' + disablePasswordAuthentication: true + publicKeys: [ + { + keyData: nestedDependencies.outputs.SSHKeyPublicKey + path: '/home/localAdminUser/.ssh/authorized_keys' + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + dependsOn: [ + nestedDependencies // Required to leverage `existing` SSH key reference + ] +} diff --git a/modules/compute/virtual-machine/tests/e2e/linux.min/dependencies.bicep b/modules/compute/virtual-machine/tests/e2e/linux.min/dependencies.bicep new file mode 100644 index 0000000000..c88f2b1230 --- /dev/null +++ b/modules/compute/virtual-machine/tests/e2e/linux.min/dependencies.bicep @@ -0,0 +1,86 @@ +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +@description('Required. The name of the Managed Identity to create.') +param managedIdentityName string + +@description('Required. The name of the Deployment Script to create for the SSH Key generation.') +param sshDeploymentScriptName string + +@description('Required. The name of the SSH Key to create.') +param sshKeyName string + +@description('Optional. The location to deploy resources to.') +param location string = resourceGroup().location + +var addressPrefix = '10.0.0.0/16' + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + } + } + ] + } +} + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: location +} + +resource msiRGContrRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(resourceGroup().id, 'Contributor', managedIdentity.id) + scope: resourceGroup() + properties: { + principalId: managedIdentity.properties.principalId + roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor + principalType: 'ServicePrincipal' + } +} + +resource sshDeploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = { + name: sshDeploymentScriptName + location: location + kind: 'AzurePowerShell' + identity: { + type: 'UserAssigned' + userAssignedIdentities: { + '${managedIdentity.id}': {} + } + } + properties: { + azPowerShellVersion: '9.0' + retentionInterval: 'P1D' + arguments: '-SSHKeyName "${sshKeyName}" -ResourceGroupName "${resourceGroup().name}"' + scriptContent: loadTextContent('../../../../../.shared/.scripts/New-SSHKey.ps1') + } + dependsOn: [ + msiRGContrRoleAssignment + ] +} + +resource sshKey 'Microsoft.Compute/sshPublicKeys@2022-03-01' = { + name: sshKeyName + location: location + properties: { + publicKey: sshDeploymentScript.properties.outputs.publicKey + } +} + +@description('The resource ID of the created Virtual Network Subnet.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id + +@description('The Public Key of the created SSH Key.') +output SSHKeyPublicKey string = sshKey.properties.publicKey diff --git a/modules/compute/virtual-machine/tests/e2e/linux.min/main.test.bicep b/modules/compute/virtual-machine/tests/e2e/linux.min/main.test.bicep new file mode 100644 index 0000000000..4c3fffb43d --- /dev/null +++ b/modules/compute/virtual-machine/tests/e2e/linux.min/main.test.bicep @@ -0,0 +1,102 @@ +targetScope = 'subscription' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-compute.virtualMachines-${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 = 'cvmlinmin' + +@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') +param enableDefaultTelemetry bool = true + +@description('Optional. A token to inject into the name of each resource.') +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: { + location: location + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + sshDeploymentScriptName: 'dep-${namePrefix}-ds-${serviceShort}' + sshKeyName: 'dep-${namePrefix}-ssh-${serviceShort}' + } +} + +// ============== // +// Test Execution // +// ============== // + +// resource sshKey 'Microsoft.Compute/sshPublicKeys@2022-03-01' existing = { +// name: sshKeyName +// scope: resourceGroup +// } + +module testDeployment '../../../main.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}' + params: { + enableDefaultTelemetry: enableDefaultTelemetry + location: location + name: '${namePrefix}${serviceShort}' + adminUsername: 'localAdminUser' + imageReference: { + publisher: 'Canonical' + offer: '0001-com-ubuntu-server-jammy' + sku: '22_04-lts-gen2' + version: 'latest' + } + nicConfigurations: [ + { + ipConfigurations: [ + { + name: 'ipconfig01' + pipConfiguration: { + publicIpNameSuffix: '-pip-01' + } + subnetResourceId: nestedDependencies.outputs.subnetResourceId + } + ] + nicSuffix: '-nic-01' + } + ] + osDisk: { + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + osType: 'Linux' + vmSize: 'Standard_DS2_v2' + disablePasswordAuthentication: true + publicKeys: [ + { + keyData: nestedDependencies.outputs.SSHKeyPublicKey + path: '/home/localAdminUser/.ssh/authorized_keys' + } + ] + } + dependsOn: [ + nestedDependencies // Required to leverage `existing` SSH key reference + ] +} diff --git a/modules/compute/virtual-machine/tests/e2e/linux/dependencies.bicep b/modules/compute/virtual-machine/tests/e2e/linux/dependencies.bicep new file mode 100644 index 0000000000..4dbd74b07b --- /dev/null +++ b/modules/compute/virtual-machine/tests/e2e/linux/dependencies.bicep @@ -0,0 +1,337 @@ +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +@description('Required. The name of the Application Security Group to create.') +param applicationSecurityGroupName string + +@description('Required. The name of the Managed Identity to create.') +param managedIdentityName string + +@description('Required. The name of the Load Balancer to create.') +param loadBalancerName string + +@description('Required. The name of the Recovery Services Vault to create.') +param recoveryServicesVaultName string + +@description('Required. The name of the Key Vault to create.') +param keyVaultName string + +@description('Required. The name of the Storage Account to create.') +param storageAccountName string + +@description('Required. The name of the Deployment Script used to upload data to the Storage Account.') +param storageUploadDeploymentScriptName string + +@description('Required. The name of the Deployment Script to create for the SSH Key generation.') +param sshDeploymentScriptName string + +@description('Required. The name of the SSH Key to create.') +param sshKeyName string + +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +var storageAccountCSEFileName = 'scriptExtensionMasterInstaller.ps1' +var addressPrefix = '10.0.0.0/16' + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + } + } + ] + } +} + +resource applicationSecurityGroup 'Microsoft.Network/applicationSecurityGroups@2023-04-01' = { + name: applicationSecurityGroupName + location: location +} + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: location +} + +resource msiRGContrRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(resourceGroup().id, 'Contributor', managedIdentity.id) + scope: resourceGroup() + properties: { + principalId: managedIdentity.properties.principalId + roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor + principalType: 'ServicePrincipal' + } +} + +resource loadBalancer 'Microsoft.Network/loadBalancers@2023-04-01' = { + name: loadBalancerName + location: location + sku: { + name: 'Standard' + } + properties: { + frontendIPConfigurations: [ + { + name: 'privateIPConfig1' + properties: { + subnet: virtualNetwork.properties.subnets[0] + } + } + ] + backendAddressPools: [ + { + name: 'servers' + } + ] + } +} + +resource recoveryServicesVault 'Microsoft.RecoveryServices/vaults@2022-04-01' = { + name: recoveryServicesVaultName + location: location + sku: { + name: 'RS0' + tier: 'Standard' + } + properties: {} + + resource backupPolicy 'backupPolicies@2022-03-01' = { + name: 'backupPolicy' + properties: { + backupManagementType: 'AzureIaasVM' + instantRPDetails: {} + schedulePolicy: { + schedulePolicyType: 'SimpleSchedulePolicy' + scheduleRunFrequency: 'Daily' + scheduleRunTimes: [ + '2019-11-07T07:00:00Z' + ] + scheduleWeeklyFrequency: 0 + } + retentionPolicy: { + retentionPolicyType: 'LongTermRetentionPolicy' + dailySchedule: { + retentionTimes: [ + '2019-11-07T07:00:00Z' + ] + retentionDuration: { + count: 180 + durationType: 'Days' + } + } + weeklySchedule: { + daysOfTheWeek: [ + 'Sunday' + ] + retentionTimes: [ + '2019-11-07T07:00:00Z' + ] + retentionDuration: { + count: 12 + durationType: 'Weeks' + } + } + monthlySchedule: { + retentionScheduleFormatType: 'Weekly' + retentionScheduleWeekly: { + daysOfTheWeek: [ + 'Sunday' + ] + weeksOfTheMonth: [ + 'First' + ] + } + retentionTimes: [ + '2019-11-07T07:00:00Z' + ] + retentionDuration: { + count: 60 + durationType: 'Months' + } + } + yearlySchedule: { + retentionScheduleFormatType: 'Weekly' + monthsOfYear: [ + 'January' + ] + retentionScheduleWeekly: { + daysOfTheWeek: [ + 'Sunday' + ] + weeksOfTheMonth: [ + 'First' + ] + } + retentionTimes: [ + '2019-11-07T07:00:00Z' + ] + retentionDuration: { + count: 10 + durationType: 'Years' + } + } + } + instantRpRetentionRangeInDays: 2 + timeZone: 'UTC' + protectedItemsCount: 0 + } + } +} + +resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = { + name: keyVaultName + location: location + properties: { + sku: { + family: 'A' + name: 'standard' + } + tenantId: tenant().tenantId + enablePurgeProtection: null + enabledForTemplateDeployment: true + enabledForDiskEncryption: true + enabledForDeployment: true + enableRbacAuthorization: true + accessPolicies: [] + } + + resource key 'keys@2022-07-01' = { + name: 'encryptionKey' + properties: { + kty: 'RSA' + } + } +} + +resource msiKVCryptoUserRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid('msi-${keyVault::key.id}-${location}-${managedIdentity.id}-KeyVault-Key-Read-RoleAssignment') + scope: keyVault::key + properties: { + principalId: managedIdentity.properties.principalId + roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') // Key Vault Crypto User + principalType: 'ServicePrincipal' + } +} + +resource storageAccount 'Microsoft.Storage/storageAccounts@2021-09-01' = { + name: storageAccountName + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' + + resource blobService 'blobServices@2021-09-01' = { + name: 'default' + + resource container 'containers@2021-09-01' = { + name: 'scripts' + } + } +} + +resource storageUpload 'Microsoft.Resources/deploymentScripts@2020-10-01' = { + name: storageUploadDeploymentScriptName + location: location + kind: 'AzurePowerShell' + identity: { + type: 'UserAssigned' + userAssignedIdentities: { + '${managedIdentity.id}': {} + } + } + properties: { + azPowerShellVersion: '9.0' + retentionInterval: 'P1D' + arguments: '-StorageAccountName "${storageAccount.name}" -ResourceGroupName "${resourceGroup().name}" -ContainerName "${storageAccount::blobService::container.name}" -FileName "${storageAccountCSEFileName}"' + scriptContent: loadTextContent('../../../../../.shared/.scripts/Set-BlobContent.ps1') + } + dependsOn: [ + msiRGContrRoleAssignment + ] +} + +resource sshDeploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = { + name: sshDeploymentScriptName + location: location + kind: 'AzurePowerShell' + identity: { + type: 'UserAssigned' + userAssignedIdentities: { + '${managedIdentity.id}': {} + } + } + properties: { + azPowerShellVersion: '9.0' + retentionInterval: 'P1D' + arguments: '-SSHKeyName "${sshKeyName}" -ResourceGroupName "${resourceGroup().name}"' + scriptContent: loadTextContent('../../../../../.shared/.scripts/New-SSHKey.ps1') + } + dependsOn: [ + msiRGContrRoleAssignment + ] +} + +resource sshKey 'Microsoft.Compute/sshPublicKeys@2022-03-01' = { + name: sshKeyName + location: location + properties: { + publicKey: sshDeploymentScript.properties.outputs.publicKey + } +} + +@description('The resource ID of the created Virtual Network Subnet.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id + +@description('The resource ID of the created Application Security Group.') +output applicationSecurityGroupResourceId string = applicationSecurityGroup.id + +@description('The principal ID of the created Managed Identity.') +output managedIdentityPrincipalId string = managedIdentity.properties.principalId + +@description('The resource ID of the created Managed Identity.') +output managedIdentityResourceId string = managedIdentity.id + +@description('The resource ID of the created Load Balancer Backend Pool.') +output loadBalancerBackendPoolResourceId string = loadBalancer.properties.backendAddressPools[0].id + +@description('The name of the created Recovery Services Vault.') +output recoveryServicesVaultName string = recoveryServicesVault.name + +@description('The name of the Resource Group, the Recovery Services Vault was created in.') +output recoveryServicesVaultResourceGroupName string = resourceGroup().name + +@description('The name of the Backup Policy created in the Backup Recovery Vault.') +output recoveryServicesVaultBackupPolicyName string = recoveryServicesVault::backupPolicy.name + +@description('The resource ID of the created Key Vault.') +output keyVaultResourceId string = keyVault.id + +@description('The URL of the created Key Vault.') +output keyVaultUrl string = keyVault.properties.vaultUri + +@description('The URL of the created Key Vault Encryption Key.') +output keyVaultEncryptionKeyUrl string = keyVault::key.properties.keyUriWithVersion + +@description('The resource ID of the created Storage Account.') +output storageAccountResourceId string = storageAccount.id + +@description('The URL of the Custom Script Extension in the created Storage Account.') +output storageAccountCSEFileUrl string = '${storageAccount.properties.primaryEndpoints.blob}${storageAccount::blobService::container.name}/${storageAccountCSEFileName}' + +@description('The name of the Custom Script Extension in the created Storage Account.') +output storageAccountCSEFileName string = storageAccountCSEFileName + +@description('The Public Key of the created SSH Key.') +output SSHKeyPublicKey string = sshKey.properties.publicKey diff --git a/modules/compute/virtual-machine/tests/e2e/linux/main.test.bicep b/modules/compute/virtual-machine/tests/e2e/linux/main.test.bicep new file mode 100644 index 0000000000..b4b5e7ba57 --- /dev/null +++ b/modules/compute/virtual-machine/tests/e2e/linux/main.test.bicep @@ -0,0 +1,314 @@ +targetScope = 'subscription' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-compute.virtualMachines-${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 = 'cvmlincom' + +@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') +param enableDefaultTelemetry bool = true + +@description('Optional. A token to inject into the name of each resource.') +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: { + location: location + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + applicationSecurityGroupName: 'dep-${namePrefix}-asg-${serviceShort}' + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}' + loadBalancerName: 'dep-${namePrefix}-lb-${serviceShort}' + recoveryServicesVaultName: 'dep-${namePrefix}-rsv-${serviceShort}' + storageAccountName: 'dep${namePrefix}sa${serviceShort}01' + storageUploadDeploymentScriptName: 'dep-${namePrefix}-sads-${serviceShort}' + sshDeploymentScriptName: 'dep-${namePrefix}-ds-${serviceShort}' + sshKeyName: 'dep-${namePrefix}-ssh-${serviceShort}' + } +} + +// Diagnostics +// =========== +module diagnosticDependencies '../../../../../.shared/.templates/diagnostic.dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-diagnosticDependencies' + params: { + storageAccountName: 'dep${namePrefix}diasa${serviceShort}01' + logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' + eventHubNamespaceEventHubName: 'dep-${namePrefix}-evh-${serviceShort}' + eventHubNamespaceName: 'dep-${namePrefix}-evhns-${serviceShort}' + location: location + } +} + +// ============== // +// Test Execution // +// ============== // + +module testDeployment '../../../main.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}' + params: { + enableDefaultTelemetry: enableDefaultTelemetry + name: '${namePrefix}${serviceShort}' + computerName: '${namePrefix}linvm1' + location: location + adminUsername: 'localAdministrator' + imageReference: { + publisher: 'Canonical' + offer: '0001-com-ubuntu-server-focal' + sku: '20_04-lts-gen2' // Note: 22.04 does not support OMS extension + version: 'latest' + } + nicConfigurations: [ + { + deleteOption: 'Delete' + ipConfigurations: [ + { + applicationSecurityGroups: [ + { + id: nestedDependencies.outputs.applicationSecurityGroupResourceId + } + ] + loadBalancerBackendAddressPools: [ + { + id: nestedDependencies.outputs.loadBalancerBackendPoolResourceId + } + ] + name: 'ipconfig01' + pipConfiguration: { + publicIpNameSuffix: '-pip-01' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + } + zones: [ + '1' + '2' + '3' + ] + subnetResourceId: nestedDependencies.outputs.subnetResourceId + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + } + ] + nicSuffix: '-nic-01' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + } + ] + osDisk: { + caching: 'ReadOnly' + createOption: 'fromImage' + deleteOption: 'Delete' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + osType: 'Linux' + vmSize: 'Standard_DS2_v2' + availabilityZone: 1 + backupPolicyName: nestedDependencies.outputs.recoveryServicesVaultBackupPolicyName + backupVaultName: nestedDependencies.outputs.recoveryServicesVaultName + backupVaultResourceGroup: nestedDependencies.outputs.recoveryServicesVaultResourceGroupName + dataDisks: [ + { + caching: 'ReadWrite' + createOption: 'Empty' + deleteOption: 'Delete' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + { + caching: 'ReadWrite' + createOption: 'Empty' + deleteOption: 'Delete' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + ] + enableAutomaticUpdates: true + patchMode: 'AutomaticByPlatform' + disablePasswordAuthentication: true + encryptionAtHost: false + extensionCustomScriptConfig: { + enabled: true + fileData: [ + { + storageAccountId: nestedDependencies.outputs.storageAccountResourceId + uri: nestedDependencies.outputs.storageAccountCSEFileUrl + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + extensionCustomScriptProtectedSetting: { + commandToExecute: 'value=$(./${nestedDependencies.outputs.storageAccountCSEFileName}); echo "$value"' + } + extensionDependencyAgentConfig: { + enabled: true + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + extensionAzureDiskEncryptionConfig: { + enabled: true + settings: { + EncryptionOperation: 'EnableEncryption' + KekVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + KeyEncryptionAlgorithm: 'RSA-OAEP' + KeyEncryptionKeyURL: nestedDependencies.outputs.keyVaultEncryptionKeyUrl + KeyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + KeyVaultURL: nestedDependencies.outputs.keyVaultUrl + ResizeOSDisk: 'false' + VolumeType: 'All' + } + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + extensionAadJoinConfig: { + enabled: true + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + extensionDSCConfig: { + enabled: false + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + extensionMonitoringAgentConfig: { + enabled: true + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + extensionNetworkWatcherAgentConfig: { + enabled: true + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + monitoringWorkspaceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + publicKeys: [ + { + keyData: nestedDependencies.outputs.SSHKeyPublicKey + path: '/home/localAdministrator/.ssh/authorized_keys' + } + ] + roleAssignments: [ + { + roleDefinitionIdOrName: 'Owner' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] + } + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + dependsOn: [ + nestedDependencies // Required to leverage `existing` SSH key reference + ] +} diff --git a/modules/compute/virtual-machine/tests/e2e/windows.atmg/dependencies.bicep b/modules/compute/virtual-machine/tests/e2e/windows.atmg/dependencies.bicep new file mode 100644 index 0000000000..a546ea7dba --- /dev/null +++ b/modules/compute/virtual-machine/tests/e2e/windows.atmg/dependencies.bicep @@ -0,0 +1,30 @@ +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +@description('Optional. The location to deploy resources to.') +param location string = resourceGroup().location + +var addressPrefix = '10.0.0.0/16' + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + } + } + ] + } +} + +@description('The resource ID of the created Virtual Network Subnet.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id diff --git a/modules/compute/virtual-machine/tests/e2e/windows.atmg/main.test.bicep b/modules/compute/virtual-machine/tests/e2e/windows.atmg/main.test.bicep new file mode 100644 index 0000000000..b1314bce14 --- /dev/null +++ b/modules/compute/virtual-machine/tests/e2e/windows.atmg/main.test.bicep @@ -0,0 +1,92 @@ +targetScope = 'subscription' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-compute.virtualMachines-${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 = 'cvmwinatmg' + +@description('Optional. The password to leverage for the login.') +@secure() +param password string = newGuid() + +@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') +param enableDefaultTelemetry bool = true + +@description('Optional. A token to inject into the name of each resource.') +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: { + location: location + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + } +} + +// ============== // +// Test Execution // +// ============== // + +module testDeployment '../../../main.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}' + params: { + enableDefaultTelemetry: enableDefaultTelemetry + location: location + name: '${namePrefix}${serviceShort}' + adminUsername: 'localAdministrator' + imageReference: { + publisher: 'MicrosoftWindowsServer' + offer: 'WindowsServer' + sku: '2022-datacenter-azure-edition' + version: 'latest' + } + nicConfigurations: [ + { + ipConfigurations: [ + { + name: 'ipconfig01' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + } + ] + nicSuffix: '-nic-01' + } + ] + osDisk: { + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + osType: 'Windows' + vmSize: 'Standard_DS2_v2' + adminPassword: password + configurationProfile: '/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesProduction' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } +} diff --git a/modules/compute/virtual-machine/tests/e2e/windows.min/dependencies.bicep b/modules/compute/virtual-machine/tests/e2e/windows.min/dependencies.bicep new file mode 100644 index 0000000000..68972ec7ec --- /dev/null +++ b/modules/compute/virtual-machine/tests/e2e/windows.min/dependencies.bicep @@ -0,0 +1,30 @@ +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +var addressPrefix = '10.0.0.0/16' + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + } + } + ] + } +} + +@description('The resource ID of the created Virtual Network Subnet.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id diff --git a/modules/compute/virtual-machine/tests/e2e/windows.min/main.test.bicep b/modules/compute/virtual-machine/tests/e2e/windows.min/main.test.bicep new file mode 100644 index 0000000000..68c34d8494 --- /dev/null +++ b/modules/compute/virtual-machine/tests/e2e/windows.min/main.test.bicep @@ -0,0 +1,85 @@ +targetScope = 'subscription' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-compute.virtualMachines-${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 = 'cvmwinmin' + +@description('Optional. The password to leverage for the login.') +@secure() +param password string = newGuid() + +@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') +param enableDefaultTelemetry bool = true + +@description('Optional. A token to inject into the name of each resource.') +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: { + location: location + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + } +} + +// ============== // +// Test Execution // +// ============== // +module testDeployment '../../../main.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}' + params: { + enableDefaultTelemetry: enableDefaultTelemetry + location: location + name: '${namePrefix}${serviceShort}' + adminUsername: 'localAdminUser' + imageReference: { + publisher: 'MicrosoftWindowsServer' + offer: 'WindowsServer' + sku: '2022-datacenter-azure-edition' + version: 'latest' + } + nicConfigurations: [ + { + ipConfigurations: [ + { + name: 'ipconfig01' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + } + ] + nicSuffix: '-nic-01' + } + ] + osDisk: { + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + osType: 'Windows' + vmSize: 'Standard_DS2_v2' + adminPassword: password + } +} diff --git a/modules/compute/virtual-machine/tests/e2e/windows.ssecmk/dependencies.bicep b/modules/compute/virtual-machine/tests/e2e/windows.ssecmk/dependencies.bicep new file mode 100644 index 0000000000..e5cb91cea0 --- /dev/null +++ b/modules/compute/virtual-machine/tests/e2e/windows.ssecmk/dependencies.bicep @@ -0,0 +1,92 @@ +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +@description('Required. The name of the Key Vault to create.') +param keyVaultName string + +@description('Required. The name of the Disk Encryption Set to create.') +param diskEncryptionSetName string + +@description('Optional. The location to deploy resources to.') +param location string = resourceGroup().location + +var addressPrefix = '10.0.0.0/16' + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + } + } + ] + } +} + +resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = { + name: keyVaultName + location: location + properties: { + sku: { + family: 'A' + name: 'standard' + } + tenantId: tenant().tenantId + enablePurgeProtection: true // Required by disk encryption set + softDeleteRetentionInDays: 7 + enabledForTemplateDeployment: true + enabledForDiskEncryption: true + enabledForDeployment: true + enableRbacAuthorization: true + accessPolicies: [] + } + + resource key 'keys@2022-07-01' = { + name: 'keyEncryptionKey' + properties: { + kty: 'RSA' + } + } +} + +resource diskEncryptionSet 'Microsoft.Compute/diskEncryptionSets@2021-04-01' = { + name: diskEncryptionSetName + location: location + identity: { + type: 'SystemAssigned' + } + properties: { + activeKey: { + sourceVault: { + id: keyVault.id + } + keyUrl: keyVault::key.properties.keyUriWithVersion + } + encryptionType: 'EncryptionAtRestWithPlatformAndCustomerKeys' + } +} + +resource keyPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(keyVault::key.id, 'Key Vault Crypto User', diskEncryptionSet.id) + scope: keyVault + properties: { + principalId: diskEncryptionSet.identity.principalId + roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e147488a-f6f5-4113-8e2d-b22465e65bf6') // Key Vault Crypto Service Encryption User + principalType: 'ServicePrincipal' + } +} + +@description('The resource ID of the created Virtual Network Subnet.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id + +@description('The resource ID of the created Disk Encryption Set.') +output diskEncryptionSetResourceId string = diskEncryptionSet.id diff --git a/modules/compute/virtual-machine/tests/e2e/windows.ssecmk/main.test.bicep b/modules/compute/virtual-machine/tests/e2e/windows.ssecmk/main.test.bicep new file mode 100644 index 0000000000..ff7c06d244 --- /dev/null +++ b/modules/compute/virtual-machine/tests/e2e/windows.ssecmk/main.test.bicep @@ -0,0 +1,110 @@ +targetScope = 'subscription' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-compute.virtualMachines-${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 = 'cvmwincmk' + +@description('Optional. The password to leverage for the login.') +@secure() +param password string = newGuid() + +@description('Generated. Used as a basis for unique resource names.') +param baseTime string = utcNow('u') + +@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') +param enableDefaultTelemetry bool = true + +@description('Optional. A token to inject into the name of each resource.') +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: { + location: location + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + // Adding base time to make the name unique as purge protection must be enabled (but may not be longer than 24 characters total) + keyVaultName: 'dep${namePrefix}kv${serviceShort}-${substring(uniqueString(baseTime), 0, 3)}' + diskEncryptionSetName: 'dep-${namePrefix}-des-${serviceShort}' + } +} + +// ============== // +// Test Execution // +// ============== // +module testDeployment '../../../main.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}' + params: { + enableDefaultTelemetry: enableDefaultTelemetry + location: location + name: '${namePrefix}${serviceShort}' + adminUsername: 'VMAdministrator' + imageReference: { + publisher: 'MicrosoftWindowsServer' + offer: 'WindowsServer' + sku: '2019-datacenter' + version: 'latest' + } + nicConfigurations: [ + { + ipConfigurations: [ + { + name: 'ipconfig01' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + } + ] + nicSuffix: '-nic-01' + } + ] + osDisk: { + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + diskEncryptionSet: { + id: nestedDependencies.outputs.diskEncryptionSetResourceId + } + } + } + osType: 'Windows' + vmSize: 'Standard_DS2_v2' + adminPassword: password + dataDisks: [ + { + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + diskEncryptionSet: { + id: nestedDependencies.outputs.diskEncryptionSetResourceId + } + } + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } +} diff --git a/modules/compute/virtual-machine/tests/e2e/windows/dependencies.bicep b/modules/compute/virtual-machine/tests/e2e/windows/dependencies.bicep new file mode 100644 index 0000000000..6a1f5fcc13 --- /dev/null +++ b/modules/compute/virtual-machine/tests/e2e/windows/dependencies.bicep @@ -0,0 +1,310 @@ +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +@description('Required. The name of the Application Security Group to create.') +param applicationSecurityGroupName string + +@description('Required. The name of the Managed Identity to create.') +param managedIdentityName string + +@description('Required. The name of the Load Balancer to create.') +param loadBalancerName string + +@description('Required. The name of the Recovery Services Vault to create.') +param recoveryServicesVaultName string + +@description('Required. The name of the Key Vault to create.') +param keyVaultName string + +@description('Required. The name of the Storage Account to create.') +param storageAccountName string + +@description('Required. The name of the Deployment Script used to upload data to the Storage Account.') +param storageUploadDeploymentScriptName string + +@description('Required. The name of the Proximity Placement Group to create.') +param proximityPlacementGroupName string + +@description('Optional. The location to deploy resources to.') +param location string = resourceGroup().location + +var storageAccountCSEFileName = 'scriptExtensionMasterInstaller.ps1' +var addressPrefix = '10.0.0.0/16' + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + } + } + ] + } +} + +resource applicationSecurityGroup 'Microsoft.Network/applicationSecurityGroups@2023-04-01' = { + name: applicationSecurityGroupName + location: location +} + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: location +} + +resource msiRGContrRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(resourceGroup().id, 'Contributor', managedIdentity.id) + scope: resourceGroup() + properties: { + principalId: managedIdentity.properties.principalId + roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor + principalType: 'ServicePrincipal' + } +} + +resource loadBalancer 'Microsoft.Network/loadBalancers@2023-04-01' = { + name: loadBalancerName + location: location + sku: { + name: 'Standard' + } + properties: { + frontendIPConfigurations: [ + { + name: 'privateIPConfig1' + properties: { + subnet: virtualNetwork.properties.subnets[0] + } + } + ] + backendAddressPools: [ + { + name: 'servers' + } + ] + } +} + +resource recoveryServicesVault 'Microsoft.RecoveryServices/vaults@2022-04-01' = { + name: recoveryServicesVaultName + location: location + sku: { + name: 'RS0' + tier: 'Standard' + } + properties: {} + + resource backupPolicy 'backupPolicies@2022-03-01' = { + name: 'backupPolicy' + properties: { + backupManagementType: 'AzureIaasVM' + instantRPDetails: {} + schedulePolicy: { + schedulePolicyType: 'SimpleSchedulePolicy' + scheduleRunFrequency: 'Daily' + scheduleRunTimes: [ + '2019-11-07T07:00:00Z' + ] + scheduleWeeklyFrequency: 0 + } + retentionPolicy: { + retentionPolicyType: 'LongTermRetentionPolicy' + dailySchedule: { + retentionTimes: [ + '2019-11-07T07:00:00Z' + ] + retentionDuration: { + count: 180 + durationType: 'Days' + } + } + weeklySchedule: { + daysOfTheWeek: [ + 'Sunday' + ] + retentionTimes: [ + '2019-11-07T07:00:00Z' + ] + retentionDuration: { + count: 12 + durationType: 'Weeks' + } + } + monthlySchedule: { + retentionScheduleFormatType: 'Weekly' + retentionScheduleWeekly: { + daysOfTheWeek: [ + 'Sunday' + ] + weeksOfTheMonth: [ + 'First' + ] + } + retentionTimes: [ + '2019-11-07T07:00:00Z' + ] + retentionDuration: { + count: 60 + durationType: 'Months' + } + } + yearlySchedule: { + retentionScheduleFormatType: 'Weekly' + monthsOfYear: [ + 'January' + ] + retentionScheduleWeekly: { + daysOfTheWeek: [ + 'Sunday' + ] + weeksOfTheMonth: [ + 'First' + ] + } + retentionTimes: [ + '2019-11-07T07:00:00Z' + ] + retentionDuration: { + count: 10 + durationType: 'Years' + } + } + } + instantRpRetentionRangeInDays: 2 + timeZone: 'UTC' + protectedItemsCount: 0 + } + } +} + +resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = { + name: keyVaultName + location: location + properties: { + sku: { + family: 'A' + name: 'standard' + } + tenantId: tenant().tenantId + enablePurgeProtection: null + enabledForTemplateDeployment: true + enabledForDiskEncryption: true + enabledForDeployment: true + enableRbacAuthorization: true + accessPolicies: [] + } + + resource key 'keys@2022-07-01' = { + name: 'encryptionKey' + properties: { + kty: 'RSA' + } + } +} + +resource msiKVReadRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid('msi-${keyVault::key.id}-${location}-${managedIdentity.id}-KeyVault-Key-Read-RoleAssignment') + scope: keyVault::key + properties: { + principalId: managedIdentity.properties.principalId + roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') // Key Vault Crypto User + principalType: 'ServicePrincipal' + } +} + +resource storageAccount 'Microsoft.Storage/storageAccounts@2021-09-01' = { + name: storageAccountName + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' + + resource blobService 'blobServices@2021-09-01' = { + name: 'default' + + resource container 'containers@2021-09-01' = { + name: 'scripts' + } + } +} + +resource storageUpload 'Microsoft.Resources/deploymentScripts@2020-10-01' = { + name: storageUploadDeploymentScriptName + location: location + kind: 'AzurePowerShell' + identity: { + type: 'UserAssigned' + userAssignedIdentities: { + '${managedIdentity.id}': {} + } + } + properties: { + azPowerShellVersion: '9.0' + retentionInterval: 'P1D' + arguments: '-StorageAccountName "${storageAccount.name}" -ResourceGroupName "${resourceGroup().name}" -ContainerName "${storageAccount::blobService::container.name}" -FileName "${storageAccountCSEFileName}"' + scriptContent: loadTextContent('../../../../../.shared/.scripts/Set-BlobContent.ps1') + } + dependsOn: [ + msiRGContrRoleAssignment + ] +} + +resource proximityPlacementGroup 'Microsoft.Compute/proximityPlacementGroups@2022-03-01' = { + name: proximityPlacementGroupName + location: location +} + +@description('The resource ID of the created Virtual Network Subnet.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id + +@description('The resource ID of the created Application Security Group.') +output applicationSecurityGroupResourceId string = applicationSecurityGroup.id + +@description('The principal ID of the created Managed Identity.') +output managedIdentityPrincipalId string = managedIdentity.properties.principalId + +@description('The resource ID of the created Managed Identity.') +output managedIdentityResourceId string = managedIdentity.id + +@description('The resource ID of the created Load Balancer Backend Pool.') +output loadBalancerBackendPoolResourceId string = loadBalancer.properties.backendAddressPools[0].id + +@description('The name of the created Recovery Services Vault.') +output recoveryServicesVaultName string = recoveryServicesVault.name + +@description('The name of the Resource Group, the Recovery Services Vault was created in.') +output recoveryServicesVaultResourceGroupName string = resourceGroup().name + +@description('The name of the Backup Policy created in the Backup Recovery Vault.') +output recoveryServicesVaultBackupPolicyName string = recoveryServicesVault::backupPolicy.name + +@description('The resource ID of the created Key Vault.') +output keyVaultResourceId string = keyVault.id + +@description('The URL of the created Key Vault.') +output keyVaultUrl string = keyVault.properties.vaultUri + +@description('The URL of the created Key Vault Encryption Key.') +output keyVaultEncryptionKeyUrl string = keyVault::key.properties.keyUriWithVersion + +@description('The resource ID of the created Storage Account.') +output storageAccountResourceId string = storageAccount.id + +@description('The name of the Custom Script Extension in the created Storage Account.') +output storageAccountCSEFileName string = storageAccountCSEFileName + +@description('The URL of the Custom Script Extension in the created Storage Account') +output storageAccountCSEFileUrl string = '${storageAccount.properties.primaryEndpoints.blob}${storageAccount::blobService::container.name}/${storageAccountCSEFileName}' + +@description('The resource ID of the created Proximity Placement Group.') +output proximityPlacementGroupResourceId string = proximityPlacementGroup.id diff --git a/modules/compute/virtual-machine/tests/e2e/windows/main.test.bicep b/modules/compute/virtual-machine/tests/e2e/windows/main.test.bicep new file mode 100644 index 0000000000..7bc8a2c00f --- /dev/null +++ b/modules/compute/virtual-machine/tests/e2e/windows/main.test.bicep @@ -0,0 +1,332 @@ +targetScope = 'subscription' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-compute.virtualMachines-${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 = 'cvmwincom' + +@description('Optional. The password to leverage for the login.') +@secure() +param password string = newGuid() + +@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') +param enableDefaultTelemetry bool = true + +@description('Optional. A token to inject into the name of each resource.') +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: { + location: location + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + applicationSecurityGroupName: 'dep-${namePrefix}-asg-${serviceShort}' + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}' + loadBalancerName: 'dep-${namePrefix}-lb-${serviceShort}' + recoveryServicesVaultName: 'dep-${namePrefix}-rsv-${serviceShort}' + storageAccountName: 'dep${namePrefix}sa${serviceShort}01' + storageUploadDeploymentScriptName: 'dep-${namePrefix}-sads-${serviceShort}' + proximityPlacementGroupName: 'dep-${namePrefix}-ppg-${serviceShort}' + } +} + +// Diagnostics +// =========== +module diagnosticDependencies '../../../../../.shared/.templates/diagnostic.dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-diagnosticDependencies' + params: { + storageAccountName: 'dep${namePrefix}diasa${serviceShort}01' + logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' + eventHubNamespaceEventHubName: 'dep-${namePrefix}-evh-${serviceShort}' + eventHubNamespaceName: 'dep-${namePrefix}-evhns-${serviceShort}' + location: location + } +} + +// ============== // +// Test Execution // +// ============== // + +module testDeployment '../../../main.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}' + params: { + enableDefaultTelemetry: enableDefaultTelemetry + location: location + name: '${namePrefix}${serviceShort}' + computerName: '${namePrefix}winvm1' + adminUsername: 'VMAdmin' + imageReference: { + publisher: 'MicrosoftWindowsServer' + offer: 'WindowsServer' + sku: '2019-datacenter' + version: 'latest' + } + nicConfigurations: [ + { + deleteOption: 'Delete' + ipConfigurations: [ + { + applicationSecurityGroups: [ + { + id: nestedDependencies.outputs.applicationSecurityGroupResourceId + } + ] + loadBalancerBackendAddressPools: [ + { + id: nestedDependencies.outputs.loadBalancerBackendPoolResourceId + } + ] + name: 'ipconfig01' + pipConfiguration: { + publicIpNameSuffix: '-pip-01' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + } + zones: [ + '1' + '2' + '3' + ] + subnetResourceId: nestedDependencies.outputs.subnetResourceId + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + } + ] + nicSuffix: '-nic-01' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + } + ] + osDisk: { + caching: 'None' + createOption: 'fromImage' + deleteOption: 'Delete' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + osType: 'Windows' + vmSize: 'Standard_DS2_v2' + adminPassword: password + availabilityZone: 2 + backupPolicyName: nestedDependencies.outputs.recoveryServicesVaultBackupPolicyName + backupVaultName: nestedDependencies.outputs.recoveryServicesVaultName + backupVaultResourceGroup: nestedDependencies.outputs.recoveryServicesVaultResourceGroupName + dataDisks: [ + { + caching: 'None' + createOption: 'Empty' + deleteOption: 'Delete' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + { + caching: 'None' + createOption: 'Empty' + deleteOption: 'Delete' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + ] + enableAutomaticUpdates: true + patchMode: 'AutomaticByPlatform' + encryptionAtHost: false + extensionAntiMalwareConfig: { + enabled: true + settings: { + AntimalwareEnabled: 'true' + Exclusions: { + Extensions: '.ext1;.ext2' + Paths: 'c:\\excluded-path-1;c:\\excluded-path-2' + Processes: 'excludedproc1.exe;excludedproc2.exe' + } + RealtimeProtectionEnabled: 'true' + ScheduledScanSettings: { + day: '7' + isEnabled: 'true' + scanType: 'Quick' + time: '120' + } + } + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + extensionCustomScriptConfig: { + enabled: true + fileData: [ + { + storageAccountId: nestedDependencies.outputs.storageAccountResourceId + uri: nestedDependencies.outputs.storageAccountCSEFileUrl + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + extensionCustomScriptProtectedSetting: { + commandToExecute: 'powershell -ExecutionPolicy Unrestricted -Command "& ./${nestedDependencies.outputs.storageAccountCSEFileName}"' + } + extensionDependencyAgentConfig: { + enabled: true + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + extensionAzureDiskEncryptionConfig: { + enabled: true + settings: { + EncryptionOperation: 'EnableEncryption' + KekVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + KeyEncryptionAlgorithm: 'RSA-OAEP' + KeyEncryptionKeyURL: nestedDependencies.outputs.keyVaultEncryptionKeyUrl + KeyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + KeyVaultURL: nestedDependencies.outputs.keyVaultUrl + ResizeOSDisk: 'false' + VolumeType: 'All' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + } + extensionAadJoinConfig: { + enabled: true + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + extensionDSCConfig: { + enabled: true + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + extensionMonitoringAgentConfig: { + enabled: true + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + extensionNetworkWatcherAgentConfig: { + enabled: true + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + monitoringWorkspaceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + proximityPlacementGroupResourceId: nestedDependencies.outputs.proximityPlacementGroupResourceId + roleAssignments: [ + { + roleDefinitionIdOrName: 'Owner' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] + } + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } +} diff --git a/modules/compute/virtual-machine/version.json b/modules/compute/virtual-machine/version.json new file mode 100644 index 0000000000..9ed3662aba --- /dev/null +++ b/modules/compute/virtual-machine/version.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.6", + "pathFilters": [ + "./main.json" + ] +} From b6f28ae7429a1236a565ca428bfde629f74e96d0 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Wed, 6 Dec 2023 11:10:17 +0100 Subject: [PATCH 03/96] move to correct folder --- .../virtual-machine/extension/README.md | 0 .../virtual-machine/extension/main.bicep | 0 .../virtual-machine/extension/main.json | 0 .../virtual-machine/extension/version.json | 0 .../res}/compute/virtual-machine/main.bicep | 0 .../modules/nested_networkInterface.bicep | 0 .../tests/e2e/linux.atmg/dependencies.bicep | 0 .../tests/e2e/linux.atmg/main.test.bicep | 0 .../tests/e2e/linux.min/dependencies.bicep | 0 .../tests/e2e/linux.min/main.test.bicep | 0 .../tests/e2e/linux/dependencies.bicep | 0 .../tests/e2e/linux/main.test.bicep | 0 .../tests/e2e/windows.atmg/dependencies.bicep | 0 .../tests/e2e/windows.atmg/main.test.bicep | 0 .../tests/e2e/windows.min/dependencies.bicep | 0 .../tests/e2e/windows.min/main.test.bicep | 0 .../e2e/windows.ssecmk/dependencies.bicep | 0 .../tests/e2e/windows.ssecmk/main.test.bicep | 0 .../tests/e2e/windows/dependencies.bicep | 0 .../tests/e2e/windows/main.test.bicep | 0 .../res}/compute/virtual-machine/version.json | 0 .../availability-set/.bicep/nested_rbac.bicep | 44 - modules/compute/availability-set/README.md | 75 - modules/compute/availability-set/main.bicep | 80 - modules/compute/availability-set/main.json | 241 - .../availability-set/test/main.test.bicep | 65 - modules/compute/availability-set/version.json | 8 - .../.bicep/nested_privateEndpoint.bicep | 58 - .../.bicep/nested_rbac.bicep | 59 - modules/compute/container-registry/README.md | 147 - modules/compute/container-registry/main.bicep | 295 -- modules/compute/container-registry/main.json | 896 ---- .../container-registry/task/task.bicep | 49 - .../test/dependencies.test.bicep | 114 - .../container-registry/test/main.test.bicep | 179 - .../compute/container-registry/test/task.yaml | 5 - .../compute/container-registry/version.json | 8 - modules/compute/custom-image-vmss/README.md | 92 - modules/compute/custom-image-vmss/main.bicep | 165 - modules/compute/custom-image-vmss/main.json | 1102 ---- .../modules/virtualNetworks.bicep | 35 - .../custom-image-vmss/test/imageConfig.json | 11 - .../custom-image-vmss/test/main.test.bicep | 23 - .../compute/custom-image-vmss/version.json | 8 - modules/compute/event-hub/README.md | 269 - modules/compute/event-hub/bicepconfig.json | 5 - modules/compute/event-hub/main.bicep | 407 -- modules/compute/event-hub/main.json | 1802 ------- .../event-hub/modules/authorizationRule.bicep | 15 - .../event-hub/modules/diagnosticSetting.bicep | 25 - .../modules/disasterRecoveryConfig.bicep | 16 - .../modules/eventHub/authorizationRule.bicep | 21 - .../modules/eventHub/consumerGroup.bicep | 20 - .../event-hub/modules/eventHub/eventHub.bicep | 71 - .../modules/eventHub/roleAssignment.bicep | 48 - .../event-hub/modules/privateEndpoint.bicep | 53 - .../event-hub/modules/roleAssignment.bicep | 42 - .../compute/event-hub/test/main.test.bicep | 237 - .../compute/event-hub/test/prereq.test.bicep | 126 - modules/compute/event-hub/version.json | 8 - modules/compute/function-app/README.md | 141 - modules/compute/function-app/bicepconfig.json | 5 - modules/compute/function-app/main.bicep | 339 -- modules/compute/function-app/main.json | 638 --- .../functions_source_code/test_1_index.js | 8 - .../compute/function-app/test/main.test.bicep | 76 - .../function-app/test/prereq.test.bicep | 96 - .../function-app/test/upload-file.bicep | 35 - modules/compute/function-app/version.json | 8 - modules/compute/virtual-machine/README.md | 3552 ------------- modules/compute/virtual-machine/main.json | 4524 ----------------- 71 files changed, 16346 deletions(-) rename {modules => avm/res}/compute/virtual-machine/extension/README.md (100%) rename {modules => avm/res}/compute/virtual-machine/extension/main.bicep (100%) rename {modules => avm/res}/compute/virtual-machine/extension/main.json (100%) rename {modules => avm/res}/compute/virtual-machine/extension/version.json (100%) rename {modules => avm/res}/compute/virtual-machine/main.bicep (100%) rename {modules => avm/res}/compute/virtual-machine/modules/nested_networkInterface.bicep (100%) rename {modules => avm/res}/compute/virtual-machine/tests/e2e/linux.atmg/dependencies.bicep (100%) rename {modules => avm/res}/compute/virtual-machine/tests/e2e/linux.atmg/main.test.bicep (100%) rename {modules => avm/res}/compute/virtual-machine/tests/e2e/linux.min/dependencies.bicep (100%) rename {modules => avm/res}/compute/virtual-machine/tests/e2e/linux.min/main.test.bicep (100%) rename {modules => avm/res}/compute/virtual-machine/tests/e2e/linux/dependencies.bicep (100%) rename {modules => avm/res}/compute/virtual-machine/tests/e2e/linux/main.test.bicep (100%) rename {modules => avm/res}/compute/virtual-machine/tests/e2e/windows.atmg/dependencies.bicep (100%) rename {modules => avm/res}/compute/virtual-machine/tests/e2e/windows.atmg/main.test.bicep (100%) rename {modules => avm/res}/compute/virtual-machine/tests/e2e/windows.min/dependencies.bicep (100%) rename {modules => avm/res}/compute/virtual-machine/tests/e2e/windows.min/main.test.bicep (100%) rename {modules => avm/res}/compute/virtual-machine/tests/e2e/windows.ssecmk/dependencies.bicep (100%) rename {modules => avm/res}/compute/virtual-machine/tests/e2e/windows.ssecmk/main.test.bicep (100%) rename {modules => avm/res}/compute/virtual-machine/tests/e2e/windows/dependencies.bicep (100%) rename {modules => avm/res}/compute/virtual-machine/tests/e2e/windows/main.test.bicep (100%) rename {modules => avm/res}/compute/virtual-machine/version.json (100%) delete mode 100644 modules/compute/availability-set/.bicep/nested_rbac.bicep delete mode 100644 modules/compute/availability-set/README.md delete mode 100644 modules/compute/availability-set/main.bicep delete mode 100644 modules/compute/availability-set/main.json delete mode 100644 modules/compute/availability-set/test/main.test.bicep delete mode 100644 modules/compute/availability-set/version.json delete mode 100644 modules/compute/container-registry/.bicep/nested_privateEndpoint.bicep delete mode 100644 modules/compute/container-registry/.bicep/nested_rbac.bicep delete mode 100644 modules/compute/container-registry/README.md delete mode 100644 modules/compute/container-registry/main.bicep delete mode 100644 modules/compute/container-registry/main.json delete mode 100644 modules/compute/container-registry/task/task.bicep delete mode 100644 modules/compute/container-registry/test/dependencies.test.bicep delete mode 100644 modules/compute/container-registry/test/main.test.bicep delete mode 100644 modules/compute/container-registry/test/task.yaml delete mode 100644 modules/compute/container-registry/version.json delete mode 100644 modules/compute/custom-image-vmss/README.md delete mode 100644 modules/compute/custom-image-vmss/main.bicep delete mode 100644 modules/compute/custom-image-vmss/main.json delete mode 100644 modules/compute/custom-image-vmss/modules/virtualNetworks.bicep delete mode 100644 modules/compute/custom-image-vmss/test/imageConfig.json delete mode 100644 modules/compute/custom-image-vmss/test/main.test.bicep delete mode 100644 modules/compute/custom-image-vmss/version.json delete mode 100644 modules/compute/event-hub/README.md delete mode 100644 modules/compute/event-hub/bicepconfig.json delete mode 100644 modules/compute/event-hub/main.bicep delete mode 100644 modules/compute/event-hub/main.json delete mode 100644 modules/compute/event-hub/modules/authorizationRule.bicep delete mode 100644 modules/compute/event-hub/modules/diagnosticSetting.bicep delete mode 100644 modules/compute/event-hub/modules/disasterRecoveryConfig.bicep delete mode 100644 modules/compute/event-hub/modules/eventHub/authorizationRule.bicep delete mode 100644 modules/compute/event-hub/modules/eventHub/consumerGroup.bicep delete mode 100644 modules/compute/event-hub/modules/eventHub/eventHub.bicep delete mode 100644 modules/compute/event-hub/modules/eventHub/roleAssignment.bicep delete mode 100644 modules/compute/event-hub/modules/privateEndpoint.bicep delete mode 100644 modules/compute/event-hub/modules/roleAssignment.bicep delete mode 100644 modules/compute/event-hub/test/main.test.bicep delete mode 100644 modules/compute/event-hub/test/prereq.test.bicep delete mode 100644 modules/compute/event-hub/version.json delete mode 100644 modules/compute/function-app/README.md delete mode 100644 modules/compute/function-app/bicepconfig.json delete mode 100644 modules/compute/function-app/main.bicep delete mode 100644 modules/compute/function-app/main.json delete mode 100644 modules/compute/function-app/test/functions_source_code/test_1_index.js delete mode 100644 modules/compute/function-app/test/main.test.bicep delete mode 100644 modules/compute/function-app/test/prereq.test.bicep delete mode 100644 modules/compute/function-app/test/upload-file.bicep delete mode 100644 modules/compute/function-app/version.json delete mode 100644 modules/compute/virtual-machine/README.md delete mode 100644 modules/compute/virtual-machine/main.json diff --git a/modules/compute/virtual-machine/extension/README.md b/avm/res/compute/virtual-machine/extension/README.md similarity index 100% rename from modules/compute/virtual-machine/extension/README.md rename to avm/res/compute/virtual-machine/extension/README.md diff --git a/modules/compute/virtual-machine/extension/main.bicep b/avm/res/compute/virtual-machine/extension/main.bicep similarity index 100% rename from modules/compute/virtual-machine/extension/main.bicep rename to avm/res/compute/virtual-machine/extension/main.bicep diff --git a/modules/compute/virtual-machine/extension/main.json b/avm/res/compute/virtual-machine/extension/main.json similarity index 100% rename from modules/compute/virtual-machine/extension/main.json rename to avm/res/compute/virtual-machine/extension/main.json diff --git a/modules/compute/virtual-machine/extension/version.json b/avm/res/compute/virtual-machine/extension/version.json similarity index 100% rename from modules/compute/virtual-machine/extension/version.json rename to avm/res/compute/virtual-machine/extension/version.json diff --git a/modules/compute/virtual-machine/main.bicep b/avm/res/compute/virtual-machine/main.bicep similarity index 100% rename from modules/compute/virtual-machine/main.bicep rename to avm/res/compute/virtual-machine/main.bicep diff --git a/modules/compute/virtual-machine/modules/nested_networkInterface.bicep b/avm/res/compute/virtual-machine/modules/nested_networkInterface.bicep similarity index 100% rename from modules/compute/virtual-machine/modules/nested_networkInterface.bicep rename to avm/res/compute/virtual-machine/modules/nested_networkInterface.bicep diff --git a/modules/compute/virtual-machine/tests/e2e/linux.atmg/dependencies.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.atmg/dependencies.bicep similarity index 100% rename from modules/compute/virtual-machine/tests/e2e/linux.atmg/dependencies.bicep rename to avm/res/compute/virtual-machine/tests/e2e/linux.atmg/dependencies.bicep diff --git a/modules/compute/virtual-machine/tests/e2e/linux.atmg/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.atmg/main.test.bicep similarity index 100% rename from modules/compute/virtual-machine/tests/e2e/linux.atmg/main.test.bicep rename to avm/res/compute/virtual-machine/tests/e2e/linux.atmg/main.test.bicep diff --git a/modules/compute/virtual-machine/tests/e2e/linux.min/dependencies.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.min/dependencies.bicep similarity index 100% rename from modules/compute/virtual-machine/tests/e2e/linux.min/dependencies.bicep rename to avm/res/compute/virtual-machine/tests/e2e/linux.min/dependencies.bicep diff --git a/modules/compute/virtual-machine/tests/e2e/linux.min/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.min/main.test.bicep similarity index 100% rename from modules/compute/virtual-machine/tests/e2e/linux.min/main.test.bicep rename to avm/res/compute/virtual-machine/tests/e2e/linux.min/main.test.bicep diff --git a/modules/compute/virtual-machine/tests/e2e/linux/dependencies.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux/dependencies.bicep similarity index 100% rename from modules/compute/virtual-machine/tests/e2e/linux/dependencies.bicep rename to avm/res/compute/virtual-machine/tests/e2e/linux/dependencies.bicep diff --git a/modules/compute/virtual-machine/tests/e2e/linux/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux/main.test.bicep similarity index 100% rename from modules/compute/virtual-machine/tests/e2e/linux/main.test.bicep rename to avm/res/compute/virtual-machine/tests/e2e/linux/main.test.bicep diff --git a/modules/compute/virtual-machine/tests/e2e/windows.atmg/dependencies.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.atmg/dependencies.bicep similarity index 100% rename from modules/compute/virtual-machine/tests/e2e/windows.atmg/dependencies.bicep rename to avm/res/compute/virtual-machine/tests/e2e/windows.atmg/dependencies.bicep diff --git a/modules/compute/virtual-machine/tests/e2e/windows.atmg/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.atmg/main.test.bicep similarity index 100% rename from modules/compute/virtual-machine/tests/e2e/windows.atmg/main.test.bicep rename to avm/res/compute/virtual-machine/tests/e2e/windows.atmg/main.test.bicep diff --git a/modules/compute/virtual-machine/tests/e2e/windows.min/dependencies.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.min/dependencies.bicep similarity index 100% rename from modules/compute/virtual-machine/tests/e2e/windows.min/dependencies.bicep rename to avm/res/compute/virtual-machine/tests/e2e/windows.min/dependencies.bicep diff --git a/modules/compute/virtual-machine/tests/e2e/windows.min/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.min/main.test.bicep similarity index 100% rename from modules/compute/virtual-machine/tests/e2e/windows.min/main.test.bicep rename to avm/res/compute/virtual-machine/tests/e2e/windows.min/main.test.bicep diff --git a/modules/compute/virtual-machine/tests/e2e/windows.ssecmk/dependencies.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.ssecmk/dependencies.bicep similarity index 100% rename from modules/compute/virtual-machine/tests/e2e/windows.ssecmk/dependencies.bicep rename to avm/res/compute/virtual-machine/tests/e2e/windows.ssecmk/dependencies.bicep diff --git a/modules/compute/virtual-machine/tests/e2e/windows.ssecmk/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.ssecmk/main.test.bicep similarity index 100% rename from modules/compute/virtual-machine/tests/e2e/windows.ssecmk/main.test.bicep rename to avm/res/compute/virtual-machine/tests/e2e/windows.ssecmk/main.test.bicep diff --git a/modules/compute/virtual-machine/tests/e2e/windows/dependencies.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows/dependencies.bicep similarity index 100% rename from modules/compute/virtual-machine/tests/e2e/windows/dependencies.bicep rename to avm/res/compute/virtual-machine/tests/e2e/windows/dependencies.bicep diff --git a/modules/compute/virtual-machine/tests/e2e/windows/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows/main.test.bicep similarity index 100% rename from modules/compute/virtual-machine/tests/e2e/windows/main.test.bicep rename to avm/res/compute/virtual-machine/tests/e2e/windows/main.test.bicep diff --git a/modules/compute/virtual-machine/version.json b/avm/res/compute/virtual-machine/version.json similarity index 100% rename from modules/compute/virtual-machine/version.json rename to avm/res/compute/virtual-machine/version.json diff --git a/modules/compute/availability-set/.bicep/nested_rbac.bicep b/modules/compute/availability-set/.bicep/nested_rbac.bicep deleted file mode 100644 index 1c6f4c3502..0000000000 --- a/modules/compute/availability-set/.bicep/nested_rbac.bicep +++ /dev/null @@ -1,44 +0,0 @@ -param description string = '' -param principalType string = '' -param principalIds array -param roleDefinitionIdOrName string -param resourceId string - -var builtInRoleNames = { - 'Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') - 'Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - 'Avere Cluster Create': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a7b1b19a-0e83-4fe5-935c-faaefbfd18c3') - 'Avere Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a') - 'Azure Service Deploy Release Management Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '21d96096-b162-414a-8302-d8354f9d91b2') - 'CAL-Custom-Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b266cd7-0bba-4ae2-8423-90ede5e1e898') - 'DevTest Labs User': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64') - 'Log Analytics Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293') - 'Log Analytics Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893') - 'Managed Application Contributor Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e') - 'Managed Application Operator Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae') - 'Managed Applications Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44') - 'masterreader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a48d7796-14b4-4889-afef-fbb65a93e5a2') - 'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa') - 'Monitoring Metrics Publisher': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb') - 'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05') - 'Reservation Purchaser': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f7b75c60-3036-4b75-91c3-6b41c27c1689') - 'Resource Policy Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') - 'Virtual Machine Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c') -} - -resource availabilitySet 'Microsoft.Compute/availabilitySets@2021-04-01' existing = { - name: last(split(resourceId, '/')) -} - -resource roleAssignment 'Microsoft.Authorization/roleAssignments@2021-04-01-preview' = [for principalId in principalIds: { - name: guid(availabilitySet.name, principalId, roleDefinitionIdOrName) - properties: { - description: description - roleDefinitionId: contains(builtInRoleNames, roleDefinitionIdOrName) ? builtInRoleNames[roleDefinitionIdOrName] : roleDefinitionIdOrName - principalId: principalId - principalType: !empty(principalType) ? principalType : null - } - scope: availabilitySet -}] diff --git a/modules/compute/availability-set/README.md b/modules/compute/availability-set/README.md deleted file mode 100644 index 35a04e0baa..0000000000 --- a/modules/compute/availability-set/README.md +++ /dev/null @@ -1,75 +0,0 @@ -# Availability Set - -This module deploys Microsoft.Compute Availability Sets and optionally available children or extensions - -## Details - -{{ Add detailed information about the module. }} - -## Parameters - -| Name | Type | Required | Description | -| :---------------------------- | :------: | :------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `name` | `string` | Yes | Required. The name of the availability set that is being created. | -| `availabilitySetFaultDomain` | `int` | No | Optional. The number of fault domains to use. | -| `availabilitySetUpdateDomain` | `int` | No | Optional. The number of update domains to use. | -| `availabilitySetSku` | `string` | No | Optional. Sku of the availability set. Use 'Aligned' for virtual machines with managed disks and 'Classic' for virtual machines with unmanaged disks. | -| `proximityPlacementGroupId` | `string` | No | Optional. Resource ID of a proximity placement group. | -| `location` | `string` | No | Optional. Resource location. | -| `lock` | `string` | No | Optional. Specify the type of lock. | -| `roleAssignments` | `array` | No | Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11' | -| `tags` | `object` | No | Optional. Tags of the availability set resource. | - -## Outputs - -| Name | Type | Description | -| :------------------ | :------: | :-------------------------------------------------------- | -| `name` | `string` | The name of the availability set | -| `resourceId` | `string` | The resource ID of the availability set | -| `resourceGroupName` | `string` | The resource group the availability set was deployed into | - -## Examples - -### Example 1 - -Example invocation with the minimum required parameters. - -```bicep -module minavs 'br/public:compute/availability-set:1.0.2' = { - name: '${uniqueString(deployment().name, 'WestEurope')}-minavs' - params: { - name: 'carml-az-avs-min-01' - } -} -``` - -### Example 2 - -Example invocation with several properties including tags & role assignments. - -```bicep -module genavs 'br/public:compute/availability-set:1.0.2' = { - name: '${uniqueString(deployment().name, 'WestEurope')}-genavs' - params: { - name: 'carml-az-avs-gen-01' - proximityPlacementGroupId: '/subscriptions/111111-1111-1111-1111-111111111111/resourceGroups/validation-rg/providers/Microsoft.Compute/proximityPlacementGroups/adp-carml-az-ppg-x-001' - availabilitySetSku: 'aligned' - availabilitySetUpdateDomain: 2 - availabilitySetFaultDomain: 2 - tags: { - tag1: 'tag1Value' - tag2: 'tag2Value' - } - roleAssignments: [ - { - roleDefinitionIdOrName: 'Reader' - principalIds: [ - '222222-2222-2222-2222-2222222222' - ] - principalType: 'ServicePrincipal' - } - ] - location: 'WestEurope' - } -} -``` \ No newline at end of file diff --git a/modules/compute/availability-set/main.bicep b/modules/compute/availability-set/main.bicep deleted file mode 100644 index aa5ab99ba3..0000000000 --- a/modules/compute/availability-set/main.bicep +++ /dev/null @@ -1,80 +0,0 @@ -metadata name = 'Availability Set' -metadata description = 'This module deploys Microsoft.Compute Availability Sets and optionally available children or extensions' -metadata owner = 'CARML' - -@description('Required. The name of the availability set that is being created.') -param name string - -@description('Optional. The number of fault domains to use.') -param availabilitySetFaultDomain int = 2 - -@description('Optional. The number of update domains to use.') -param availabilitySetUpdateDomain int = 5 - -@description('Optional. Sku of the availability set. Use \'Aligned\' for virtual machines with managed disks and \'Classic\' for virtual machines with unmanaged disks.') -param availabilitySetSku string = 'Aligned' - -@description('Optional. Resource ID of a proximity placement group.') -param proximityPlacementGroupId string = '' - -@description('Optional. Resource location.') -param location string = resourceGroup().location - -@allowed([ - 'CanNotDelete' - 'NotSpecified' - 'ReadOnly' -]) -@description('Optional. Specify the type of lock.') -param lock string = 'NotSpecified' - -@description('Optional. Array of role assignment objects that contain the \'roleDefinitionIdOrName\' and \'principalId\' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'') -param roleAssignments array = [] - -@description('Optional. Tags of the availability set resource.') -param tags object = {} - -resource availabilitySet 'Microsoft.Compute/availabilitySets@2021-07-01' = { - name: name - location: location - tags: tags - properties: { - platformFaultDomainCount: availabilitySetFaultDomain - platformUpdateDomainCount: availabilitySetUpdateDomain - proximityPlacementGroup: !empty(proximityPlacementGroupId) ? { - id: proximityPlacementGroupId - } : null - } - sku: { - name: availabilitySetSku - } -} - -resource availabilitySet_lock 'Microsoft.Authorization/locks@2017-04-01' = if (lock != 'NotSpecified') { - name: '${availabilitySet.name}-${lock}-lock' - properties: { - level: lock - notes: lock == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot modify the resource or child resources.' - } - scope: availabilitySet -} - -module availabilitySet_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: { - name: '${uniqueString(deployment().name, location)}-AvSet-Rbac-${index}' - params: { - description: contains(roleAssignment, 'description') ? roleAssignment.description : '' - principalIds: roleAssignment.principalIds - roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName - principalType: contains(roleAssignment, 'principalType') ? roleAssignment.principalType : '' - resourceId: availabilitySet.id - } -}] - -@description('The name of the availability set') -output name string = availabilitySet.name - -@description('The resource ID of the availability set') -output resourceId string = availabilitySet.id - -@description('The resource group the availability set was deployed into') -output resourceGroupName string = resourceGroup().name diff --git a/modules/compute/availability-set/main.json b/modules/compute/availability-set/main.json deleted file mode 100644 index 34639b12a3..0000000000 --- a/modules/compute/availability-set/main.json +++ /dev/null @@ -1,241 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.19.5.34762", - "templateHash": "18288547414035236019" - }, - "name": "Availability Set", - "description": "This module deploys Microsoft.Compute Availability Sets and optionally available children or extensions", - "owner": "CARML" - }, - "parameters": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the availability set that is being created." - } - }, - "availabilitySetFaultDomain": { - "type": "int", - "defaultValue": 2, - "metadata": { - "description": "Optional. The number of fault domains to use." - } - }, - "availabilitySetUpdateDomain": { - "type": "int", - "defaultValue": 5, - "metadata": { - "description": "Optional. The number of update domains to use." - } - }, - "availabilitySetSku": { - "type": "string", - "defaultValue": "Aligned", - "metadata": { - "description": "Optional. Sku of the availability set. Use 'Aligned' for virtual machines with managed disks and 'Classic' for virtual machines with unmanaged disks." - } - }, - "proximityPlacementGroupId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Resource ID of a proximity placement group." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. Resource location." - } - }, - "lock": { - "type": "string", - "defaultValue": "NotSpecified", - "metadata": { - "description": "Optional. Specify the type of lock." - }, - "allowedValues": [ - "CanNotDelete", - "NotSpecified", - "ReadOnly" - ] - }, - "roleAssignments": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'" - } - }, - "tags": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Optional. Tags of the availability set resource." - } - } - }, - "resources": [ - { - "type": "Microsoft.Compute/availabilitySets", - "apiVersion": "2021-07-01", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "properties": { - "platformFaultDomainCount": "[parameters('availabilitySetFaultDomain')]", - "platformUpdateDomainCount": "[parameters('availabilitySetUpdateDomain')]", - "proximityPlacementGroup": "[if(not(empty(parameters('proximityPlacementGroupId'))), createObject('id', parameters('proximityPlacementGroupId')), null())]" - }, - "sku": { - "name": "[parameters('availabilitySetSku')]" - } - }, - { - "condition": "[not(equals(parameters('lock'), 'NotSpecified'))]", - "type": "Microsoft.Authorization/locks", - "apiVersion": "2017-04-01", - "scope": "[format('Microsoft.Compute/availabilitySets/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", - "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.Compute/availabilitySets', parameters('name'))]" - ] - }, - { - "copy": { - "name": "availabilitySet_rbac", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-AvSet-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Compute/availabilitySets', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.19.5.34762", - "templateHash": "13867729327786497095" - } - }, - "parameters": { - "description": { - "type": "string", - "defaultValue": "" - }, - "principalType": { - "type": "string", - "defaultValue": "" - }, - "principalIds": { - "type": "array" - }, - "roleDefinitionIdOrName": { - "type": "string" - }, - "resourceId": { - "type": "string" - } - }, - "variables": { - "builtInRoleNames": { - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Avere Cluster Create": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a7b1b19a-0e83-4fe5-935c-faaefbfd18c3')]", - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Azure Service Deploy Release Management Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '21d96096-b162-414a-8302-d8354f9d91b2')]", - "CAL-Custom-Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b266cd7-0bba-4ae2-8423-90ede5e1e898')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "masterreader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a48d7796-14b4-4889-afef-fbb65a93e5a2')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Metrics Publisher": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Reservation Purchaser": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f7b75c60-3036-4b75-91c3-6b41c27c1689')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2021-04-01-preview", - "scope": "[format('Microsoft.Compute/availabilitySets/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(last(split(parameters('resourceId'), '/')), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Compute/availabilitySets', parameters('name'))]" - ] - } - ], - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the availability set" - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the availability set" - }, - "value": "[resourceId('Microsoft.Compute/availabilitySets', parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The resource group the availability set was deployed into" - }, - "value": "[resourceGroup().name]" - } - } -} \ No newline at end of file diff --git a/modules/compute/availability-set/test/main.test.bicep b/modules/compute/availability-set/test/main.test.bicep deleted file mode 100644 index 2bf46dd84f..0000000000 --- a/modules/compute/availability-set/test/main.test.bicep +++ /dev/null @@ -1,65 +0,0 @@ -// ========== // -// Parameters // -// ========== // - -// Shared -@description('Optional. The location to deploy resources to') -param location string = resourceGroup().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 = 'avs' - -// ========== // -// Test Setup // -// ========== // - -// General resources -// ================= -resource proximityPlacementGroup 'Microsoft.Compute/proximityPlacementGroups@2021-11-01' = { - name: 'adp-${serviceShort}-az-ppg-x-01' - location: location -} - -resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: 'adp-${serviceShort}-az-msi-x-01' - location: location -} - -// ============== // -// Test Execution // -// ============== // - -// TEST 1 - MIN -module minavs '../main.bicep' = { - name: '${uniqueString(deployment().name, location)}-minavs' - params: { - name: '${serviceShort}-az-avs-min-01' - location: location - } -} - -// TEST 2 - GENERAL -module genavs '../main.bicep' = { - name: '${uniqueString(deployment().name, location)}-genavs' - params: { - name: '${serviceShort}-az-avs-gen-01' - proximityPlacementGroupId: proximityPlacementGroup.id - availabilitySetSku: 'aligned' - availabilitySetUpdateDomain: 2 - availabilitySetFaultDomain: 2 - tags: { - tag1: 'tag1Value' - tag2: 'tag2Value' - } - roleAssignments: [ - { - roleDefinitionIdOrName: 'Reader' - principalIds: [ - managedIdentity.properties.principalId - ] - principalType: 'ServicePrincipal' - } - ] - location: location - } -} diff --git a/modules/compute/availability-set/version.json b/modules/compute/availability-set/version.json deleted file mode 100644 index e40897e287..0000000000 --- a/modules/compute/availability-set/version.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "1.0", - "pathFilters": [ - "./main.json", - "./metadata.json" - ] -} \ No newline at end of file diff --git a/modules/compute/container-registry/.bicep/nested_privateEndpoint.bicep b/modules/compute/container-registry/.bicep/nested_privateEndpoint.bicep deleted file mode 100644 index eafeabc00e..0000000000 --- a/modules/compute/container-registry/.bicep/nested_privateEndpoint.bicep +++ /dev/null @@ -1,58 +0,0 @@ -param location string -param tags object -param manualApprovalEnabled bool -param privateEndpoints array - -var varPrivateEndpoints = [for (p, i) in privateEndpoints: { - name: p.name - privateLinkServiceId: p.privateLinkServiceId - groupIds: p.groupIds - subnetId: p.subnetId - privateDnsZones: contains(p, 'privateDnsZones') ? p.privateDnsZones : [] - customNetworkInterfaceName: contains(p, 'customNetworkInterfaceName') ? p.customNetworkInterfaceName : null -}] - -@batchSize(1) -resource privateEndpoint 'Microsoft.Network/privateEndpoints@2022-05-01' = [for endpoint in varPrivateEndpoints: { - name: '${endpoint.name}-${uniqueString(endpoint.name, endpoint.subnetId, endpoint.privateLinkServiceId)}' - location: location - tags: tags - properties: { - privateLinkServiceConnections: manualApprovalEnabled ? null : [ - { - name: endpoint.name - properties: { - privateLinkServiceId: endpoint.privateLinkServiceId - groupIds: !empty(endpoint.groupIds) ? endpoint.groupIds : null - } - } - ] - manualPrivateLinkServiceConnections: manualApprovalEnabled ? [ - { - name: endpoint.name - properties: { - privateLinkServiceId: endpoint.privateLinkServiceId - groupIds: !empty(endpoint.groupIds) ? endpoint.groupIds : null - } - } - ] : null - subnet: { - id: endpoint.subnetId - } - customNetworkInterfaceName: endpoint.customNetworkInterfaceName - } -}] - -@batchSize(1) -resource privateDnsZoneGroup 'Microsoft.Network/privateEndpoints/privateDnsZoneGroups@2022-05-01' = [for (endpoint, i) in varPrivateEndpoints: { - name: 'default' - parent: privateEndpoint[i] - properties: { - privateDnsZoneConfigs: [for privateDnsZone in endpoint.privateDnsZones: { - name: contains(privateDnsZone, 'name') ? privateDnsZone.name : 'default' - properties: { - privateDnsZoneId: privateDnsZone.zoneId - } - }] - } -}] diff --git a/modules/compute/container-registry/.bicep/nested_rbac.bicep b/modules/compute/container-registry/.bicep/nested_rbac.bicep deleted file mode 100644 index ccd434646e..0000000000 --- a/modules/compute/container-registry/.bicep/nested_rbac.bicep +++ /dev/null @@ -1,59 +0,0 @@ -param description string = '' -param principalIds array -param principalType string = '' -param roleDefinitionIdOrName string -param resourceId string - -var builtInRoleNames = { - Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') - Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - 'Avere Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a') - 'Avere Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9') - 'Backup Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b') - 'Backup Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324') - 'Cosmos DB Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa') - 'DevTest Labs User': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64') - 'DocumentDB Account Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450') - 'Log Analytics Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293') - 'Log Analytics Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893') - 'Managed Application Contributor Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e') - 'Managed Application Operator Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae') - 'Managed Applications Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44') - 'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa') - 'Monitoring Metrics Publisher': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb') - 'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05') - 'Network Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7') - 'Private DNS Zone Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f') - 'Resource Policy Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608') - 'Site Recovery Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567') - 'Site Recovery Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca') - 'SQL Managed Instance Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d') - 'SQL Security Manager': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3') - 'Storage Account Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') - 'Virtual Machine Administrator Login': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4') - 'Virtual Machine Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c') - 'Virtual Machine User Login': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52') - AcrDelete: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c2f4ef07-c644-48eb-af81-4b1b4947fb11') - AcrImageSigner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c2f4ef07-c644-48eb-af81-4b1b4947fb11') - AcrPull: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d') - AcrPush: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8311e382-0749-4cb8-b61a-304f252e45ec') - AcrQuarantineReader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'cdda3590-29a3-44f6-95f2-9f980659eb04') - AcrQuarantineWriter: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c8d4ff99-41c3-41a8-9f60-21dfdad59608') -} - -resource containerRegistry 'Microsoft.ContainerRegistry/registries@2021-09-01' existing = { - name: last(split(resourceId, '/')) -} - -resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for principalId in principalIds: { - name: guid(containerRegistry.name, principalId, roleDefinitionIdOrName) - properties: { - description: description - roleDefinitionId: contains(builtInRoleNames, roleDefinitionIdOrName) ? builtInRoleNames[roleDefinitionIdOrName] : roleDefinitionIdOrName - principalId: principalId - principalType: !empty(principalType) ? principalType : null - } - scope: containerRegistry -}] diff --git a/modules/compute/container-registry/README.md b/modules/compute/container-registry/README.md deleted file mode 100644 index 477259e0ff..0000000000 --- a/modules/compute/container-registry/README.md +++ /dev/null @@ -1,147 +0,0 @@ -# Container Registry - -This module deploys Container Registry (Microsoft.ContainerRegistry/registries) and optionally available integrations. - -## Details - -[Azure Container Registry (ACR)](http://aka.ms/acr) is a hosted registry for Docker and Open Container Initiative (OCI) artifacts. This module provides an Infrastructure as Code alternative for management of Container Registry using Bicep, and is intended to mirror the available functionality of provisioning with Azure Portal or CLI. - -## Parameters - -| Name | Type | Required | Description | -| :-------------------------------------- | :------: | :------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `name` | `string` | Yes | The name of the Azure Container Registry. | -| `location` | `string` | No | Location for all resources. | -| `tags` | `object` | No | Tags for all resource(s). | -| `skuName` | `string` | No | The SKU of the Azure Container Registry. | -| `adminUserEnabled` | `bool` | No | Toggle the Azure Container Registry admin user. | -| `publicNetworkAccessEnabled` | `bool` | No | Toggle public network access to Azure Container Registry. | -| `publicAzureAccessEnabled` | `bool` | No | When public network access is disabled, toggle this to allow Azure services to bypass the public network access rule. | -| `networkAllowedIpRanges` | `array` | No | A list of IP or IP ranges in CIDR format, that should be allowed access to Azure Container Registry. | -| `networkDefaultAction` | `string` | No | The default action to take when no network rule match is found for accessing Azure Container Registry. | -| `roleAssignments` | `array` | No | Array of role assignment objects that contain the 'roleDefinitionIdOrName'(string) and 'principalIds'(array of strings) to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11' | -| `lock` | `string` | No | Specify the type of lock. | -| `privateEndpoints` | `array` | No | Define Private Endpoints that should be created for Azure Container Registry. | -| `privateEndpointsApprovalEnabled` | `bool` | No | Toggle if Private Endpoints manual approval for Azure Container Registry should be enabled. | -| `zoneRedundancyEnabled` | `bool` | No | Toggle if Zone Redundancy should be enabled on Azure Container Registry. | -| `replicationLocations` | `array` | No | Array of Azure Location configurations that this Azure Container Registry should replicate too. | -| `dataEndpointEnabled` | `bool` | No | Toggle if a single data endpoint per region for serving data from Azure Container Registry should be enabled. | -| `encryptionEnabled` | `bool` | No | Toggle if encryption should be enabled on Azure Container Registry. | -| `exportPolicyEnabled` | `bool` | No | Toggle if export policy should be enabled on Azure Container Registry. | -| `quarantinePolicyEnabled` | `bool` | No | Toggle if quarantine policy should be enabled on Azure Container Registry. | -| `retentionPolicyEnabled` | `bool` | No | Toggle if retention policy should be enabled on Azure Container Registry. | -| `retentionPolicyInDays` | `int` | No | Configure the retention policy in days for Azure Container Registry. Only effective is 'retentionPolicyEnabled' is 'true'. | -| `trustPolicyEnabled` | `bool` | No | Toggle if trust policy should be enabled on Azure Container Registry. | -| `encryptionKeyVaultIdentity` | `string` | No | The client ID of the identity which will be used to access Key Vault. | -| `encryptionKeyVaultKeyIdentifier` | `string` | No | The Key Vault URI to access the encryption key. | -| `diagnosticLogsRetentionInDays` | `int` | No | Specifies the number of days that logs will be kept for; a value of 0 will retain data indefinitely. | -| `diagnosticStorageAccountId` | `string` | No | Resource ID of the diagnostic storage account. | -| `diagnosticWorkspaceId` | `string` | No | Resource ID of the diagnostic log analytics workspace. | -| `diagnosticEventHubAuthorizationRuleId` | `string` | No | 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. | -| `diagnosticEventHubName` | `string` | No | 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. | -| `logsToEnable` | `array` | No | The name of logs that will be streamed. | -| `metricsToEnable` | `array` | No | The name of metrics that will be streamed. | -| `tasks` | `array` | No | Optional. The list of ACR tasks to create. | - -## Outputs - -| Name | Type | Description | -| :------------------ | :------: | :----------------------------------------------------------------- | -| `resourceGroupName` | `string` | The resource group the Azure Container Registry was deployed into. | -| `resourceId` | `string` | The resource ID of the Azure Container Registry. | -| `name` | `string` | The name of the Azure Container Registry. | -| `loginServer` | `string` | The login server URL of the Azure Container Registry. | - -## Examples - -### Example 1 - -An example of how to deploy Azure Container Registry using the minimum required parameters. - -```bicep -module containerRegistry 'br/public:compute/container-registry:1.1.1' = { - name: '${uniqueString(deployment().name, 'eastus')}-container-registry' - params: { - name: 'acr${uniqueString(deployment().name, location)}' - location: 'eastus' - } -} -``` - -### Example 2 - -An example of how to deploy a 'Premium' SKU instance of Azure Container Registry with private networking. - -```bicep -param subnetId string -param privateDnsZoneId string - -module containerRegistry 'br/public:compute/container-registry:1.1.1' = { - name: '${uniqueString(deployment().name, 'eastus')}-container-registry' - params: { - name: 'acr${uniqueString(deployment().name, location)}' - location: 'eastus' - skuName: 'Premium' - privateEndpoints: [ - { - name: 'endpoint1' - subnetId: subnetId - privateDnsZoneId: privateDnsZoneId - } - ] - tasks: [ { - taskName: 'task1' - status: 'Enabled' - platform: { - os: 'Linux' - architecture: 'Amd64' - } - agentConfiguration: { - cpu: 2 - } - trigger: { - timerTriggers: [ - { - name: 'trigger1' - status: 'Enabled' - schedule: '*/1 * * * Mon-Fri' - } - ] - } - step: { - type: 'EncodedTask' - encodedTaskContent: loadFileAsBase64('task.yaml') - } - identity: { - type: 'SystemAssigned' - } - } - ] - } -} -``` - -### Example 3 - -An example of how to deploy a 'Premium' SKU instance of Azure Container Registry with replication to multiple Azure Locations. - -```bicep -module containerRegistry 'br/public:compute/container-registry:1.1.1' = { - name: '${uniqueString(deployment().name, 'eastus')}-container-registry' - params: { - name: 'acr${uniqueString(deployment().name, location)}' - location: 'eastus' - skuName: 'Premium' - replicationLocations: [ - { - location: 'eastus2' - } - { - location: 'northeurope' - regionEndpointEnabled: true - zoneRedundancy: true - } - ] - } -} -``` \ No newline at end of file diff --git a/modules/compute/container-registry/main.bicep b/modules/compute/container-registry/main.bicep deleted file mode 100644 index 6a6d4e4e0e..0000000000 --- a/modules/compute/container-registry/main.bicep +++ /dev/null @@ -1,295 +0,0 @@ -metadata name = 'Container Registry' -metadata description = 'This module deploys Container Registry (Microsoft.ContainerRegistry/registries) and optionally available integrations.' -metadata owner = 'thomasriley' - -@minLength(5) -@maxLength(50) -@description('The name of the Azure Container Registry.') -param name string - -@description('Location for all resources.') -param location string = resourceGroup().location - -@description('Tags for all resource(s).') -param tags object = {} - -@description('The SKU of the Azure Container Registry.') -@allowed([ - 'Basic' - 'Standard' - 'Premium' -]) -param skuName string = 'Basic' - -@description('Toggle the Azure Container Registry admin user.') -param adminUserEnabled bool = false - -@description('Toggle public network access to Azure Container Registry.') -param publicNetworkAccessEnabled bool = true - -@description('When public network access is disabled, toggle this to allow Azure services to bypass the public network access rule.') -param publicAzureAccessEnabled bool = true - -@description('A list of IP or IP ranges in CIDR format, that should be allowed access to Azure Container Registry.') -param networkAllowedIpRanges array = [] - -@description('The default action to take when no network rule match is found for accessing Azure Container Registry.') -@allowed([ - 'Allow' - 'Deny' -]) -param networkDefaultAction string = 'Deny' - -@description('Array of role assignment objects that contain the \'roleDefinitionIdOrName\'(string) and \'principalIds\'(array of strings) to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'') -param roleAssignments array = [] - -@allowed([ - 'CanNotDelete' - 'NotSpecified' - 'ReadOnly' -]) -@description('Specify the type of lock.') -param lock string = 'NotSpecified' - -@description('Define Private Endpoints that should be created for Azure Container Registry.') -param privateEndpoints array = [] - -@description('Toggle if Private Endpoints manual approval for Azure Container Registry should be enabled.') -param privateEndpointsApprovalEnabled bool = false - -@description('Toggle if Zone Redundancy should be enabled on Azure Container Registry.') -param zoneRedundancyEnabled bool = false - -@description('Array of Azure Location configurations that this Azure Container Registry should replicate too.') -param replicationLocations array = [] - -@description('Toggle if a single data endpoint per region for serving data from Azure Container Registry should be enabled.') -param dataEndpointEnabled bool = false - -@description('Toggle if encryption should be enabled on Azure Container Registry.') -param encryptionEnabled bool = false - -@description('Toggle if export policy should be enabled on Azure Container Registry.') -param exportPolicyEnabled bool = false - -@description('Toggle if quarantine policy should be enabled on Azure Container Registry.') -param quarantinePolicyEnabled bool = false - -@description('Toggle if retention policy should be enabled on Azure Container Registry.') -param retentionPolicyEnabled bool = false - -@description('Configure the retention policy in days for Azure Container Registry. Only effective is \'retentionPolicyEnabled\' is \'true\'.') -param retentionPolicyInDays int = 10 - -@description('Toggle if trust policy should be enabled on Azure Container Registry.') -param trustPolicyEnabled bool = false - -@description('The client ID of the identity which will be used to access Key Vault.') -param encryptionKeyVaultIdentity string = '' - -@description('The Key Vault URI to access the encryption key.') -param encryptionKeyVaultKeyIdentifier string = '' - -@description('Specifies the number of days that logs will be kept for; a value of 0 will retain data indefinitely.') -@minValue(0) -@maxValue(365) -param diagnosticLogsRetentionInDays int = 365 - -@description('Resource ID of the diagnostic storage account.') -param diagnosticStorageAccountId string = '' - -@description('Resource ID of the diagnostic log analytics workspace.') -param diagnosticWorkspaceId string = '' - -@description('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.') -param diagnosticEventHubAuthorizationRuleId string = '' - -@description('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.') -param diagnosticEventHubName string = '' - -@description('The name of logs that will be streamed.') -@allowed([ - 'ContainerRegistryRepositoryEvents' - 'ContainerRegistryLoginEvents' -]) -param logsToEnable array = [ - 'ContainerRegistryRepositoryEvents' - 'ContainerRegistryLoginEvents' -] - -@description('The name of metrics that will be streamed.') -@allowed([ - 'AllMetrics' -]) -param metricsToEnable array = [ - 'AllMetrics' -] - -@description('Optional. The list of ACR tasks to create.') -param tasks array = [] - -var diagnosticsLogs = [for log in logsToEnable: { - category: log - enabled: true - retentionPolicy: { - enabled: true - days: diagnosticLogsRetentionInDays - } -}] - -var diagnosticsMetrics = [for metric in metricsToEnable: { - category: metric - timeGrain: null - enabled: true - retentionPolicy: { - enabled: true - days: diagnosticLogsRetentionInDays - } -}] - -var varNetworkAllowedIpRanges = [for item in networkAllowedIpRanges: { - value: item - action: 'Allow' -}] - -var IS_PREMIUM_SKU = skuName == 'Premium' - -var varPrivateEndpoints = [for privateEndpoint in privateEndpoints: { - name: '${privateEndpoint.name}-${containerRegistry.name}' - privateLinkServiceId: containerRegistry.id - groupIds: [ - 'registry' - ] - subnetId: privateEndpoint.subnetId - privateDnsZones: contains(privateEndpoint, 'privateDnsZoneId') ? [ - { - name: 'default' - zoneId: privateEndpoint.privateDnsZoneId - } - ] : [] -}] - -var varReplicationLocations = [for replicationLocation in replicationLocations: { - location: replicationLocation.location - regionEndpointEnabled: contains(replicationLocation, 'regionEndpointEnabled') ? replicationLocation.regionEndpointEnabled : false - zoneRedundancy: contains(replicationLocation, 'zoneRedundancy') ? replicationLocation.zoneRedundancy : false -}] - -resource containerRegistry 'Microsoft.ContainerRegistry/registries@2021-09-01' = { - name: name - location: location - tags: tags - sku: { - name: skuName - } - properties: { - adminUserEnabled: adminUserEnabled - publicNetworkAccess: IS_PREMIUM_SKU ? publicNetworkAccessEnabled ? 'Enabled' : 'Disabled' : null - networkRuleBypassOptions: IS_PREMIUM_SKU ? publicAzureAccessEnabled ? 'AzureServices' : 'None' : null - networkRuleSet: IS_PREMIUM_SKU ? { - defaultAction: networkDefaultAction - ipRules: varNetworkAllowedIpRanges - } : null - dataEndpointEnabled: dataEndpointEnabled - encryption: IS_PREMIUM_SKU ? encryptionEnabled ? { - keyVaultProperties: { - identity: encryptionKeyVaultIdentity - keyIdentifier: encryptionKeyVaultKeyIdentifier - } - status: 'enabled' - } : null : null - zoneRedundancy: IS_PREMIUM_SKU ? zoneRedundancyEnabled ? 'Enabled' : 'Disabled' : null - policies: { - exportPolicy: publicAzureAccessEnabled == 'false' ? { - status: exportPolicyEnabled ? 'enabled' : 'disabled' - } : null - quarantinePolicy: { - status: quarantinePolicyEnabled ? 'enabled' : 'disabled' - } - retentionPolicy: IS_PREMIUM_SKU ? retentionPolicyEnabled ? { - days: retentionPolicyInDays - status: 'enabled' - } : null : null - trustPolicy: IS_PREMIUM_SKU ? trustPolicyEnabled ? { - status: 'enabled' - type: 'Notary' - } : null : null - } - } -} - -resource replications 'Microsoft.ContainerRegistry/registries/replications@2021-09-01' = [for replicationLocation in varReplicationLocations: if (IS_PREMIUM_SKU) { - name: replicationLocation.location - parent: containerRegistry - location: replicationLocation.location - tags: tags - properties: { - regionEndpointEnabled: replicationLocation.regionEndpointEnabled - zoneRedundancy: replicationLocation.zoneRedundancy ? 'Enabled' : 'Disabled' - } -}] - -resource containerRegistry_lock 'Microsoft.Authorization/locks@2020-05-01' = if (lock != 'NotSpecified') { - name: '${containerRegistry.name}-${lock}-lock' - properties: { - level: lock - notes: lock == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot modify the resource or child resources.' - } - scope: containerRegistry -} - -resource containerRegistry_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if (!empty(diagnosticStorageAccountId) || !empty(diagnosticWorkspaceId) || !empty(diagnosticEventHubAuthorizationRuleId) || !empty(diagnosticEventHubName)) { - name: '${containerRegistry.name}-diagnosticSettings' - properties: { - storageAccountId: !empty(diagnosticStorageAccountId) ? diagnosticStorageAccountId : null - workspaceId: !empty(diagnosticWorkspaceId) ? diagnosticWorkspaceId : null - eventHubAuthorizationRuleId: !empty(diagnosticEventHubAuthorizationRuleId) ? diagnosticEventHubAuthorizationRuleId : null - eventHubName: !empty(diagnosticEventHubName) ? diagnosticEventHubName : null - metrics: diagnosticsMetrics - logs: diagnosticsLogs - } - scope: containerRegistry -} - -module containerRegistry_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: { - name: '${uniqueString(deployment().name, location)}-acr-rbac-${index}' - params: { - description: contains(roleAssignment, 'description') ? roleAssignment.description : '' - principalIds: roleAssignment.principalIds - roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName - principalType: contains(roleAssignment, 'principalType') ? roleAssignment.principalType : '' - resourceId: containerRegistry.id - } -}] - -module containerRegistry_privateEndpoint '.bicep/nested_privateEndpoint.bicep' = { - name: '${uniqueString(deployment().name, location)}-acr-private-endpoints' - params: { - location: location - privateEndpoints: varPrivateEndpoints - tags: tags - manualApprovalEnabled: privateEndpointsApprovalEnabled - } -} - -module task 'task/task.bicep' = { - name: '${uniqueString(deployment().name, location)}-acr-task' - params: { - acrName: containerRegistry.name - location: location - tasks: tasks - loginServer: containerRegistry.properties.loginServer - } -} - -@description('The resource group the Azure Container Registry was deployed into.') -output resourceGroupName string = resourceGroup().name - -@description('The resource ID of the Azure Container Registry.') -output resourceId string = containerRegistry.id - -@description('The name of the Azure Container Registry.') -output name string = containerRegistry.name - -@description('The login server URL of the Azure Container Registry.') -output loginServer string = containerRegistry.properties.loginServer diff --git a/modules/compute/container-registry/main.json b/modules/compute/container-registry/main.json deleted file mode 100644 index c002f0d291..0000000000 --- a/modules/compute/container-registry/main.json +++ /dev/null @@ -1,896 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.20.4.51522", - "templateHash": "15501758245983767624" - }, - "name": "Container Registry", - "description": "This module deploys Container Registry (Microsoft.ContainerRegistry/registries) and optionally available integrations.", - "owner": "thomasriley" - }, - "parameters": { - "name": { - "type": "string", - "minLength": 5, - "maxLength": 50, - "metadata": { - "description": "The name of the Azure Container Registry." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Location for all resources." - } - }, - "tags": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Tags for all resource(s)." - } - }, - "skuName": { - "type": "string", - "defaultValue": "Basic", - "allowedValues": [ - "Basic", - "Standard", - "Premium" - ], - "metadata": { - "description": "The SKU of the Azure Container Registry." - } - }, - "adminUserEnabled": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Toggle the Azure Container Registry admin user." - } - }, - "publicNetworkAccessEnabled": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Toggle public network access to Azure Container Registry." - } - }, - "publicAzureAccessEnabled": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "When public network access is disabled, toggle this to allow Azure services to bypass the public network access rule." - } - }, - "networkAllowedIpRanges": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "A list of IP or IP ranges in CIDR format, that should be allowed access to Azure Container Registry." - } - }, - "networkDefaultAction": { - "type": "string", - "defaultValue": "Deny", - "allowedValues": [ - "Allow", - "Deny" - ], - "metadata": { - "description": "The default action to take when no network rule match is found for accessing Azure Container Registry." - } - }, - "roleAssignments": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Array of role assignment objects that contain the 'roleDefinitionIdOrName'(string) and 'principalIds'(array of strings) to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'" - } - }, - "lock": { - "type": "string", - "defaultValue": "NotSpecified", - "allowedValues": [ - "CanNotDelete", - "NotSpecified", - "ReadOnly" - ], - "metadata": { - "description": "Specify the type of lock." - } - }, - "privateEndpoints": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Define Private Endpoints that should be created for Azure Container Registry." - } - }, - "privateEndpointsApprovalEnabled": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Toggle if Private Endpoints manual approval for Azure Container Registry should be enabled." - } - }, - "zoneRedundancyEnabled": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Toggle if Zone Redundancy should be enabled on Azure Container Registry." - } - }, - "replicationLocations": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Array of Azure Location configurations that this Azure Container Registry should replicate too." - } - }, - "dataEndpointEnabled": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Toggle if a single data endpoint per region for serving data from Azure Container Registry should be enabled." - } - }, - "encryptionEnabled": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Toggle if encryption should be enabled on Azure Container Registry." - } - }, - "exportPolicyEnabled": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Toggle if export policy should be enabled on Azure Container Registry." - } - }, - "quarantinePolicyEnabled": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Toggle if quarantine policy should be enabled on Azure Container Registry." - } - }, - "retentionPolicyEnabled": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Toggle if retention policy should be enabled on Azure Container Registry." - } - }, - "retentionPolicyInDays": { - "type": "int", - "defaultValue": 10, - "metadata": { - "description": "Configure the retention policy in days for Azure Container Registry. Only effective is 'retentionPolicyEnabled' is 'true'." - } - }, - "trustPolicyEnabled": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Toggle if trust policy should be enabled on Azure Container Registry." - } - }, - "encryptionKeyVaultIdentity": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "The client ID of the identity which will be used to access Key Vault." - } - }, - "encryptionKeyVaultKeyIdentifier": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "The Key Vault URI to access the encryption key." - } - }, - "diagnosticLogsRetentionInDays": { - "type": "int", - "defaultValue": 365, - "minValue": 0, - "maxValue": 365, - "metadata": { - "description": "Specifies the number of days that logs will be kept for; a value of 0 will retain data indefinitely." - } - }, - "diagnosticStorageAccountId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Resource ID of the diagnostic storage account." - } - }, - "diagnosticWorkspaceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Resource ID of the diagnostic log analytics workspace." - } - }, - "diagnosticEventHubAuthorizationRuleId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "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." - } - }, - "diagnosticEventHubName": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "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." - } - }, - "logsToEnable": { - "type": "array", - "defaultValue": [ - "ContainerRegistryRepositoryEvents", - "ContainerRegistryLoginEvents" - ], - "allowedValues": [ - "ContainerRegistryRepositoryEvents", - "ContainerRegistryLoginEvents" - ], - "metadata": { - "description": "The name of logs that will be streamed." - } - }, - "metricsToEnable": { - "type": "array", - "defaultValue": [ - "AllMetrics" - ], - "allowedValues": [ - "AllMetrics" - ], - "metadata": { - "description": "The name of metrics that will be streamed." - } - }, - "tasks": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. The list of ACR tasks to create." - } - } - }, - "variables": { - "copy": [ - { - "name": "diagnosticsLogs", - "count": "[length(parameters('logsToEnable'))]", - "input": { - "category": "[parameters('logsToEnable')[copyIndex('diagnosticsLogs')]]", - "enabled": true, - "retentionPolicy": { - "enabled": true, - "days": "[parameters('diagnosticLogsRetentionInDays')]" - } - } - }, - { - "name": "diagnosticsMetrics", - "count": "[length(parameters('metricsToEnable'))]", - "input": { - "category": "[parameters('metricsToEnable')[copyIndex('diagnosticsMetrics')]]", - "timeGrain": null, - "enabled": true, - "retentionPolicy": { - "enabled": true, - "days": "[parameters('diagnosticLogsRetentionInDays')]" - } - } - }, - { - "name": "varNetworkAllowedIpRanges", - "count": "[length(parameters('networkAllowedIpRanges'))]", - "input": { - "value": "[parameters('networkAllowedIpRanges')[copyIndex('varNetworkAllowedIpRanges')]]", - "action": "Allow" - } - }, - { - "name": "varPrivateEndpoints", - "count": "[length(parameters('privateEndpoints'))]", - "input": { - "name": "[format('{0}-{1}', parameters('privateEndpoints')[copyIndex('varPrivateEndpoints')].name, parameters('name'))]", - "privateLinkServiceId": "[resourceId('Microsoft.ContainerRegistry/registries', parameters('name'))]", - "groupIds": [ - "registry" - ], - "subnetId": "[parameters('privateEndpoints')[copyIndex('varPrivateEndpoints')].subnetId]", - "privateDnsZones": "[if(contains(parameters('privateEndpoints')[copyIndex('varPrivateEndpoints')], 'privateDnsZoneId'), createArray(createObject('name', 'default', 'zoneId', parameters('privateEndpoints')[copyIndex('varPrivateEndpoints')].privateDnsZoneId)), createArray())]" - } - }, - { - "name": "varReplicationLocations", - "count": "[length(parameters('replicationLocations'))]", - "input": { - "location": "[parameters('replicationLocations')[copyIndex('varReplicationLocations')].location]", - "regionEndpointEnabled": "[if(contains(parameters('replicationLocations')[copyIndex('varReplicationLocations')], 'regionEndpointEnabled'), parameters('replicationLocations')[copyIndex('varReplicationLocations')].regionEndpointEnabled, false())]", - "zoneRedundancy": "[if(contains(parameters('replicationLocations')[copyIndex('varReplicationLocations')], 'zoneRedundancy'), parameters('replicationLocations')[copyIndex('varReplicationLocations')].zoneRedundancy, false())]" - } - } - ], - "IS_PREMIUM_SKU": "[equals(parameters('skuName'), 'Premium')]" - }, - "resources": [ - { - "type": "Microsoft.ContainerRegistry/registries", - "apiVersion": "2021-09-01", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "sku": { - "name": "[parameters('skuName')]" - }, - "properties": { - "adminUserEnabled": "[parameters('adminUserEnabled')]", - "publicNetworkAccess": "[if(variables('IS_PREMIUM_SKU'), if(parameters('publicNetworkAccessEnabled'), 'Enabled', 'Disabled'), null())]", - "networkRuleBypassOptions": "[if(variables('IS_PREMIUM_SKU'), if(parameters('publicAzureAccessEnabled'), 'AzureServices', 'None'), null())]", - "networkRuleSet": "[if(variables('IS_PREMIUM_SKU'), createObject('defaultAction', parameters('networkDefaultAction'), 'ipRules', variables('varNetworkAllowedIpRanges')), null())]", - "dataEndpointEnabled": "[parameters('dataEndpointEnabled')]", - "encryption": "[if(variables('IS_PREMIUM_SKU'), if(parameters('encryptionEnabled'), createObject('keyVaultProperties', createObject('identity', parameters('encryptionKeyVaultIdentity'), 'keyIdentifier', parameters('encryptionKeyVaultKeyIdentifier')), 'status', 'enabled'), null()), null())]", - "zoneRedundancy": "[if(variables('IS_PREMIUM_SKU'), if(parameters('zoneRedundancyEnabled'), 'Enabled', 'Disabled'), null())]", - "policies": { - "exportPolicy": "[if(equals(parameters('publicAzureAccessEnabled'), 'false'), createObject('status', if(parameters('exportPolicyEnabled'), 'enabled', 'disabled')), null())]", - "quarantinePolicy": { - "status": "[if(parameters('quarantinePolicyEnabled'), 'enabled', 'disabled')]" - }, - "retentionPolicy": "[if(variables('IS_PREMIUM_SKU'), if(parameters('retentionPolicyEnabled'), createObject('days', parameters('retentionPolicyInDays'), 'status', 'enabled'), null()), null())]", - "trustPolicy": "[if(variables('IS_PREMIUM_SKU'), if(parameters('trustPolicyEnabled'), createObject('status', 'enabled', 'type', 'Notary'), null()), null())]" - } - } - }, - { - "copy": { - "name": "replications", - "count": "[length(variables('varReplicationLocations'))]" - }, - "condition": "[variables('IS_PREMIUM_SKU')]", - "type": "Microsoft.ContainerRegistry/registries/replications", - "apiVersion": "2021-09-01", - "name": "[format('{0}/{1}', parameters('name'), variables('varReplicationLocations')[copyIndex()].location)]", - "location": "[variables('varReplicationLocations')[copyIndex()].location]", - "tags": "[parameters('tags')]", - "properties": { - "regionEndpointEnabled": "[variables('varReplicationLocations')[copyIndex()].regionEndpointEnabled]", - "zoneRedundancy": "[if(variables('varReplicationLocations')[copyIndex()].zoneRedundancy, 'Enabled', 'Disabled')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.ContainerRegistry/registries', parameters('name'))]" - ] - }, - { - "condition": "[not(equals(parameters('lock'), 'NotSpecified'))]", - "type": "Microsoft.Authorization/locks", - "apiVersion": "2020-05-01", - "scope": "[format('Microsoft.ContainerRegistry/registries/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", - "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.ContainerRegistry/registries', parameters('name'))]" - ] - }, - { - "condition": "[or(or(or(not(empty(parameters('diagnosticStorageAccountId'))), not(empty(parameters('diagnosticWorkspaceId')))), not(empty(parameters('diagnosticEventHubAuthorizationRuleId')))), not(empty(parameters('diagnosticEventHubName'))))]", - "type": "Microsoft.Insights/diagnosticSettings", - "apiVersion": "2021-05-01-preview", - "scope": "[format('Microsoft.ContainerRegistry/registries/{0}', parameters('name'))]", - "name": "[format('{0}-diagnosticSettings', parameters('name'))]", - "properties": { - "storageAccountId": "[if(not(empty(parameters('diagnosticStorageAccountId'))), parameters('diagnosticStorageAccountId'), null())]", - "workspaceId": "[if(not(empty(parameters('diagnosticWorkspaceId'))), parameters('diagnosticWorkspaceId'), null())]", - "eventHubAuthorizationRuleId": "[if(not(empty(parameters('diagnosticEventHubAuthorizationRuleId'))), parameters('diagnosticEventHubAuthorizationRuleId'), null())]", - "eventHubName": "[if(not(empty(parameters('diagnosticEventHubName'))), parameters('diagnosticEventHubName'), null())]", - "metrics": "[variables('diagnosticsMetrics')]", - "logs": "[variables('diagnosticsLogs')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.ContainerRegistry/registries', parameters('name'))]" - ] - }, - { - "copy": { - "name": "containerRegistry_rbac", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-acr-rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.ContainerRegistry/registries', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.20.4.51522", - "templateHash": "11276824333704269750" - } - }, - "parameters": { - "description": { - "type": "string", - "defaultValue": "" - }, - "principalIds": { - "type": "array" - }, - "principalType": { - "type": "string", - "defaultValue": "" - }, - "roleDefinitionIdOrName": { - "type": "string" - }, - "resourceId": { - "type": "string" - } - }, - "variables": { - "builtInRoleNames": { - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Metrics Publisher": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "AcrDelete": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c2f4ef07-c644-48eb-af81-4b1b4947fb11')]", - "AcrImageSigner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c2f4ef07-c644-48eb-af81-4b1b4947fb11')]", - "AcrPull": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d')]", - "AcrPush": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8311e382-0749-4cb8-b61a-304f252e45ec')]", - "AcrQuarantineReader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'cdda3590-29a3-44f6-95f2-9f980659eb04')]", - "AcrQuarantineWriter": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c8d4ff99-41c3-41a8-9f60-21dfdad59608')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.ContainerRegistry/registries/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(last(split(parameters('resourceId'), '/')), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.ContainerRegistry/registries', parameters('name'))]" - ] - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-acr-private-endpoints', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "location": { - "value": "[parameters('location')]" - }, - "privateEndpoints": { - "value": "[variables('varPrivateEndpoints')]" - }, - "tags": { - "value": "[parameters('tags')]" - }, - "manualApprovalEnabled": { - "value": "[parameters('privateEndpointsApprovalEnabled')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.20.4.51522", - "templateHash": "1569431369010361825" - } - }, - "parameters": { - "location": { - "type": "string" - }, - "tags": { - "type": "object" - }, - "manualApprovalEnabled": { - "type": "bool" - }, - "privateEndpoints": { - "type": "array" - } - }, - "variables": { - "copy": [ - { - "name": "varPrivateEndpoints", - "count": "[length(parameters('privateEndpoints'))]", - "input": { - "name": "[parameters('privateEndpoints')[copyIndex('varPrivateEndpoints')].name]", - "privateLinkServiceId": "[parameters('privateEndpoints')[copyIndex('varPrivateEndpoints')].privateLinkServiceId]", - "groupIds": "[parameters('privateEndpoints')[copyIndex('varPrivateEndpoints')].groupIds]", - "subnetId": "[parameters('privateEndpoints')[copyIndex('varPrivateEndpoints')].subnetId]", - "privateDnsZones": "[if(contains(parameters('privateEndpoints')[copyIndex('varPrivateEndpoints')], 'privateDnsZones'), parameters('privateEndpoints')[copyIndex('varPrivateEndpoints')].privateDnsZones, createArray())]", - "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex('varPrivateEndpoints')], 'customNetworkInterfaceName'), parameters('privateEndpoints')[copyIndex('varPrivateEndpoints')].customNetworkInterfaceName, null())]" - } - } - ] - }, - "resources": [ - { - "copy": { - "name": "privateEndpoint", - "count": "[length(variables('varPrivateEndpoints'))]", - "mode": "serial", - "batchSize": 1 - }, - "type": "Microsoft.Network/privateEndpoints", - "apiVersion": "2022-05-01", - "name": "[format('{0}-{1}', variables('varPrivateEndpoints')[copyIndex()].name, uniqueString(variables('varPrivateEndpoints')[copyIndex()].name, variables('varPrivateEndpoints')[copyIndex()].subnetId, variables('varPrivateEndpoints')[copyIndex()].privateLinkServiceId))]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "properties": { - "privateLinkServiceConnections": "[if(parameters('manualApprovalEnabled'), null(), createArray(createObject('name', variables('varPrivateEndpoints')[copyIndex()].name, 'properties', createObject('privateLinkServiceId', variables('varPrivateEndpoints')[copyIndex()].privateLinkServiceId, 'groupIds', if(not(empty(variables('varPrivateEndpoints')[copyIndex()].groupIds)), variables('varPrivateEndpoints')[copyIndex()].groupIds, null())))))]", - "manualPrivateLinkServiceConnections": "[if(parameters('manualApprovalEnabled'), createArray(createObject('name', variables('varPrivateEndpoints')[copyIndex()].name, 'properties', createObject('privateLinkServiceId', variables('varPrivateEndpoints')[copyIndex()].privateLinkServiceId, 'groupIds', if(not(empty(variables('varPrivateEndpoints')[copyIndex()].groupIds)), variables('varPrivateEndpoints')[copyIndex()].groupIds, null())))), null())]", - "subnet": { - "id": "[variables('varPrivateEndpoints')[copyIndex()].subnetId]" - }, - "customNetworkInterfaceName": "[variables('varPrivateEndpoints')[copyIndex()].customNetworkInterfaceName]" - } - }, - { - "copy": { - "name": "privateDnsZoneGroup", - "count": "[length(variables('varPrivateEndpoints'))]", - "mode": "serial", - "batchSize": 1 - }, - "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", - "apiVersion": "2022-05-01", - "name": "[format('{0}/{1}', format('{0}-{1}', variables('varPrivateEndpoints')[copyIndex()].name, uniqueString(variables('varPrivateEndpoints')[copyIndex()].name, variables('varPrivateEndpoints')[copyIndex()].subnetId, variables('varPrivateEndpoints')[copyIndex()].privateLinkServiceId)), 'default')]", - "properties": { - "copy": [ - { - "name": "privateDnsZoneConfigs", - "count": "[length(variables('varPrivateEndpoints')[copyIndex()].privateDnsZones)]", - "input": { - "name": "[if(contains(variables('varPrivateEndpoints')[copyIndex()].privateDnsZones[copyIndex('privateDnsZoneConfigs')], 'name'), variables('varPrivateEndpoints')[copyIndex()].privateDnsZones[copyIndex('privateDnsZoneConfigs')].name, 'default')]", - "properties": { - "privateDnsZoneId": "[variables('varPrivateEndpoints')[copyIndex()].privateDnsZones[copyIndex('privateDnsZoneConfigs')].zoneId]" - } - } - } - ] - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', format('{0}-{1}', variables('varPrivateEndpoints')[copyIndex()].name, uniqueString(variables('varPrivateEndpoints')[copyIndex()].name, variables('varPrivateEndpoints')[copyIndex()].subnetId, variables('varPrivateEndpoints')[copyIndex()].privateLinkServiceId)))]" - ] - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.ContainerRegistry/registries', parameters('name'))]" - ] - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-acr-task', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "acrName": { - "value": "[parameters('name')]" - }, - "location": { - "value": "[parameters('location')]" - }, - "tasks": { - "value": "[parameters('tasks')]" - }, - "loginServer": { - "value": "[reference(resourceId('Microsoft.ContainerRegistry/registries', parameters('name')), '2021-09-01').loginServer]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.20.4.51522", - "templateHash": "15495887558517410579" - } - }, - "parameters": { - "acrName": { - "type": "string" - }, - "location": { - "type": "string" - }, - "loginServer": { - "type": "string" - }, - "tasks": { - "type": "array", - "defaultValue": [] - } - }, - "resources": [ - { - "copy": { - "name": "task", - "count": "[length(parameters('tasks'))]" - }, - "type": "Microsoft.ContainerRegistry/registries/tasks", - "apiVersion": "2019-06-01-preview", - "name": "[format('{0}/{1}', parameters('acrName'), parameters('tasks')[copyIndex()].taskName)]", - "location": "[parameters('location')]", - "identity": "[parameters('tasks')[copyIndex()].identity]", - "properties": { - "status": "[parameters('tasks')[copyIndex()].status]", - "platform": "[parameters('tasks')[copyIndex()].platform]", - "agentConfiguration": "[parameters('tasks')[copyIndex()].agentConfiguration]", - "trigger": "[parameters('tasks')[copyIndex()].trigger]", - "step": "[parameters('tasks')[copyIndex()].step]", - "credentials": { - "customRegistries": { - "[format('{0}', parameters('loginServer'))]": "[if(equals(parameters('tasks')[copyIndex()].identity.type, 'SystemAssigned'), createObject('identity', '[system]'), createObject())]" - } - } - } - }, - { - "copy": { - "name": "containerRegistry_rbac", - "count": "[length(parameters('tasks'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-acr-task-rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": { - "value": "[format('role assignment for task {0}', parameters('tasks')[copyIndex()].taskName)]" - }, - "roleDefinitionIdOrName": { - "value": "Contributor" - }, - "principalIds": { - "value": [ - "[reference(resourceId('Microsoft.ContainerRegistry/registries/tasks', parameters('acrName'), parameters('tasks')[copyIndex()].taskName), '2019-06-01-preview', 'full').identity.principalId]" - ] - }, - "principalType": { - "value": "ServicePrincipal" - }, - "resourceId": { - "value": "[resourceId('Microsoft.ContainerRegistry/registries', parameters('acrName'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.20.4.51522", - "templateHash": "11276824333704269750" - } - }, - "parameters": { - "description": { - "type": "string", - "defaultValue": "" - }, - "principalIds": { - "type": "array" - }, - "principalType": { - "type": "string", - "defaultValue": "" - }, - "roleDefinitionIdOrName": { - "type": "string" - }, - "resourceId": { - "type": "string" - } - }, - "variables": { - "builtInRoleNames": { - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Metrics Publisher": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "AcrDelete": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c2f4ef07-c644-48eb-af81-4b1b4947fb11')]", - "AcrImageSigner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c2f4ef07-c644-48eb-af81-4b1b4947fb11')]", - "AcrPull": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d')]", - "AcrPush": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8311e382-0749-4cb8-b61a-304f252e45ec')]", - "AcrQuarantineReader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'cdda3590-29a3-44f6-95f2-9f980659eb04')]", - "AcrQuarantineWriter": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c8d4ff99-41c3-41a8-9f60-21dfdad59608')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.ContainerRegistry/registries/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(last(split(parameters('resourceId'), '/')), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.ContainerRegistry/registries/tasks', parameters('acrName'), parameters('tasks')[copyIndex()].taskName)]" - ] - } - ], - "outputs": { - "tasksRoleAssignments": { - "type": "array", - "copy": { - "count": "[length(parameters('tasks'))]", - "input": { - "description": "[format('role assignment for task {0}', parameters('tasks')[copyIndex()].taskName)]", - "roleDefinitionIdOrName": "Contributor", - "principalType": "ServicePrincipal", - "principalIds": "[reference(resourceId('Microsoft.ContainerRegistry/registries/tasks', parameters('acrName'), parameters('tasks')[copyIndex()].taskName), '2019-06-01-preview', 'full').identity.principalId]" - } - } - } - } - } - }, - "dependsOn": [ - "[resourceId('Microsoft.ContainerRegistry/registries', parameters('name'))]" - ] - } - ], - "outputs": { - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The resource group the Azure Container Registry was deployed into." - }, - "value": "[resourceGroup().name]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the Azure Container Registry." - }, - "value": "[resourceId('Microsoft.ContainerRegistry/registries', parameters('name'))]" - }, - "name": { - "type": "string", - "metadata": { - "description": "The name of the Azure Container Registry." - }, - "value": "[parameters('name')]" - }, - "loginServer": { - "type": "string", - "metadata": { - "description": "The login server URL of the Azure Container Registry." - }, - "value": "[reference(resourceId('Microsoft.ContainerRegistry/registries', parameters('name')), '2021-09-01').loginServer]" - } - } -} \ No newline at end of file diff --git a/modules/compute/container-registry/task/task.bicep b/modules/compute/container-registry/task/task.bicep deleted file mode 100644 index 9619762292..0000000000 --- a/modules/compute/container-registry/task/task.bicep +++ /dev/null @@ -1,49 +0,0 @@ -param acrName string -param location string -param loginServer string -param tasks array = [] - -resource containerRegistry 'Microsoft.ContainerRegistry/registries@2023-01-01-preview' existing = { - name: acrName -} - -resource task 'Microsoft.ContainerRegistry/registries/tasks@2019-06-01-preview' = [for task in tasks: { - name: task.taskName - location: location - parent: containerRegistry - identity: task.identity - properties: { - status: task.status - platform: task.platform - agentConfiguration: task.agentConfiguration - trigger: task.trigger - step: task.step - credentials: { - customRegistries: { - '${loginServer}': task.identity.type == 'SystemAssigned' ? { - identity: '[system]' - } : {} - } - } - } -}] - -module containerRegistry_rbac '../.bicep/nested_rbac.bicep' = [for (t, index) in tasks: { - name: '${uniqueString(deployment().name, location)}-acr-task-rbac-${index}' - params: { - description: 'role assignment for task ${t.taskName}' - roleDefinitionIdOrName: 'Contributor' - principalIds: [ - task[index].identity.principalId - ] - principalType: 'ServicePrincipal' - resourceId: containerRegistry.id - } -}] - -output tasksRoleAssignments array = [for (t, index) in tasks: { - description: 'role assignment for task ${t.taskName}' - roleDefinitionIdOrName: 'Contributor' - principalType: 'ServicePrincipal' - principalIds: task[index].identity.principalId -}] diff --git a/modules/compute/container-registry/test/dependencies.test.bicep b/modules/compute/container-registry/test/dependencies.test.bicep deleted file mode 100644 index ce03711a12..0000000000 --- a/modules/compute/container-registry/test/dependencies.test.bicep +++ /dev/null @@ -1,114 +0,0 @@ -param location string -param name string -param prefix string - -resource storageAccount 'Microsoft.Storage/storageAccounts@2022-05-01' = { - name: '${prefix}${name}01' - kind: 'StorageV2' - sku: { - name: 'Standard_LRS' - } - location: location - properties: { - allowBlobPublicAccess: false - } -} - -resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' = { - name: '${prefix}-law-${name}-01' - location: location -} - -resource eventHubNamespace 'Microsoft.EventHub/namespaces@2021-11-01' = { - name: '${prefix}-evhns-${name}-01' - location: location -} - -resource eventHub 'Microsoft.EventHub/namespaces/eventhubs@2021-11-01' = { - name: '${prefix}-evh-${name}-01' - parent: eventHubNamespace -} - -resource authorizationRule 'Microsoft.EventHub/namespaces/authorizationRules@2022-01-01-preview' = { - name: 'RootManageSharedAccessKey' - properties: { - rights: [ - 'Listen' - 'Manage' - 'Send' - ] - } - parent: eventHubNamespace -} - -resource virtualNetwork 'Microsoft.Network/virtualNetworks@2022-05-01' = { - name: '${prefix}-${name}-vnet' - location: location - properties: { - addressSpace: { - addressPrefixes: [ - '10.0.0.0/16' - ] - } - subnets: [ - { - name: '${name}-subnet-0' - properties: { - addressPrefix: '10.0.0.0/24' - privateEndpointNetworkPolicies: 'Disabled' - } - } - { - name: '${name}-subnet-1' - properties: { - addressPrefix: '10.0.1.0/24' - privateEndpointNetworkPolicies: 'Disabled' - } - } - ] - } -} - -resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { - name: 'privatelink.azurecr.io' - location: 'global' - properties: {} -} - -resource virtualNetworkLinks 'Microsoft.Network/privateDnsZones/virtualNetworkLinks@2020-06-01' = { - parent: privateDNSZone - name: '${prefix}-${name}-vnet-link' - location: 'global' - properties: { - registrationEnabled: false - virtualNetwork: { - id: virtualNetwork.id - } - } -} - -resource managedIdentity_01 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: '${prefix}-${name}-01' - location: location -} - -resource managedIdentity_02 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: '${prefix}-${name}-02' - location: location -} - -output storageAccountId string = storageAccount.id -output workspaceId string = logAnalyticsWorkspace.id -output vnetId string = virtualNetwork.id -output subnetIds array = [ - virtualNetwork.properties.subnets[0].id - virtualNetwork.properties.subnets[1].id -] -output privateDNSZoneId string = privateDNSZone.id -output eventHubNamespaceId string = eventHubNamespace.id -output eventHubName string = eventHub.name -output authorizationRuleId string = authorizationRule.id -output identityPrincipalIds array = [ - managedIdentity_01.properties.principalId - managedIdentity_02.properties.principalId -] diff --git a/modules/compute/container-registry/test/main.test.bicep b/modules/compute/container-registry/test/main.test.bicep deleted file mode 100644 index 636822edca..0000000000 --- a/modules/compute/container-registry/test/main.test.bicep +++ /dev/null @@ -1,179 +0,0 @@ -targetScope = 'resourceGroup' - -// ========== // -// Parameters // -// ========== // - -param location string = 'westus2' -param serviceShort string = 'acr' -var uniqueName = uniqueString(resourceGroup().id, deployment().name, location) - -// ============ // -// Dependencies // -// ============ // - -module dependencies 'dependencies.test.bicep' = { - name: 'test-dependencies' - params: { - name: serviceShort - location: location - prefix: uniqueName - } -} - -// ===== // -// Tests // -// ===== // - -// Test 01 - Basic SKU - Minimal Parameters -module test_01 '../main.bicep' = { - name: '${uniqueName}-test-01' - params: { - name: 'test01${uniqueName}' - location: location - } -} - -// Test 02 - Standard SKU - Parameters, RBAC and Diagnostic Settings -module test_02 '../main.bicep' = { - name: '${uniqueName}-test-02' - params: { - name: 'test02${uniqueName}' - location: location - skuName: 'Standard' - adminUserEnabled: true - tags: { - tag1: 'tag1value' - tag2: 'tag2value' - } - diagnosticStorageAccountId: dependencies.outputs.storageAccountId - diagnosticWorkspaceId: dependencies.outputs.workspaceId - roleAssignments: [ - { - roleDefinitionIdOrName: 'AcrPull' - principalIds: [ dependencies.outputs.identityPrincipalIds[0] ] - } - ] - tasks: [ { - taskName: 'task1' - status: 'Enabled' - platform: { - os: 'Linux' - architecture: 'Amd64' - } - agentConfiguration: { - cpu: 2 - } - trigger: { - timerTriggers: [ - { - name: 'trigger1' - status: 'Enabled' - schedule: '*/1 * * * Mon-Fri' - } - ] - } - step: { - type: 'EncodedTask' - encodedTaskContent: loadFileAsBase64('task.yaml') - } - identity: { - type: 'SystemAssigned' - } - } - ] - } -} - -// Test 03 - Standard SKU - Parameters, RBAC and Diagnostic Settings -module test_03 '../main.bicep' = { - name: '${uniqueName}-test-03' - params: { - name: 'test03${uniqueName}' - location: location - skuName: 'Standard' - adminUserEnabled: false - diagnosticEventHubAuthorizationRuleId: dependencies.outputs.authorizationRuleId - diagnosticEventHubName: dependencies.outputs.eventHubName - roleAssignments: [ - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d') // AcrPull - principalIds: [ dependencies.outputs.identityPrincipalIds[1] ] - } - ] - } -} - -// Test 04 - Premium Test - Network Rules & Zone Redundancy -module test_04 '../main.bicep' = { - name: '${uniqueName}-test-04' - params: { - name: 'test04${uniqueName}' - location: location - skuName: 'Premium' - publicAzureAccessEnabled: false - networkAllowedIpRanges: [ - '20.112.52.29' - '20.53.204.50' - ] - zoneRedundancyEnabled: true - } -} - -// Test 05 - Premium Test - Private Endpoint -module test_05 '../main.bicep' = { - name: '${uniqueName}-test-05' - params: { - name: 'test05${uniqueName}' - location: location - skuName: 'Premium' - publicNetworkAccessEnabled: false - privateEndpoints: [ - { - name: 'endpoint1' - subnetId: dependencies.outputs.subnetIds[0] - } - { - name: 'endpoint2' - subnetId: dependencies.outputs.subnetIds[1] - privateDnsZoneId: dependencies.outputs.privateDNSZoneId - } - ] - } -} - -// Test 06 - Premium Test - Private Endpoint -module test_06 '../main.bicep' = { - name: '${uniqueName}-test-06' - params: { - name: 'test06${uniqueName}' - location: location - skuName: 'Premium' - publicNetworkAccessEnabled: false - exportPolicyEnabled: true - quarantinePolicyEnabled: true - retentionPolicyEnabled: true - retentionPolicyInDays: 5 - trustPolicyEnabled: true - } -} - -// Test 07 - Premium Test - Replication -module test_07 '../main.bicep' = { - name: '${uniqueName}-test-07' - params: { - name: 'test07${uniqueName}' - location: location - skuName: 'Premium' - replicationLocations: [ - { - location: 'eastus2' - } - { - location: 'northeurope' - regionEndpointEnabled: true - zoneRedundancy: true - } - ] - } -} diff --git a/modules/compute/container-registry/test/task.yaml b/modules/compute/container-registry/test/task.yaml deleted file mode 100644 index 745b33f770..0000000000 --- a/modules/compute/container-registry/test/task.yaml +++ /dev/null @@ -1,5 +0,0 @@ -version: v1.1.0 -steps: - - cmd: acr purge --filter 'hello:.*' --untagged --ago 1d - disableWorkingDirectoryOverride: true - timeout: 3600 \ No newline at end of file diff --git a/modules/compute/container-registry/version.json b/modules/compute/container-registry/version.json deleted file mode 100644 index 455678cf6f..0000000000 --- a/modules/compute/container-registry/version.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "1.1", - "pathFilters": [ - "./main.json", - "./metadata.json" - ] -} \ No newline at end of file diff --git a/modules/compute/custom-image-vmss/README.md b/modules/compute/custom-image-vmss/README.md deleted file mode 100644 index 9755513c6b..0000000000 --- a/modules/compute/custom-image-vmss/README.md +++ /dev/null @@ -1,92 +0,0 @@ -# Azure VMSS with Custom Image - -Create an Azure VMSS Cluster with a Custom Image to simplify creation of Marketplace Applications - -## Details - -The Azure Marketplace makes it easy to [create and publish](https://learn.microsoft.com/en-us/azure/marketplace/azure-vm-use-own-image) custom Virtual Machine images. -Customers can then use the custom image to create a Virtual Machine or [Scale Set](https://learn.microsoft.com/en-us/azure/virtual-machine-scale-sets/overview). But, if custom configurations are required, the user must provide the proper custom data input. Creating a [Marketplace Application](https://learn.microsoft.com/en-us/azure/marketplace/azure-app-offer-setup) enables publishers to customize the [creation experince](https://learn.microsoft.com/en-us/azure/azure-resource-manager/managed-applications/create-uidefinition-overview) in the portal. -This Bicep Module can be used to easily wrap a Marketplace or Community image for use on Azure VMSS. - -## Parameters - -| Name | Type | Required | Description | -| :--------------------------- | :------------: | :------: | :----------------------------------------------------------------------------------------------------------------------- | -| `location` | `string` | No | Deployment Location | -| `vmssName` | `string` | Yes | Name of VMSS Cluster | -| `vmssSku` | `string` | No | GameDev Sku | -| `vmssImgPublisher` | `string` | No | Image Publisher | -| `vmssImgProduct` | `string` | No | Image Product Id | -| `vmssImgSku` | `string` | No | Image Sku | -| `vmssImgVersion` | `string` | No | GameDev Image Product Id | -| `vmssOsDiskType` | `string` | No | GameDev Disk Type | -| `vmssInstanceCount` | `int` | No | VMSS Instance Count | -| `administratorLogin` | `string` | Yes | Administrator Login for access | -| `passwordAdministratorLogin` | `securestring` | Yes | Administrator Password for access | -| `vnetName` | `string` | No | Virtual Network Resource Name | -| `subnetName` | `string` | No | Virtual Network Subnet Name | -| `networkSecurityGroupName` | `string` | No | Virtual Network Security Group Name | -| `vnetAddressPrefix` | `string` | No | Virtual Network Address Prefix | -| `subnetAddressPrefix` | `string` | No | Virtual Network Subnet Address Prefix | -| `imageLocation` | `string` | No | Parameter used for debugging with trail offer | -| `communityGalleryImageId` | `string` | No | Pointer to community gallery image. Example: /CommunityGalleries//Images//Versions/ | -| `customData` | `string` | No | Base64 Encoded string to provide to VMSS for configuration | - -## Outputs - -| Name | Type | Description | -| :----- | :------: | :----------------------------------------- | -| `id` | `string` | Resource Id of Virtual Machine Scale Set | -| `name` | `string` | Resource Name of Virtual Machine Scale Set | - -## Examples - -### Example 1 - -The custom data can be loaded from a file. - -```bicep -var communityGalleryImageId = '/CommunityGalleries/${sharedGalleryID}/Images/${definitionId}/Versions/${imageVer}' - -var customData = loadFileAsBase64('imageConfig.json') - -module Example1 'br/public:compute/custom-image-vmss:1.0.2' = { - name: 'Example1' - params: { - location: location - administratorLogin: uniqueString(resourceGroup().name) - passwordAdministratorLogin: guid(resourceGroup().name) - vmssName: uniqueString(resourceGroup().name) - communityGalleryImageId: communityGalleryImageId - customData: customData - } -} - -``` - -### Example 2 - -The custom data may also be created directly in Bicep, so that the settings may be provided at deployment time. - -```bicep -param developer_mode bool = true - -var communityGalleryImageId = '/CommunityGalleries/${sharedGalleryId}/Images/${definitionId}/Versions/${imageVer}' - -var customData = { - developer_mode: developer_mode -} - -module Example2 'br/public:compute/custom-image-vmss:1.0.2' = { - name: 'Example2' - params: { - location: location - administratorLogin: uniqueString(resourceGroup().name) - passwordAdministratorLogin: guid(resourceGroup().name) - vmssName: uniqueString(resourceGroup().name) - communityGalleryImageId: communityGalleryImageId - customData: base64(string(customData)) - } -} - -``` \ No newline at end of file diff --git a/modules/compute/custom-image-vmss/main.bicep b/modules/compute/custom-image-vmss/main.bicep deleted file mode 100644 index e0502e4721..0000000000 --- a/modules/compute/custom-image-vmss/main.bicep +++ /dev/null @@ -1,165 +0,0 @@ -metadata name = 'Azure VMSS with Custom Image' -metadata description = 'Create an Azure VMSS Cluster with a Custom Image to simplify creation of Marketplace Applications' -metadata owner = 'dciborow' - -@description('Deployment Location') -param location string = resourceGroup().location - -@description('Name of VMSS Cluster') -param vmssName string - -@description('GameDev Sku') -param vmssSku string = 'Standard_D4ds_v4' - -@description('Image Publisher') -param vmssImgPublisher string = '' - -@description('Image Product Id') -param vmssImgProduct string = '' - -@description('Image Sku') -param vmssImgSku string = '' - -@description('GameDev Image Product Id') -param vmssImgVersion string = 'latest' - -@description('GameDev Disk Type') -param vmssOsDiskType string = 'Premium_LRS' - -@description('VMSS Instance Count') -@maxValue(100) -@minValue(1) -param vmssInstanceCount int = 1 - -@description('Administrator Login for access') -param administratorLogin string - -@description('Administrator Password for access') -@secure() -param passwordAdministratorLogin string - -@description('Virtual Network Resource Name') -param vnetName string = 'vnet-${vmssName}' - -@description('Virtual Network Subnet Name') -param subnetName string = 'subnet${vmssName}' - -@description('Virtual Network Security Group Name') -param networkSecurityGroupName string = 'nsg-${vmssName}' - -@description('Virtual Network Address Prefix') -param vnetAddressPrefix string = '172.17.72.0/24' //Change as needed - -@description('Virtual Network Subnet Address Prefix') -param subnetAddressPrefix string = '172.17.72.0/25' // 172.17.72.[0-128] is part of this subnet - -@allowed([ - 'gallery' - 'marketplace' -]) -@description('Parameter used for debugging with trail offer') -param imageLocation string = 'marketplace' - -@description('Pointer to community gallery image. Example: /CommunityGalleries//Images//Versions/') -param communityGalleryImageId string = '' - -@description('Base64 Encoded string to provide to VMSS for configuration') -param customData string = '' - -var locations = { - gallery: { - plan: null - imageReference: { communityGalleryImageId: communityGalleryImageId } - } - marketplace: { - plan: { - name: vmssImgSku - publisher: vmssImgPublisher - product: vmssImgProduct - } - imageReference: { - publisher: vmssImgPublisher - offer: vmssImgProduct - sku: vmssImgSku - version: vmssImgVersion - } - } -} - -module vnet 'modules/virtualNetworks.bicep' = { - name: '${vnetName}-${uniqueString(resourceGroup().name, location)}' - params: { - location: location - vnetName: vnetName - subnetName: subnetName - networkSecurityGroupName: networkSecurityGroupName - vnetAddressPrefix: vnetAddressPrefix - subnetAddressPrefix: subnetAddressPrefix - } -} - -resource vmss 'Microsoft.Compute/virtualMachineScaleSets@2022-03-01' = { - name: '${vmssName}-${uniqueString(resourceGroup().name, location)}' - location: location - sku: { - name: vmssSku - tier: 'Standard' - capacity: vmssInstanceCount - } - plan: locations[imageLocation].plan - properties: { - singlePlacementGroup: false - upgradePolicy: { - mode: 'Manual' - } - virtualMachineProfile: { - storageProfile: { - osDisk: { - createOption: 'FromImage' - caching: 'ReadWrite' - managedDisk: { - storageAccountType: vmssOsDiskType - } - } - imageReference: locations[imageLocation].imageReference - } - networkProfile: { - networkInterfaceConfigurations: [ - { - name: '${vmssName}Nic' - properties: { - primary: true - ipConfigurations: [ - { - name: '${vmssName}IpConfig' - properties: { - subnet: { - id: resourceId('Microsoft.Network/virtualNetworks/subnets', vnetName, subnetName) - } - } - } - ] - networkSecurityGroup: { - id: vnet.outputs.nsgID - } - } - } - ] - } - osProfile: { - computerNamePrefix: vmssName - adminUsername: administratorLogin - adminPassword: passwordAdministratorLogin - customData: customData - } - priority: 'Regular' - } - overprovision: false - } -} - -@description('Resource Id of Virtual Machine Scale Set') -output id string = vmss.id - -@description('Resource Name of Virtual Machine Scale Set') -output name string = vmss.name diff --git a/modules/compute/custom-image-vmss/main.json b/modules/compute/custom-image-vmss/main.json deleted file mode 100644 index 06fde7c959..0000000000 --- a/modules/compute/custom-image-vmss/main.json +++ /dev/null @@ -1,1102 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.19.5.34762", - "templateHash": "1275515054012573586" - }, - "name": "Azure VMSS with Custom Image", - "description": "Create an Azure VMSS Cluster with a Custom Image to simplify creation of Marketplace Applications", - "owner": "dciborow" - }, - "parameters": { - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Deployment Location" - } - }, - "vmssName": { - "type": "string", - "metadata": { - "description": "Name of VMSS Cluster" - } - }, - "vmssSku": { - "type": "string", - "defaultValue": "Standard_D4ds_v4", - "metadata": { - "description": "GameDev Sku" - } - }, - "vmssImgPublisher": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Image Publisher" - } - }, - "vmssImgProduct": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Image Product Id" - } - }, - "vmssImgSku": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Image Sku" - } - }, - "vmssImgVersion": { - "type": "string", - "defaultValue": "latest", - "metadata": { - "description": "GameDev Image Product Id" - } - }, - "vmssOsDiskType": { - "type": "string", - "defaultValue": "Premium_LRS", - "metadata": { - "description": "GameDev Disk Type" - } - }, - "vmssInstanceCount": { - "type": "int", - "defaultValue": 1, - "minValue": 1, - "maxValue": 100, - "metadata": { - "description": "VMSS Instance Count" - } - }, - "administratorLogin": { - "type": "string", - "metadata": { - "description": "Administrator Login for access" - } - }, - "passwordAdministratorLogin": { - "type": "securestring", - "metadata": { - "description": "Administrator Password for access" - } - }, - "vnetName": { - "type": "string", - "defaultValue": "[format('vnet-{0}', parameters('vmssName'))]", - "metadata": { - "description": "Virtual Network Resource Name" - } - }, - "subnetName": { - "type": "string", - "defaultValue": "[format('subnet{0}', parameters('vmssName'))]", - "metadata": { - "description": "Virtual Network Subnet Name" - } - }, - "networkSecurityGroupName": { - "type": "string", - "defaultValue": "[format('nsg-{0}', parameters('vmssName'))]", - "metadata": { - "description": "Virtual Network Security Group Name" - } - }, - "vnetAddressPrefix": { - "type": "string", - "defaultValue": "172.17.72.0/24", - "metadata": { - "description": "Virtual Network Address Prefix" - } - }, - "subnetAddressPrefix": { - "type": "string", - "defaultValue": "172.17.72.0/25", - "metadata": { - "description": "Virtual Network Subnet Address Prefix" - } - }, - "imageLocation": { - "type": "string", - "defaultValue": "marketplace", - "metadata": { - "description": "Parameter used for debugging with trail offer" - }, - "allowedValues": [ - "gallery", - "marketplace" - ] - }, - "communityGalleryImageId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Pointer to community gallery image. Example: /CommunityGalleries//Images//Versions/" - } - }, - "customData": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Base64 Encoded string to provide to VMSS for configuration" - } - } - }, - "variables": { - "locations": { - "gallery": { - "plan": null, - "imageReference": { - "communityGalleryImageId": "[parameters('communityGalleryImageId')]" - } - }, - "marketplace": { - "plan": { - "name": "[parameters('vmssImgSku')]", - "publisher": "[parameters('vmssImgPublisher')]", - "product": "[parameters('vmssImgProduct')]" - }, - "imageReference": { - "publisher": "[parameters('vmssImgPublisher')]", - "offer": "[parameters('vmssImgProduct')]", - "sku": "[parameters('vmssImgSku')]", - "version": "[parameters('vmssImgVersion')]" - } - } - } - }, - "resources": [ - { - "type": "Microsoft.Compute/virtualMachineScaleSets", - "apiVersion": "2022-03-01", - "name": "[format('{0}-{1}', parameters('vmssName'), uniqueString(resourceGroup().name, parameters('location')))]", - "location": "[parameters('location')]", - "sku": { - "name": "[parameters('vmssSku')]", - "tier": "Standard", - "capacity": "[parameters('vmssInstanceCount')]" - }, - "plan": "[variables('locations')[parameters('imageLocation')].plan]", - "properties": { - "singlePlacementGroup": false, - "upgradePolicy": { - "mode": "Manual" - }, - "virtualMachineProfile": { - "storageProfile": { - "osDisk": { - "createOption": "FromImage", - "caching": "ReadWrite", - "managedDisk": { - "storageAccountType": "[parameters('vmssOsDiskType')]" - } - }, - "imageReference": "[variables('locations')[parameters('imageLocation')].imageReference]" - }, - "networkProfile": { - "networkInterfaceConfigurations": [ - { - "name": "[format('{0}Nic', parameters('vmssName'))]", - "properties": { - "primary": true, - "ipConfigurations": [ - { - "name": "[format('{0}IpConfig', parameters('vmssName'))]", - "properties": { - "subnet": { - "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('subnetName'))]" - } - } - } - ], - "networkSecurityGroup": { - "id": "[reference(resourceId('Microsoft.Resources/deployments', format('{0}-{1}', parameters('vnetName'), uniqueString(resourceGroup().name, parameters('location')))), '2022-09-01').outputs.nsgID.value]" - } - } - } - ] - }, - "osProfile": { - "computerNamePrefix": "[parameters('vmssName')]", - "adminUsername": "[parameters('administratorLogin')]", - "adminPassword": "[parameters('passwordAdministratorLogin')]", - "customData": "[parameters('customData')]" - }, - "priority": "Regular" - }, - "overprovision": false - }, - "dependsOn": [ - "[resourceId('Microsoft.Resources/deployments', format('{0}-{1}', parameters('vnetName'), uniqueString(resourceGroup().name, parameters('location'))))]" - ] - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-{1}', parameters('vnetName'), uniqueString(resourceGroup().name, parameters('location')))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "location": { - "value": "[parameters('location')]" - }, - "vnetName": { - "value": "[parameters('vnetName')]" - }, - "subnetName": { - "value": "[parameters('subnetName')]" - }, - "networkSecurityGroupName": { - "value": "[parameters('networkSecurityGroupName')]" - }, - "vnetAddressPrefix": { - "value": "[parameters('vnetAddressPrefix')]" - }, - "subnetAddressPrefix": { - "value": "[parameters('subnetAddressPrefix')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.19.5.34762", - "templateHash": "10388055362477215042" - } - }, - "parameters": { - "location": { - "type": "string" - }, - "vnetAddressPrefix": { - "type": "string" - }, - "subnetAddressPrefix": { - "type": "string" - }, - "vnetName": { - "type": "string" - }, - "subnetName": { - "type": "string" - }, - "networkSecurityGroupName": { - "type": "string" - } - }, - "resources": [ - { - "type": "Microsoft.Network/networkSecurityGroups", - "apiVersion": "2021-08-01", - "name": "[parameters('networkSecurityGroupName')]", - "location": "[parameters('location')]" - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-minvnet', uniqueString(deployment().name, 'WestEurope'))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "location": { - "value": "[parameters('location')]" - }, - "name": { - "value": "[parameters('vnetName')]" - }, - "subnets": { - "value": [ - { - "name": "[parameters('subnetName')]", - "addressPrefix": "[parameters('subnetAddressPrefix')]", - "networkSecurityGroup": { - "id": "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('networkSecurityGroupName'))]" - } - } - ] - }, - "addressPrefixes": { - "value": [ - "[parameters('vnetAddressPrefix')]" - ] - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.9.1.41621", - "templateHash": "10893164274897986397" - } - }, - "parameters": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The Virtual Network (vNet) Name." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. Location for all resources." - } - }, - "addressPrefixes": { - "type": "array", - "metadata": { - "description": "Required. An Array of 1 or more IP Address Prefixes for the Virtual Network." - } - }, - "subnets": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. An Array of subnets to deploy to the Virtual Network." - } - }, - "dnsServers": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. DNS Servers associated to the Virtual Network." - } - }, - "ddosProtectionPlanId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Resource ID of the DDoS protection plan to assign the VNET to. If it's left blank, DDoS protection will not be configured. If it's provided, the VNET created by this template will be attached to the referenced DDoS protection plan. The DDoS protection plan can exist in the same or in a different subscription." - } - }, - "virtualNetworkPeerings": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. Virtual Network Peerings configurations" - } - }, - "diagnosticLogsRetentionInDays": { - "type": "int", - "defaultValue": 365, - "maxValue": 365, - "minValue": 0, - "metadata": { - "description": "Optional. Specifies the number of days that logs will be kept for; a value of 0 will retain data indefinitely." - } - }, - "diagnosticStorageAccountId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Resource ID of the diagnostic storage account." - } - }, - "diagnosticWorkspaceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Resource ID of the diagnostic log analytics workspace." - } - }, - "diagnosticEventHubAuthorizationRuleId": { - "type": "string", - "defaultValue": "", - "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." - } - }, - "diagnosticEventHubName": { - "type": "string", - "defaultValue": "", - "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." - } - }, - "lock": { - "type": "string", - "defaultValue": "NotSpecified", - "metadata": { - "description": "Optional. Specify the type of lock." - }, - "allowedValues": [ - "CanNotDelete", - "NotSpecified", - "ReadOnly" - ] - }, - "roleAssignments": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'" - } - }, - "tags": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Optional. Tags of the resource." - } - }, - "logsToEnable": { - "type": "array", - "defaultValue": [ - "VMProtectionAlerts" - ], - "allowedValues": [ - "VMProtectionAlerts" - ], - "metadata": { - "description": "Optional. The name of logs that will be streamed." - } - }, - "metricsToEnable": { - "type": "array", - "defaultValue": [ - "AllMetrics" - ], - "allowedValues": [ - "AllMetrics" - ], - "metadata": { - "description": "Optional. The name of metrics that will be streamed." - } - } - }, - "variables": { - "copy": [ - { - "name": "diagnosticsLogs", - "count": "[length(parameters('logsToEnable'))]", - "input": { - "category": "[parameters('logsToEnable')[copyIndex('diagnosticsLogs')]]", - "enabled": true, - "retentionPolicy": { - "enabled": true, - "days": "[parameters('diagnosticLogsRetentionInDays')]" - } - } - }, - { - "name": "diagnosticsMetrics", - "count": "[length(parameters('metricsToEnable'))]", - "input": { - "category": "[parameters('metricsToEnable')[copyIndex('diagnosticsMetrics')]]", - "timeGrain": null, - "enabled": true, - "retentionPolicy": { - "enabled": true, - "days": "[parameters('diagnosticLogsRetentionInDays')]" - } - } - } - ], - "dnsServers_var": { - "dnsServers": "[array(parameters('dnsServers'))]" - }, - "ddosProtectionPlan": { - "id": "[parameters('ddosProtectionPlanId')]" - } - }, - "resources": [ - { - "type": "Microsoft.Network/virtualNetworks", - "apiVersion": "2021-05-01", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "properties": { - "copy": [ - { - "name": "subnets", - "count": "[length(parameters('subnets'))]", - "input": { - "name": "[parameters('subnets')[copyIndex('subnets')].name]", - "properties": { - "addressPrefix": "[parameters('subnets')[copyIndex('subnets')].addressPrefix]", - "addressPrefixes": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'addressPrefixes'), parameters('subnets')[copyIndex('subnets')].addressPrefixes, createArray())]", - "applicationGatewayIpConfigurations": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'applicationGatewayIpConfigurations'), parameters('subnets')[copyIndex('subnets')].applicationGatewayIpConfigurations, createArray())]", - "delegations": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'delegations'), parameters('subnets')[copyIndex('subnets')].delegations, createArray())]", - "ipAllocations": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'ipAllocations'), parameters('subnets')[copyIndex('subnets')].ipAllocations, createArray())]", - "natGateway": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'natGatewayId'), createObject('id', parameters('subnets')[copyIndex('subnets')].natGatewayId), json('null'))]", - "networkSecurityGroup": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'networkSecurityGroupId'), createObject('id', parameters('subnets')[copyIndex('subnets')].networkSecurityGroupId), json('null'))]", - "privateEndpointNetworkPolicies": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'privateEndpointNetworkPolicies'), parameters('subnets')[copyIndex('subnets')].privateEndpointNetworkPolicies, null())]", - "privateLinkServiceNetworkPolicies": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'privateLinkServiceNetworkPolicies'), parameters('subnets')[copyIndex('subnets')].privateLinkServiceNetworkPolicies, null())]", - "routeTable": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'routeTableId'), createObject('id', parameters('subnets')[copyIndex('subnets')].routeTableId), json('null'))]", - "serviceEndpoints": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'serviceEndpoints'), parameters('subnets')[copyIndex('subnets')].serviceEndpoints, createArray())]", - "serviceEndpointPolicies": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'serviceEndpointPolicies'), parameters('subnets')[copyIndex('subnets')].serviceEndpointPolicies, createArray())]" - } - } - } - ], - "addressSpace": { - "addressPrefixes": "[parameters('addressPrefixes')]" - }, - "ddosProtectionPlan": "[if(not(empty(parameters('ddosProtectionPlanId'))), variables('ddosProtectionPlan'), null())]", - "dhcpOptions": "[if(not(empty(parameters('dnsServers'))), variables('dnsServers_var'), null())]", - "enableDdosProtection": "[not(empty(parameters('ddosProtectionPlanId')))]" - } - }, - { - "condition": "[not(equals(parameters('lock'), 'NotSpecified'))]", - "type": "Microsoft.Authorization/locks", - "apiVersion": "2017-04-01", - "scope": "[format('Microsoft.Network/virtualNetworks/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", - "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/virtualNetworks', parameters('name'))]" - ] - }, - { - "condition": "[or(or(or(not(empty(parameters('diagnosticStorageAccountId'))), not(empty(parameters('diagnosticWorkspaceId')))), not(empty(parameters('diagnosticEventHubAuthorizationRuleId')))), not(empty(parameters('diagnosticEventHubName'))))]", - "type": "Microsoft.Insights/diagnosticSettings", - "apiVersion": "2021-05-01-preview", - "scope": "[format('Microsoft.Network/virtualNetworks/{0}', parameters('name'))]", - "name": "[format('{0}-diagnosticSettings', parameters('name'))]", - "properties": { - "storageAccountId": "[if(not(empty(parameters('diagnosticStorageAccountId'))), parameters('diagnosticStorageAccountId'), null())]", - "workspaceId": "[if(not(empty(parameters('diagnosticWorkspaceId'))), parameters('diagnosticWorkspaceId'), null())]", - "eventHubAuthorizationRuleId": "[if(not(empty(parameters('diagnosticEventHubAuthorizationRuleId'))), parameters('diagnosticEventHubAuthorizationRuleId'), null())]", - "eventHubName": "[if(not(empty(parameters('diagnosticEventHubName'))), parameters('diagnosticEventHubName'), null())]", - "metrics": "[variables('diagnosticsMetrics')]", - "logs": "[variables('diagnosticsLogs')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/virtualNetworks', parameters('name'))]" - ] - }, - { - "copy": { - "name": "virtualNetwork_peering_local", - "count": "[length(parameters('virtualNetworkPeerings'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2020-10-01", - "name": "[format('{0}-virtualNetworkPeering-local-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "localVnetName": { - "value": "[parameters('name')]" - }, - "remoteVirtualNetworkId": { - "value": "[parameters('virtualNetworkPeerings')[copyIndex()].remoteVirtualNetworkId]" - }, - "name": { - "value": "[if(contains(parameters('virtualNetworkPeerings')[copyIndex()], 'name'), parameters('virtualNetworkPeerings')[copyIndex()].name, format('{0}-{1}', parameters('name'), last(split(parameters('virtualNetworkPeerings')[copyIndex()].remoteVirtualNetworkId, '/'))))]" - }, - "allowForwardedTraffic": { - "value": "[if(contains(parameters('virtualNetworkPeerings')[copyIndex()], 'allowForwardedTraffic'), parameters('virtualNetworkPeerings')[copyIndex()].allowForwardedTraffic, true())]" - }, - "allowGatewayTransit": { - "value": "[if(contains(parameters('virtualNetworkPeerings')[copyIndex()], 'allowGatewayTransit'), parameters('virtualNetworkPeerings')[copyIndex()].allowGatewayTransit, false())]" - }, - "allowVirtualNetworkAccess": { - "value": "[if(contains(parameters('virtualNetworkPeerings')[copyIndex()], 'allowVirtualNetworkAccess'), parameters('virtualNetworkPeerings')[copyIndex()].allowVirtualNetworkAccess, true())]" - }, - "doNotVerifyRemoteGateways": { - "value": "[if(contains(parameters('virtualNetworkPeerings')[copyIndex()], 'doNotVerifyRemoteGateways'), parameters('virtualNetworkPeerings')[copyIndex()].doNotVerifyRemoteGateways, true())]" - }, - "useRemoteGateways": { - "value": "[if(contains(parameters('virtualNetworkPeerings')[copyIndex()], 'useRemoteGateways'), parameters('virtualNetworkPeerings')[copyIndex()].useRemoteGateways, false())]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.9.1.41621", - "templateHash": "7913383313645172292" - } - }, - "parameters": { - "name": { - "type": "string", - "defaultValue": "[format('{0}-{1}', parameters('localVnetName'), last(split(parameters('remoteVirtualNetworkId'), '/')))]", - "metadata": { - "description": "Optional. The Name of Vnet Peering resource. If not provided, default value will be localVnetName-remoteVnetName" - } - }, - "localVnetName": { - "type": "string", - "metadata": { - "description": "Required. The Name of the Virtual Network to add the peering to." - } - }, - "remoteVirtualNetworkId": { - "type": "string", - "metadata": { - "description": "Required. The Resource ID of the VNet that is this Local VNet is being peered to. Should be in the format of a Resource ID" - } - }, - "allowForwardedTraffic": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Whether the forwarded traffic from the VMs in the local virtual network will be allowed/disallowed in remote virtual network. Default is true" - } - }, - "allowGatewayTransit": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. If gateway links can be used in remote virtual networking to link to this virtual network. Default is false" - } - }, - "allowVirtualNetworkAccess": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Whether the VMs in the local virtual network space would be able to access the VMs in remote virtual network space. Default is true" - } - }, - "doNotVerifyRemoteGateways": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. If we need to verify the provisioning state of the remote gateway. Default is true" - } - }, - "useRemoteGateways": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. If remote gateways can be used on this virtual network. If the flag is set to true, and allowGatewayTransit on remote peering is also true, virtual network will use gateways of remote virtual network for transit. Only one peering can have this flag set to true. This flag cannot be set if virtual network already has a gateway. Default is false" - } - } - }, - "resources": [ - { - "type": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings", - "apiVersion": "2022-01-01", - "name": "[format('{0}/{1}', parameters('localVnetName'), parameters('name'))]", - "properties": { - "allowForwardedTraffic": "[parameters('allowForwardedTraffic')]", - "allowGatewayTransit": "[parameters('allowGatewayTransit')]", - "allowVirtualNetworkAccess": "[parameters('allowVirtualNetworkAccess')]", - "doNotVerifyRemoteGateways": "[parameters('doNotVerifyRemoteGateways')]", - "useRemoteGateways": "[parameters('useRemoteGateways')]", - "remoteVirtualNetwork": { - "id": "[parameters('remoteVirtualNetworkId')]" - } - } - } - ], - "outputs": { - "resourceGroupName": { - "type": "string", - "value": "[resourceGroup().name]", - "metadata": { - "description": "The resource group the virtual network peering was deployed into" - } - }, - "name": { - "type": "string", - "value": "[parameters('name')]", - "metadata": { - "description": "The name of the virtual network peering" - } - }, - "resourceId": { - "type": "string", - "value": "[resourceId('Microsoft.Network/virtualNetworks/virtualNetworkPeerings', parameters('localVnetName'), parameters('name'))]", - "metadata": { - "description": "The resource ID of the virtual network peering" - } - } - } - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/virtualNetworks', parameters('name'))]" - ] - }, - { - "condition": "[if(contains(parameters('virtualNetworkPeerings')[copyIndex()], 'remotePeeringEnabled'), equals(parameters('virtualNetworkPeerings')[copyIndex()].remotePeeringEnabled, true()), false())]", - "copy": { - "name": "virtualNetwork_peering_remote", - "count": "[length(parameters('virtualNetworkPeerings'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2020-10-01", - "name": "[format('{0}-virtualNetworkPeering-remote-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "subscriptionId": "[split(parameters('virtualNetworkPeerings')[copyIndex()].remoteVirtualNetworkId, '/')[2]]", - "resourceGroup": "[split(parameters('virtualNetworkPeerings')[copyIndex()].remoteVirtualNetworkId, '/')[4]]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "localVnetName": { - "value": "[last(split(parameters('virtualNetworkPeerings')[copyIndex()].remoteVirtualNetworkId, '/'))]" - }, - "remoteVirtualNetworkId": { - "value": "[resourceId('Microsoft.Network/virtualNetworks', parameters('name'))]" - }, - "name": { - "value": "[if(contains(parameters('virtualNetworkPeerings')[copyIndex()], 'remotePeeringName'), parameters('virtualNetworkPeerings')[copyIndex()].remotePeeringName, format('{0}-{1}', last(split(parameters('virtualNetworkPeerings')[copyIndex()].remoteVirtualNetworkId, '/')), parameters('name')))]" - }, - "allowForwardedTraffic": { - "value": "[if(contains(parameters('virtualNetworkPeerings')[copyIndex()], 'remotePeeringAllowForwardedTraffic'), parameters('virtualNetworkPeerings')[copyIndex()].remotePeeringAllowForwardedTraffic, true())]" - }, - "allowGatewayTransit": { - "value": "[if(contains(parameters('virtualNetworkPeerings')[copyIndex()], 'remotePeeringAllowGatewayTransit'), parameters('virtualNetworkPeerings')[copyIndex()].remotePeeringAllowGatewayTransit, false())]" - }, - "allowVirtualNetworkAccess": { - "value": "[if(contains(parameters('virtualNetworkPeerings')[copyIndex()], 'remotePeeringAllowVirtualNetworkAccess'), parameters('virtualNetworkPeerings')[copyIndex()].remotePeeringAllowVirtualNetworkAccess, true())]" - }, - "doNotVerifyRemoteGateways": { - "value": "[if(contains(parameters('virtualNetworkPeerings')[copyIndex()], 'remotePeeringDoNotVerifyRemoteGateways'), parameters('virtualNetworkPeerings')[copyIndex()].remotePeeringDoNotVerifyRemoteGateways, true())]" - }, - "useRemoteGateways": { - "value": "[if(contains(parameters('virtualNetworkPeerings')[copyIndex()], 'remotePeeringUseRemoteGateways'), parameters('virtualNetworkPeerings')[copyIndex()].remotePeeringUseRemoteGateways, false())]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.9.1.41621", - "templateHash": "7913383313645172292" - } - }, - "parameters": { - "name": { - "type": "string", - "defaultValue": "[format('{0}-{1}', parameters('localVnetName'), last(split(parameters('remoteVirtualNetworkId'), '/')))]", - "metadata": { - "description": "Optional. The Name of Vnet Peering resource. If not provided, default value will be localVnetName-remoteVnetName" - } - }, - "localVnetName": { - "type": "string", - "metadata": { - "description": "Required. The Name of the Virtual Network to add the peering to." - } - }, - "remoteVirtualNetworkId": { - "type": "string", - "metadata": { - "description": "Required. The Resource ID of the VNet that is this Local VNet is being peered to. Should be in the format of a Resource ID" - } - }, - "allowForwardedTraffic": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Whether the forwarded traffic from the VMs in the local virtual network will be allowed/disallowed in remote virtual network. Default is true" - } - }, - "allowGatewayTransit": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. If gateway links can be used in remote virtual networking to link to this virtual network. Default is false" - } - }, - "allowVirtualNetworkAccess": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Whether the VMs in the local virtual network space would be able to access the VMs in remote virtual network space. Default is true" - } - }, - "doNotVerifyRemoteGateways": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. If we need to verify the provisioning state of the remote gateway. Default is true" - } - }, - "useRemoteGateways": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. If remote gateways can be used on this virtual network. If the flag is set to true, and allowGatewayTransit on remote peering is also true, virtual network will use gateways of remote virtual network for transit. Only one peering can have this flag set to true. This flag cannot be set if virtual network already has a gateway. Default is false" - } - } - }, - "resources": [ - { - "type": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings", - "apiVersion": "2022-01-01", - "name": "[format('{0}/{1}', parameters('localVnetName'), parameters('name'))]", - "properties": { - "allowForwardedTraffic": "[parameters('allowForwardedTraffic')]", - "allowGatewayTransit": "[parameters('allowGatewayTransit')]", - "allowVirtualNetworkAccess": "[parameters('allowVirtualNetworkAccess')]", - "doNotVerifyRemoteGateways": "[parameters('doNotVerifyRemoteGateways')]", - "useRemoteGateways": "[parameters('useRemoteGateways')]", - "remoteVirtualNetwork": { - "id": "[parameters('remoteVirtualNetworkId')]" - } - } - } - ], - "outputs": { - "resourceGroupName": { - "type": "string", - "value": "[resourceGroup().name]", - "metadata": { - "description": "The resource group the virtual network peering was deployed into" - } - }, - "name": { - "type": "string", - "value": "[parameters('name')]", - "metadata": { - "description": "The name of the virtual network peering" - } - }, - "resourceId": { - "type": "string", - "value": "[resourceId('Microsoft.Network/virtualNetworks/virtualNetworkPeerings', parameters('localVnetName'), parameters('name'))]", - "metadata": { - "description": "The resource ID of the virtual network peering" - } - } - } - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/virtualNetworks', parameters('name'))]" - ] - }, - { - "copy": { - "name": "virtualNetwork_rbac", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2020-10-01", - "name": "[format('{0}-VNet-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": { - "value": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), parameters('roleAssignments')[copyIndex()].description, '')]" - }, - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "principalType": { - "value": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), parameters('roleAssignments')[copyIndex()].principalType, '')]" - }, - "resourceId": { - "value": "[resourceId('Microsoft.Network/virtualNetworks', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.9.1.41621", - "templateHash": "6570518281545653594" - } - }, - "parameters": { - "description": { - "type": "string", - "defaultValue": "" - }, - "principalIds": { - "type": "array" - }, - "principalType": { - "type": "string", - "defaultValue": "" - }, - "roleDefinitionIdOrName": { - "type": "string" - }, - "resourceId": { - "type": "string" - } - }, - "variables": { - "builtInRoleNames": { - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Metrics Publisher": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/virtualNetworks/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(last(split(parameters('resourceId'), '/')), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/virtualNetworks', parameters('name'))]" - ] - } - ], - "outputs": { - "resourceGroupName": { - "type": "string", - "value": "[resourceGroup().name]", - "metadata": { - "description": "The resource group the virtual network was deployed into" - } - }, - "resourceId": { - "type": "string", - "value": "[resourceId('Microsoft.Network/virtualNetworks', parameters('name'))]", - "metadata": { - "description": "The resource ID of the virtual network" - } - }, - "name": { - "type": "string", - "value": "[parameters('name')]", - "metadata": { - "description": "The name of the virtual network" - } - }, - "subnetNames": { - "type": "array", - "copy": { - "count": "[length(parameters('subnets'))]", - "input": "[parameters('subnets')[copyIndex()].name]" - }, - "metadata": { - "description": "The names of the deployed subnets" - } - }, - "subnetResourceIds": { - "type": "array", - "copy": { - "count": "[length(parameters('subnets'))]", - "input": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('name'), parameters('subnets')[copyIndex()].name)]" - }, - "metadata": { - "description": "The resource IDs of the deployed subnets" - } - } - } - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('networkSecurityGroupName'))]" - ] - } - ], - "outputs": { - "vnetId": { - "type": "string", - "value": "[reference(resourceId('Microsoft.Resources/deployments', format('{0}-minvnet', uniqueString(deployment().name, 'WestEurope'))), '2022-09-01').outputs.resourceId.value]" - }, - "vnet": { - "type": "string", - "value": "[reference(resourceId('Microsoft.Resources/deployments', format('{0}-minvnet', uniqueString(deployment().name, 'WestEurope'))), '2022-09-01').outputs.name.value]" - }, - "nsgID": { - "type": "string", - "value": "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('networkSecurityGroupName'))]" - }, - "subnetName": { - "type": "string", - "value": "[parameters('subnetName')]" - } - } - } - } - } - ], - "outputs": { - "id": { - "type": "string", - "metadata": { - "description": "Resource Id of Virtual Machine Scale Set" - }, - "value": "[resourceId('Microsoft.Compute/virtualMachineScaleSets', format('{0}-{1}', parameters('vmssName'), uniqueString(resourceGroup().name, parameters('location'))))]" - }, - "name": { - "type": "string", - "metadata": { - "description": "Resource Name of Virtual Machine Scale Set" - }, - "value": "[format('{0}-{1}', parameters('vmssName'), uniqueString(resourceGroup().name, parameters('location')))]" - } - } -} \ No newline at end of file diff --git a/modules/compute/custom-image-vmss/modules/virtualNetworks.bicep b/modules/compute/custom-image-vmss/modules/virtualNetworks.bicep deleted file mode 100644 index b69153ad8c..0000000000 --- a/modules/compute/custom-image-vmss/modules/virtualNetworks.bicep +++ /dev/null @@ -1,35 +0,0 @@ -param location string -param vnetAddressPrefix string -param subnetAddressPrefix string -param vnetName string -param subnetName string -param networkSecurityGroupName string - -//By Default the nsg will allow the vnet access and deny all other access -resource networkSecurityGroup 'Microsoft.Network/networkSecurityGroups@2021-08-01' = { - name: networkSecurityGroupName - location: location -} - -module minvnet 'br/public:network/virtual-network:1.0.3' = { - name: '${uniqueString(deployment().name, 'WestEurope')}-minvnet' - params: { - location: location - name: vnetName - subnets: [ - { - name: subnetName - addressPrefix: subnetAddressPrefix - networkSecurityGroup: { - id: networkSecurityGroup.id - } - } - ] - addressPrefixes: [vnetAddressPrefix] - } -} - -output vnetId string = minvnet.outputs.resourceId -output vnet string = minvnet.outputs.name -output nsgID string = networkSecurityGroup.id -output subnetName string = subnetName diff --git a/modules/compute/custom-image-vmss/test/imageConfig.json b/modules/compute/custom-image-vmss/test/imageConfig.json deleted file mode 100644 index 5a9db3ec9e..0000000000 --- a/modules/compute/custom-image-vmss/test/imageConfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "scylla_yaml": { - "cluster_name": "azure_test", - "experimental": "True", - "auto_bootstrap": "True", - "seed_provider": [{"class_name": "org.apache.cassandra.locator.SimpleSeedProvider", - "parameters": [{"seeds": "172.17.0.5"}]}], - "auto_snapshot": "False" - }, - "developer_mode": "True" -} \ No newline at end of file diff --git a/modules/compute/custom-image-vmss/test/main.test.bicep b/modules/compute/custom-image-vmss/test/main.test.bicep deleted file mode 100644 index f32d88aa22..0000000000 --- a/modules/compute/custom-image-vmss/test/main.test.bicep +++ /dev/null @@ -1,23 +0,0 @@ -/* -Write deployment tests in this file. Any module that references the main -module file is a deployment test. Make sure at least one test is added. -*/ -@description('Deployment Location') -param location string = 'eastus' - -var communityGalleryImageId = '/CommunityGalleries/scylladb-7e8d8a04-23db-487d-87ec-0e175c0615bb/Images/scylla-enterprise-2023.1' - -var customData = loadFileAsBase64('imageConfig.json') - -module test1 '../main.bicep' = { - name: 'Test1' - params: { - location: location - administratorLogin: uniqueString(resourceGroup().name) - passwordAdministratorLogin: guid(resourceGroup().name) - vmssName: uniqueString(resourceGroup().name) - communityGalleryImageId: communityGalleryImageId - customData: customData - imageLocation: 'gallery' - } -} diff --git a/modules/compute/custom-image-vmss/version.json b/modules/compute/custom-image-vmss/version.json deleted file mode 100644 index e40897e287..0000000000 --- a/modules/compute/custom-image-vmss/version.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "1.0", - "pathFilters": [ - "./main.json", - "./metadata.json" - ] -} \ No newline at end of file diff --git a/modules/compute/event-hub/README.md b/modules/compute/event-hub/README.md deleted file mode 100644 index 860c44bb6f..0000000000 --- a/modules/compute/event-hub/README.md +++ /dev/null @@ -1,269 +0,0 @@ -# Azure Event-Hub - -This module deploys Microsoft.data event clusters, event namespaces, event hubs and associated configurations. - -## Details - -[Azure Event Hubs](https://azure.microsoft.com/en-us/products/event-hubs/) is a fully managed, real-time data ingestion service that’s simple, trusted, and scalable. This module provides an Infrastructure as Code alternative for management of Azure event hubs using Bicep, and is intended to mirror the available functionality of provisioning with Azure Portal or CLI. - -## Parameters - -| Name | Type | Required | Description | -| :--------------------------------- | :------: | :------: | :---------------------------------------------------------------------------------------------------------------------------- | -| `clusterName` | `string` | No | Optional. Name for the Event Hub cluster, Alphanumerics and hyphens characters, Start with letter, End with letter or number. | -| `clusterCapacity` | `int` | No | Optional. The quantity of Event Hubs Cluster Capacity Units contained in this cluster. | -| `location` | `string` | No | Required. Location for all resources. | -| `tags` | `object` | No | Optional. Tags of the resource. | -| `namespaces` | `array` | No | Required. The list of the event hub namespaces with its configurations to be created. | -| `namespaceAuthorizationRules` | `array` | No | Optional. Authorization Rules for the Event Hub Namespace. | -| `namespaceRoleAssignments` | `array` | No | Optional. Role assignments for the namespace. | -| `namespaceDisasterRecoveryConfigs` | `array` | No | Optional. The disaster recovery config for the namespace. | -| `namespaceDiagnosticSettings` | `array` | No | Optional. The Diagnostics Settings config for the namespace. | -| `eventHubs` | `array` | No | Optional. Name for the eventhub with its all configurations to be created. | -| `eventHubAuthorizationRules` | `array` | No | Optional. Authorization Rules for the Event Hub . | -| `eventHubConsumerGroups` | `array` | No | Optional. consumer groups for the Event Hub . | -| `namespacePrivateEndpoints` | `array` | No | Private Endpoints that should be created for Azure EventHub Namespaces. | - -## Outputs - -| Name | Type | Description | -| :----------------------------- | :-----: | :-------------------------------------- | -| `eventHubNamespaceNames` | `array` | Azure Event Hub namespace names. | -| `eventHubNamespaceResourceIds` | `array` | Azure Event Hub namespace resource Ids. | - -## Examples - -### Example 1 - -```bicep -module evh 'br/public:compute/event-hub:2.0.2' = { - name: 'evh-${uniqueString(deployment().name, 'eastus2')}' - params: { - location: 'eastus2' - clusterName: 'evhcluster1' - clusterCapacity: 2 - namespaces: [ - { - name: 'testns1' - capacity: 2 - isAutoInflateEnabled: true - maximumThroughputUnits: 6 - zoneRedundant: true - publicNetworkAccess: false - } - { - name: 'testns2' - sku: 'Basic' - } - ] - namespaceAuthorizationRules: [ - { - name: 'authrule01' - rights: [ 'Listen', 'Manage', 'Send' ] - namespaceName: 'testns1' - } - { - name: 'authrule02' - rights: [ 'Listen' ] - namespaceName: 'testns1' - } - ] - eventHubs: [ - { - name: 'evh1' - messageRetentionInDays: 4 - partitionCount: 4 - namespaceName: 'testns1' - } - { - name: 'evh2' - messageRetentionInDays: 7 - partitionCount: 2 - namespaceName: 'testns1' - } - ] - eventHubAuthorizationRules: [ - { - name: 'evh-rule01' - rights: [ 'Listen', 'Manage', 'Send' ] - namespaceName: 'testns1' - eventHubName: 'evh1' - } - ] - eventHubConsumerGroups: [ - { - name: 'cg01' - namespaceName: 'testns1' - eventHubName: 'evh1' - } - ] - tags: { - tag1: 'tag1value' - tag2: 'tag2value' - } - } -} -``` - -### Example 2 - -```bicep -module evhns 'br/public:compute/event-hub:2.0.2' = { - name: 'evhns-${uniqueString(deployment().name, 'eastus')}' - params: { - location: 'eastus' - namespaces: [ - { - name: 'testns' - sku: 'Premium' - capacity: 2 - zoneRedundant: true - } - ] - namespaceRoleAssignments: [ - { - name: 'rol01' - description: 'Reader Role Assignment' - principalIds: [ '30ec80f4-43d7-1280-99ba-2571db1cc45b' ] - principalType: 'ServicePrincipal' - roleDefinitionIdOrName: 'f526a384-b230-433a-b45c-95f59c4a2dec' // Azure Event Hubs Data Owner - namespaceName: 'testns' - } - ] - eventHubs: [ - { - name: 'evh' - messageRetentionInDays: 1 - partitionCount: 1 - namespaceName: 'testns' - roleAssignments: [ - { - name: 'role01' - roleDefinitionIdOrName: 'Contributor' - description: 'Contributor Role Assignment' - principalIds: [ '10ec80f4-43d7-1280-99aa-2571db1cc45b' ] - principalType: 'ServicePrincipal' - } - ] - } - ] - } -} -``` - -### Example 3 - -```bicep -module evhns 'br/public:compute/event-hub:2.0.2' = { - name: 'evhns-${uniqueString(deployment().name, 'eastus')}' - params: { - location: 'eastus' - namespaces: [ - { - name: 'testns3' - sku: 'Standard' - capacity: 4 - publicNetworkAccess: 'Disabled' - } - ] - namespacePrivateEndpoints: [ - { - name: 'endpoint1' - subnetId: dependencies.outputs.subnetIds[0] - namespaceName: 'testns3' - manualApprovalEnabled: true - } - { - name: 'endpoint2' - subnetId: dependencies.outputs.subnetIds[1] - privateDnsZoneId: dependencies.outputs.privateDNSZoneId - namespaceName: 'testns3' - } - ] - namespaceDiagnosticSettings: [ - { - name: 'testds' - namespaceName: 'testns3' - eventHubAuthorizationRuleId: < external evenetHub authorizationRuleId > - eventHubName: < external eventHub name - metricsSettings: [ - { - category: 'AllMetrics' - timeGrain: 'PT1M' - enabled: true - retentionPolicy: { - days: 7 - enabled: true - } - } - ] - logsSettings: [ - { - category: 'OperationalLogs' - enabled: true - retentionPolicy: { - days: 36 - enabled: true - } - } - { - category: 'ArchiveLogs' - enabled: true - } - ] - } - ] - } -} -``` - -### Example 4 - -```bicep -module eventhubnamespace 'br/public:compute/event-hub:2.0.2' = { - name: 'evhns-${uniqueString(deployment().name, 'eastus')}' - params: { - location: 'eastus' - namespaces: [ - { - name: 'testns4' - sku: 'Standard' - capacity: 1 - zoneRedundant: false - } - ] - eventHubs: [ - { - name: 'testevh' - messageRetentionInDays: 1 - partitionCount: 2 - namespaceName: 'testns4' - captureDescriptionEnabled: true - captureDescriptionDestinationBlobContainer: << external storageAccount blob container name >> - captureDescriptionDestinationStorageAccountResourceId: << external storageAccount Id >> - } - ] - namespaceDiagnosticSettings: [ - { - name: 'ds' - namespaceName: 'testns4' - storageAccountId: << external storageAccount Id >> - workspaceId: << external long analytics workspace Id >> - metricsSettings: [ { category: 'AllMetrics', enabled: true, retentionPolicy: { days: 365, enabled: true } } ] - logsSettings: [ - { - category: 'ArchiveLogs' - enabled: true - retentionPolicy: { days: 7, enabled: true } - } - { - category: 'RuntimeAuditLogs' - enabled: true - retentionPolicy: { days: 3, enabled: true } - } - ] - } - ] - } -} -``` \ No newline at end of file diff --git a/modules/compute/event-hub/bicepconfig.json b/modules/compute/event-hub/bicepconfig.json deleted file mode 100644 index 763ace4e09..0000000000 --- a/modules/compute/event-hub/bicepconfig.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "experimentalFeaturesEnabled": { - "userDefinedTypes": true - } -} \ No newline at end of file diff --git a/modules/compute/event-hub/main.bicep b/modules/compute/event-hub/main.bicep deleted file mode 100644 index c7a7c11de6..0000000000 --- a/modules/compute/event-hub/main.bicep +++ /dev/null @@ -1,407 +0,0 @@ -metadata name = 'Azure Event-Hub' -metadata description = 'This module deploys Microsoft.data event clusters, event namespaces, event hubs and associated configurations.' -metadata owner = 'sumit-salunke' - -@description('Optional. Name for the Event Hub cluster, Alphanumerics and hyphens characters, Start with letter, End with letter or number.') -// We can not pass default variable value ''. Because it was showing The template resource '' of type 'Microsoft.EventHub/clusters' at line '1' is not valid. The name property cannot be null or empty. -param clusterName string = 'null' - -@description('Optional. The quantity of Event Hubs Cluster Capacity Units contained in this cluster.') -param clusterCapacity int = 1 - -@description('Required. Location for all resources.') -param location string = resourceGroup().location - -@description('Optional. Tags of the resource.') -param tags object = {} - -@description('Required. The list of the event hub namespaces with its configurations to be created.') -param namespaces namespacesType[] = [ - { - name: 'evhns001' - sku: 'Standard' - capacity: 1 - disableLocalAuth: false - kafkaEnabled: true - isAutoInflateEnabled: false - maximumThroughputUnits: 0 - zoneRedundant: false - minimumTlsVersion: '1.2' - publicNetworkAccess: 'Enabled' - } -] - -@description('Optional. Authorization Rules for the Event Hub Namespace.') -param namespaceAuthorizationRules authorizationRulesType[] = [] - -@description('Optional. Role assignments for the namespace.') -param namespaceRoleAssignments namespaceRoleAssignmentsType[] = [] - -@description('Optional. The disaster recovery config for the namespace.') -param namespaceDisasterRecoveryConfigs namespaceDisasterRecoveryConfigsType[] = [] - -@description('Optional. The Diagnostics Settings config for the namespace.') -param namespaceDiagnosticSettings namespaceDiagnosticSettingsType[] = [] - -@description('Optional. Name for the eventhub with its all configurations to be created.') -param eventHubs eventHubsType[] = [] - -@description('Optional. Authorization Rules for the Event Hub .') -param eventHubAuthorizationRules authorizationRulesType[] = [] - -@description('Optional. consumer groups for the Event Hub .') -param eventHubConsumerGroups eventHubConsumerGroupsType[] = [] - -@description('Private Endpoints that should be created for Azure EventHub Namespaces.') -param namespacePrivateEndpoints privateEndpointType[] = [] - -resource cluster 'Microsoft.EventHub/clusters@2022-10-01-preview' = if (clusterName != 'null') { - name: clusterName - location: location - tags: tags - sku: { - name: 'Dedicated' - capacity: clusterCapacity - } -} - -resource evhns 'Microsoft.EventHub/namespaces@2022-10-01-preview' = [for ns in namespaces: { - name: ns.name - location: location - sku: { - name: ns.?sku ?? 'Standard' - capacity: ns.?capacity ?? 1 - } - properties: { - disableLocalAuth: ns.?disableLocalAuth ?? false - kafkaEnabled: ns.?kafkaEnabled ?? true - isAutoInflateEnabled: ns.?isAutoInflateEnabled ?? false - maximumThroughputUnits: ns.?maximumThroughputUnits ?? 0 - zoneRedundant: ns.?zoneRedundant ?? false - clusterArmId: (clusterName != 'null') ? cluster.id : null - minimumTlsVersion: ns.?minimumTlsVersion ?? '1.2' - publicNetworkAccess: ns.?publicNetworkAccess ?? 'Enabled' - } - tags: tags -}] - -module evhns_authorizationRules 'modules/authorizationRule.bicep' = [for (rule, index) in namespaceAuthorizationRules: { - name: '${uniqueString(deployment().name, location)}-evhns-authrule-${index}' - params: { - name: rule.name - rights: rule.rights - namespaceName: rule.namespaceName - } - dependsOn: [ - evhns - ] -}] - -module evhns_roleAssignments 'modules/roleAssignment.bicep' = [for (role, index) in namespaceRoleAssignments: { - name: '${deployment().name}-evhns-role-${index}' - params: { - roleName: role.?name ?? '' - description: role.?description ?? '' - principalIds: role.principalIds - principalType: role.?principalType ?? '' - roleDefinitionIdOrName: role.roleDefinitionIdOrName - namespaceName: role.namespaceName - } - dependsOn: [ - evhns - ] -}] - -module evhns_disasterRecoveryConfigs 'modules/disasterRecoveryConfig.bicep' = [for (drConfig, index) in namespaceDisasterRecoveryConfigs: { - name: '${uniqueString(deployment().name, location)}-evhns-drconfig-${index}' - params: { - name: drConfig.name - partnerNamespaceId: drConfig.partnerNamespaceId - namespaceName: drConfig.namespaceName - } - dependsOn: [ - evhns - ] -}] - -module evh 'modules/eventHub/eventHub.bicep' = [for (evh, index) in eventHubs: { - name: '${uniqueString(deployment().name, location)}-evh-${index}' - params: { - namespaceName: evh.namespaceName - name: evh.name - messageRetentionInDays: evh.?messageRetentionInDays ?? 1 - partitionCount: evh.?partitionCount ?? 2 - status: evh.?status ?? 'Active' - captureDescriptionEnabled: evh.?captureDescriptionEnabled ?? false - captureDescriptionEncoding: evh.?captureDescriptionEncoding ?? 'Avro' - captureDescriptionIntervalInSeconds: evh.?captureDescriptionIntervalInSeconds ?? 300 - captureDescriptionSizeLimitInBytes: evh.?captureDescriptionSizeLimitInBytes ?? 314572800 - captureDescriptionSkipEmptyArchives: evh.?captureDescriptionSkipEmptyArchives ?? false - captureDescriptionDestinationName: evh.?captureDescriptionDestinationName ?? 'EventHubArchive.AzureBlockBlob' - captureDescriptionDestinationArchiveNameFormat: evh.?captureDescriptionDestinationArchiveNameFormat ?? '{Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}' - captureDescriptionDestinationBlobContainer: evh.?captureDescriptionDestinationBlobContainer ?? '' - captureDescriptionDestinationStorageAccountResourceId: evh.?captureDescriptionDestinationStorageAccountResourceId ?? '' - captureDescriptionDestinationdataLakeAccountName: evh.?captureDescriptionDestinationdataLakeAccountName ?? '' - captureDescriptionDestinationdataLakeFolderPath: evh.?captureDescriptionDestinationdataLakeFolderPath ?? '' - captureDescriptionDestinationdataLakeSubscriptionId: evh.?captureDescriptionDestinationdataLakeSubscriptionId ?? '' - roleAssignments: evh.?roleAssignments ?? [] - } - dependsOn: [ - evhns - ] -}] - -module evh_authorizationRules 'modules/eventHub/authorizationRule.bicep' = [for (rule, index) in eventHubAuthorizationRules: { - name: '${uniqueString(deployment().name, location)}-evh-authrule-${index}' - params: { - namespaceName: rule.namespaceName - eventHubName: rule.eventHubName - name: rule.name - rights: rule.rights - } - dependsOn: [ - evh - ] -}] - -module evh_consumerGroups 'modules/eventHub/consumerGroup.bicep' = [for (cg, index) in eventHubConsumerGroups: { - name: '${deployment().name}-evh-cg-${index}' - params: { - namespaceName: cg.namespaceName - eventHubName: cg.eventHubName - name: cg.name - userMetadata: cg.?userMetadata ?? '' - } - dependsOn: [ - evh - ] -}] - -module evhns_diagnosticSettings 'modules/diagnosticSetting.bicep' = [for (ds, index) in namespaceDiagnosticSettings: { - name: '${deployment().name}-evhns-diagnosticSettings-${index}' - params: { - namespaceName: ds.namespaceName - name: ds.name - storageAccountId: ds.?storageAccountId ?? '' - workspaceId: ds.?workspaceId ?? '' - eventHubAuthorizationRuleId: ds.?eventHubAuthorizationRuleId ?? '' - eventHubName: ds.?eventHubName ?? '' - metricsSettings: ds.?metricsSettings ?? [] - logsSettings: ds.?logsSettings ?? [] - } - dependsOn: [ - evhns - ] -}] - -module evhns_privateEndpoints 'modules/privateEndpoint.bicep' = [for (pep, index) in namespacePrivateEndpoints: { - name: '${uniqueString(deployment().name)}-evhns-pep-${index}' - params: { - name: pep.name - namespaceName: pep.namespaceName - location: location - groupIds: pep.?groupIds ?? [ 'namespace' ] - subnetId: pep.subnetId - privateDnsZoneId: pep.?privateDnsZoneId ?? '' - tags: tags - manualApprovalEnabled: pep.?manualApprovalEnabled ?? false - } - dependsOn: [ - evhns - ] -}] - -// output -@description('Azure Event Hub namespace names.') -output eventHubNamespaceNames array = [for ns in namespaces: ns.name] - -@description('Azure Event Hub namespace resource Ids.') -output eventHubNamespaceResourceIds array = [for ns in namespaces: resourceId('Microsoft.EventHub/namespaces', ns.name)] - -// user defined type -type namespacesType = { - @description('Name of the Event Hub Namespace.') - name: string - @description('SKU of the Event Hub Namespace. Possible values are "Basic" or "Standard" or "Premium') - sku: ('Basic' | 'Standard' | 'Premium')?// Default 'Standard' - @description('Event Hubs throughput units for Basic or Standard tiers where value should be 0 to 20 units. For Premium tier, value should be 0 to 10 premium units.') - capacity: int?// Default 1 - @description('Enabling this property creates a Standard Event Hubs Namespace in regions supported availability zones.') - zoneRedundant: bool?// Default false - @description('Whether to enable AutoInflate or not.') - isAutoInflateEnabled: bool?// Default false - @description('Upper limit of throughput units when AutoInflate is enabled.') - maximumThroughputUnits: int?// Default 0 - @description('Whether to enable Kafka or not.') - kafkaEnabled: bool?// Default 'true' - @description('Whethere tp disable SAS authentication or not.') - disableLocalAuth: bool?// Default false - @description('Whether to enable public network access or not.') - publicNetworkAccess: ('Enabled' | 'Disabled' | 'SecuredByPerimeter')?// Default 'Enabled' - @description('Set the minimum TLS version for the Event Hub Namespace.') - minimumTlsVersion: ('1.0' | '1.1' | '1.2')?// Default '1.2' - -} - -type authorizationRulesType = { - @description('Name of the namespace authorization rule.') - name: string - @description('The rights associated with the rule.') - rights: string[] - @description('The eventhub namespace name.') - namespaceName: string - @description('The eventhub name. Optional if the authorization rule is for namespace and not for an eventhub.') - eventHubName: string? -} - -type namespaceRoleAssignmentsType = { - @description('Name of the namespace role assignment.') - name: string? - @description('The description of the role assignment.') - description: string? - @description('The principal ids associated with the role assignment.') - principalIds: string[] - @description('The principal type associated with the role assignment.') - principalType: ('Device' | 'ForeignGroup' | 'Group' | 'ServicePrincipal' | 'User')? - @description('The role definition id or name associated with the role assignment.') - roleDefinitionIdOrName: string - @description('The eventhub namespace name.') - namespaceName: string -} - -type eventHubRoleAssignmentsType = { - @description('Name of the namespace role assignment.') - name: string? - @description('The description of the role assignment.') - description: string? - @description('The principal ids associated with the role assignment.') - principalIds: string[] - @description('The principal type associated with the role assignment.') - principalType: ('Device' | 'ForeignGroup' | 'Group' | 'ServicePrincipal' | 'User')? - @description('The role definition id or name associated with the role assignment.') - roleDefinitionIdOrName: string -} - -type namespaceDisasterRecoveryConfigsType = { - @description('Name of the namespace disaster recovery config.') - name: string - @description('The resource id of the secondary partner namespace, which is part of GEO DR pairing.') - partnerNamespaceId: string - @description('The eventhub namespace name.') - namespaceName: string -} - -type eventHubsType = { - @description('Name of the Event Hub.') - name: string - @description('The eventhub namespace name.') - namespaceName: string - @description('Number of partitions created for the Event Hub, allowed values are from 1 to 32 partitions.') - partitionCount: int?// Default 2 - @description('Number of days to retain the events for this Event Hub, value should be 1 to 7 days.') - messageRetentionInDays: int?// Default 1 - @description('A value that indicates whether capture description is enabled.') - captureDescriptionEnabled: bool?// Default false - @description('TEnumerates the possible values for the encoding format of capture description.') - captureDescriptionEncoding: ('Avro' | 'Parquet')?// Default 'Avro' - @description('The time window allows you to set the frequency with which the capture to Azure Blobs will happen, value should between 60 to 900 seconds.') - captureDescriptionIntervalInSeconds: int? - @description('The size window defines the amount of data built up in your Event Hub before an capture operation, value should be between 10485760 to 524288000 bytes.') - captureDescriptionSizeLimitInBytes: int? - @description('A value that indicates whether to Skip Empty Archives') - captureDescriptionSkipEmptyArchives: bool? - @description('The eventhub capture destination name.') - captureDescriptionDestinationName: ('EventHubArchive.AzureBlockBlob' | 'EventHubArchive.AzureDataLake')?// Default 'EventHubArchive.AzureBlockBlob' - @description('Blob naming convention for archive, e.g. {Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}.') - captureDescriptionDestinationArchiveNameFormat: string? - @description('The eventhub capture description destination blob container name.') - captureDescriptionDestinationBlobContainer: string? - @description('TSubscription Id of Azure Data Lake Store') - captureDescriptionDestinationStorageAccountResourceId: string? - @description('The Azure Data Lake Store name for the captured events') - captureDescriptionDestinationdataLakeAccountName: string? - @description('The destination folder path for the captured events') - captureDescriptionDestinationdataLakeFolderPath: string? - @description('Subscription Id of Azure Data Lake Store') - captureDescriptionDestinationdataLakeSubscriptionId: string? - @description('The role assignements scoped to event hub.') - roleAssignments: eventHubRoleAssignmentsType[]? - @description('The possible values for the status of the Event Hub..') - status: ('Active' | 'Disabled' | 'SendDisabled')?// Default 'Active' -} - -type eventHubConsumerGroupsType = { - @description('Name of the Event Hub Consumer Group.') - name: string - @description('The eventhub namespace name.') - namespaceName: string - @description('The eventhub name.') - eventHubName: string - @description('The user metadata.') - userMetadata: string? -} - -type namespaceDiagnosticSettingsType = { - @description('Name of the namespace diagnostic setting.') - name: string - @description('The eventhub namespace name.') - namespaceName: string - @description('The log analytics workspace id.') - workspaceId: string? - @description('The storage account id.') - storageAccountId: string? - @description('The eventhub name.') - eventHubName: string? - @description('The eventhub authorization rule id.') - eventHubAuthorizationRuleId: string? - @description('The list of metic settings.') - metricsSettings: metricSettingsType[] - @description('The list of logs settings.') - logsSettings: logSettingsType[] -} - -type metricSettingsType = { - @description('A value indicating whether this category is enabled.') - enabled: bool - @description('The category of the metrics.') - category: ('AllMetrics') - @description('The time grain of the metric in ISO8601 format.') - timeGrain: string? - @description('The retention policy of the metric.') - retentionPolicy: retentionPolicyType? -} - -type retentionPolicyType = { - @description('The retention period of the metric.') - days: int - @description('The retention policy enabled flag.') - enabled: bool -} - -type logSettingsType = { - @description('A value indicating whether this log is enabled.') - enabled: bool - @description('The category of the logs.') - category: string? - @description('The category group of the logs.') - categoryGroup: ('allLogs' | 'audit')? - @description('The retention policy of the logs.') - retentionPolicy: retentionPolicyType? -} - -type privateEndpointType = { - @description('The name of the private endpoint.') - name: string - @description('The eventhub namespace name.') - namespaceName: string - @description('The subnet that the private endpoint should be created in.') - subnetId: string - @description('The subresource name of the target Azure resource that private endpoint will connect to.') - groupIds: array?// Default ['namespace'] - @description('The ID of the private DNS zone in which private endpoint will register its private IP address.') - privateDnsZoneId: string? - @description('When set to true, users will need to manually approve the private endpoint connection request.') - manualApprovalEnabled: bool?// Default false - @description('Tags for the resource.') - tags: { *: string }? -} diff --git a/modules/compute/event-hub/main.json b/modules/compute/event-hub/main.json deleted file mode 100644 index 501f76b1cd..0000000000 --- a/modules/compute/event-hub/main.json +++ /dev/null @@ -1,1802 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "1.10-experimental", - "contentVersion": "1.0.0.0", - "metadata": { - "_EXPERIMENTAL_WARNING": "Symbolic name support in ARM is experimental, and should be enabled for testing purposes only. Do not enable this setting for any production usage, or you may be unexpectedly broken at any time!", - "_generator": { - "name": "bicep", - "version": "0.19.5.34762", - "templateHash": "13506265071276900614" - }, - "name": "Azure Event-Hub", - "description": "This module deploys Microsoft.data event clusters, event namespaces, event hubs and associated configurations.", - "owner": "sumit-salunke" - }, - "definitions": { - "namespacesType": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Name of the Event Hub Namespace." - } - }, - "sku": { - "type": "string", - "allowedValues": [ - "Basic", - "Premium", - "Standard" - ], - "nullable": true, - "metadata": { - "description": "SKU of the Event Hub Namespace. Possible values are \"Basic\" or \"Standard\" or \"Premium" - } - }, - "capacity": { - "type": "int", - "nullable": true, - "metadata": { - "description": "Event Hubs throughput units for Basic or Standard tiers where value should be 0 to 20 units. For Premium tier, value should be 0 to 10 premium units." - } - }, - "zoneRedundant": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Enabling this property creates a Standard Event Hubs Namespace in regions supported availability zones." - } - }, - "isAutoInflateEnabled": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Whether to enable AutoInflate or not." - } - }, - "maximumThroughputUnits": { - "type": "int", - "nullable": true, - "metadata": { - "description": "Upper limit of throughput units when AutoInflate is enabled." - } - }, - "kafkaEnabled": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Whether to enable Kafka or not." - } - }, - "disableLocalAuth": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Whethere tp disable SAS authentication or not." - } - }, - "publicNetworkAccess": { - "type": "string", - "allowedValues": [ - "Disabled", - "Enabled", - "SecuredByPerimeter" - ], - "nullable": true, - "metadata": { - "description": "Whether to enable public network access or not." - } - }, - "minimumTlsVersion": { - "type": "string", - "allowedValues": [ - "1.0", - "1.1", - "1.2" - ], - "nullable": true, - "metadata": { - "description": "Set the minimum TLS version for the Event Hub Namespace." - } - } - } - }, - "authorizationRulesType": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Name of the namespace authorization rule." - } - }, - "rights": { - "type": "array", - "items": { - "type": "string" - }, - "metadata": { - "description": "The rights associated with the rule." - } - }, - "namespaceName": { - "type": "string", - "metadata": { - "description": "The eventhub namespace name." - } - }, - "eventHubName": { - "type": "string", - "nullable": true, - "metadata": { - "description": "The eventhub name. Optional if the authorization rule is for namespace and not for an eventhub." - } - } - } - }, - "namespaceRoleAssignmentsType": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Name of the namespace role assignment." - } - }, - "description": { - "type": "string", - "nullable": true, - "metadata": { - "description": "The description of the role assignment." - } - }, - "principalIds": { - "type": "array", - "items": { - "type": "string" - }, - "metadata": { - "description": "The principal ids associated with the role assignment." - } - }, - "principalType": { - "type": "string", - "allowedValues": [ - "Device", - "ForeignGroup", - "Group", - "ServicePrincipal", - "User" - ], - "nullable": true, - "metadata": { - "description": "The principal type associated with the role assignment." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "The role definition id or name associated with the role assignment." - } - }, - "namespaceName": { - "type": "string", - "metadata": { - "description": "The eventhub namespace name." - } - } - } - }, - "eventHubRoleAssignmentsType": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Name of the namespace role assignment." - } - }, - "description": { - "type": "string", - "nullable": true, - "metadata": { - "description": "The description of the role assignment." - } - }, - "principalIds": { - "type": "array", - "items": { - "type": "string" - }, - "metadata": { - "description": "The principal ids associated with the role assignment." - } - }, - "principalType": { - "type": "string", - "allowedValues": [ - "Device", - "ForeignGroup", - "Group", - "ServicePrincipal", - "User" - ], - "nullable": true, - "metadata": { - "description": "The principal type associated with the role assignment." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "The role definition id or name associated with the role assignment." - } - } - } - }, - "namespaceDisasterRecoveryConfigsType": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Name of the namespace disaster recovery config." - } - }, - "partnerNamespaceId": { - "type": "string", - "metadata": { - "description": "The resource id of the secondary partner namespace, which is part of GEO DR pairing." - } - }, - "namespaceName": { - "type": "string", - "metadata": { - "description": "The eventhub namespace name." - } - } - } - }, - "eventHubsType": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Name of the Event Hub." - } - }, - "namespaceName": { - "type": "string", - "metadata": { - "description": "The eventhub namespace name." - } - }, - "partitionCount": { - "type": "int", - "nullable": true, - "metadata": { - "description": "Number of partitions created for the Event Hub, allowed values are from 1 to 32 partitions." - } - }, - "messageRetentionInDays": { - "type": "int", - "nullable": true, - "metadata": { - "description": "Number of days to retain the events for this Event Hub, value should be 1 to 7 days." - } - }, - "captureDescriptionEnabled": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "A value that indicates whether capture description is enabled." - } - }, - "captureDescriptionEncoding": { - "type": "string", - "allowedValues": [ - "Avro", - "Parquet" - ], - "nullable": true, - "metadata": { - "description": "TEnumerates the possible values for the encoding format of capture description." - } - }, - "captureDescriptionIntervalInSeconds": { - "type": "int", - "nullable": true, - "metadata": { - "description": "The time window allows you to set the frequency with which the capture to Azure Blobs will happen, value should between 60 to 900 seconds." - } - }, - "captureDescriptionSizeLimitInBytes": { - "type": "int", - "nullable": true, - "metadata": { - "description": "The size window defines the amount of data built up in your Event Hub before an capture operation, value should be between 10485760 to 524288000 bytes." - } - }, - "captureDescriptionSkipEmptyArchives": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "A value that indicates whether to Skip Empty Archives" - } - }, - "captureDescriptionDestinationName": { - "type": "string", - "allowedValues": [ - "EventHubArchive.AzureBlockBlob", - "EventHubArchive.AzureDataLake" - ], - "nullable": true, - "metadata": { - "description": "The eventhub capture destination name." - } - }, - "captureDescriptionDestinationArchiveNameFormat": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Blob naming convention for archive, e.g. {Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}." - } - }, - "captureDescriptionDestinationBlobContainer": { - "type": "string", - "nullable": true, - "metadata": { - "description": "The eventhub capture description destination blob container name." - } - }, - "captureDescriptionDestinationStorageAccountResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "TSubscription Id of Azure Data Lake Store" - } - }, - "captureDescriptionDestinationdataLakeAccountName": { - "type": "string", - "nullable": true, - "metadata": { - "description": "The Azure Data Lake Store name for the captured events" - } - }, - "captureDescriptionDestinationdataLakeFolderPath": { - "type": "string", - "nullable": true, - "metadata": { - "description": "The destination folder path for the captured events" - } - }, - "captureDescriptionDestinationdataLakeSubscriptionId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Subscription Id of Azure Data Lake Store" - } - }, - "roleAssignments": { - "type": "array", - "items": { - "$ref": "#/definitions/eventHubRoleAssignmentsType" - }, - "nullable": true, - "metadata": { - "description": "The role assignements scoped to event hub." - } - }, - "status": { - "type": "string", - "allowedValues": [ - "Active", - "Disabled", - "SendDisabled" - ], - "nullable": true, - "metadata": { - "description": "The possible values for the status of the Event Hub.." - } - } - } - }, - "eventHubConsumerGroupsType": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Name of the Event Hub Consumer Group." - } - }, - "namespaceName": { - "type": "string", - "metadata": { - "description": "The eventhub namespace name." - } - }, - "eventHubName": { - "type": "string", - "metadata": { - "description": "The eventhub name." - } - }, - "userMetadata": { - "type": "string", - "nullable": true, - "metadata": { - "description": "The user metadata." - } - } - } - }, - "namespaceDiagnosticSettingsType": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Name of the namespace diagnostic setting." - } - }, - "namespaceName": { - "type": "string", - "metadata": { - "description": "The eventhub namespace name." - } - }, - "workspaceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "The log analytics workspace id." - } - }, - "storageAccountId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "The storage account id." - } - }, - "eventHubName": { - "type": "string", - "nullable": true, - "metadata": { - "description": "The eventhub name." - } - }, - "eventHubAuthorizationRuleId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "The eventhub authorization rule id." - } - }, - "metricsSettings": { - "type": "array", - "items": { - "$ref": "#/definitions/metricSettingsType" - }, - "metadata": { - "description": "The list of metic settings." - } - }, - "logsSettings": { - "type": "array", - "items": { - "$ref": "#/definitions/logSettingsType" - }, - "metadata": { - "description": "The list of logs settings." - } - } - } - }, - "metricSettingsType": { - "type": "object", - "properties": { - "enabled": { - "type": "bool", - "metadata": { - "description": "A value indicating whether this category is enabled." - } - }, - "category": { - "type": "string", - "allowedValues": [ - "AllMetrics" - ], - "metadata": { - "description": "The category of the metrics." - } - }, - "timeGrain": { - "type": "string", - "nullable": true, - "metadata": { - "description": "The time grain of the metric in ISO8601 format." - } - }, - "retentionPolicy": { - "$ref": "#/definitions/retentionPolicyType", - "nullable": true, - "metadata": { - "description": "The retention policy of the metric." - } - } - } - }, - "retentionPolicyType": { - "type": "object", - "properties": { - "days": { - "type": "int", - "metadata": { - "description": "The retention period of the metric." - } - }, - "enabled": { - "type": "bool", - "metadata": { - "description": "The retention policy enabled flag." - } - } - } - }, - "logSettingsType": { - "type": "object", - "properties": { - "enabled": { - "type": "bool", - "metadata": { - "description": "A value indicating whether this log is enabled." - } - }, - "category": { - "type": "string", - "nullable": true, - "metadata": { - "description": "The category of the logs." - } - }, - "categoryGroup": { - "type": "string", - "allowedValues": [ - "allLogs", - "audit" - ], - "nullable": true, - "metadata": { - "description": "The category group of the logs." - } - }, - "retentionPolicy": { - "$ref": "#/definitions/retentionPolicyType", - "nullable": true, - "metadata": { - "description": "The retention policy of the logs." - } - } - } - }, - "privateEndpointType": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the private endpoint." - } - }, - "namespaceName": { - "type": "string", - "metadata": { - "description": "The eventhub namespace name." - } - }, - "subnetId": { - "type": "string", - "metadata": { - "description": "The subnet that the private endpoint should be created in." - } - }, - "groupIds": { - "type": "array", - "nullable": true, - "metadata": { - "description": "The subresource name of the target Azure resource that private endpoint will connect to." - } - }, - "privateDnsZoneId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "The ID of the private DNS zone in which private endpoint will register its private IP address." - } - }, - "manualApprovalEnabled": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "When set to true, users will need to manually approve the private endpoint connection request." - } - }, - "tags": { - "type": "object", - "additionalProperties": { - "type": "string" - }, - "nullable": true, - "metadata": { - "description": "Tags for the resource." - } - } - } - } - }, - "parameters": { - "clusterName": { - "type": "string", - "defaultValue": "null", - "metadata": { - "description": "Optional. Name for the Event Hub cluster, Alphanumerics and hyphens characters, Start with letter, End with letter or number." - } - }, - "clusterCapacity": { - "type": "int", - "defaultValue": 1, - "metadata": { - "description": "Optional. The quantity of Event Hubs Cluster Capacity Units contained in this cluster." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Required. Location for all resources." - } - }, - "tags": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Optional. Tags of the resource." - } - }, - "namespaces": { - "type": "array", - "items": { - "$ref": "#/definitions/namespacesType" - }, - "defaultValue": [ - { - "name": "evhns001", - "sku": "Standard", - "capacity": 1, - "disableLocalAuth": false, - "kafkaEnabled": true, - "isAutoInflateEnabled": false, - "maximumThroughputUnits": 0, - "zoneRedundant": false, - "minimumTlsVersion": "1.2", - "publicNetworkAccess": "Enabled" - } - ], - "metadata": { - "description": "Required. The list of the event hub namespaces with its configurations to be created." - } - }, - "namespaceAuthorizationRules": { - "type": "array", - "items": { - "$ref": "#/definitions/authorizationRulesType" - }, - "defaultValue": [], - "metadata": { - "description": "Optional. Authorization Rules for the Event Hub Namespace." - } - }, - "namespaceRoleAssignments": { - "type": "array", - "items": { - "$ref": "#/definitions/namespaceRoleAssignmentsType" - }, - "defaultValue": [], - "metadata": { - "description": "Optional. Role assignments for the namespace." - } - }, - "namespaceDisasterRecoveryConfigs": { - "type": "array", - "items": { - "$ref": "#/definitions/namespaceDisasterRecoveryConfigsType" - }, - "defaultValue": [], - "metadata": { - "description": "Optional. The disaster recovery config for the namespace." - } - }, - "namespaceDiagnosticSettings": { - "type": "array", - "items": { - "$ref": "#/definitions/namespaceDiagnosticSettingsType" - }, - "defaultValue": [], - "metadata": { - "description": "Optional. The Diagnostics Settings config for the namespace." - } - }, - "eventHubs": { - "type": "array", - "items": { - "$ref": "#/definitions/eventHubsType" - }, - "defaultValue": [], - "metadata": { - "description": "Optional. Name for the eventhub with its all configurations to be created." - } - }, - "eventHubAuthorizationRules": { - "type": "array", - "items": { - "$ref": "#/definitions/authorizationRulesType" - }, - "defaultValue": [], - "metadata": { - "description": "Optional. Authorization Rules for the Event Hub ." - } - }, - "eventHubConsumerGroups": { - "type": "array", - "items": { - "$ref": "#/definitions/eventHubConsumerGroupsType" - }, - "defaultValue": [], - "metadata": { - "description": "Optional. consumer groups for the Event Hub ." - } - }, - "namespacePrivateEndpoints": { - "type": "array", - "items": { - "$ref": "#/definitions/privateEndpointType" - }, - "defaultValue": [], - "metadata": { - "description": "Private Endpoints that should be created for Azure EventHub Namespaces." - } - } - }, - "resources": { - "cluster": { - "condition": "[not(equals(parameters('clusterName'), 'null'))]", - "type": "Microsoft.EventHub/clusters", - "apiVersion": "2022-10-01-preview", - "name": "[parameters('clusterName')]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "sku": { - "name": "Dedicated", - "capacity": "[parameters('clusterCapacity')]" - } - }, - "evhns": { - "copy": { - "name": "evhns", - "count": "[length(parameters('namespaces'))]" - }, - "type": "Microsoft.EventHub/namespaces", - "apiVersion": "2022-10-01-preview", - "name": "[parameters('namespaces')[copyIndex()].name]", - "location": "[parameters('location')]", - "sku": { - "name": "[coalesce(tryGet(parameters('namespaces')[copyIndex()], 'sku'), 'Standard')]", - "capacity": "[coalesce(tryGet(parameters('namespaces')[copyIndex()], 'capacity'), 1)]" - }, - "properties": { - "disableLocalAuth": "[coalesce(tryGet(parameters('namespaces')[copyIndex()], 'disableLocalAuth'), false())]", - "kafkaEnabled": "[coalesce(tryGet(parameters('namespaces')[copyIndex()], 'kafkaEnabled'), true())]", - "isAutoInflateEnabled": "[coalesce(tryGet(parameters('namespaces')[copyIndex()], 'isAutoInflateEnabled'), false())]", - "maximumThroughputUnits": "[coalesce(tryGet(parameters('namespaces')[copyIndex()], 'maximumThroughputUnits'), 0)]", - "zoneRedundant": "[coalesce(tryGet(parameters('namespaces')[copyIndex()], 'zoneRedundant'), false())]", - "clusterArmId": "[if(not(equals(parameters('clusterName'), 'null')), resourceId('Microsoft.EventHub/clusters', parameters('clusterName')), null())]", - "minimumTlsVersion": "[coalesce(tryGet(parameters('namespaces')[copyIndex()], 'minimumTlsVersion'), '1.2')]", - "publicNetworkAccess": "[coalesce(tryGet(parameters('namespaces')[copyIndex()], 'publicNetworkAccess'), 'Enabled')]" - }, - "tags": "[parameters('tags')]", - "dependsOn": [ - "cluster" - ] - }, - "evhns_authorizationRules": { - "copy": { - "name": "evhns_authorizationRules", - "count": "[length(parameters('namespaceAuthorizationRules'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-evhns-authrule-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "name": { - "value": "[parameters('namespaceAuthorizationRules')[copyIndex()].name]" - }, - "rights": { - "value": "[parameters('namespaceAuthorizationRules')[copyIndex()].rights]" - }, - "namespaceName": { - "value": "[parameters('namespaceAuthorizationRules')[copyIndex()].namespaceName]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "1.10-experimental", - "contentVersion": "1.0.0.0", - "metadata": { - "_EXPERIMENTAL_WARNING": "Symbolic name support in ARM is experimental, and should be enabled for testing purposes only. Do not enable this setting for any production usage, or you may be unexpectedly broken at any time!", - "_generator": { - "name": "bicep", - "version": "0.19.5.34762", - "templateHash": "16560230268819578887" - } - }, - "parameters": { - "namespaceName": { - "type": "string" - }, - "name": { - "type": "string" - }, - "rights": { - "type": "array" - } - }, - "resources": { - "namespace": { - "existing": true, - "type": "Microsoft.EventHub/namespaces", - "apiVersion": "2022-10-01-preview", - "name": "[parameters('namespaceName')]" - }, - "namespaceAuthorizationRule": { - "type": "Microsoft.EventHub/namespaces/authorizationRules", - "apiVersion": "2022-10-01-preview", - "name": "[format('{0}/{1}', parameters('namespaceName'), parameters('name'))]", - "properties": { - "rights": "[parameters('rights')]" - } - } - } - } - }, - "dependsOn": [ - "evhns" - ] - }, - "evhns_roleAssignments": { - "copy": { - "name": "evhns_roleAssignments", - "count": "[length(parameters('namespaceRoleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-evhns-role-{1}', deployment().name, copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "roleName": { - "value": "[coalesce(tryGet(parameters('namespaceRoleAssignments')[copyIndex()], 'name'), '')]" - }, - "description": { - "value": "[coalesce(tryGet(parameters('namespaceRoleAssignments')[copyIndex()], 'description'), '')]" - }, - "principalIds": { - "value": "[parameters('namespaceRoleAssignments')[copyIndex()].principalIds]" - }, - "principalType": { - "value": "[coalesce(tryGet(parameters('namespaceRoleAssignments')[copyIndex()], 'principalType'), '')]" - }, - "roleDefinitionIdOrName": { - "value": "[parameters('namespaceRoleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "namespaceName": { - "value": "[parameters('namespaceRoleAssignments')[copyIndex()].namespaceName]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "1.10-experimental", - "contentVersion": "1.0.0.0", - "metadata": { - "_EXPERIMENTAL_WARNING": "Symbolic name support in ARM is experimental, and should be enabled for testing purposes only. Do not enable this setting for any production usage, or you may be unexpectedly broken at any time!", - "_generator": { - "name": "bicep", - "version": "0.19.5.34762", - "templateHash": "10570742932814464407" - } - }, - "parameters": { - "roleName": { - "type": "string" - }, - "description": { - "type": "string" - }, - "principalIds": { - "type": "array" - }, - "roleDefinitionIdOrName": { - "type": "string" - }, - "principalType": { - "type": "string" - }, - "namespaceName": { - "type": "string" - } - }, - "variables": { - "builtInRoleNames": { - "Azure Event Hubs Data Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f526a384-b230-433a-b45c-95f59c4a2dec')]", - "Azure Event Hubs Data Receiver": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a638d3c7-ab3a-418d-83e6-5f17a39d4fde')]", - "Azure Event Hubs Data Sender": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2b629674-e913-4c01-ae53-ef4638d8f975')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Schema Registry Contributor (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5dffeca3-4936-4216-b2bc-10343a5abb25')]", - "Schema Registry Reader (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2c56ea50-c6b3-40a6-83c0-9d98858bc7d2')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" - } - }, - "resources": { - "namespace": { - "existing": true, - "type": "Microsoft.EventHub/namespaces", - "apiVersion": "2022-10-01-preview", - "name": "[parameters('namespaceName')]" - }, - "roleAssignment": { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.EventHub/namespaces/{0}', parameters('namespaceName'))]", - "name": "[guid(parameters('roleName'), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], subscriptionResourceId('Microsoft.Authorization/roleDefinitions', parameters('roleDefinitionIdOrName')))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]" - } - } - } - } - }, - "dependsOn": [ - "evhns" - ] - }, - "evhns_disasterRecoveryConfigs": { - "copy": { - "name": "evhns_disasterRecoveryConfigs", - "count": "[length(parameters('namespaceDisasterRecoveryConfigs'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-evhns-drconfig-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "name": { - "value": "[parameters('namespaceDisasterRecoveryConfigs')[copyIndex()].name]" - }, - "partnerNamespaceId": { - "value": "[parameters('namespaceDisasterRecoveryConfigs')[copyIndex()].partnerNamespaceId]" - }, - "namespaceName": { - "value": "[parameters('namespaceDisasterRecoveryConfigs')[copyIndex()].namespaceName]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "1.10-experimental", - "contentVersion": "1.0.0.0", - "metadata": { - "_EXPERIMENTAL_WARNING": "Symbolic name support in ARM is experimental, and should be enabled for testing purposes only. Do not enable this setting for any production usage, or you may be unexpectedly broken at any time!", - "_generator": { - "name": "bicep", - "version": "0.19.5.34762", - "templateHash": "14264603254199121226" - } - }, - "parameters": { - "namespaceName": { - "type": "string" - }, - "name": { - "type": "string" - }, - "partnerNamespaceId": { - "type": "string", - "defaultValue": "" - } - }, - "resources": { - "namespace": { - "existing": true, - "type": "Microsoft.EventHub/namespaces", - "apiVersion": "2022-10-01-preview", - "name": "[parameters('namespaceName')]" - }, - "disasterRecoveryConfig": { - "type": "Microsoft.EventHub/namespaces/disasterRecoveryConfigs", - "apiVersion": "2022-10-01-preview", - "name": "[format('{0}/{1}', parameters('namespaceName'), parameters('name'))]", - "properties": { - "partnerNamespace": "[parameters('partnerNamespaceId')]", - "alternateName": "alternateName" - } - } - } - } - }, - "dependsOn": [ - "evhns" - ] - }, - "evh": { - "copy": { - "name": "evh", - "count": "[length(parameters('eventHubs'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-evh-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "namespaceName": { - "value": "[parameters('eventHubs')[copyIndex()].namespaceName]" - }, - "name": { - "value": "[parameters('eventHubs')[copyIndex()].name]" - }, - "messageRetentionInDays": { - "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'messageRetentionInDays'), 1)]" - }, - "partitionCount": { - "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'partitionCount'), 2)]" - }, - "status": { - "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'status'), 'Active')]" - }, - "captureDescriptionEnabled": { - "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'captureDescriptionEnabled'), false())]" - }, - "captureDescriptionEncoding": { - "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'captureDescriptionEncoding'), 'Avro')]" - }, - "captureDescriptionIntervalInSeconds": { - "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'captureDescriptionIntervalInSeconds'), 300)]" - }, - "captureDescriptionSizeLimitInBytes": { - "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'captureDescriptionSizeLimitInBytes'), 314572800)]" - }, - "captureDescriptionSkipEmptyArchives": { - "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'captureDescriptionSkipEmptyArchives'), false())]" - }, - "captureDescriptionDestinationName": { - "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'captureDescriptionDestinationName'), 'EventHubArchive.AzureBlockBlob')]" - }, - "captureDescriptionDestinationArchiveNameFormat": { - "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'captureDescriptionDestinationArchiveNameFormat'), '{Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}')]" - }, - "captureDescriptionDestinationBlobContainer": { - "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'captureDescriptionDestinationBlobContainer'), '')]" - }, - "captureDescriptionDestinationStorageAccountResourceId": { - "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'captureDescriptionDestinationStorageAccountResourceId'), '')]" - }, - "captureDescriptionDestinationdataLakeAccountName": { - "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'captureDescriptionDestinationdataLakeAccountName'), '')]" - }, - "captureDescriptionDestinationdataLakeFolderPath": { - "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'captureDescriptionDestinationdataLakeFolderPath'), '')]" - }, - "captureDescriptionDestinationdataLakeSubscriptionId": { - "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'captureDescriptionDestinationdataLakeSubscriptionId'), '')]" - }, - "roleAssignments": { - "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'roleAssignments'), createArray())]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "1.10-experimental", - "contentVersion": "1.0.0.0", - "metadata": { - "_EXPERIMENTAL_WARNING": "Symbolic name support in ARM is experimental, and should be enabled for testing purposes only. Do not enable this setting for any production usage, or you may be unexpectedly broken at any time!", - "_generator": { - "name": "bicep", - "version": "0.19.5.34762", - "templateHash": "168464517665905008" - } - }, - "parameters": { - "namespaceName": { - "type": "string" - }, - "name": { - "type": "string" - }, - "messageRetentionInDays": { - "type": "int" - }, - "partitionCount": { - "type": "int" - }, - "captureDescriptionEnabled": { - "type": "bool" - }, - "captureDescriptionDestinationName": { - "type": "string" - }, - "captureDescriptionDestinationArchiveNameFormat": { - "type": "string" - }, - "captureDescriptionDestinationBlobContainer": { - "type": "string" - }, - "captureDescriptionDestinationStorageAccountResourceId": { - "type": "string" - }, - "captureDescriptionDestinationdataLakeAccountName": { - "type": "string" - }, - "captureDescriptionDestinationdataLakeFolderPath": { - "type": "string" - }, - "captureDescriptionDestinationdataLakeSubscriptionId": { - "type": "string" - }, - "captureDescriptionEncoding": { - "type": "string" - }, - "captureDescriptionIntervalInSeconds": { - "type": "int" - }, - "captureDescriptionSizeLimitInBytes": { - "type": "int" - }, - "captureDescriptionSkipEmptyArchives": { - "type": "bool" - }, - "roleAssignments": { - "type": "array" - }, - "status": { - "type": "string" - } - }, - "variables": { - "eventHubPropertiesSimple": { - "messageRetentionInDays": "[parameters('messageRetentionInDays')]", - "partitionCount": "[parameters('partitionCount')]", - "status": "[parameters('status')]" - }, - "eventHubPropertiesWithCapture": { - "messageRetentionInDays": "[parameters('messageRetentionInDays')]", - "partitionCount": "[parameters('partitionCount')]", - "captureDescription": { - "destination": { - "name": "[parameters('captureDescriptionDestinationName')]", - "properties": { - "archiveNameFormat": "[parameters('captureDescriptionDestinationArchiveNameFormat')]", - "blobContainer": "[parameters('captureDescriptionDestinationBlobContainer')]", - "storageAccountResourceId": "[parameters('captureDescriptionDestinationStorageAccountResourceId')]", - "dataLakeAccountName": "[parameters('captureDescriptionDestinationdataLakeAccountName')]", - "dataLakeFolderPath": "[parameters('captureDescriptionDestinationdataLakeFolderPath')]", - "dataLakeSubscriptionId": "[parameters('captureDescriptionDestinationdataLakeSubscriptionId')]" - } - }, - "enabled": "[parameters('captureDescriptionEnabled')]", - "encoding": "[parameters('captureDescriptionEncoding')]", - "intervalInSeconds": "[parameters('captureDescriptionIntervalInSeconds')]", - "sizeLimitInBytes": "[parameters('captureDescriptionSizeLimitInBytes')]", - "skipEmptyArchives": "[parameters('captureDescriptionSkipEmptyArchives')]", - "status": "[parameters('status')]" - } - } - }, - "resources": { - "namespace": { - "existing": true, - "type": "Microsoft.EventHub/namespaces", - "apiVersion": "2022-10-01-preview", - "name": "[parameters('namespaceName')]" - }, - "eventHub": { - "type": "Microsoft.EventHub/namespaces/eventhubs", - "apiVersion": "2022-10-01-preview", - "name": "[format('{0}/{1}', parameters('namespaceName'), parameters('name'))]", - "properties": "[if(parameters('captureDescriptionEnabled'), variables('eventHubPropertiesWithCapture'), variables('eventHubPropertiesSimple'))]" - }, - "eventHub_roleAssignments": { - "copy": { - "name": "eventHub_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-evh-role-{1}', deployment().name, copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": { - "value": "[coalesce(tryGet(parameters('roleAssignments')[copyIndex()], 'description'), '')]" - }, - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": { - "value": "[coalesce(tryGet(parameters('roleAssignments')[copyIndex()], 'principalType'), '')]" - }, - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "roleName": { - "value": "[coalesce(tryGet(parameters('roleAssignments')[copyIndex()], 'name'), '')]" - }, - "namespaceName": { - "value": "[parameters('namespaceName')]" - }, - "eventHubName": { - "value": "[parameters('name')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "1.10-experimental", - "contentVersion": "1.0.0.0", - "metadata": { - "_EXPERIMENTAL_WARNING": "Symbolic name support in ARM is experimental, and should be enabled for testing purposes only. Do not enable this setting for any production usage, or you may be unexpectedly broken at any time!", - "_generator": { - "name": "bicep", - "version": "0.19.5.34762", - "templateHash": "14896444724696374233" - } - }, - "parameters": { - "roleName": { - "type": "string" - }, - "description": { - "type": "string" - }, - "principalIds": { - "type": "array" - }, - "roleDefinitionIdOrName": { - "type": "string" - }, - "principalType": { - "type": "string" - }, - "namespaceName": { - "type": "string" - }, - "eventHubName": { - "type": "string" - } - }, - "variables": { - "builtInRoleNames": { - "Azure Event Hubs Data Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f526a384-b230-433a-b45c-95f59c4a2dec')]", - "Azure Event Hubs Data Receiver": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a638d3c7-ab3a-418d-83e6-5f17a39d4fde')]", - "Azure Event Hubs Data Sender": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2b629674-e913-4c01-ae53-ef4638d8f975')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Schema Registry Contributor (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5dffeca3-4936-4216-b2bc-10343a5abb25')]", - "Schema Registry Reader (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2c56ea50-c6b3-40a6-83c0-9d98858bc7d2')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" - } - }, - "resources": { - "namespace": { - "existing": true, - "type": "Microsoft.EventHub/namespaces", - "apiVersion": "2022-10-01-preview", - "name": "[parameters('namespaceName')]" - }, - "eventHub": { - "existing": true, - "type": "Microsoft.EventHub/namespaces/eventhubs", - "apiVersion": "2022-10-01-preview", - "name": "[format('{0}/{1}', parameters('namespaceName'), parameters('eventHubName'))]" - }, - "roleAssignment": { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.EventHub/namespaces/{0}/eventhubs/{1}', parameters('namespaceName'), parameters('eventHubName'))]", - "name": "[guid(parameters('roleName'), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], subscriptionResourceId('Microsoft.Authorization/roleDefinitions', parameters('roleDefinitionIdOrName')))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]" - } - } - } - } - } - } - } - } - }, - "dependsOn": [ - "evhns" - ] - }, - "evh_authorizationRules": { - "copy": { - "name": "evh_authorizationRules", - "count": "[length(parameters('eventHubAuthorizationRules'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-evh-authrule-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "namespaceName": { - "value": "[parameters('eventHubAuthorizationRules')[copyIndex()].namespaceName]" - }, - "eventHubName": { - "value": "[parameters('eventHubAuthorizationRules')[copyIndex()].eventHubName]" - }, - "name": { - "value": "[parameters('eventHubAuthorizationRules')[copyIndex()].name]" - }, - "rights": { - "value": "[parameters('eventHubAuthorizationRules')[copyIndex()].rights]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "1.10-experimental", - "contentVersion": "1.0.0.0", - "metadata": { - "_EXPERIMENTAL_WARNING": "Symbolic name support in ARM is experimental, and should be enabled for testing purposes only. Do not enable this setting for any production usage, or you may be unexpectedly broken at any time!", - "_generator": { - "name": "bicep", - "version": "0.19.5.34762", - "templateHash": "3736679263237493437" - } - }, - "parameters": { - "namespaceName": { - "type": "string" - }, - "eventHubName": { - "type": "string" - }, - "name": { - "type": "string" - }, - "rights": { - "type": "array" - } - }, - "resources": { - "namespace": { - "existing": true, - "type": "Microsoft.EventHub/namespaces", - "apiVersion": "2022-10-01-preview", - "name": "[parameters('namespaceName')]" - }, - "eventhub": { - "existing": true, - "type": "Microsoft.EventHub/namespaces/eventhubs", - "apiVersion": "2022-10-01-preview", - "name": "[format('{0}/{1}', parameters('namespaceName'), parameters('eventHubName'))]" - }, - "eventHubAuthorizationRule": { - "type": "Microsoft.EventHub/namespaces/eventhubs/authorizationRules", - "apiVersion": "2022-10-01-preview", - "name": "[format('{0}/{1}/{2}', parameters('namespaceName'), parameters('eventHubName'), parameters('name'))]", - "properties": { - "rights": "[parameters('rights')]" - } - } - } - } - }, - "dependsOn": [ - "evh" - ] - }, - "evh_consumerGroups": { - "copy": { - "name": "evh_consumerGroups", - "count": "[length(parameters('eventHubConsumerGroups'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-evh-cg-{1}', deployment().name, copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "namespaceName": { - "value": "[parameters('eventHubConsumerGroups')[copyIndex()].namespaceName]" - }, - "eventHubName": { - "value": "[parameters('eventHubConsumerGroups')[copyIndex()].eventHubName]" - }, - "name": { - "value": "[parameters('eventHubConsumerGroups')[copyIndex()].name]" - }, - "userMetadata": { - "value": "[coalesce(tryGet(parameters('eventHubConsumerGroups')[copyIndex()], 'userMetadata'), '')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "1.10-experimental", - "contentVersion": "1.0.0.0", - "metadata": { - "_EXPERIMENTAL_WARNING": "Symbolic name support in ARM is experimental, and should be enabled for testing purposes only. Do not enable this setting for any production usage, or you may be unexpectedly broken at any time!", - "_generator": { - "name": "bicep", - "version": "0.19.5.34762", - "templateHash": "250162708936612016" - } - }, - "parameters": { - "namespaceName": { - "type": "string" - }, - "eventHubName": { - "type": "string" - }, - "name": { - "type": "string" - }, - "userMetadata": { - "type": "string" - } - }, - "resources": { - "namespace::eventhub": { - "existing": true, - "type": "Microsoft.EventHub/namespaces/eventhubs", - "apiVersion": "2022-10-01-preview", - "name": "[format('{0}/{1}', parameters('namespaceName'), parameters('eventHubName'))]" - }, - "namespace": { - "existing": true, - "type": "Microsoft.EventHub/namespaces", - "apiVersion": "2022-10-01-preview", - "name": "[parameters('namespaceName')]" - }, - "consumerGroup": { - "type": "Microsoft.EventHub/namespaces/eventhubs/consumergroups", - "apiVersion": "2022-10-01-preview", - "name": "[format('{0}/{1}/{2}', parameters('namespaceName'), parameters('eventHubName'), parameters('name'))]", - "properties": { - "userMetadata": "[if(not(empty(parameters('userMetadata'))), parameters('userMetadata'), null())]" - } - } - } - } - }, - "dependsOn": [ - "evh" - ] - }, - "evhns_diagnosticSettings": { - "copy": { - "name": "evhns_diagnosticSettings", - "count": "[length(parameters('namespaceDiagnosticSettings'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-evhns-diagnosticSettings-{1}', deployment().name, copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "namespaceName": { - "value": "[parameters('namespaceDiagnosticSettings')[copyIndex()].namespaceName]" - }, - "name": { - "value": "[parameters('namespaceDiagnosticSettings')[copyIndex()].name]" - }, - "storageAccountId": { - "value": "[coalesce(tryGet(parameters('namespaceDiagnosticSettings')[copyIndex()], 'storageAccountId'), '')]" - }, - "workspaceId": { - "value": "[coalesce(tryGet(parameters('namespaceDiagnosticSettings')[copyIndex()], 'workspaceId'), '')]" - }, - "eventHubAuthorizationRuleId": { - "value": "[coalesce(tryGet(parameters('namespaceDiagnosticSettings')[copyIndex()], 'eventHubAuthorizationRuleId'), '')]" - }, - "eventHubName": { - "value": "[coalesce(tryGet(parameters('namespaceDiagnosticSettings')[copyIndex()], 'eventHubName'), '')]" - }, - "metricsSettings": { - "value": "[coalesce(tryGet(parameters('namespaceDiagnosticSettings')[copyIndex()], 'metricsSettings'), createArray())]" - }, - "logsSettings": { - "value": "[coalesce(tryGet(parameters('namespaceDiagnosticSettings')[copyIndex()], 'logsSettings'), createArray())]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "1.10-experimental", - "contentVersion": "1.0.0.0", - "metadata": { - "_EXPERIMENTAL_WARNING": "Symbolic name support in ARM is experimental, and should be enabled for testing purposes only. Do not enable this setting for any production usage, or you may be unexpectedly broken at any time!", - "_generator": { - "name": "bicep", - "version": "0.19.5.34762", - "templateHash": "1483698508983111743" - } - }, - "parameters": { - "namespaceName": { - "type": "string" - }, - "name": { - "type": "string" - }, - "storageAccountId": { - "type": "string" - }, - "workspaceId": { - "type": "string" - }, - "eventHubAuthorizationRuleId": { - "type": "string" - }, - "eventHubName": { - "type": "string" - }, - "metricsSettings": { - "type": "array" - }, - "logsSettings": { - "type": "array" - } - }, - "resources": { - "namespace": { - "existing": true, - "type": "Microsoft.EventHub/namespaces", - "apiVersion": "2022-10-01-preview", - "name": "[parameters('namespaceName')]" - }, - "namespace_diagnosticSettings": { - "type": "Microsoft.Insights/diagnosticSettings", - "apiVersion": "2021-05-01-preview", - "scope": "[format('Microsoft.EventHub/namespaces/{0}', parameters('namespaceName'))]", - "name": "[parameters('name')]", - "properties": { - "storageAccountId": "[if(not(empty(parameters('storageAccountId'))), parameters('storageAccountId'), null())]", - "workspaceId": "[if(not(empty(parameters('workspaceId'))), parameters('workspaceId'), null())]", - "eventHubAuthorizationRuleId": "[if(not(empty(parameters('eventHubAuthorizationRuleId'))), parameters('eventHubAuthorizationRuleId'), null())]", - "eventHubName": "[if(not(empty(parameters('eventHubName'))), parameters('eventHubName'), null())]", - "metrics": "[parameters('metricsSettings')]", - "logs": "[parameters('logsSettings')]" - } - } - } - } - }, - "dependsOn": [ - "evhns" - ] - }, - "evhns_privateEndpoints": { - "copy": { - "name": "evhns_privateEndpoints", - "count": "[length(parameters('namespacePrivateEndpoints'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-evhns-pep-{1}', uniqueString(deployment().name), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "name": { - "value": "[parameters('namespacePrivateEndpoints')[copyIndex()].name]" - }, - "namespaceName": { - "value": "[parameters('namespacePrivateEndpoints')[copyIndex()].namespaceName]" - }, - "location": { - "value": "[parameters('location')]" - }, - "groupIds": { - "value": "[coalesce(tryGet(parameters('namespacePrivateEndpoints')[copyIndex()], 'groupIds'), createArray('namespace'))]" - }, - "subnetId": { - "value": "[parameters('namespacePrivateEndpoints')[copyIndex()].subnetId]" - }, - "privateDnsZoneId": { - "value": "[coalesce(tryGet(parameters('namespacePrivateEndpoints')[copyIndex()], 'privateDnsZoneId'), '')]" - }, - "tags": { - "value": "[parameters('tags')]" - }, - "manualApprovalEnabled": { - "value": "[coalesce(tryGet(parameters('namespacePrivateEndpoints')[copyIndex()], 'manualApprovalEnabled'), false())]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "1.10-experimental", - "contentVersion": "1.0.0.0", - "metadata": { - "_EXPERIMENTAL_WARNING": "Symbolic name support in ARM is experimental, and should be enabled for testing purposes only. Do not enable this setting for any production usage, or you may be unexpectedly broken at any time!", - "_generator": { - "name": "bicep", - "version": "0.19.5.34762", - "templateHash": "11271554108121564487" - } - }, - "parameters": { - "location": { - "type": "string" - }, - "tags": { - "type": "object" - }, - "manualApprovalEnabled": { - "type": "bool" - }, - "namespaceName": { - "type": "string" - }, - "name": { - "type": "string" - }, - "groupIds": { - "type": "array" - }, - "subnetId": { - "type": "string" - }, - "privateDnsZoneId": { - "type": "string" - } - }, - "resources": { - "privateEndpoint::privateDnsZoneGroup": { - "condition": "[not(empty(parameters('privateDnsZoneId')))]", - "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", - "apiVersion": "2022-05-01", - "name": "[format('{0}/{1}', parameters('name'), 'default')]", - "properties": { - "privateDnsZoneConfigs": [ - { - "name": "default", - "properties": { - "privateDnsZoneId": "[parameters('privateDnsZoneId')]" - } - } - ] - }, - "dependsOn": [ - "privateEndpoint" - ] - }, - "namespace": { - "existing": true, - "type": "Microsoft.EventHub/namespaces", - "apiVersion": "2022-10-01-preview", - "name": "[parameters('namespaceName')]" - }, - "privateEndpoint": { - "type": "Microsoft.Network/privateEndpoints", - "apiVersion": "2022-05-01", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "properties": { - "privateLinkServiceConnections": "[if(parameters('manualApprovalEnabled'), null(), createArray(createObject('name', parameters('name'), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.EventHub/namespaces', parameters('namespaceName')), 'groupIds', if(not(empty(parameters('groupIds'))), parameters('groupIds'), null())))))]", - "manualPrivateLinkServiceConnections": "[if(parameters('manualApprovalEnabled'), createArray(createObject('name', parameters('name'), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.EventHub/namespaces', parameters('namespaceName')), 'groupIds', if(not(empty(parameters('groupIds'))), parameters('groupIds'), null())))), null())]", - "subnet": { - "id": "[parameters('subnetId')]" - } - } - } - } - } - }, - "dependsOn": [ - "evhns" - ] - } - }, - "outputs": { - "eventHubNamespaceNames": { - "type": "array", - "metadata": { - "description": "Azure Event Hub namespace names." - }, - "copy": { - "count": "[length(parameters('namespaces'))]", - "input": "[parameters('namespaces')[copyIndex()].name]" - } - }, - "eventHubNamespaceResourceIds": { - "type": "array", - "metadata": { - "description": "Azure Event Hub namespace resource Ids." - }, - "copy": { - "count": "[length(parameters('namespaces'))]", - "input": "[resourceId('Microsoft.EventHub/namespaces', parameters('namespaces')[copyIndex()].name)]" - } - } - } -} \ No newline at end of file diff --git a/modules/compute/event-hub/modules/authorizationRule.bicep b/modules/compute/event-hub/modules/authorizationRule.bicep deleted file mode 100644 index 62e4dc4e07..0000000000 --- a/modules/compute/event-hub/modules/authorizationRule.bicep +++ /dev/null @@ -1,15 +0,0 @@ -param namespaceName string -param name string -param rights array - -resource namespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' existing = { - name: namespaceName -} - -resource namespaceAuthorizationRule 'Microsoft.EventHub/namespaces/authorizationRules@2022-10-01-preview' = { - name: name - parent: namespace - properties: { - rights: rights - } -} diff --git a/modules/compute/event-hub/modules/diagnosticSetting.bicep b/modules/compute/event-hub/modules/diagnosticSetting.bicep deleted file mode 100644 index 636eeb9654..0000000000 --- a/modules/compute/event-hub/modules/diagnosticSetting.bicep +++ /dev/null @@ -1,25 +0,0 @@ -param namespaceName string -param name string -param storageAccountId string -param workspaceId string -param eventHubAuthorizationRuleId string -param eventHubName string -param metricsSettings array -param logsSettings array - -resource namespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' existing = { - name: namespaceName -} - -resource namespace_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = { - name: name - properties: { - storageAccountId: !empty(storageAccountId) ? storageAccountId : null - workspaceId: !empty(workspaceId) ? workspaceId : null - eventHubAuthorizationRuleId: !empty(eventHubAuthorizationRuleId) ? eventHubAuthorizationRuleId : null - eventHubName: !empty(eventHubName) ? eventHubName : null - metrics: metricsSettings - logs: logsSettings - } - scope: namespace -} diff --git a/modules/compute/event-hub/modules/disasterRecoveryConfig.bicep b/modules/compute/event-hub/modules/disasterRecoveryConfig.bicep deleted file mode 100644 index f330977228..0000000000 --- a/modules/compute/event-hub/modules/disasterRecoveryConfig.bicep +++ /dev/null @@ -1,16 +0,0 @@ -param namespaceName string -param name string -param partnerNamespaceId string = '' - -resource namespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' existing = { - name: namespaceName -} - -resource disasterRecoveryConfig 'Microsoft.EventHub/namespaces/disasterRecoveryConfigs@2022-10-01-preview' = { - name: name - parent: namespace - properties: { - partnerNamespace: partnerNamespaceId - alternateName: 'alternateName' - } -} diff --git a/modules/compute/event-hub/modules/eventHub/authorizationRule.bicep b/modules/compute/event-hub/modules/eventHub/authorizationRule.bicep deleted file mode 100644 index 36d3b11c6b..0000000000 --- a/modules/compute/event-hub/modules/eventHub/authorizationRule.bicep +++ /dev/null @@ -1,21 +0,0 @@ -param namespaceName string -param eventHubName string -param name string -param rights array - -resource namespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' existing = { - name: namespaceName -} - -resource eventhub 'Microsoft.EventHub/namespaces/eventHubs@2022-10-01-preview' existing = { - name: eventHubName - parent: namespace -} - -resource eventHubAuthorizationRule 'Microsoft.EventHub/namespaces/eventhubs/authorizationRules@2022-10-01-preview' = { - name: name - parent: eventhub - properties: { - rights: rights - } -} diff --git a/modules/compute/event-hub/modules/eventHub/consumerGroup.bicep b/modules/compute/event-hub/modules/eventHub/consumerGroup.bicep deleted file mode 100644 index 6d55eeeae0..0000000000 --- a/modules/compute/event-hub/modules/eventHub/consumerGroup.bicep +++ /dev/null @@ -1,20 +0,0 @@ -param namespaceName string -param eventHubName string -param name string -param userMetadata string - -resource namespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' existing = { - name: namespaceName - - resource eventhub 'eventHubs@2022-10-01-preview' existing = { - name: eventHubName - } -} - -resource consumerGroup 'Microsoft.EventHub/namespaces/eventhubs/consumergroups@2022-10-01-preview' = { - name: name - parent: namespace::eventhub - properties: { - userMetadata: !empty(userMetadata) ? userMetadata : null - } -} diff --git a/modules/compute/event-hub/modules/eventHub/eventHub.bicep b/modules/compute/event-hub/modules/eventHub/eventHub.bicep deleted file mode 100644 index dc4b4c04b9..0000000000 --- a/modules/compute/event-hub/modules/eventHub/eventHub.bicep +++ /dev/null @@ -1,71 +0,0 @@ -param namespaceName string -param name string -param messageRetentionInDays int -param partitionCount int -param captureDescriptionEnabled bool -param captureDescriptionDestinationName string -param captureDescriptionDestinationArchiveNameFormat string -param captureDescriptionDestinationBlobContainer string -param captureDescriptionDestinationStorageAccountResourceId string -param captureDescriptionDestinationdataLakeAccountName string -param captureDescriptionDestinationdataLakeFolderPath string -param captureDescriptionDestinationdataLakeSubscriptionId string -param captureDescriptionEncoding string -param captureDescriptionIntervalInSeconds int -param captureDescriptionSizeLimitInBytes int -param captureDescriptionSkipEmptyArchives bool -param roleAssignments array -param status string - -var eventHubPropertiesSimple = { - messageRetentionInDays: messageRetentionInDays - partitionCount: partitionCount - status: status -} - -var eventHubPropertiesWithCapture = { - messageRetentionInDays: messageRetentionInDays - partitionCount: partitionCount - captureDescription: { - destination: { - name: captureDescriptionDestinationName - properties: { - archiveNameFormat: captureDescriptionDestinationArchiveNameFormat - blobContainer: captureDescriptionDestinationBlobContainer - storageAccountResourceId: captureDescriptionDestinationStorageAccountResourceId - dataLakeAccountName: captureDescriptionDestinationdataLakeAccountName - dataLakeFolderPath: captureDescriptionDestinationdataLakeFolderPath - dataLakeSubscriptionId: captureDescriptionDestinationdataLakeSubscriptionId - } - } - enabled: captureDescriptionEnabled - encoding: captureDescriptionEncoding - intervalInSeconds: captureDescriptionIntervalInSeconds - sizeLimitInBytes: captureDescriptionSizeLimitInBytes - skipEmptyArchives: captureDescriptionSkipEmptyArchives - status: status - } -} - -resource namespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' existing = { - name: namespaceName -} - -resource eventHub 'Microsoft.EventHub/namespaces/eventhubs@2022-10-01-preview' = { - name: name - parent: namespace - properties: captureDescriptionEnabled ? eventHubPropertiesWithCapture : eventHubPropertiesSimple -} - -module eventHub_roleAssignments './roleAssignment.bicep' = [for (role, index) in roleAssignments: { - name: '${deployment().name}-evh-role-${index}' - params: { - description: role.?description ?? '' - principalIds: role.principalIds - principalType: role.?principalType ?? '' - roleDefinitionIdOrName: role.roleDefinitionIdOrName - roleName: role.?name ?? '' - namespaceName: namespaceName - eventHubName: name - } -}] diff --git a/modules/compute/event-hub/modules/eventHub/roleAssignment.bicep b/modules/compute/event-hub/modules/eventHub/roleAssignment.bicep deleted file mode 100644 index a4c605afd2..0000000000 --- a/modules/compute/event-hub/modules/eventHub/roleAssignment.bicep +++ /dev/null @@ -1,48 +0,0 @@ -param roleName string -param description string -param principalIds array -param roleDefinitionIdOrName string -param principalType string -param namespaceName string -param eventHubName string - -var builtInRoleNames = { - 'Azure Event Hubs Data Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f526a384-b230-433a-b45c-95f59c4a2dec') - 'Azure Event Hubs Data Receiver': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a638d3c7-ab3a-418d-83e6-5f17a39d4fde') - 'Azure Event Hubs Data Sender': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2b629674-e913-4c01-ae53-ef4638d8f975') - Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'Log Analytics Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293') - 'Log Analytics Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893') - 'Managed Application Contributor Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e') - 'Managed Application Operator Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae') - 'Managed Applications Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44') - 'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa') - 'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05') - Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') - Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - 'Resource Policy Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608') - 'Role Based Access Control Administrator (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168') - 'Schema Registry Contributor (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5dffeca3-4936-4216-b2bc-10343a5abb25') - 'Schema Registry Reader (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2c56ea50-c6b3-40a6-83c0-9d98858bc7d2') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') -} - -resource namespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' existing = { - name: namespaceName -} - -resource eventHub 'Microsoft.EventHub/namespaces/eventhubs@2022-10-01-preview' existing = { - name: eventHubName - parent: namespace -} - -resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for principalId in principalIds: { - name: guid(roleName, principalId, roleDefinitionIdOrName) - properties: { - description: description - roleDefinitionId: contains(builtInRoleNames, roleDefinitionIdOrName) ? builtInRoleNames[roleDefinitionIdOrName] : subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionIdOrName) - principalId: principalId - principalType: !empty(principalType) ? any(principalType) : null - } - scope: eventHub -}] diff --git a/modules/compute/event-hub/modules/privateEndpoint.bicep b/modules/compute/event-hub/modules/privateEndpoint.bicep deleted file mode 100644 index ad0d2a7103..0000000000 --- a/modules/compute/event-hub/modules/privateEndpoint.bicep +++ /dev/null @@ -1,53 +0,0 @@ -param location string -param tags object -param manualApprovalEnabled bool -param namespaceName string -param name string -param groupIds array -param subnetId string -param privateDnsZoneId string - -resource namespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' existing = { - name: namespaceName -} - -resource privateEndpoint 'Microsoft.Network/privateEndpoints@2022-05-01' = { - name: name - location: location - tags: tags - properties: { - privateLinkServiceConnections: manualApprovalEnabled ? null : [ - { - name: name - properties: { - privateLinkServiceId: namespace.id - groupIds: !empty(groupIds) ? groupIds : null - } - } - ] - manualPrivateLinkServiceConnections: manualApprovalEnabled ? [ - { - name: name - properties: { - privateLinkServiceId: namespace.id - groupIds: !empty(groupIds) ? groupIds : null - } - } - ] : null - subnet: { - id: subnetId - } - } - resource privateDnsZoneGroup 'privateDnsZoneGroups@2022-05-01' = if (!empty(privateDnsZoneId)) { - name: 'default' - properties: { - privateDnsZoneConfigs: [ { - name: 'default' - properties: { - privateDnsZoneId: privateDnsZoneId - } - } ] - } - } - -} diff --git a/modules/compute/event-hub/modules/roleAssignment.bicep b/modules/compute/event-hub/modules/roleAssignment.bicep deleted file mode 100644 index 251520a79b..0000000000 --- a/modules/compute/event-hub/modules/roleAssignment.bicep +++ /dev/null @@ -1,42 +0,0 @@ -param roleName string -param description string -param principalIds array -param roleDefinitionIdOrName string -param principalType string -param namespaceName string - -var builtInRoleNames = { - 'Azure Event Hubs Data Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f526a384-b230-433a-b45c-95f59c4a2dec') - 'Azure Event Hubs Data Receiver': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a638d3c7-ab3a-418d-83e6-5f17a39d4fde') - 'Azure Event Hubs Data Sender': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2b629674-e913-4c01-ae53-ef4638d8f975') - Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'Log Analytics Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293') - 'Log Analytics Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893') - 'Managed Application Contributor Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e') - 'Managed Application Operator Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae') - 'Managed Applications Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44') - 'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa') - 'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05') - Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') - Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - 'Resource Policy Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608') - 'Role Based Access Control Administrator (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168') - 'Schema Registry Contributor (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5dffeca3-4936-4216-b2bc-10343a5abb25') - 'Schema Registry Reader (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2c56ea50-c6b3-40a6-83c0-9d98858bc7d2') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') -} - -resource namespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' existing = { - name: namespaceName -} - -resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for principalId in principalIds: { - name: guid(roleName, principalId, roleDefinitionIdOrName) - properties: { - description: description - roleDefinitionId: contains(builtInRoleNames, roleDefinitionIdOrName) ? builtInRoleNames[roleDefinitionIdOrName] : subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionIdOrName) - principalId: principalId - principalType: !empty(principalType) ? any(principalType) : null - } - scope: namespace -}] diff --git a/modules/compute/event-hub/test/main.test.bicep b/modules/compute/event-hub/test/main.test.bicep deleted file mode 100644 index 9942af1400..0000000000 --- a/modules/compute/event-hub/test/main.test.bicep +++ /dev/null @@ -1,237 +0,0 @@ -targetScope = 'resourceGroup' -param location string = 'eastus2' -var uniqueName = uniqueString(resourceGroup().id, deployment().name, location) -param serviceShort string = 'eventhub' - -// ============= // -// Prerequisites // -// ============= // - -module dependencies 'prereq.test.bicep' = { - name: 'test-prereq' - params: { - name: serviceShort - location: location - prefix: uniqueName - } -} - -// Test 01 - Standard SKU with cluster and Parameters, AuthorizationRules(namespace,eventHub), EventHuba, ConsumerGroups -module test_01 '../main.bicep' = { - name: 'test01-${uniqueName}' - params: { - location: location - namespaces: [ - { - name: 'test01-${uniqueName}-ns1' - capacity: 2 - isAutoInflateEnabled: true - maximumThroughputUnits: 6 - zoneRedundant: true - } - { - name: 'test01-${uniqueName}-ns2' - sku: 'Basic' - } - ] - namespaceAuthorizationRules: [ - { - name: 'test01-${uniqueName}-ns-authrule01' - rights: [ 'Listen', 'Manage', 'Send' ] - namespaceName: 'test01-${uniqueName}-ns1' - } - { - name: 'test01-${uniqueName}-ns-authrule02' - rights: [ 'Listen' ] - namespaceName: 'test01-${uniqueName}-ns1' - } - ] - eventHubs: [ - { - name: 'test01-${uniqueName}-evh1' - messageRetentionInDays: 4 - partitionCount: 4 - namespaceName: 'test01-${uniqueName}-ns1' - } - { - name: 'test01-${uniqueName}-evh2' - messageRetentionInDays: 7 - partitionCount: 2 - namespaceName: 'test01-${uniqueName}-ns1' - } - ] - eventHubAuthorizationRules: [ - { - name: 'test01-${uniqueName}-evh-rule01' - rights: [ 'Listen', 'Manage', 'Send' ] - namespaceName: 'test01-${uniqueName}-ns1' - eventHubName: 'test01-${uniqueName}-evh1' - } - ] - eventHubConsumerGroups: [ - { - name: 'test01-${uniqueName}-cg01' - namespaceName: 'test01-${uniqueName}-ns1' - eventHubName: 'test01-${uniqueName}-evh1' - } - ] - tags: { - tag1: 'tag1value' - tag2: 'tag2value' - } - } -} - -// Test 02 - Premium SKU - Role Assignments at namespace and eventHub scope -module test_02 '../main.bicep' = { - name: 'test02-${uniqueName}' - params: { - location: location - namespaces: [ - { - name: 'test02-${uniqueName}-ns' - sku: 'Premium' - capacity: 2 - zoneRedundant: true - } - ] - namespaceRoleAssignments: [ - { - name: 'test02-${uniqueName}-rol01' - description: 'Reader Role Assignment' - principalIds: [ dependencies.outputs.identityPrincipalIds[1] ] - principalType: 'ServicePrincipal' - roleDefinitionIdOrName: 'f526a384-b230-433a-b45c-95f59c4a2dec' // Azure Event Hubs Data Owner - namespaceName: 'test02-${uniqueName}-ns' - } - ] - eventHubs: [ - { - name: 'test02-${uniqueName}-evh' - messageRetentionInDays: 1 - partitionCount: 1 - namespaceName: 'test02-${uniqueName}-ns' - roleAssignments: [ - { - roleDefinitionIdOrName: 'Contributor' - description: 'Contributor Role Assignment' - principalIds: [ dependencies.outputs.identityPrincipalIds[0] ] - principalType: 'ServicePrincipal' - - } - ] - } - ] - } -} - -// Test 03 - Standard SKU - PrivateEndpoints, DiagnosticSettings with EventHub -module test_03 '../main.bicep' = { - name: 'test03-${uniqueName}' - params: { - location: location - namespaces: [ - { - name: 'test03-${uniqueName}-ns' - sku: 'Standard' - capacity: 4 - publicNetworkAccess: 'Disabled' - } - ] - namespacePrivateEndpoints: [ - { - name: 'endpoint1' - subnetId: dependencies.outputs.subnetIds[0] - namespaceName: 'test03-${uniqueName}-ns' - manualApprovalEnabled: true - } - { - name: 'endpoint2' - subnetId: dependencies.outputs.subnetIds[1] - privateDnsZoneId: dependencies.outputs.privateDNSZoneId - namespaceName: 'test03-${uniqueName}-ns' - } - ] - namespaceDiagnosticSettings: [ - { - name: 'test03-${uniqueName}-ds' - namespaceName: 'test03-${uniqueName}-ns' - eventHubAuthorizationRuleId: dependencies.outputs.authorizationRuleId - eventHubName: dependencies.outputs.eventHubName - metricsSettings: [ - { - category: 'AllMetrics' - timeGrain: 'PT1M' - enabled: true - retentionPolicy: { - days: 7 - enabled: true - } - } - ] - logsSettings: [ - { - category: 'OperationalLogs' - enabled: true - retentionPolicy: { - days: 36 - enabled: true - } - } - { - category: 'ArchiveLogs' - enabled: true - } - ] - } - ] - } -} - -// Test 04 - Standard SKU - Event Hub Capture to StorageAccount, DiagnosticSettings with StorageAccount and LogAnalyticsWorkspace -module test_04 '../main.bicep' = { - name: 'test04-${uniqueName}' - params: { - location: location - namespaces: [ - { - name: 'test04-${uniqueName}-ns' - sku: 'Standard' - capacity: 1 - zoneRedundant: false - } - ] - eventHubs: [ - { - name: 'test04-${uniqueName}-evh' - messageRetentionInDays: 1 - partitionCount: 2 - namespaceName: 'test04-${uniqueName}-ns' - captureDescriptionEnabled: true - captureDescriptionDestinationBlobContainer: dependencies.outputs.containerName - captureDescriptionDestinationStorageAccountResourceId: dependencies.outputs.storageAccountId - } - ] - namespaceDiagnosticSettings: [ - { - name: 'test04-${uniqueName}-ds' - namespaceName: 'test04-${uniqueName}-ns' - storageAccountId: dependencies.outputs.storageAccountId - workspaceId: dependencies.outputs.workspaceId - metricsSettings: [ { category: 'AllMetrics', enabled: true, retentionPolicy: { days: 365, enabled: true } } ] - logsSettings: [ - { - category: 'ArchiveLogs' - enabled: true - retentionPolicy: { days: 7, enabled: true } - } - { - category: 'RuntimeAuditLogs' - enabled: true - retentionPolicy: { days: 3, enabled: true } - } - ] - } - ] - } -} diff --git a/modules/compute/event-hub/test/prereq.test.bicep b/modules/compute/event-hub/test/prereq.test.bicep deleted file mode 100644 index 5e8f51a329..0000000000 --- a/modules/compute/event-hub/test/prereq.test.bicep +++ /dev/null @@ -1,126 +0,0 @@ -param location string -param name string -param prefix string -param blobServiceName string = 'default' - -resource storageAccount 'Microsoft.Storage/storageAccounts@2022-05-01' = { - name: '${name}${prefix}01' - kind: 'StorageV2' - sku: { - name: 'Standard_LRS' - } - location: location - properties: { - allowBlobPublicAccess: false - } -} - -resource blobService 'Microsoft.Storage/storageAccounts/blobServices@2021-06-01' = { - name: blobServiceName - parent: storageAccount -} - -resource container 'Microsoft.Storage/storageAccounts/blobServices/containers@2021-06-01' = { - name: '${name}${prefix}01' - parent: blobService - properties: {} -} - -resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' = { - name: 'law-${name}${prefix}-01' - location: location -} - -resource eventHubNamespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' = { - name: 'evhns-${name}${prefix}-01' - location: location -} - -resource eventHub 'Microsoft.EventHub/namespaces/eventhubs@2022-10-01-preview' = { - name: 'eventHub-${name}${prefix}-01' - parent: eventHubNamespace -} - -resource authorizationRule 'Microsoft.EventHub/namespaces/authorizationRules@2022-01-01-preview' = { - name: 'RootManageSharedAccessKey' - properties: { - rights: [ - 'Listen' - 'Manage' - 'Send' - ] - } - parent: eventHubNamespace -} - -resource virtualNetwork 'Microsoft.Network/virtualNetworks@2022-05-01' = { - name: 'vnet-${name}${prefix}-01' - location: location - properties: { - addressSpace: { - addressPrefixes: [ - '10.0.0.0/16' - ] - } - subnets: [ - { - name: '${name}-subnet-0' - properties: { - addressPrefix: '10.0.0.0/24' - privateEndpointNetworkPolicies: 'Disabled' - } - } - { - name: '${name}-subnet-1' - properties: { - addressPrefix: '10.0.1.0/24' - privateEndpointNetworkPolicies: 'Disabled' - } - } - ] - } -} - -resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { - name: 'privatelink.servicebus.windows.net' - location: 'global' - properties: {} -} - -resource virtualNetworkLinks 'Microsoft.Network/privateDnsZones/virtualNetworkLinks@2020-06-01' = { - parent: privateDNSZone - name: '${name}-${prefix}-vnet-link' - location: 'global' - properties: { - registrationEnabled: false - virtualNetwork: { - id: virtualNetwork.id - } - } -} - -resource managedIdentity_01 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: '${name}-${prefix}-01' - location: location -} - -resource managedIdentity_02 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: '${name}-${prefix}-02' - location: location -} - -output storageAccountId string = storageAccount.id -output containerName string = container.name -output workspaceId string = logAnalyticsWorkspace.id -output eventHubNamespaceId string = eventHubNamespace.id -output eventHubName string = eventHub.name -output authorizationRuleId string = authorizationRule.id -output subnetIds array = [ - virtualNetwork.properties.subnets[0].id - virtualNetwork.properties.subnets[1].id -] -output privateDNSZoneId string = privateDNSZone.id -output identityPrincipalIds array = [ - managedIdentity_01.properties.principalId - managedIdentity_02.properties.principalId -] diff --git a/modules/compute/event-hub/version.json b/modules/compute/event-hub/version.json deleted file mode 100644 index 4727c64800..0000000000 --- a/modules/compute/event-hub/version.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "2.0", - "pathFilters": [ - "./main.json", - "./metadata.json" - ] -} \ No newline at end of file diff --git a/modules/compute/function-app/README.md b/modules/compute/function-app/README.md deleted file mode 100644 index e774998081..0000000000 --- a/modules/compute/function-app/README.md +++ /dev/null @@ -1,141 +0,0 @@ -# Function app module - -Module to create function app for your application - -## Details - -This is a low-level Bicep module for managing Azure Functions, it supports an array of function, also the user has the option to either choose use user assigned identity or system assigned identity and also support the storage account to be in different resource group. - -## Parameters - -| Name | Type | Required | Description | -| :-------------------------------- | :------: | :------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `name` | `string` | Yes | Required. Name for the Azure Function App. | -| `location` | `string` | Yes | Required. Location for all resources. | -| `tags` | `object` | No | Optional. Tags for all resources within Azure Function App module. | -| `sku` | `object` | No | Required. Defines the name, tier, size, family and capacity of the app service plan. | -| `serverOS` | `string` | No | Optional. Kind of server OS. | -| `perSiteScaling` | `bool` | No | Optional. If true, apps assigned to this app service plan can be scaled independently. If false, apps assigned to this app service plan will scale to all instances of the plan. | -| `maximumElasticWorkerCount` | `int` | No | Optional. Maximum number of total workers allowed for this ElasticScaleEnabled app service plan. | -| `targetWorkerCount` | `int` | No | Optional. Scaling worker count. | -| `targetWorkerSizeId` | `int` | No | Optional. The instance size of the hosting plan (small, medium, or large). | -| `identityType` | `string` | No | Optional. The type of identity used for the virtual machine. The type 'SystemAssigned, UserAssigned' includes both an implicitly created identity and a set of user assigned identities. The type 'None' will remove any identities from the sites ( app or functionapp). | -| `userAssignedIdentityId` | `string` | No | Optional. Specify the resource ID of the user assigned Managed Identity, if 'identity' is set as 'UserAssigned'. | -| `httpsOnly` | `bool` | No | Optional. Configures a site to accept only HTTPS requests. Issues redirect for HTTP requests. | -| `appServiceEnvironmentId` | `string` | No | Optional. The resource ID of the app service environment to use for this resource. | -| `clientAffinityEnabled` | `bool` | No | Optional. If client affinity is enabled. | -| `kind` | `string` | No | Required. Type of site to deploy. | -| `functionsExtensionVersion` | `string` | No | Optional. Version of the function extension. | -| `functionAppEditMode` | `string` | No | Dictates whether editing in the Azure portal is enabled. | -| `functionsWorkerRuntime` | `string` | No | Optional. Runtime of the function worker. WARNING: NOT ALL OSes SUPPORT ALL RUNTIMES! | -| `functionsDefaultNodeversion` | `string` | No | Optional. NodeJS version. | -| `publicNetworkAccessForIngestion` | `string` | No | Optional. The network access type for accessing Application Insights ingestion. - Enabled or Disabled. | -| `publicNetworkAccessForQuery` | `string` | No | Optional. The network access type for accessing Application Insights query. - Enabled or Disabled. | -| `appInsightsType` | `string` | No | Optional. Application type. | -| `appInsightsKind` | `string` | No | Optional. The kind of application that this component refers to, used to customize UI. | -| `enableInsights` | `bool` | No | Optional. Enabled or Disable Insights for Azure functions. | -| `workspaceResourceId` | `string` | No | Optional. Resource ID of the log analytics workspace which the data will be ingested to, if enableaInsights is false. | -| `functions` | `array` | No | Optional. List of Azure function (Actual object where our code resides). | -| `enableVnetIntegration` | `bool` | No | Optional. Enable Vnet Integration or not. | -| `subnetId` | `string` | No | Optional. The subnet that will be integrated to enable vnet Integration. | -| `enableSourceControl` | `bool` | No | Optional. Enable Source control for the function. | -| `repoUrl` | `string` | No | Optional. Repository or source control URL. | -| `branch` | `string` | No | Optional. Name of branch to use for deployment. | -| `storageAccountName` | `string` | Yes | Required. Name of the storage account used by function app. | -| `isManualIntegration` | `bool` | No | Optional. to limit to manual integration; to enable continuous integration (which configures webhooks into online repos like GitHub). | -| `isMercurial` | `bool` | No | Optional. true for a Mercurial repository; false for a Git repository. | -| `storageAccountResourceGroup` | `string` | Yes | Required. Resource Group of storage account used by function app. | -| `enablePackageDeploy` | `bool` | No | Optional. True to deploy functions from zip package. "functionPackageUri" must be specified if enabled. The package option and sourcecontrol option should not be enabled at the same time. | -| `functionPackageUri` | `string` | No | Optional. URI to the function source code zip package, must be accessible by the deployer. E.g. A zip file on Azure storage in the same resource group. | -| `enableDockerContainer` | `bool` | No | Optional. Enable docker image deployment. | -| `dockerImage` | `string` | No | Optional. This will be required when enableDockerContainer passed as true. | -| `extraAppSettings` | `object` | No | Optional. Extra app settings that should be provisioned while creating the function app. Note! Settings below should not be included unless absolutely necessary, because settings in this param will override the ones added by the module:
AzureWebJobsStorage
AzureWebJobsDashboard
WEBSITE_CONTENTSHARE
WEBSITE_CONTENTAZUREFILECONNECTIONSTRING
FUNCTIONS_EXTENSION_VERSION
FUNCTIONS_WORKER_RUNTIME
WEBSITE_NODE_DEFAULT_VERSION
APPINSIGHTS_INSTRUMENTATIONKEY
APPLICATIONINSIGHTS_CONNECTION_STRING | -| `ftpsState` | `string` | No | The state of FTP / FTPS service. | -| `minTlsVersion` | `string` | No | Configures the minimum version of TLS required for SSL requests. | -| `linuxFxVersion` | `string` | No | Linux App Framework and version. e.g. PYTHON|3.9 | -| `connectionStringProperties` | `object` | No | The connection strings properties | - -## Outputs - -| Name | Type | Description | -| :---------------- | :------: | :------------------------------------------------------------------------ | -| `siteId` | `string` | Get resource id for app or functionapp. | -| `siteName` | `string` | Get resource name for app or functionapp. | -| `serverfarmsId` | `string` | Get resource ID of the app service plan. | -| `serverfarmsName` | `string` | Get name of the app service plan. | -| `functions` | `array` | Array of functions having name , language,isDisabled and id of functions. | -| `sitePrincipalId` | `string` | Principal Id of the identity assigned to the function app. | - -## Examples - -### Example 1 - -```bicep -@description(''' -In example, function app is using pre-built docker image, -deploy your code to Azure Functions as a custom Docker container using a image provided. -''') -module funcApp 'br/public:bicep/compute/function-app:2.0.1' = { - name: 'func1${uniqueString(name)}' - dependsOn: [ - dependencies - ] - params: { - name: take(replace('fun1-${name}', '.', ''), 55) - location: location - sku: { - name: 'Y1' - tier: 'Dynamic' - size: 'Y1' - family: 'Y' - capacity: 0 - } - tags: tags - storageAccountName: dependencies.outputs.saAccountName - storageAccountResourceGroup: resourceGroup().name - enableSourceControl: false - enableDockerContainer: true - dockerImage: 'mcr.microsoft.com/azure-functions/dotnet:4-appservice-quickstart' - serverOS: 'Linux' - } - scope: resourceGroup() -} - -### Example 2 -@description(''' -In example, function app uses source control option for -Continuous deployment for Azure Functions ie. repoUrl param value. -''') -module funcApp 'br/public:bicep/compute/function-app:2.0.1' = { - name: 'func2-${uniqueString(name)}' - scope: resourceGroup() - dependsOn: [ - dependencies - ] - params: { - name: take(replace('fun2-${name}', '.', ''), 55) - location: location - sku: { - name: 'EP1' - tier: 'ElasticPremium' - size: 'EP1' - family: 'EP' - capacity: 1 - } - tags: tags - maximumElasticWorkerCount: 20 - enableVnetIntegration: true - enableInsights: true - workspaceResourceId: dependencies.outputs.workspacesId - subnetId: dependencies.outputs.subnetResourceIds - functionsExtensionVersion: '~4' - functionsWorkerRuntime: 'powershell' - storageAccountName: dependencies.outputs.saAccountName - storageAccountResourceGroup: resourceGroup().name - enableSourceControl: true - repoUrl: 'https://github.com/Azure/KeyVault-Secrets-Rotation-Redis-PowerShell.git' - enableDockerContainer: false - } -} - -``` \ No newline at end of file diff --git a/modules/compute/function-app/bicepconfig.json b/modules/compute/function-app/bicepconfig.json deleted file mode 100644 index 072e1e7264..0000000000 --- a/modules/compute/function-app/bicepconfig.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "experimentalFeaturesEnabled": { - "userDefinedTypes": true - } -} diff --git a/modules/compute/function-app/main.bicep b/modules/compute/function-app/main.bicep deleted file mode 100644 index f7635586e9..0000000000 --- a/modules/compute/function-app/main.bicep +++ /dev/null @@ -1,339 +0,0 @@ -metadata name = 'Function app module' -metadata description = 'Module to create function app for your application' -metadata owner = 'rhalloul' - -/*param section*/ -@description('Required. Name for the Azure Function App.') -@maxLength(64) -param name string - -@description('Required. Location for all resources.') -param location string - -@description('Optional. Tags for all resources within Azure Function App module.') -param tags object = {} - -@description('Required. Defines the name, tier, size, family and capacity of the app service plan.') -param sku object = { - name: 'Y1' - tier: 'Dynamic' - size: 'Y1' - family: 'Y' - capacity: 0 -} - -@description('Optional. Kind of server OS.') -@allowed([ 'Windows', 'Linux' ]) -param serverOS string = 'Windows' - -@description('Optional. If true, apps assigned to this app service plan can be scaled independently. If false, apps assigned to this app service plan will scale to all instances of the plan.') -param perSiteScaling bool = false - -@description('Optional. Maximum number of total workers allowed for this ElasticScaleEnabled app service plan.') -param maximumElasticWorkerCount int = 0 - -@description('Optional. Scaling worker count.') -param targetWorkerCount int = 0 - -@description('Optional. The instance size of the hosting plan (small, medium, or large).') -@allowed([ 0, 1, 2 ]) -param targetWorkerSizeId int = 0 - -@allowed(['None', 'SystemAssigned', 'UserAssigned', 'SystemAssigned, UserAssigned' -]) -@description('Optional. The type of identity used for the virtual machine. The type \'SystemAssigned, UserAssigned\' includes both an implicitly created identity and a set of user assigned identities. The type \'None\' will remove any identities from the sites ( app or functionapp).') -param identityType string = 'SystemAssigned' - -@description('Optional. Specify the resource ID of the user assigned Managed Identity, if \'identity\' is set as \'UserAssigned\'.') -param userAssignedIdentityId string = '' - -@description('Optional. Configures a site to accept only HTTPS requests. Issues redirect for HTTP requests.') -param httpsOnly bool = true - -@description('Optional. The resource ID of the app service environment to use for this resource.') -param appServiceEnvironmentId string = '' - -@description('Optional. If client affinity is enabled.') -param clientAffinityEnabled bool = true - -@description('Required. Type of site to deploy.') -@allowed([ 'functionapp', 'app' ]) -param kind string = 'functionapp' - -@description('Optional. Version of the function extension.') -param functionsExtensionVersion string = '~4' - -@description('Dictates whether editing in the Azure portal is enabled.') -@allowed(['readonly', 'readwrite']) -param functionAppEditMode string = 'readonly' - -@description('Optional. Runtime of the function worker. WARNING: NOT ALL OSes SUPPORT ALL RUNTIMES!') -@allowed(['dotnet', 'node', 'python', 'java', 'powershell', '']) -param functionsWorkerRuntime string = '' - -@description('Optional. NodeJS version.') -param functionsDefaultNodeversion string = '~14' - -@allowed([ 'Disabled', 'Enabled' ]) -@description('Optional. The network access type for accessing Application Insights ingestion. - Enabled or Disabled.') -param publicNetworkAccessForIngestion string = 'Enabled' - -@allowed([ 'Disabled', 'Enabled' ]) -@description('Optional. The network access type for accessing Application Insights query. - Enabled or Disabled.') -param publicNetworkAccessForQuery string = 'Enabled' - -@description('Optional. Application type.') -@allowed([ 'web', 'other' ]) -param appInsightsType string = 'web' - -@description('Optional. The kind of application that this component refers to, used to customize UI.') -param appInsightsKind string = 'azfunc' - -@description('Optional. Enabled or Disable Insights for Azure functions.') -param enableInsights bool = false - -@description('Optional. Resource ID of the log analytics workspace which the data will be ingested to, if enableaInsights is false.') -param workspaceResourceId string = '' - -@description('Optional. List of Azure function (Actual object where our code resides).') -param functions functionType[] = [] - -@description('Optional. Enable Vnet Integration or not.') -param enableVnetIntegration bool = false - -@description('Optional. The subnet that will be integrated to enable vnet Integration.') -param subnetId string = '' - -@description('Optional. Enable Source control for the function.') -param enableSourceControl bool = false - -@description('Optional. Repository or source control URL.') -param repoUrl string = '' - -@description('Optional. Name of branch to use for deployment.') -param branch string = 'main' - -@description('Required. Name of the storage account used by function app.') -param storageAccountName string - -@description('Optional. to limit to manual integration; to enable continuous integration (which configures webhooks into online repos like GitHub).') -param isManualIntegration bool = true - -@description('Optional. true for a Mercurial repository; false for a Git repository.') -param isMercurial bool = false - -@description('Required. Resource Group of storage account used by function app.') -param storageAccountResourceGroup string - -@description('Optional. True to deploy functions from zip package. "functionPackageUri" must be specified if enabled. The package option and sourcecontrol option should not be enabled at the same time.') -param enablePackageDeploy bool = false - -@description('Optional. URI to the function source code zip package, must be accessible by the deployer. E.g. A zip file on Azure storage in the same resource group.') -param functionPackageUri string = '' - -@description('Optional. Enable docker image deployment.') -param enableDockerContainer bool = false - -@description('Optional. This will be required when enableDockerContainer passed as true.') -param dockerImage string = '' - -@description('''Optional. Extra app settings that should be provisioned while creating the function app. Note! Settings below should not be included unless absolutely necessary, because settings in this param will override the ones added by the module: -AzureWebJobsStorage -AzureWebJobsDashboard -WEBSITE_CONTENTSHARE -WEBSITE_CONTENTAZUREFILECONNECTIONSTRING -FUNCTIONS_EXTENSION_VERSION -FUNCTIONS_WORKER_RUNTIME -WEBSITE_NODE_DEFAULT_VERSION -APPINSIGHTS_INSTRUMENTATIONKEY -APPLICATIONINSIGHTS_CONNECTION_STRING''') -param extraAppSettings object = {} - -@description('The kind of resource. Empty string means windows.') -var servicePlanKind = serverOS == 'Linux' ? toLower(serverOS) : '' - -@description('The state of FTP / FTPS service.') -@allowed(['Disabled', 'AllAllowed', 'FtpsOnly']) -param ftpsState string = 'Disabled' - -@description('Configures the minimum version of TLS required for SSL requests.') -@allowed(['1.0', '1.1', '1.2']) -param minTlsVersion string = '1.2' - -@description('Linux App Framework and version. e.g. PYTHON|3.9') -param linuxFxVersion string = '' - -@description('The connection strings properties') -param connectionStringProperties object = {} - -@description('Defines storageAccounts for Azure Function App.') -resource storageAccount 'Microsoft.Storage/storageAccounts@2021-06-01' existing = { - name: storageAccountName - scope: resourceGroup(storageAccountResourceGroup) -} - -@description('Defines Application service plan.') -resource serverfarms 'Microsoft.Web/serverfarms@2021-02-01' = { - name: name - location: location - tags: tags - sku: sku - kind: servicePlanKind - properties: { - perSiteScaling: perSiteScaling - maximumElasticWorkerCount: maximumElasticWorkerCount - reserved: serverOS == 'Linux' - targetWorkerCount: targetWorkerCount - targetWorkerSizeId: targetWorkerSizeId - } -} - -@description('If enabled, this will help monitor the application using the log analytics workspace.') -resource appInsights 'Microsoft.Insights/components@2020-02-02' = if (enableInsights) { - name: 'ai-${name}' - location: location - kind: appInsightsKind - properties: { - Application_Type: appInsightsType - WorkspaceResourceId: workspaceResourceId - publicNetworkAccessForIngestion: publicNetworkAccessForIngestion - publicNetworkAccessForQuery: publicNetworkAccessForQuery - } - tags: tags -} - -@description('''The app or function app resource. -Note: This is not actual Azure Function App this will be container for storing multiple functions.''') -resource sites 'Microsoft.Web/sites@2022-03-01' = { - name: name - location: location - tags: tags - kind: kind - identity: { - type: identityType - userAssignedIdentities: (identityType == 'UserAssigned' || identityType == 'SystemAssigned, UserAssigned') ? { - '${userAssignedIdentityId}': {} - } : null - } - properties: { - siteConfig: { - linuxFxVersion: enableDockerContainer ? 'DOCKER|${dockerImage}' : linuxFxVersion ?? null - ftpsState: ftpsState - minTlsVersion: minTlsVersion - } - serverFarmId: serverfarms.id - httpsOnly: httpsOnly - hostingEnvironmentProfile: !empty(appServiceEnvironmentId) ? { - id: appServiceEnvironmentId - } : null - clientAffinityEnabled: clientAffinityEnabled - } -} - -@description('Appsettings/config for the sites (app or functionapp).') -resource config 'Microsoft.Web/sites/config@2021-02-01' = { - parent: sites - name: 'appsettings' - properties: union({ - AzureWebJobsStorage: !empty(storageAccount.id) ? 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};AccountKey=${storageAccount.listKeys().keys[0].value};' : any(null) - AzureWebJobsDashboard: !empty(storageAccount.id) ? 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};AccountKey=${storageAccount.listKeys().keys[0].value};' : any(null) - WEBSITE_CONTENTSHARE: name - WEBSITE_CONTENTAZUREFILECONNECTIONSTRING: !empty(storageAccount.id) ? 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};AccountKey=${storageAccount.listKeys().keys[0].value};' : any(null) - FUNCTIONS_EXTENSION_VERSION: functionsExtensionVersion - FUNCTION_APP_EDIT_MODE: functionAppEditMode - FUNCTIONS_WORKER_RUNTIME: sites.kind == 'functionapp' && !empty(functionsWorkerRuntime) ? functionsWorkerRuntime : any(null) - WEBSITE_NODE_DEFAULT_VERSION: sites.kind == 'functionapp' && functionsWorkerRuntime == 'node' && !empty(functionsDefaultNodeversion) ? functionsDefaultNodeversion : any(null) - APPINSIGHTS_INSTRUMENTATIONKEY: !empty(appInsights.id) && enableInsights ? appInsights.properties.InstrumentationKey : any(null) - APPLICATIONINSIGHTS_CONNECTION_STRING: !empty(appInsights.id) && enableInsights ? appInsights.properties.ConnectionString : any(null) - }, extraAppSettings) - dependsOn: enableVnetIntegration ? [ networkConfig ] : [] -} - -resource connectionString 'Microsoft.Web/sites/config@2022-03-01' = if (!empty(connectionStringProperties)) { - name: 'connectionstrings' - kind: 'string' - parent: sites - properties: connectionStringProperties -} - -resource networkConfig 'Microsoft.Web/sites/networkConfig@2022-03-01' = if (enableVnetIntegration == true) { - parent: sites - name: 'virtualNetwork' - properties: { - subnetResourceId: subnetId - } -} - -@description('The resources actual is function where code exits.') -@batchSize(1) -resource azureFunction 'Microsoft.Web/sites/functions@2021-02-01' = [for function in functions: { - dependsOn: [ - serverfarms - config - ] - parent: sites - name: function.name - properties: { - language: function.properties.language - config: function.properties.config - isDisabled: function.properties.isDisabled - files: function.properties.files - } -}] - -resource sourcecontrol 'Microsoft.Web/sites/sourcecontrols@2022-03-01' = if (enableSourceControl) { - parent: sites - name: 'web' - properties: { - repoUrl: repoUrl - branch: branch - isManualIntegration: isManualIntegration - isMercurial: isMercurial - } -} - -@description('Deploy function app from zip file.') -resource extensions 'Microsoft.Web/sites/extensions@2022-03-01' = if (enablePackageDeploy) { - parent: sites - name: 'MSDeploy' - properties: { - packageUri: functionPackageUri - } -} - -/*output section*/ -@description('Get resource id for app or functionapp.') -output siteId string = sites.id - -@description('Get resource name for app or functionapp.') -output siteName string = sites.name - -@description('Get resource ID of the app service plan.') -output serverfarmsId string = serverfarms.id - -@description('Get name of the app service plan.') -output serverfarmsName string = serverfarms.name - -@description('Array of functions having name , language,isDisabled and id of functions.') -output functions array = [for function in functions: { - name: function.name - language: function.properties.language - isDisabled: function.properties.isDisabled - id: '${sites.id}/functions/${function.name}' - files: function.properties.files -}] - -@description('Principal Id of the identity assigned to the function app.') -output sitePrincipalId string = (sites.identity.type == 'SystemAssigned') ? sites.identity.principalId : '' - - -// user defined types -type functionType = { - name: string - properties: { - language: string - config: object - isDisabled: bool - files: object - } -} diff --git a/modules/compute/function-app/main.json b/modules/compute/function-app/main.json deleted file mode 100644 index c84ed7edbe..0000000000 --- a/modules/compute/function-app/main.json +++ /dev/null @@ -1,638 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "1.10-experimental", - "contentVersion": "1.0.0.0", - "metadata": { - "_EXPERIMENTAL_WARNING": "Symbolic name support in ARM is experimental, and should be enabled for testing purposes only. Do not enable this setting for any production usage, or you may be unexpectedly broken at any time!", - "_generator": { - "name": "bicep", - "version": "0.19.5.34762", - "templateHash": "4252297606944310030" - }, - "name": "Function app module", - "description": "Module to create function app for your application", - "owner": "rhalloul" - }, - "definitions": { - "functionType": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "properties": { - "type": "object", - "properties": { - "language": { - "type": "string" - }, - "config": { - "type": "object" - }, - "isDisabled": { - "type": "bool" - }, - "files": { - "type": "object" - } - } - } - } - } - }, - "parameters": { - "name": { - "type": "string", - "maxLength": 64, - "metadata": { - "description": "Required. Name for the Azure Function App." - } - }, - "location": { - "type": "string", - "metadata": { - "description": "Required. Location for all resources." - } - }, - "tags": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Optional. Tags for all resources within Azure Function App module." - } - }, - "sku": { - "type": "object", - "defaultValue": { - "name": "Y1", - "tier": "Dynamic", - "size": "Y1", - "family": "Y", - "capacity": 0 - }, - "metadata": { - "description": "Required. Defines the name, tier, size, family and capacity of the app service plan." - } - }, - "serverOS": { - "type": "string", - "defaultValue": "Windows", - "allowedValues": [ - "Windows", - "Linux" - ], - "metadata": { - "description": "Optional. Kind of server OS." - } - }, - "perSiteScaling": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. If true, apps assigned to this app service plan can be scaled independently. If false, apps assigned to this app service plan will scale to all instances of the plan." - } - }, - "maximumElasticWorkerCount": { - "type": "int", - "defaultValue": 0, - "metadata": { - "description": "Optional. Maximum number of total workers allowed for this ElasticScaleEnabled app service plan." - } - }, - "targetWorkerCount": { - "type": "int", - "defaultValue": 0, - "metadata": { - "description": "Optional. Scaling worker count." - } - }, - "targetWorkerSizeId": { - "type": "int", - "defaultValue": 0, - "allowedValues": [ - 0, - 1, - 2 - ], - "metadata": { - "description": "Optional. The instance size of the hosting plan (small, medium, or large)." - } - }, - "identityType": { - "type": "string", - "defaultValue": "SystemAssigned", - "metadata": { - "description": "Optional. The type of identity used for the virtual machine. The type 'SystemAssigned, UserAssigned' includes both an implicitly created identity and a set of user assigned identities. The type 'None' will remove any identities from the sites ( app or functionapp)." - }, - "allowedValues": [ - "None", - "SystemAssigned", - "UserAssigned", - "SystemAssigned, UserAssigned" - ] - }, - "userAssignedIdentityId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Specify the resource ID of the user assigned Managed Identity, if 'identity' is set as 'UserAssigned'." - } - }, - "httpsOnly": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Configures a site to accept only HTTPS requests. Issues redirect for HTTP requests." - } - }, - "appServiceEnvironmentId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The resource ID of the app service environment to use for this resource." - } - }, - "clientAffinityEnabled": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. If client affinity is enabled." - } - }, - "kind": { - "type": "string", - "defaultValue": "functionapp", - "allowedValues": [ - "functionapp", - "app" - ], - "metadata": { - "description": "Required. Type of site to deploy." - } - }, - "functionsExtensionVersion": { - "type": "string", - "defaultValue": "~4", - "metadata": { - "description": "Optional. Version of the function extension." - } - }, - "functionAppEditMode": { - "type": "string", - "defaultValue": "readonly", - "allowedValues": [ - "readonly", - "readwrite" - ], - "metadata": { - "description": "Dictates whether editing in the Azure portal is enabled." - } - }, - "functionsWorkerRuntime": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "dotnet", - "node", - "python", - "java", - "powershell", - "" - ], - "metadata": { - "description": "Optional. Runtime of the function worker. WARNING: NOT ALL OSes SUPPORT ALL RUNTIMES!" - } - }, - "functionsDefaultNodeversion": { - "type": "string", - "defaultValue": "~14", - "metadata": { - "description": "Optional. NodeJS version." - } - }, - "publicNetworkAccessForIngestion": { - "type": "string", - "defaultValue": "Enabled", - "metadata": { - "description": "Optional. The network access type for accessing Application Insights ingestion. - Enabled or Disabled." - }, - "allowedValues": [ - "Disabled", - "Enabled" - ] - }, - "publicNetworkAccessForQuery": { - "type": "string", - "defaultValue": "Enabled", - "metadata": { - "description": "Optional. The network access type for accessing Application Insights query. - Enabled or Disabled." - }, - "allowedValues": [ - "Disabled", - "Enabled" - ] - }, - "appInsightsType": { - "type": "string", - "defaultValue": "web", - "allowedValues": [ - "web", - "other" - ], - "metadata": { - "description": "Optional. Application type." - } - }, - "appInsightsKind": { - "type": "string", - "defaultValue": "azfunc", - "metadata": { - "description": "Optional. The kind of application that this component refers to, used to customize UI." - } - }, - "enableInsights": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Enabled or Disable Insights for Azure functions." - } - }, - "workspaceResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Resource ID of the log analytics workspace which the data will be ingested to, if enableaInsights is false." - } - }, - "functions": { - "type": "array", - "items": { - "$ref": "#/definitions/functionType" - }, - "defaultValue": [], - "metadata": { - "description": "Optional. List of Azure function (Actual object where our code resides)." - } - }, - "enableVnetIntegration": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Enable Vnet Integration or not." - } - }, - "subnetId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The subnet that will be integrated to enable vnet Integration." - } - }, - "enableSourceControl": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Enable Source control for the function." - } - }, - "repoUrl": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Repository or source control URL." - } - }, - "branch": { - "type": "string", - "defaultValue": "main", - "metadata": { - "description": "Optional. Name of branch to use for deployment." - } - }, - "storageAccountName": { - "type": "string", - "metadata": { - "description": "Required. Name of the storage account used by function app." - } - }, - "isManualIntegration": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. to limit to manual integration; to enable continuous integration (which configures webhooks into online repos like GitHub)." - } - }, - "isMercurial": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. true for a Mercurial repository; false for a Git repository." - } - }, - "storageAccountResourceGroup": { - "type": "string", - "metadata": { - "description": "Required. Resource Group of storage account used by function app." - } - }, - "enablePackageDeploy": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. True to deploy functions from zip package. \"functionPackageUri\" must be specified if enabled. The package option and sourcecontrol option should not be enabled at the same time." - } - }, - "functionPackageUri": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. URI to the function source code zip package, must be accessible by the deployer. E.g. A zip file on Azure storage in the same resource group." - } - }, - "enableDockerContainer": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Enable docker image deployment." - } - }, - "dockerImage": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. This will be required when enableDockerContainer passed as true." - } - }, - "extraAppSettings": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Optional. Extra app settings that should be provisioned while creating the function app. Note! Settings below should not be included unless absolutely necessary, because settings in this param will override the ones added by the module:\nAzureWebJobsStorage\nAzureWebJobsDashboard\nWEBSITE_CONTENTSHARE\nWEBSITE_CONTENTAZUREFILECONNECTIONSTRING\nFUNCTIONS_EXTENSION_VERSION\nFUNCTIONS_WORKER_RUNTIME\nWEBSITE_NODE_DEFAULT_VERSION\nAPPINSIGHTS_INSTRUMENTATIONKEY\nAPPLICATIONINSIGHTS_CONNECTION_STRING" - } - }, - "ftpsState": { - "type": "string", - "defaultValue": "Disabled", - "allowedValues": [ - "Disabled", - "AllAllowed", - "FtpsOnly" - ], - "metadata": { - "description": "The state of FTP / FTPS service." - } - }, - "minTlsVersion": { - "type": "string", - "defaultValue": "1.2", - "allowedValues": [ - "1.0", - "1.1", - "1.2" - ], - "metadata": { - "description": "Configures the minimum version of TLS required for SSL requests." - } - }, - "linuxFxVersion": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Linux App Framework and version. e.g. PYTHON|3.9" - } - }, - "connectionStringProperties": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "The connection strings properties" - } - } - }, - "variables": { - "servicePlanKind": "[if(equals(parameters('serverOS'), 'Linux'), toLower(parameters('serverOS')), '')]" - }, - "resources": { - "storageAccount": { - "existing": true, - "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2021-06-01", - "resourceGroup": "[parameters('storageAccountResourceGroup')]", - "name": "[parameters('storageAccountName')]", - "metadata": { - "description": "Defines storageAccounts for Azure Function App." - } - }, - "serverfarms": { - "type": "Microsoft.Web/serverfarms", - "apiVersion": "2021-02-01", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "sku": "[parameters('sku')]", - "kind": "[variables('servicePlanKind')]", - "properties": { - "perSiteScaling": "[parameters('perSiteScaling')]", - "maximumElasticWorkerCount": "[parameters('maximumElasticWorkerCount')]", - "reserved": "[equals(parameters('serverOS'), 'Linux')]", - "targetWorkerCount": "[parameters('targetWorkerCount')]", - "targetWorkerSizeId": "[parameters('targetWorkerSizeId')]" - }, - "metadata": { - "description": "Defines Application service plan." - } - }, - "appInsights": { - "condition": "[parameters('enableInsights')]", - "type": "Microsoft.Insights/components", - "apiVersion": "2020-02-02", - "name": "[format('ai-{0}', parameters('name'))]", - "location": "[parameters('location')]", - "kind": "[parameters('appInsightsKind')]", - "properties": { - "Application_Type": "[parameters('appInsightsType')]", - "WorkspaceResourceId": "[parameters('workspaceResourceId')]", - "publicNetworkAccessForIngestion": "[parameters('publicNetworkAccessForIngestion')]", - "publicNetworkAccessForQuery": "[parameters('publicNetworkAccessForQuery')]" - }, - "tags": "[parameters('tags')]", - "metadata": { - "description": "If enabled, this will help monitor the application using the log analytics workspace." - } - }, - "sites": { - "type": "Microsoft.Web/sites", - "apiVersion": "2022-03-01", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "kind": "[parameters('kind')]", - "identity": { - "type": "[parameters('identityType')]", - "userAssignedIdentities": "[if(or(equals(parameters('identityType'), 'UserAssigned'), equals(parameters('identityType'), 'SystemAssigned, UserAssigned')), createObject(format('{0}', parameters('userAssignedIdentityId')), createObject()), null())]" - }, - "properties": { - "siteConfig": { - "linuxFxVersion": "[if(parameters('enableDockerContainer'), format('DOCKER|{0}', parameters('dockerImage')), coalesce(parameters('linuxFxVersion'), null()))]", - "ftpsState": "[parameters('ftpsState')]", - "minTlsVersion": "[parameters('minTlsVersion')]" - }, - "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('name'))]", - "httpsOnly": "[parameters('httpsOnly')]", - "hostingEnvironmentProfile": "[if(not(empty(parameters('appServiceEnvironmentId'))), createObject('id', parameters('appServiceEnvironmentId')), null())]", - "clientAffinityEnabled": "[parameters('clientAffinityEnabled')]" - }, - "dependsOn": [ - "serverfarms" - ], - "metadata": { - "description": "The app or function app resource.\nNote: This is not actual Azure Function App this will be container for storing multiple functions." - } - }, - "config": { - "type": "Microsoft.Web/sites/config", - "apiVersion": "2021-02-01", - "name": "[format('{0}/{1}', parameters('name'), 'appsettings')]", - "properties": "[union(createObject('AzureWebJobsStorage', if(not(empty(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('storageAccountResourceGroup')), 'Microsoft.Storage/storageAccounts', parameters('storageAccountName')))), format('DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};', parameters('storageAccountName'), listKeys(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('storageAccountResourceGroup')), 'Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2021-06-01').keys[0].value), null()), 'AzureWebJobsDashboard', if(not(empty(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('storageAccountResourceGroup')), 'Microsoft.Storage/storageAccounts', parameters('storageAccountName')))), format('DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};', parameters('storageAccountName'), listKeys(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('storageAccountResourceGroup')), 'Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2021-06-01').keys[0].value), null()), 'WEBSITE_CONTENTSHARE', parameters('name'), 'WEBSITE_CONTENTAZUREFILECONNECTIONSTRING', if(not(empty(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('storageAccountResourceGroup')), 'Microsoft.Storage/storageAccounts', parameters('storageAccountName')))), format('DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};', parameters('storageAccountName'), listKeys(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('storageAccountResourceGroup')), 'Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2021-06-01').keys[0].value), null()), 'FUNCTIONS_EXTENSION_VERSION', parameters('functionsExtensionVersion'), 'FUNCTION_APP_EDIT_MODE', parameters('functionAppEditMode'), 'FUNCTIONS_WORKER_RUNTIME', if(and(equals(reference('sites', '2022-03-01', 'full').kind, 'functionapp'), not(empty(parameters('functionsWorkerRuntime')))), parameters('functionsWorkerRuntime'), null()), 'WEBSITE_NODE_DEFAULT_VERSION', if(and(and(equals(reference('sites', '2022-03-01', 'full').kind, 'functionapp'), equals(parameters('functionsWorkerRuntime'), 'node')), not(empty(parameters('functionsDefaultNodeversion')))), parameters('functionsDefaultNodeversion'), null()), 'APPINSIGHTS_INSTRUMENTATIONKEY', if(and(not(empty(resourceId('Microsoft.Insights/components', format('ai-{0}', parameters('name'))))), parameters('enableInsights')), reference('appInsights').InstrumentationKey, null()), 'APPLICATIONINSIGHTS_CONNECTION_STRING', if(and(not(empty(resourceId('Microsoft.Insights/components', format('ai-{0}', parameters('name'))))), parameters('enableInsights')), reference('appInsights').ConnectionString, null())), parameters('extraAppSettings'))]", - "dependsOn": [ - "appInsights", - "networkConfig", - "sites" - ], - "metadata": { - "description": "Appsettings/config for the sites (app or functionapp)." - } - }, - "connectionString": { - "condition": "[not(empty(parameters('connectionStringProperties')))]", - "type": "Microsoft.Web/sites/config", - "apiVersion": "2022-03-01", - "name": "[format('{0}/{1}', parameters('name'), 'connectionstrings')]", - "kind": "string", - "properties": "[parameters('connectionStringProperties')]", - "dependsOn": [ - "sites" - ] - }, - "networkConfig": { - "condition": "[equals(parameters('enableVnetIntegration'), true())]", - "type": "Microsoft.Web/sites/networkConfig", - "apiVersion": "2022-03-01", - "name": "[format('{0}/{1}', parameters('name'), 'virtualNetwork')]", - "properties": { - "subnetResourceId": "[parameters('subnetId')]" - }, - "dependsOn": [ - "sites" - ] - }, - "azureFunction": { - "copy": { - "name": "azureFunction", - "count": "[length(parameters('functions'))]", - "mode": "serial", - "batchSize": 1 - }, - "type": "Microsoft.Web/sites/functions", - "apiVersion": "2021-02-01", - "name": "[format('{0}/{1}', parameters('name'), parameters('functions')[copyIndex()].name)]", - "properties": { - "language": "[parameters('functions')[copyIndex()].properties.language]", - "config": "[parameters('functions')[copyIndex()].properties.config]", - "isDisabled": "[parameters('functions')[copyIndex()].properties.isDisabled]", - "files": "[parameters('functions')[copyIndex()].properties.files]" - }, - "dependsOn": [ - "config", - "serverfarms", - "sites" - ], - "metadata": { - "description": "The resources actual is function where code exits." - } - }, - "sourcecontrol": { - "condition": "[parameters('enableSourceControl')]", - "type": "Microsoft.Web/sites/sourcecontrols", - "apiVersion": "2022-03-01", - "name": "[format('{0}/{1}', parameters('name'), 'web')]", - "properties": { - "repoUrl": "[parameters('repoUrl')]", - "branch": "[parameters('branch')]", - "isManualIntegration": "[parameters('isManualIntegration')]", - "isMercurial": "[parameters('isMercurial')]" - }, - "dependsOn": [ - "sites" - ] - }, - "extensions": { - "condition": "[parameters('enablePackageDeploy')]", - "type": "Microsoft.Web/sites/extensions", - "apiVersion": "2022-03-01", - "name": "[format('{0}/{1}', parameters('name'), 'MSDeploy')]", - "properties": { - "packageUri": "[parameters('functionPackageUri')]" - }, - "dependsOn": [ - "sites" - ], - "metadata": { - "description": "Deploy function app from zip file." - } - } - }, - "outputs": { - "siteId": { - "type": "string", - "metadata": { - "description": "Get resource id for app or functionapp." - }, - "value": "[resourceId('Microsoft.Web/sites', parameters('name'))]" - }, - "siteName": { - "type": "string", - "metadata": { - "description": "Get resource name for app or functionapp." - }, - "value": "[parameters('name')]" - }, - "serverfarmsId": { - "type": "string", - "metadata": { - "description": "Get resource ID of the app service plan." - }, - "value": "[resourceId('Microsoft.Web/serverfarms', parameters('name'))]" - }, - "serverfarmsName": { - "type": "string", - "metadata": { - "description": "Get name of the app service plan." - }, - "value": "[parameters('name')]" - }, - "functions": { - "type": "array", - "metadata": { - "description": "Array of functions having name , language,isDisabled and id of functions." - }, - "copy": { - "count": "[length(parameters('functions'))]", - "input": { - "name": "[parameters('functions')[copyIndex()].name]", - "language": "[parameters('functions')[copyIndex()].properties.language]", - "isDisabled": "[parameters('functions')[copyIndex()].properties.isDisabled]", - "id": "[format('{0}/functions/{1}', resourceId('Microsoft.Web/sites', parameters('name')), parameters('functions')[copyIndex()].name)]", - "files": "[parameters('functions')[copyIndex()].properties.files]" - } - } - }, - "sitePrincipalId": { - "type": "string", - "metadata": { - "description": "Principal Id of the identity assigned to the function app." - }, - "value": "[if(equals(reference('sites', '2022-03-01', 'full').identity.type, 'SystemAssigned'), reference('sites', '2022-03-01', 'full').identity.principalId, '')]" - } - } -} \ No newline at end of file diff --git a/modules/compute/function-app/test/functions_source_code/test_1_index.js b/modules/compute/function-app/test/functions_source_code/test_1_index.js deleted file mode 100644 index ab0f3ebe67..0000000000 --- a/modules/compute/function-app/test/functions_source_code/test_1_index.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = async function (context, myTimer) { - var timeStamp = new Date().toISOString(); - if (myTimer.IsPastDue) { - context.log('JavaScript is running late!'); - } - context.bindings.outputBlob2 = 'hello func2'; - context.log('written hello to blob func2', timeStamp); context.log('JavaScript timer trigger function ran!', timeStamp); -}; diff --git a/modules/compute/function-app/test/main.test.bicep b/modules/compute/function-app/test/main.test.bicep deleted file mode 100644 index 6e14fe01a8..0000000000 --- a/modules/compute/function-app/test/main.test.bicep +++ /dev/null @@ -1,76 +0,0 @@ -param name string = deployment().name -param location string = resourceGroup().location - -param tags object = { - costcenter: '000' - environment: 'dev' - location: resourceGroup().location -} - -module dependencies 'prereq.test.bicep' = { - scope: resourceGroup() - name: 'dependencies-${uniqueString(resourceGroup().id)}' - params: { - name: name - location: location - tags: tags - } -} - -module test1 '../main.bicep' = { - name: 'func01-${uniqueString(name)}' - dependsOn: [ - dependencies - ] - params: { - name: take(replace('func01-${name}', '.', ''), 55) - location: location - sku: { - name: 'Y1' - tier: 'Dynamic' - size: 'Y1' - family: 'Y' - capacity: 0 - } - tags: tags - storageAccountName: dependencies.outputs.saAccountName - storageAccountResourceGroup: resourceGroup().name - enableSourceControl: false - enableDockerContainer: true - dockerImage: 'mcr.microsoft.com/azure-functions/dotnet:4-appservice-quickstart' - serverOS: 'Linux' - } - scope: resourceGroup() -} - -// module test2 '../main.bicep' = { -// name: 'func02-${uniqueString(name)}' -// scope: resourceGroup() -// dependsOn: [ -// dependencies -// ] -// params: { -// name: take(replace('func02-${name}', '.', ''), 55) -// location: location -// sku: { -// name: 'EP1' -// tier: 'ElasticPremium' -// size: 'EP1' -// family: 'EP' -// capacity: 1 -// } -// tags: tags -// maximumElasticWorkerCount: 20 -// enableVnetIntegration: true -// enableInsights: true -// workspaceResourceId: dependencies.outputs.workspacesId -// subnetId: dependencies.outputs.subnetResourceIds -// functionsExtensionVersion: '~4' -// functionsWorkerRuntime: 'powershell' -// storageAccountName: dependencies.outputs.saAccountName -// storageAccountResourceGroup: resourceGroup().name -// enableSourceControl: true -// repoUrl: 'https://github.com/Azure/KeyVault-Secrets-Rotation-Redis-PowerShell.git' -// enableDockerContainer: false -// } -// } diff --git a/modules/compute/function-app/test/prereq.test.bicep b/modules/compute/function-app/test/prereq.test.bicep deleted file mode 100644 index 480d9f4d17..0000000000 --- a/modules/compute/function-app/test/prereq.test.bicep +++ /dev/null @@ -1,96 +0,0 @@ -param location string -param name string -param tags object - -var maxNameLength = 24 -var uniqueStoragename = length(uniqueString(name)) > maxNameLength ? substring(replace(guid(name, resourceGroup().name, subscription().id), '-', ''), 0, maxNameLength) : substring(replace(guid(name, resourceGroup().name, subscription().id), '-', ''), 0, maxNameLength) - -module vnet 'br/public:network/virtual-network:1.1.2' = { - name: 'vnet-network-${uniqueString(resourceGroup().id)}' - params: { - name: 'vnet-${uniqueString(resourceGroup().id)}' - addressPrefixes: [ - '10.0.0.0/16' - ] - subnets: [ - { - name: 'function-app' - addressPrefix: '10.0.3.0/24' - delegations: [ - { - name: 'Delegation' - properties: { - serviceName: 'Microsoft.Web/serverfarms' - } - } - ] - serviceEndpoints: [ - { - service: 'Microsoft.Storage' - } - ] - } - { - name: 'storage' - addressPrefix: '10.0.4.0/24' - serviceEndpoints: [ - { - service: 'Microsoft.Storage' - } - ] - } - ] - } -} - -resource storageAccount 'Microsoft.Storage/storageAccounts@2021-06-01' = { - name: uniqueStoragename - location: location - sku: { - name: 'Standard_LRS' - } - kind: 'StorageV2' - properties: { - accessTier: 'Cool' - minimumTlsVersion: 'TLS1_2' - supportsHttpsTrafficOnly: true - allowBlobPublicAccess: true - allowSharedKeyAccess: true - networkAcls: { - bypass: 'AzureServices' - defaultAction: 'Allow' - } - publicNetworkAccess: 'Enabled' - } -} - -resource userAssignedIdentities 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: 'test2-${uniqueString(resourceGroup().id)}' - location: location -} - -resource workspaces 'Microsoft.OperationalInsights/workspaces@2022-10-01' = { - name: 'functionapp-workspace' - location: location - tags: tags - properties: { - sku: { - name: 'PerGB2018' - } - } -} - -@description('get Identity id.') -output userAssignedIdentitiesId string = userAssignedIdentities.id - -@description('get Identity name.') -output userAssignedIdentitiesName string = userAssignedIdentities.name - -@description('get OperationalInsights workspaces id.') -output workspacesId string = workspaces.id - -@description('get the subnets associated with the virtual network.') -output subnetResourceIds string = vnet.outputs.subnetResourceIds[0] - -@description('Name of the storage account used by function app.') -output saAccountName string = storageAccount.name diff --git a/modules/compute/function-app/test/upload-file.bicep b/modules/compute/function-app/test/upload-file.bicep deleted file mode 100644 index 65930aa614..0000000000 --- a/modules/compute/function-app/test/upload-file.bicep +++ /dev/null @@ -1,35 +0,0 @@ -param location string -param storageAccountName string -param containerName string - -var filename = 'functionapp.zip' -var zipfile = loadFileAsBase64('./data/functionapp.zip') - -resource storageAccount 'Microsoft.Storage/storageAccounts@2022-05-01' existing = { - name: storageAccountName -} - -resource uploadFunctionZip 'Microsoft.Resources/deploymentScripts@2020-10-01' = { - name: 'upload-zipfile' - location: location - kind: 'AzureCLI' - properties: { - azCliVersion: '2.26.1' - timeout: 'PT5M' - retentionInterval: 'PT1H' - environmentVariables: [ - { - name: 'AZURE_STORAGE_ACCOUNT' - value: storageAccountName - } - { - name: 'AZURE_STORAGE_KEY' - secureValue: storageAccount.listKeys().keys[0].value - } - ] - scriptContent: 'echo "${zipfile}" | base64 -d > ${filename} && az storage blob upload -f ${filename} -c ${containerName} -n ${filename}' - } -} - -@description('URI of the function app source code zip file.') -output zipFileUri string = '${storageAccount.properties.primaryEndpoints.blob}${containerName}/${filename}' diff --git a/modules/compute/function-app/version.json b/modules/compute/function-app/version.json deleted file mode 100644 index 4727c64800..0000000000 --- a/modules/compute/function-app/version.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "2.0", - "pathFilters": [ - "./main.json", - "./metadata.json" - ] -} \ No newline at end of file diff --git a/modules/compute/virtual-machine/README.md b/modules/compute/virtual-machine/README.md deleted file mode 100644 index b92ce4549a..0000000000 --- a/modules/compute/virtual-machine/README.md +++ /dev/null @@ -1,3552 +0,0 @@ -# Virtual Machines `[Microsoft.Compute/virtualMachines]` - -This module deploys a Virtual Machine with one or multiple NICs and optionally one or multiple public IPs. - -## Navigation - -- [Resource Types](#Resource-Types) -- [Usage examples](#Usage-examples) -- [Parameters](#Parameters) -- [Outputs](#Outputs) -- [Cross-referenced modules](#Cross-referenced-modules) -- [Notes](#Notes) - -## Resource Types - -| Resource Type | API Version | -| :-- | :-- | -| `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | -| `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | -| `Microsoft.Automanage/configurationProfileAssignments` | [2021-04-30-preview](https://learn.microsoft.com/en-us/azure/templates) | -| `Microsoft.Compute/virtualMachines` | [2022-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Compute/2022-11-01/virtualMachines) | -| `Microsoft.Compute/virtualMachines/extensions` | [2022-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Compute/2022-11-01/virtualMachines/extensions) | -| `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | -| `Microsoft.Network/networkInterfaces` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/networkInterfaces) | -| `Microsoft.Network/publicIPAddresses` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/publicIPAddresses) | -| `Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems` | [2023-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.RecoveryServices/2023-01-01/vaults/backupFabrics/protectionContainers/protectedItems) | - -## 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:bicep/modules/compute.virtual-machine:1.0.0`. - -- [Linux.Atmg](#example-1-linuxatmg) -- [Linux.Min](#example-2-linuxmin) -- [Linux](#example-3-linux) -- [Windows.Atmg](#example-4-windowsatmg) -- [Windows.Min](#example-5-windowsmin) -- [Windows.Ssecmk](#example-6-windowsssecmk) -- [Windows](#example-7-windows) - -### Example 1: _Linux.Atmg_ - -

- -via Bicep module - -```bicep -module virtualMachine 'br:bicep/modules/compute.virtual-machine:1.0.0' = { - name: '${uniqueString(deployment().name, location)}-test-cvmlinatmg' - params: { - // Required parameters - adminUsername: 'localAdminUser' - imageReference: { - offer: '0001-com-ubuntu-server-jammy' - publisher: 'Canonical' - sku: '22_04-lts-gen2' - version: 'latest' - } - nicConfigurations: [ - { - ipConfigurations: [ - { - name: 'ipconfig01' - pipConfiguration: { - publicIpNameSuffix: '-pip-01' - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } - subnetResourceId: '' - zones: [ - '1' - '2' - '3' - ] - } - ] - nicSuffix: '-nic-01' - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } - ] - osDisk: { - diskSizeGB: '128' - managedDisk: { - storageAccountType: 'Premium_LRS' - } - } - osType: 'Linux' - vmSize: 'Standard_DS2_v2' - // Non-required parameters - configurationProfile: '/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesProduction' - disablePasswordAuthentication: true - enableDefaultTelemetry: '' - location: '' - name: 'cvmlinatmg' - publicKeys: [ - { - keyData: '' - path: '/home/localAdminUser/.ssh/authorized_keys' - } - ] - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } -} -``` - -
-

- -

- -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 - "adminUsername": { - "value": "localAdminUser" - }, - "imageReference": { - "value": { - "offer": "0001-com-ubuntu-server-jammy", - "publisher": "Canonical", - "sku": "22_04-lts-gen2", - "version": "latest" - } - }, - "nicConfigurations": { - "value": [ - { - "ipConfigurations": [ - { - "name": "ipconfig01", - "pipConfiguration": { - "publicIpNameSuffix": "-pip-01", - "tags": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - }, - "subnetResourceId": "", - "zones": [ - "1", - "2", - "3" - ] - } - ], - "nicSuffix": "-nic-01", - "tags": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - ] - }, - "osDisk": { - "value": { - "diskSizeGB": "128", - "managedDisk": { - "storageAccountType": "Premium_LRS" - } - } - }, - "osType": { - "value": "Linux" - }, - "vmSize": { - "value": "Standard_DS2_v2" - }, - // Non-required parameters - "configurationProfile": { - "value": "/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesProduction" - }, - "disablePasswordAuthentication": { - "value": true - }, - "enableDefaultTelemetry": { - "value": "" - }, - "location": { - "value": "" - }, - "name": { - "value": "cvmlinatmg" - }, - "publicKeys": { - "value": [ - { - "keyData": "", - "path": "/home/localAdminUser/.ssh/authorized_keys" - } - ] - }, - "tags": { - "value": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - } -} -``` - -
-

- -### Example 2: _Linux.Min_ - -

- -via Bicep module - -```bicep -module virtualMachine 'br:bicep/modules/compute.virtual-machine:1.0.0' = { - name: '${uniqueString(deployment().name, location)}-test-cvmlinmin' - params: { - // Required parameters - adminUsername: 'localAdminUser' - imageReference: { - offer: '0001-com-ubuntu-server-jammy' - publisher: 'Canonical' - sku: '22_04-lts-gen2' - version: 'latest' - } - nicConfigurations: [ - { - ipConfigurations: [ - { - name: 'ipconfig01' - pipConfiguration: { - publicIpNameSuffix: '-pip-01' - } - subnetResourceId: '' - } - ] - nicSuffix: '-nic-01' - } - ] - osDisk: { - diskSizeGB: '128' - managedDisk: { - storageAccountType: 'Premium_LRS' - } - } - osType: 'Linux' - vmSize: 'Standard_DS2_v2' - // Non-required parameters - disablePasswordAuthentication: true - enableDefaultTelemetry: '' - location: '' - name: 'cvmlinmin' - publicKeys: [ - { - keyData: '' - path: '/home/localAdminUser/.ssh/authorized_keys' - } - ] - } -} -``` - -
-

- -

- -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 - "adminUsername": { - "value": "localAdminUser" - }, - "imageReference": { - "value": { - "offer": "0001-com-ubuntu-server-jammy", - "publisher": "Canonical", - "sku": "22_04-lts-gen2", - "version": "latest" - } - }, - "nicConfigurations": { - "value": [ - { - "ipConfigurations": [ - { - "name": "ipconfig01", - "pipConfiguration": { - "publicIpNameSuffix": "-pip-01" - }, - "subnetResourceId": "" - } - ], - "nicSuffix": "-nic-01" - } - ] - }, - "osDisk": { - "value": { - "diskSizeGB": "128", - "managedDisk": { - "storageAccountType": "Premium_LRS" - } - } - }, - "osType": { - "value": "Linux" - }, - "vmSize": { - "value": "Standard_DS2_v2" - }, - // Non-required parameters - "disablePasswordAuthentication": { - "value": true - }, - "enableDefaultTelemetry": { - "value": "" - }, - "location": { - "value": "" - }, - "name": { - "value": "cvmlinmin" - }, - "publicKeys": { - "value": [ - { - "keyData": "", - "path": "/home/localAdminUser/.ssh/authorized_keys" - } - ] - } - } -} -``` - -
-

- -### Example 3: _Linux_ - -

- -via Bicep module - -```bicep -module virtualMachine 'br:bicep/modules/compute.virtual-machine:1.0.0' = { - name: '${uniqueString(deployment().name, location)}-test-cvmlincom' - params: { - // Required parameters - adminUsername: 'localAdministrator' - imageReference: { - offer: '0001-com-ubuntu-server-focal' - publisher: 'Canonical' - sku: '' - version: 'latest' - } - nicConfigurations: [ - { - deleteOption: 'Delete' - diagnosticSettings: [ - { - eventHubAuthorizationRuleResourceId: '' - eventHubName: '' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - name: 'customSetting' - storageAccountResourceId: '' - workspaceResourceId: '' - } - ] - ipConfigurations: [ - { - applicationSecurityGroups: [ - { - id: '' - } - ] - diagnosticSettings: [ - { - eventHubAuthorizationRuleResourceId: '' - eventHubName: '' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - name: 'customSetting' - storageAccountResourceId: '' - workspaceResourceId: '' - } - ] - loadBalancerBackendAddressPools: [ - { - id: '' - } - ] - name: 'ipconfig01' - pipConfiguration: { - publicIpNameSuffix: '-pip-01' - roleAssignments: [ - { - principalId: '' - principalType: 'ServicePrincipal' - roleDefinitionIdOrName: 'Reader' - } - ] - } - subnetResourceId: '' - zones: [ - '1' - '2' - '3' - ] - } - ] - nicSuffix: '-nic-01' - roleAssignments: [ - { - principalId: '' - principalType: 'ServicePrincipal' - roleDefinitionIdOrName: 'Reader' - } - ] - } - ] - osDisk: { - caching: 'ReadOnly' - createOption: 'fromImage' - deleteOption: 'Delete' - diskSizeGB: '128' - managedDisk: { - storageAccountType: 'Premium_LRS' - } - } - osType: 'Linux' - vmSize: 'Standard_DS2_v2' - // Non-required parameters - availabilityZone: 1 - backupPolicyName: '' - backupVaultName: '' - backupVaultResourceGroup: '' - computerName: 'linvm1' - dataDisks: [ - { - caching: 'ReadWrite' - createOption: 'Empty' - deleteOption: 'Delete' - diskSizeGB: '128' - managedDisk: { - storageAccountType: 'Premium_LRS' - } - } - { - caching: 'ReadWrite' - createOption: 'Empty' - deleteOption: 'Delete' - diskSizeGB: '128' - managedDisk: { - storageAccountType: 'Premium_LRS' - } - } - ] - disablePasswordAuthentication: true - enableAutomaticUpdates: true - enableDefaultTelemetry: '' - encryptionAtHost: false - extensionAadJoinConfig: { - enabled: true - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } - extensionAzureDiskEncryptionConfig: { - enabled: true - settings: { - EncryptionOperation: 'EnableEncryption' - KekVaultResourceId: '' - KeyEncryptionAlgorithm: 'RSA-OAEP' - KeyEncryptionKeyURL: '' - KeyVaultResourceId: '' - KeyVaultURL: '' - ResizeOSDisk: 'false' - VolumeType: 'All' - } - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } - extensionCustomScriptConfig: { - enabled: true - fileData: [ - { - storageAccountId: '' - uri: '' - } - ] - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } - extensionCustomScriptProtectedSetting: { - commandToExecute: '' - } - extensionDependencyAgentConfig: { - enabled: true - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } - extensionDSCConfig: { - enabled: false - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } - extensionMonitoringAgentConfig: { - enabled: true - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } - extensionNetworkWatcherAgentConfig: { - enabled: true - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } - location: '' - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - managedIdentities: { - systemAssigned: true - userAssignedResourceIds: [ - '' - ] - } - monitoringWorkspaceId: '' - name: 'cvmlincom' - patchMode: 'AutomaticByPlatform' - publicKeys: [ - { - keyData: '' - path: '/home/localAdministrator/.ssh/authorized_keys' - } - ] - roleAssignments: [ - { - principalId: '' - principalType: 'ServicePrincipal' - roleDefinitionIdOrName: 'Owner' - } - { - principalId: '' - principalType: 'ServicePrincipal' - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - } - { - principalId: '' - principalType: 'ServicePrincipal' - roleDefinitionIdOrName: '' - } - ] - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } -} -``` - -
-

- -

- -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 - "adminUsername": { - "value": "localAdministrator" - }, - "imageReference": { - "value": { - "offer": "0001-com-ubuntu-server-focal", - "publisher": "Canonical", - "sku": "", - "version": "latest" - } - }, - "nicConfigurations": { - "value": [ - { - "deleteOption": "Delete", - "diagnosticSettings": [ - { - "eventHubAuthorizationRuleResourceId": "", - "eventHubName": "", - "metricCategories": [ - { - "category": "AllMetrics" - } - ], - "name": "customSetting", - "storageAccountResourceId": "", - "workspaceResourceId": "" - } - ], - "ipConfigurations": [ - { - "applicationSecurityGroups": [ - { - "id": "" - } - ], - "diagnosticSettings": [ - { - "eventHubAuthorizationRuleResourceId": "", - "eventHubName": "", - "metricCategories": [ - { - "category": "AllMetrics" - } - ], - "name": "customSetting", - "storageAccountResourceId": "", - "workspaceResourceId": "" - } - ], - "loadBalancerBackendAddressPools": [ - { - "id": "" - } - ], - "name": "ipconfig01", - "pipConfiguration": { - "publicIpNameSuffix": "-pip-01", - "roleAssignments": [ - { - "principalId": "", - "principalType": "ServicePrincipal", - "roleDefinitionIdOrName": "Reader" - } - ] - }, - "subnetResourceId": "", - "zones": [ - "1", - "2", - "3" - ] - } - ], - "nicSuffix": "-nic-01", - "roleAssignments": [ - { - "principalId": "", - "principalType": "ServicePrincipal", - "roleDefinitionIdOrName": "Reader" - } - ] - } - ] - }, - "osDisk": { - "value": { - "caching": "ReadOnly", - "createOption": "fromImage", - "deleteOption": "Delete", - "diskSizeGB": "128", - "managedDisk": { - "storageAccountType": "Premium_LRS" - } - } - }, - "osType": { - "value": "Linux" - }, - "vmSize": { - "value": "Standard_DS2_v2" - }, - // Non-required parameters - "availabilityZone": { - "value": 1 - }, - "backupPolicyName": { - "value": "" - }, - "backupVaultName": { - "value": "" - }, - "backupVaultResourceGroup": { - "value": "" - }, - "computerName": { - "value": "linvm1" - }, - "dataDisks": { - "value": [ - { - "caching": "ReadWrite", - "createOption": "Empty", - "deleteOption": "Delete", - "diskSizeGB": "128", - "managedDisk": { - "storageAccountType": "Premium_LRS" - } - }, - { - "caching": "ReadWrite", - "createOption": "Empty", - "deleteOption": "Delete", - "diskSizeGB": "128", - "managedDisk": { - "storageAccountType": "Premium_LRS" - } - } - ] - }, - "disablePasswordAuthentication": { - "value": true - }, - "enableAutomaticUpdates": { - "value": true - }, - "enableDefaultTelemetry": { - "value": "" - }, - "encryptionAtHost": { - "value": false - }, - "extensionAadJoinConfig": { - "value": { - "enabled": true, - "tags": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - }, - "extensionAzureDiskEncryptionConfig": { - "value": { - "enabled": true, - "settings": { - "EncryptionOperation": "EnableEncryption", - "KekVaultResourceId": "", - "KeyEncryptionAlgorithm": "RSA-OAEP", - "KeyEncryptionKeyURL": "", - "KeyVaultResourceId": "", - "KeyVaultURL": "", - "ResizeOSDisk": "false", - "VolumeType": "All" - }, - "tags": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - }, - "extensionCustomScriptConfig": { - "value": { - "enabled": true, - "fileData": [ - { - "storageAccountId": "", - "uri": "" - } - ], - "tags": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - }, - "extensionCustomScriptProtectedSetting": { - "value": { - "commandToExecute": "" - } - }, - "extensionDependencyAgentConfig": { - "value": { - "enabled": true, - "tags": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - }, - "extensionDSCConfig": { - "value": { - "enabled": false, - "tags": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - }, - "extensionMonitoringAgentConfig": { - "value": { - "enabled": true, - "tags": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - }, - "extensionNetworkWatcherAgentConfig": { - "value": { - "enabled": true, - "tags": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - }, - "location": { - "value": "" - }, - "lock": { - "value": { - "kind": "CanNotDelete", - "name": "myCustomLockName" - } - }, - "managedIdentities": { - "value": { - "systemAssigned": true, - "userAssignedResourceIds": [ - "" - ] - } - }, - "monitoringWorkspaceId": { - "value": "" - }, - "name": { - "value": "cvmlincom" - }, - "patchMode": { - "value": "AutomaticByPlatform" - }, - "publicKeys": { - "value": [ - { - "keyData": "", - "path": "/home/localAdministrator/.ssh/authorized_keys" - } - ] - }, - "roleAssignments": { - "value": [ - { - "principalId": "", - "principalType": "ServicePrincipal", - "roleDefinitionIdOrName": "Owner" - }, - { - "principalId": "", - "principalType": "ServicePrincipal", - "roleDefinitionIdOrName": "b24988ac-6180-42a0-ab88-20f7382dd24c" - }, - { - "principalId": "", - "principalType": "ServicePrincipal", - "roleDefinitionIdOrName": "" - } - ] - }, - "tags": { - "value": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - } -} -``` - -
-

- -### Example 4: _Windows.Atmg_ - -

- -via Bicep module - -```bicep -module virtualMachine 'br:bicep/modules/compute.virtual-machine:1.0.0' = { - name: '${uniqueString(deployment().name, location)}-test-cvmwinatmg' - params: { - // Required parameters - adminUsername: 'localAdministrator' - imageReference: { - offer: 'WindowsServer' - publisher: 'MicrosoftWindowsServer' - sku: '2022-datacenter-azure-edition' - version: 'latest' - } - nicConfigurations: [ - { - ipConfigurations: [ - { - name: 'ipconfig01' - subnetResourceId: '' - } - ] - nicSuffix: '-nic-01' - } - ] - osDisk: { - diskSizeGB: '128' - managedDisk: { - storageAccountType: 'Premium_LRS' - } - } - osType: 'Windows' - vmSize: 'Standard_DS2_v2' - // Non-required parameters - adminPassword: '' - configurationProfile: '/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesProduction' - enableDefaultTelemetry: '' - location: '' - name: 'cvmwinatmg' - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } -} -``` - -
-

- -

- -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 - "adminUsername": { - "value": "localAdministrator" - }, - "imageReference": { - "value": { - "offer": "WindowsServer", - "publisher": "MicrosoftWindowsServer", - "sku": "2022-datacenter-azure-edition", - "version": "latest" - } - }, - "nicConfigurations": { - "value": [ - { - "ipConfigurations": [ - { - "name": "ipconfig01", - "subnetResourceId": "" - } - ], - "nicSuffix": "-nic-01" - } - ] - }, - "osDisk": { - "value": { - "diskSizeGB": "128", - "managedDisk": { - "storageAccountType": "Premium_LRS" - } - } - }, - "osType": { - "value": "Windows" - }, - "vmSize": { - "value": "Standard_DS2_v2" - }, - // Non-required parameters - "adminPassword": { - "value": "" - }, - "configurationProfile": { - "value": "/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesProduction" - }, - "enableDefaultTelemetry": { - "value": "" - }, - "location": { - "value": "" - }, - "name": { - "value": "cvmwinatmg" - }, - "tags": { - "value": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - } -} -``` - -
-

- -### Example 5: _Windows.Min_ - -

- -via Bicep module - -```bicep -module virtualMachine 'br:bicep/modules/compute.virtual-machine:1.0.0' = { - name: '${uniqueString(deployment().name, location)}-test-cvmwinmin' - params: { - // Required parameters - adminUsername: 'localAdminUser' - imageReference: { - offer: 'WindowsServer' - publisher: 'MicrosoftWindowsServer' - sku: '2022-datacenter-azure-edition' - version: 'latest' - } - nicConfigurations: [ - { - ipConfigurations: [ - { - name: 'ipconfig01' - subnetResourceId: '' - } - ] - nicSuffix: '-nic-01' - } - ] - osDisk: { - diskSizeGB: '128' - managedDisk: { - storageAccountType: 'Premium_LRS' - } - } - osType: 'Windows' - vmSize: 'Standard_DS2_v2' - // Non-required parameters - adminPassword: '' - enableDefaultTelemetry: '' - location: '' - name: 'cvmwinmin' - } -} -``` - -
-

- -

- -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 - "adminUsername": { - "value": "localAdminUser" - }, - "imageReference": { - "value": { - "offer": "WindowsServer", - "publisher": "MicrosoftWindowsServer", - "sku": "2022-datacenter-azure-edition", - "version": "latest" - } - }, - "nicConfigurations": { - "value": [ - { - "ipConfigurations": [ - { - "name": "ipconfig01", - "subnetResourceId": "" - } - ], - "nicSuffix": "-nic-01" - } - ] - }, - "osDisk": { - "value": { - "diskSizeGB": "128", - "managedDisk": { - "storageAccountType": "Premium_LRS" - } - } - }, - "osType": { - "value": "Windows" - }, - "vmSize": { - "value": "Standard_DS2_v2" - }, - // Non-required parameters - "adminPassword": { - "value": "" - }, - "enableDefaultTelemetry": { - "value": "" - }, - "location": { - "value": "" - }, - "name": { - "value": "cvmwinmin" - } - } -} -``` - -
-

- -### Example 6: _Windows.Ssecmk_ - -

- -via Bicep module - -```bicep -module virtualMachine 'br:bicep/modules/compute.virtual-machine:1.0.0' = { - name: '${uniqueString(deployment().name, location)}-test-cvmwincmk' - params: { - // Required parameters - adminUsername: 'VMAdministrator' - imageReference: { - offer: 'WindowsServer' - publisher: 'MicrosoftWindowsServer' - sku: '2019-datacenter' - version: 'latest' - } - nicConfigurations: [ - { - ipConfigurations: [ - { - name: 'ipconfig01' - subnetResourceId: '' - } - ] - nicSuffix: '-nic-01' - } - ] - osDisk: { - diskSizeGB: '128' - managedDisk: { - diskEncryptionSet: { - id: '' - } - storageAccountType: 'Premium_LRS' - } - } - osType: 'Windows' - vmSize: 'Standard_DS2_v2' - // Non-required parameters - adminPassword: '' - dataDisks: [ - { - diskSizeGB: '128' - managedDisk: { - diskEncryptionSet: { - id: '' - } - storageAccountType: 'Premium_LRS' - } - } - ] - enableDefaultTelemetry: '' - location: '' - name: 'cvmwincmk' - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } -} -``` - -
-

- -

- -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 - "adminUsername": { - "value": "VMAdministrator" - }, - "imageReference": { - "value": { - "offer": "WindowsServer", - "publisher": "MicrosoftWindowsServer", - "sku": "2019-datacenter", - "version": "latest" - } - }, - "nicConfigurations": { - "value": [ - { - "ipConfigurations": [ - { - "name": "ipconfig01", - "subnetResourceId": "" - } - ], - "nicSuffix": "-nic-01" - } - ] - }, - "osDisk": { - "value": { - "diskSizeGB": "128", - "managedDisk": { - "diskEncryptionSet": { - "id": "" - }, - "storageAccountType": "Premium_LRS" - } - } - }, - "osType": { - "value": "Windows" - }, - "vmSize": { - "value": "Standard_DS2_v2" - }, - // Non-required parameters - "adminPassword": { - "value": "" - }, - "dataDisks": { - "value": [ - { - "diskSizeGB": "128", - "managedDisk": { - "diskEncryptionSet": { - "id": "" - }, - "storageAccountType": "Premium_LRS" - } - } - ] - }, - "enableDefaultTelemetry": { - "value": "" - }, - "location": { - "value": "" - }, - "name": { - "value": "cvmwincmk" - }, - "tags": { - "value": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - } -} -``` - -
-

- -### Example 7: _Windows_ - -

- -via Bicep module - -```bicep -module virtualMachine 'br:bicep/modules/compute.virtual-machine:1.0.0' = { - name: '${uniqueString(deployment().name, location)}-test-cvmwincom' - params: { - // Required parameters - adminUsername: 'VMAdmin' - imageReference: { - offer: 'WindowsServer' - publisher: 'MicrosoftWindowsServer' - sku: '2019-datacenter' - version: 'latest' - } - nicConfigurations: [ - { - deleteOption: 'Delete' - diagnosticSettings: [ - { - eventHubAuthorizationRuleResourceId: '' - eventHubName: '' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - name: 'customSetting' - storageAccountResourceId: '' - workspaceResourceId: '' - } - ] - ipConfigurations: [ - { - applicationSecurityGroups: [ - { - id: '' - } - ] - diagnosticSettings: [ - { - eventHubAuthorizationRuleResourceId: '' - eventHubName: '' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - name: 'customSetting' - storageAccountResourceId: '' - workspaceResourceId: '' - } - ] - loadBalancerBackendAddressPools: [ - { - id: '' - } - ] - name: 'ipconfig01' - pipConfiguration: { - publicIpNameSuffix: '-pip-01' - roleAssignments: [ - { - principalId: '' - principalType: 'ServicePrincipal' - roleDefinitionIdOrName: 'Reader' - } - ] - } - subnetResourceId: '' - zones: [ - '1' - '2' - '3' - ] - } - ] - nicSuffix: '-nic-01' - roleAssignments: [ - { - principalId: '' - principalType: 'ServicePrincipal' - roleDefinitionIdOrName: 'Reader' - } - ] - } - ] - osDisk: { - caching: 'None' - createOption: 'fromImage' - deleteOption: 'Delete' - diskSizeGB: '128' - managedDisk: { - storageAccountType: 'Premium_LRS' - } - } - osType: 'Windows' - vmSize: 'Standard_DS2_v2' - // Non-required parameters - adminPassword: '' - availabilityZone: 2 - backupPolicyName: '' - backupVaultName: '' - backupVaultResourceGroup: '' - computerName: 'winvm1' - dataDisks: [ - { - caching: 'None' - createOption: 'Empty' - deleteOption: 'Delete' - diskSizeGB: '128' - managedDisk: { - storageAccountType: 'Premium_LRS' - } - } - { - caching: 'None' - createOption: 'Empty' - deleteOption: 'Delete' - diskSizeGB: '128' - managedDisk: { - storageAccountType: 'Premium_LRS' - } - } - ] - enableAutomaticUpdates: true - enableDefaultTelemetry: '' - encryptionAtHost: false - extensionAadJoinConfig: { - enabled: true - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } - extensionAntiMalwareConfig: { - enabled: true - settings: { - AntimalwareEnabled: 'true' - Exclusions: { - Extensions: '.ext1;.ext2' - Paths: 'c:\\excluded-path-1;c:\\excluded-path-2' - Processes: 'excludedproc1.exe;excludedproc2.exe' - } - RealtimeProtectionEnabled: 'true' - ScheduledScanSettings: { - day: '7' - isEnabled: 'true' - scanType: 'Quick' - time: '120' - } - } - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } - extensionAzureDiskEncryptionConfig: { - enabled: true - settings: { - EncryptionOperation: 'EnableEncryption' - KekVaultResourceId: '' - KeyEncryptionAlgorithm: 'RSA-OAEP' - KeyEncryptionKeyURL: '' - KeyVaultResourceId: '' - KeyVaultURL: '' - ResizeOSDisk: 'false' - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - VolumeType: 'All' - } - } - extensionCustomScriptConfig: { - enabled: true - fileData: [ - { - storageAccountId: '' - uri: '' - } - ] - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } - extensionCustomScriptProtectedSetting: { - commandToExecute: '' - } - extensionDependencyAgentConfig: { - enabled: true - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } - extensionDSCConfig: { - enabled: true - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } - extensionMonitoringAgentConfig: { - enabled: true - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } - extensionNetworkWatcherAgentConfig: { - enabled: true - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } - location: '' - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - managedIdentities: { - systemAssigned: true - userAssignedResourceIds: [ - '' - ] - } - monitoringWorkspaceId: '' - name: 'cvmwincom' - patchMode: 'AutomaticByPlatform' - proximityPlacementGroupResourceId: '' - roleAssignments: [ - { - principalId: '' - principalType: 'ServicePrincipal' - roleDefinitionIdOrName: 'Owner' - } - { - principalId: '' - principalType: 'ServicePrincipal' - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - } - { - principalId: '' - principalType: 'ServicePrincipal' - roleDefinitionIdOrName: '' - } - ] - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } -} -``` - -
-

- -

- -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 - "adminUsername": { - "value": "VMAdmin" - }, - "imageReference": { - "value": { - "offer": "WindowsServer", - "publisher": "MicrosoftWindowsServer", - "sku": "2019-datacenter", - "version": "latest" - } - }, - "nicConfigurations": { - "value": [ - { - "deleteOption": "Delete", - "diagnosticSettings": [ - { - "eventHubAuthorizationRuleResourceId": "", - "eventHubName": "", - "metricCategories": [ - { - "category": "AllMetrics" - } - ], - "name": "customSetting", - "storageAccountResourceId": "", - "workspaceResourceId": "" - } - ], - "ipConfigurations": [ - { - "applicationSecurityGroups": [ - { - "id": "" - } - ], - "diagnosticSettings": [ - { - "eventHubAuthorizationRuleResourceId": "", - "eventHubName": "", - "metricCategories": [ - { - "category": "AllMetrics" - } - ], - "name": "customSetting", - "storageAccountResourceId": "", - "workspaceResourceId": "" - } - ], - "loadBalancerBackendAddressPools": [ - { - "id": "" - } - ], - "name": "ipconfig01", - "pipConfiguration": { - "publicIpNameSuffix": "-pip-01", - "roleAssignments": [ - { - "principalId": "", - "principalType": "ServicePrincipal", - "roleDefinitionIdOrName": "Reader" - } - ] - }, - "subnetResourceId": "", - "zones": [ - "1", - "2", - "3" - ] - } - ], - "nicSuffix": "-nic-01", - "roleAssignments": [ - { - "principalId": "", - "principalType": "ServicePrincipal", - "roleDefinitionIdOrName": "Reader" - } - ] - } - ] - }, - "osDisk": { - "value": { - "caching": "None", - "createOption": "fromImage", - "deleteOption": "Delete", - "diskSizeGB": "128", - "managedDisk": { - "storageAccountType": "Premium_LRS" - } - } - }, - "osType": { - "value": "Windows" - }, - "vmSize": { - "value": "Standard_DS2_v2" - }, - // Non-required parameters - "adminPassword": { - "value": "" - }, - "availabilityZone": { - "value": 2 - }, - "backupPolicyName": { - "value": "" - }, - "backupVaultName": { - "value": "" - }, - "backupVaultResourceGroup": { - "value": "" - }, - "computerName": { - "value": "winvm1" - }, - "dataDisks": { - "value": [ - { - "caching": "None", - "createOption": "Empty", - "deleteOption": "Delete", - "diskSizeGB": "128", - "managedDisk": { - "storageAccountType": "Premium_LRS" - } - }, - { - "caching": "None", - "createOption": "Empty", - "deleteOption": "Delete", - "diskSizeGB": "128", - "managedDisk": { - "storageAccountType": "Premium_LRS" - } - } - ] - }, - "enableAutomaticUpdates": { - "value": true - }, - "enableDefaultTelemetry": { - "value": "" - }, - "encryptionAtHost": { - "value": false - }, - "extensionAadJoinConfig": { - "value": { - "enabled": true, - "tags": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - }, - "extensionAntiMalwareConfig": { - "value": { - "enabled": true, - "settings": { - "AntimalwareEnabled": "true", - "Exclusions": { - "Extensions": ".ext1;.ext2", - "Paths": "c:\\excluded-path-1;c:\\excluded-path-2", - "Processes": "excludedproc1.exe;excludedproc2.exe" - }, - "RealtimeProtectionEnabled": "true", - "ScheduledScanSettings": { - "day": "7", - "isEnabled": "true", - "scanType": "Quick", - "time": "120" - } - }, - "tags": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - }, - "extensionAzureDiskEncryptionConfig": { - "value": { - "enabled": true, - "settings": { - "EncryptionOperation": "EnableEncryption", - "KekVaultResourceId": "", - "KeyEncryptionAlgorithm": "RSA-OAEP", - "KeyEncryptionKeyURL": "", - "KeyVaultResourceId": "", - "KeyVaultURL": "", - "ResizeOSDisk": "false", - "tags": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - }, - "VolumeType": "All" - } - } - }, - "extensionCustomScriptConfig": { - "value": { - "enabled": true, - "fileData": [ - { - "storageAccountId": "", - "uri": "" - } - ], - "tags": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - }, - "extensionCustomScriptProtectedSetting": { - "value": { - "commandToExecute": "" - } - }, - "extensionDependencyAgentConfig": { - "value": { - "enabled": true, - "tags": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - }, - "extensionDSCConfig": { - "value": { - "enabled": true, - "tags": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - }, - "extensionMonitoringAgentConfig": { - "value": { - "enabled": true, - "tags": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - }, - "extensionNetworkWatcherAgentConfig": { - "value": { - "enabled": true, - "tags": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - }, - "location": { - "value": "" - }, - "lock": { - "value": { - "kind": "CanNotDelete", - "name": "myCustomLockName" - } - }, - "managedIdentities": { - "value": { - "systemAssigned": true, - "userAssignedResourceIds": [ - "" - ] - } - }, - "monitoringWorkspaceId": { - "value": "" - }, - "name": { - "value": "cvmwincom" - }, - "patchMode": { - "value": "AutomaticByPlatform" - }, - "proximityPlacementGroupResourceId": { - "value": "" - }, - "roleAssignments": { - "value": [ - { - "principalId": "", - "principalType": "ServicePrincipal", - "roleDefinitionIdOrName": "Owner" - }, - { - "principalId": "", - "principalType": "ServicePrincipal", - "roleDefinitionIdOrName": "b24988ac-6180-42a0-ab88-20f7382dd24c" - }, - { - "principalId": "", - "principalType": "ServicePrincipal", - "roleDefinitionIdOrName": "" - } - ] - }, - "tags": { - "value": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - } -} -``` - -
-

- - -## Parameters - -**Required parameters** - -| Parameter | Type | Description | -| :-- | :-- | :-- | -| [`adminUsername`](#parameter-adminusername) | securestring | Administrator username. | -| [`configurationProfile`](#parameter-configurationprofile) | string | The configuration profile of automanage. | -| [`imageReference`](#parameter-imagereference) | object | OS image reference. In case of marketplace images, it's the combination of the publisher, offer, sku, version attributes. In case of custom images it's the resource ID of the custom image. | -| [`nicConfigurations`](#parameter-nicconfigurations) | array | Configures NICs and PIPs. | -| [`osDisk`](#parameter-osdisk) | object | Specifies the OS disk. For security reasons, it is recommended to specify DiskEncryptionSet into the osDisk object. Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. | -| [`osType`](#parameter-ostype) | string | The chosen OS type. | -| [`vmSize`](#parameter-vmsize) | string | Specifies the size for the VMs. | - -**Optional parameters** - -| Parameter | Type | Description | -| :-- | :-- | :-- | -| [`additionalUnattendContent`](#parameter-additionalunattendcontent) | array | Specifies additional base-64 encoded XML formatted information that can be included in the Unattend.xml file, which is used by Windows Setup. - AdditionalUnattendContent object. | -| [`adminPassword`](#parameter-adminpassword) | securestring | When specifying a Windows Virtual Machine, this value should be passed. | -| [`allowExtensionOperations`](#parameter-allowextensionoperations) | bool | Specifies whether extension operations should be allowed on the virtual machine. This may only be set to False when no extensions are present on the virtual machine. | -| [`availabilitySetResourceId`](#parameter-availabilitysetresourceid) | string | Resource ID of an availability set. Cannot be used in combination with availability zone nor scale set. | -| [`availabilityZone`](#parameter-availabilityzone) | int | If set to 1, 2 or 3, the availability zone for all VMs is hardcoded to that value. If zero, then availability zones is not used. Cannot be used in combination with availability set nor scale set. | -| [`backupPolicyName`](#parameter-backuppolicyname) | string | Backup policy the VMs should be using for backup. If not provided, it will use the DefaultPolicy from the backup recovery service vault. | -| [`backupVaultName`](#parameter-backupvaultname) | string | Recovery service vault name to add VMs to backup. | -| [`backupVaultResourceGroup`](#parameter-backupvaultresourcegroup) | string | Resource group of the backup recovery service vault. If not provided the current resource group name is considered by default. | -| [`bootDiagnostics`](#parameter-bootdiagnostics) | bool | Whether boot diagnostics should be enabled on the Virtual Machine. Boot diagnostics will be enabled with a managed storage account if no bootDiagnosticsStorageAccountName value is provided. If bootDiagnostics and bootDiagnosticsStorageAccountName values are not provided, boot diagnostics will be disabled. | -| [`bootDiagnosticStorageAccountName`](#parameter-bootdiagnosticstorageaccountname) | string | Custom storage account used to store boot diagnostic information. Boot diagnostics will be enabled with a custom storage account if a value is provided. | -| [`bootDiagnosticStorageAccountUri`](#parameter-bootdiagnosticstorageaccounturi) | string | Storage account boot diagnostic base URI. | -| [`certificatesToBeInstalled`](#parameter-certificatestobeinstalled) | array | Specifies set of certificates that should be installed onto the virtual machine. | -| [`computerName`](#parameter-computername) | string | Can be used if the computer name needs to be different from the Azure VM resource name. If not used, the resource name will be used as computer name. | -| [`customData`](#parameter-customdata) | string | Custom data associated to the VM, this value will be automatically converted into base64 to account for the expected VM format. | -| [`dataDisks`](#parameter-datadisks) | array | Specifies the data disks. For security reasons, it is recommended to specify DiskEncryptionSet into the dataDisk object. Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. | -| [`dedicatedHostId`](#parameter-dedicatedhostid) | string | Specifies resource ID about the dedicated host that the virtual machine resides in. | -| [`disablePasswordAuthentication`](#parameter-disablepasswordauthentication) | bool | Specifies whether password authentication should be disabled. | -| [`enableAutomaticUpdates`](#parameter-enableautomaticupdates) | bool | Indicates whether Automatic Updates is enabled for the Windows virtual machine. Default value is true. When patchMode is set to Manual, this parameter must be set to false. For virtual machine scale sets, this property can be updated and updates will take effect on OS reprovisioning. | -| [`enableDefaultTelemetry`](#parameter-enabledefaulttelemetry) | bool | Enable telemetry via a Globally Unique Identifier (GUID). | -| [`enableEvictionPolicy`](#parameter-enableevictionpolicy) | bool | Specifies the eviction policy for the low priority virtual machine. Will result in 'Deallocate' eviction policy. | -| [`encryptionAtHost`](#parameter-encryptionathost) | bool | This property can be used by user in the request to enable or disable the Host Encryption for the virtual machine. This will enable the encryption for all the disks including Resource/Temp disk at host itself. For security reasons, it is recommended to set encryptionAtHost to True. Restrictions: Cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. | -| [`extensionAadJoinConfig`](#parameter-extensionaadjoinconfig) | object | The configuration for the [AAD Join] extension. Must at least contain the ["enabled": true] property to be executed. | -| [`extensionAntiMalwareConfig`](#parameter-extensionantimalwareconfig) | object | The configuration for the [Anti Malware] extension. Must at least contain the ["enabled": true] property to be executed. | -| [`extensionAzureDiskEncryptionConfig`](#parameter-extensionazurediskencryptionconfig) | object | The configuration for the [Azure Disk Encryption] extension. Must at least contain the ["enabled": true] property to be executed. Restrictions: Cannot be enabled on disks that have encryption at host enabled. Managed disks encrypted using Azure Disk Encryption cannot be encrypted using customer-managed keys. | -| [`extensionCustomScriptConfig`](#parameter-extensioncustomscriptconfig) | object | The configuration for the [Custom Script] extension. Must at least contain the ["enabled": true] property to be executed. | -| [`extensionCustomScriptProtectedSetting`](#parameter-extensioncustomscriptprotectedsetting) | secureObject | Any object that contains the extension specific protected settings. | -| [`extensionDependencyAgentConfig`](#parameter-extensiondependencyagentconfig) | object | The configuration for the [Dependency Agent] extension. Must at least contain the ["enabled": true] property to be executed. | -| [`extensionDomainJoinConfig`](#parameter-extensiondomainjoinconfig) | object | The configuration for the [Domain Join] extension. Must at least contain the ["enabled": true] property to be executed. | -| [`extensionDomainJoinPassword`](#parameter-extensiondomainjoinpassword) | securestring | Required if name is specified. Password of the user specified in user parameter. | -| [`extensionDSCConfig`](#parameter-extensiondscconfig) | object | The configuration for the [Desired State Configuration] extension. Must at least contain the ["enabled": true] property to be executed. | -| [`extensionMonitoringAgentConfig`](#parameter-extensionmonitoringagentconfig) | object | The configuration for the [Monitoring Agent] extension. Must at least contain the ["enabled": true] property to be executed. | -| [`extensionNetworkWatcherAgentConfig`](#parameter-extensionnetworkwatcheragentconfig) | object | The configuration for the [Network Watcher Agent] extension. Must at least contain the ["enabled": true] property to be executed. | -| [`licenseType`](#parameter-licensetype) | string | Specifies that the image or disk that is being used was licensed on-premises. This element is only used for images that contain the Windows Server operating system. | -| [`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. The system-assigned managed identity will automatically be enabled if extensionAadJoinConfig.enabled = "True". | -| [`maxPriceForLowPriorityVm`](#parameter-maxpriceforlowpriorityvm) | string | Specifies the maximum price you are willing to pay for a low priority VM/VMSS. This price is in US Dollars. | -| [`monitoringWorkspaceId`](#parameter-monitoringworkspaceid) | string | Resource ID of the monitoring log analytics workspace. Must be set when extensionMonitoringAgentConfig is set to true. | -| [`name`](#parameter-name) | string | The name of the virtual machine to be created. You should use a unique prefix to reduce name collisions in Active Directory. If no value is provided, a 10 character long unique string will be generated based on the Resource Group's name. | -| [`patchAssessmentMode`](#parameter-patchassessmentmode) | string | VM guest patching assessment mode. Set it to 'AutomaticByPlatform' to enable automatically check for updates every 24 hours. | -| [`patchMode`](#parameter-patchmode) | string | VM guest patching orchestration mode. 'AutomaticByOS' & 'Manual' are for Windows only, 'ImageDefault' for Linux only. Refer to 'https://learn.microsoft.com/en-us/azure/virtual-machines/automatic-vm-guest-patching'. | -| [`plan`](#parameter-plan) | object | Specifies information about the marketplace image used to create the virtual machine. This element is only used for marketplace images. Before you can use a marketplace image from an API, you must enable the image for programmatic use. | -| [`priority`](#parameter-priority) | string | Specifies the priority for the virtual machine. | -| [`provisionVMAgent`](#parameter-provisionvmagent) | bool | Indicates whether virtual machine agent should be provisioned on the virtual machine. When this property is not specified in the request body, default behavior is to set it to true. This will ensure that VM Agent is installed on the VM so that extensions can be added to the VM later. | -| [`proximityPlacementGroupResourceId`](#parameter-proximityplacementgroupresourceid) | string | Resource ID of a proximity placement group. | -| [`publicKeys`](#parameter-publickeys) | array | The list of SSH public keys used to authenticate with linux based VMs. | -| [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | -| [`sasTokenValidityLength`](#parameter-sastokenvaliditylength) | string | SAS token validity length to use to download files from storage accounts. Usage: 'PT8H' - valid for 8 hours; 'P5D' - valid for 5 days; 'P1Y' - valid for 1 year. When not provided, the SAS token will be valid for 8 hours. | -| [`secureBootEnabled`](#parameter-securebootenabled) | bool | Specifies whether secure boot should be enabled on the virtual machine. This parameter is part of the UefiSettings. SecurityType should be set to TrustedLaunch to enable UefiSettings. | -| [`securityType`](#parameter-securitytype) | string | Specifies the SecurityType of the virtual machine. It is set as TrustedLaunch to enable UefiSettings. | -| [`tags`](#parameter-tags) | object | Tags of the resource. | -| [`timeZone`](#parameter-timezone) | string | Specifies the time zone of the virtual machine. e.g. 'Pacific Standard Time'. Possible values can be `TimeZoneInfo.id` value from time zones returned by `TimeZoneInfo.GetSystemTimeZones`. | -| [`ultraSSDEnabled`](#parameter-ultrassdenabled) | bool | The flag that enables or disables a capability to have one or more managed data disks with UltraSSD_LRS storage account type on the VM or VMSS. Managed disks with storage account type UltraSSD_LRS can be added to a virtual machine or virtual machine scale set only if this property is enabled. | -| [`vTpmEnabled`](#parameter-vtpmenabled) | bool | Specifies whether vTPM should be enabled on the virtual machine. This parameter is part of the UefiSettings. SecurityType should be set to TrustedLaunch to enable UefiSettings. | -| [`winRM`](#parameter-winrm) | object | Specifies the Windows Remote Management listeners. This enables remote Windows PowerShell. - WinRMConfiguration object. | - -**Generated parameters** - -| Parameter | Type | Description | -| :-- | :-- | :-- | -| [`baseTime`](#parameter-basetime) | string | Do not provide a value! This date value is used to generate a registration token. | - -### Parameter: `adminUsername` - -Administrator username. - -- Required: Yes -- Type: securestring - -### Parameter: `configurationProfile` - -The configuration profile of automanage. - -- Required: No -- Type: string -- Default: `''` -- Allowed: - ```Bicep - [ - '' - '/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesDevTest' - '/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesProduction' - ] - ``` - -### Parameter: `imageReference` - -OS image reference. In case of marketplace images, it's the combination of the publisher, offer, sku, version attributes. In case of custom images it's the resource ID of the custom image. - -- Required: Yes -- Type: object - -### Parameter: `nicConfigurations` - -Configures NICs and PIPs. - -- Required: Yes -- Type: array - -### Parameter: `osDisk` - -Specifies the OS disk. For security reasons, it is recommended to specify DiskEncryptionSet into the osDisk object. Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. - -- Required: Yes -- Type: object - -### Parameter: `osType` - -The chosen OS type. - -- Required: Yes -- Type: string -- Allowed: - ```Bicep - [ - 'Linux' - 'Windows' - ] - ``` - -### Parameter: `vmSize` - -Specifies the size for the VMs. - -- Required: Yes -- Type: string - -### Parameter: `additionalUnattendContent` - -Specifies additional base-64 encoded XML formatted information that can be included in the Unattend.xml file, which is used by Windows Setup. - AdditionalUnattendContent object. - -- Required: No -- Type: array -- Default: `[]` - -### Parameter: `adminPassword` - -When specifying a Windows Virtual Machine, this value should be passed. - -- Required: No -- Type: securestring -- Default: `''` - -### Parameter: `allowExtensionOperations` - -Specifies whether extension operations should be allowed on the virtual machine. This may only be set to False when no extensions are present on the virtual machine. - -- Required: No -- Type: bool -- Default: `True` - -### Parameter: `availabilitySetResourceId` - -Resource ID of an availability set. Cannot be used in combination with availability zone nor scale set. - -- Required: No -- Type: string -- Default: `''` - -### Parameter: `availabilityZone` - -If set to 1, 2 or 3, the availability zone for all VMs is hardcoded to that value. If zero, then availability zones is not used. Cannot be used in combination with availability set nor scale set. - -- Required: No -- Type: int -- Default: `0` -- Allowed: - ```Bicep - [ - 0 - 1 - 2 - 3 - ] - ``` - -### Parameter: `backupPolicyName` - -Backup policy the VMs should be using for backup. If not provided, it will use the DefaultPolicy from the backup recovery service vault. - -- Required: No -- Type: string -- Default: `'DefaultPolicy'` - -### Parameter: `backupVaultName` - -Recovery service vault name to add VMs to backup. - -- Required: No -- Type: string -- Default: `''` - -### Parameter: `backupVaultResourceGroup` - -Resource group of the backup recovery service vault. If not provided the current resource group name is considered by default. - -- Required: No -- Type: string -- Default: `[resourceGroup().name]` - -### Parameter: `bootDiagnostics` - -Whether boot diagnostics should be enabled on the Virtual Machine. Boot diagnostics will be enabled with a managed storage account if no bootDiagnosticsStorageAccountName value is provided. If bootDiagnostics and bootDiagnosticsStorageAccountName values are not provided, boot diagnostics will be disabled. - -- Required: No -- Type: bool -- Default: `False` - -### Parameter: `bootDiagnosticStorageAccountName` - -Custom storage account used to store boot diagnostic information. Boot diagnostics will be enabled with a custom storage account if a value is provided. - -- Required: No -- Type: string -- Default: `''` - -### Parameter: `bootDiagnosticStorageAccountUri` - -Storage account boot diagnostic base URI. - -- Required: No -- Type: string -- Default: `[format('.blob.{0}/', environment().suffixes.storage)]` - -### Parameter: `certificatesToBeInstalled` - -Specifies set of certificates that should be installed onto the virtual machine. - -- Required: No -- Type: array -- Default: `[]` - -### Parameter: `computerName` - -Can be used if the computer name needs to be different from the Azure VM resource name. If not used, the resource name will be used as computer name. - -- Required: No -- Type: string -- Default: `[parameters('name')]` - -### Parameter: `customData` - -Custom data associated to the VM, this value will be automatically converted into base64 to account for the expected VM format. - -- Required: No -- Type: string -- Default: `''` - -### Parameter: `dataDisks` - -Specifies the data disks. For security reasons, it is recommended to specify DiskEncryptionSet into the dataDisk object. Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. - -- Required: No -- Type: array -- Default: `[]` - -### Parameter: `dedicatedHostId` - -Specifies resource ID about the dedicated host that the virtual machine resides in. - -- Required: No -- Type: string -- Default: `''` - -### Parameter: `disablePasswordAuthentication` - -Specifies whether password authentication should be disabled. - -- Required: No -- Type: bool -- Default: `False` - -### Parameter: `enableAutomaticUpdates` - -Indicates whether Automatic Updates is enabled for the Windows virtual machine. Default value is true. When patchMode is set to Manual, this parameter must be set to false. For virtual machine scale sets, this property can be updated and updates will take effect on OS reprovisioning. - -- Required: No -- Type: bool -- Default: `True` - -### Parameter: `enableDefaultTelemetry` - -Enable telemetry via a Globally Unique Identifier (GUID). - -- Required: No -- Type: bool -- Default: `True` - -### Parameter: `enableEvictionPolicy` - -Specifies the eviction policy for the low priority virtual machine. Will result in 'Deallocate' eviction policy. - -- Required: No -- Type: bool -- Default: `False` - -### Parameter: `encryptionAtHost` - -This property can be used by user in the request to enable or disable the Host Encryption for the virtual machine. This will enable the encryption for all the disks including Resource/Temp disk at host itself. For security reasons, it is recommended to set encryptionAtHost to True. Restrictions: Cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. - -- Required: No -- Type: bool -- Default: `True` - -### Parameter: `extensionAadJoinConfig` - -The configuration for the [AAD Join] extension. Must at least contain the ["enabled": true] property to be executed. - -- Required: No -- Type: object -- Default: - ```Bicep - { - enabled: false - } - ``` - -### Parameter: `extensionAntiMalwareConfig` - -The configuration for the [Anti Malware] extension. Must at least contain the ["enabled": true] property to be executed. - -- Required: No -- Type: object -- Default: - ```Bicep - { - enabled: false - } - ``` - -### Parameter: `extensionAzureDiskEncryptionConfig` - -The configuration for the [Azure Disk Encryption] extension. Must at least contain the ["enabled": true] property to be executed. Restrictions: Cannot be enabled on disks that have encryption at host enabled. Managed disks encrypted using Azure Disk Encryption cannot be encrypted using customer-managed keys. - -- Required: No -- Type: object -- Default: - ```Bicep - { - enabled: false - } - ``` - -### Parameter: `extensionCustomScriptConfig` - -The configuration for the [Custom Script] extension. Must at least contain the ["enabled": true] property to be executed. - -- Required: No -- Type: object -- Default: - ```Bicep - { - enabled: false - fileData: [] - } - ``` - -### Parameter: `extensionCustomScriptProtectedSetting` - -Any object that contains the extension specific protected settings. - -- Required: No -- Type: secureObject -- Default: `{}` - -### Parameter: `extensionDependencyAgentConfig` - -The configuration for the [Dependency Agent] extension. Must at least contain the ["enabled": true] property to be executed. - -- Required: No -- Type: object -- Default: - ```Bicep - { - enabled: false - } - ``` - -### Parameter: `extensionDomainJoinConfig` - -The configuration for the [Domain Join] extension. Must at least contain the ["enabled": true] property to be executed. - -- Required: No -- Type: object -- Default: - ```Bicep - { - enabled: false - } - ``` - -### Parameter: `extensionDomainJoinPassword` - -Required if name is specified. Password of the user specified in user parameter. - -- Required: No -- Type: securestring -- Default: `''` - -### Parameter: `extensionDSCConfig` - -The configuration for the [Desired State Configuration] extension. Must at least contain the ["enabled": true] property to be executed. - -- Required: No -- Type: object -- Default: - ```Bicep - { - enabled: false - } - ``` - -### Parameter: `extensionMonitoringAgentConfig` - -The configuration for the [Monitoring Agent] extension. Must at least contain the ["enabled": true] property to be executed. - -- Required: No -- Type: object -- Default: - ```Bicep - { - enabled: false - } - ``` - -### Parameter: `extensionNetworkWatcherAgentConfig` - -The configuration for the [Network Watcher Agent] extension. Must at least contain the ["enabled": true] property to be executed. - -- Required: No -- Type: object -- Default: - ```Bicep - { - enabled: false - } - ``` - -### Parameter: `licenseType` - -Specifies that the image or disk that is being used was licensed on-premises. This element is only used for images that contain the Windows Server operating system. - -- Required: No -- Type: string -- Default: `''` -- Allowed: - ```Bicep - [ - '' - 'Windows_Client' - 'Windows_Server' - ] - ``` - -### Parameter: `location` - -Location for all resources. - -- Required: No -- Type: string -- Default: `[resourceGroup().location]` - -### Parameter: `lock` - -The lock settings of the service. - -- Required: No -- Type: object - -**Optional parameters** - -| Parameter | Type | Description | -| :-- | :-- | :-- | -| [`kind`](#parameter-lockkind) | string | Specify the type of lock. | -| [`name`](#parameter-lockname) | string | Specify the name of lock. | - -### Parameter: `lock.kind` - -Specify the type of lock. - -- Required: No -- Type: string -- Allowed: - ```Bicep - [ - 'CanNotDelete' - 'None' - 'ReadOnly' - ] - ``` - -### Parameter: `lock.name` - -Specify the name of lock. - -- Required: No -- Type: string - -### Parameter: `managedIdentities` - -The managed identity definition for this resource. The system-assigned managed identity will automatically be enabled if extensionAadJoinConfig.enabled = "True". - -- Required: No -- Type: object - -**Optional parameters** - -| 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. | - -### Parameter: `managedIdentities.systemAssigned` - -Enables system assigned managed identity on the resource. - -- Required: No -- Type: bool - -### Parameter: `managedIdentities.userAssignedResourceIds` - -The resource ID(s) to assign to the resource. - -- Required: No -- Type: array - -### Parameter: `maxPriceForLowPriorityVm` - -Specifies the maximum price you are willing to pay for a low priority VM/VMSS. This price is in US Dollars. - -- Required: No -- Type: string -- Default: `''` - -### Parameter: `monitoringWorkspaceId` - -Resource ID of the monitoring log analytics workspace. Must be set when extensionMonitoringAgentConfig is set to true. - -- Required: No -- Type: string -- Default: `''` - -### Parameter: `name` - -The name of the virtual machine to be created. You should use a unique prefix to reduce name collisions in Active Directory. If no value is provided, a 10 character long unique string will be generated based on the Resource Group's name. - -- Required: No -- Type: string -- Default: `[take(toLower(uniqueString(resourceGroup().name)), 10)]` - -### Parameter: `patchAssessmentMode` - -VM guest patching assessment mode. Set it to 'AutomaticByPlatform' to enable automatically check for updates every 24 hours. - -- Required: No -- Type: string -- Default: `'ImageDefault'` -- Allowed: - ```Bicep - [ - 'AutomaticByPlatform' - 'ImageDefault' - ] - ``` - -### Parameter: `patchMode` - -VM guest patching orchestration mode. 'AutomaticByOS' & 'Manual' are for Windows only, 'ImageDefault' for Linux only. Refer to 'https://learn.microsoft.com/en-us/azure/virtual-machines/automatic-vm-guest-patching'. - -- Required: No -- Type: string -- Default: `''` -- Allowed: - ```Bicep - [ - '' - 'AutomaticByOS' - 'AutomaticByPlatform' - 'ImageDefault' - 'Manual' - ] - ``` - -### Parameter: `plan` - -Specifies information about the marketplace image used to create the virtual machine. This element is only used for marketplace images. Before you can use a marketplace image from an API, you must enable the image for programmatic use. - -- Required: No -- Type: object -- Default: `{}` - -### Parameter: `priority` - -Specifies the priority for the virtual machine. - -- Required: No -- Type: string -- Default: `'Regular'` -- Allowed: - ```Bicep - [ - 'Low' - 'Regular' - 'Spot' - ] - ``` - -### Parameter: `provisionVMAgent` - -Indicates whether virtual machine agent should be provisioned on the virtual machine. When this property is not specified in the request body, default behavior is to set it to true. This will ensure that VM Agent is installed on the VM so that extensions can be added to the VM later. - -- Required: No -- Type: bool -- Default: `True` - -### Parameter: `proximityPlacementGroupResourceId` - -Resource ID of a proximity placement group. - -- Required: No -- Type: string -- Default: `''` - -### Parameter: `publicKeys` - -The list of SSH public keys used to authenticate with linux based VMs. - -- Required: No -- Type: array -- Default: `[]` - -### Parameter: `roleAssignments` - -Array of role assignments to create. - -- Required: No -- Type: array - -**Required parameters** - -| Parameter | Type | Description | -| :-- | :-- | :-- | -| [`principalId`](#parameter-roleassignmentsprincipalid) | string | The principal ID of the principal (user/group/identity) to assign the role to. | -| [`roleDefinitionIdOrName`](#parameter-roleassignmentsroledefinitionidorname) | string | 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'. | - -**Optional parameters** - -| Parameter | Type | Description | -| :-- | :-- | :-- | -| [`condition`](#parameter-roleassignmentscondition) | string | 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`](#parameter-roleassignmentsconditionversion) | string | Version of the condition. | -| [`delegatedManagedIdentityResourceId`](#parameter-roleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | -| [`description`](#parameter-roleassignmentsdescription) | string | The description of the role assignment. | -| [`principalType`](#parameter-roleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. | - -### Parameter: `roleAssignments.principalId` - -The principal ID of the principal (user/group/identity) to assign the role to. - -- Required: Yes -- Type: string - -### Parameter: `roleAssignments.roleDefinitionIdOrName` - -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'. - -- Required: Yes -- Type: string - -### Parameter: `roleAssignments.condition` - -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" - -- Required: No -- Type: string - -### Parameter: `roleAssignments.conditionVersion` - -Version of the condition. - -- Required: No -- Type: string -- Allowed: - ```Bicep - [ - '2.0' - ] - ``` - -### Parameter: `roleAssignments.delegatedManagedIdentityResourceId` - -The Resource Id of the delegated managed identity resource. - -- Required: No -- Type: string - -### Parameter: `roleAssignments.description` - -The description of the role assignment. - -- Required: No -- Type: string - -### Parameter: `roleAssignments.principalType` - -The principal type of the assigned principal ID. - -- Required: No -- Type: string -- Allowed: - ```Bicep - [ - 'Device' - 'ForeignGroup' - 'Group' - 'ServicePrincipal' - 'User' - ] - ``` - -### Parameter: `sasTokenValidityLength` - -SAS token validity length to use to download files from storage accounts. Usage: 'PT8H' - valid for 8 hours; 'P5D' - valid for 5 days; 'P1Y' - valid for 1 year. When not provided, the SAS token will be valid for 8 hours. - -- Required: No -- Type: string -- Default: `'PT8H'` - -### Parameter: `secureBootEnabled` - -Specifies whether secure boot should be enabled on the virtual machine. This parameter is part of the UefiSettings. SecurityType should be set to TrustedLaunch to enable UefiSettings. - -- Required: No -- Type: bool -- Default: `False` - -### Parameter: `securityType` - -Specifies the SecurityType of the virtual machine. It is set as TrustedLaunch to enable UefiSettings. - -- Required: No -- Type: string -- Default: `''` - -### Parameter: `tags` - -Tags of the resource. - -- Required: No -- Type: object - -### Parameter: `timeZone` - -Specifies the time zone of the virtual machine. e.g. 'Pacific Standard Time'. Possible values can be `TimeZoneInfo.id` value from time zones returned by `TimeZoneInfo.GetSystemTimeZones`. - -- Required: No -- Type: string -- Default: `''` - -### Parameter: `ultraSSDEnabled` - -The flag that enables or disables a capability to have one or more managed data disks with UltraSSD_LRS storage account type on the VM or VMSS. Managed disks with storage account type UltraSSD_LRS can be added to a virtual machine or virtual machine scale set only if this property is enabled. - -- Required: No -- Type: bool -- Default: `False` - -### Parameter: `vTpmEnabled` - -Specifies whether vTPM should be enabled on the virtual machine. This parameter is part of the UefiSettings. SecurityType should be set to TrustedLaunch to enable UefiSettings. - -- Required: No -- Type: bool -- Default: `False` - -### Parameter: `winRM` - -Specifies the Windows Remote Management listeners. This enables remote Windows PowerShell. - WinRMConfiguration object. - -- Required: No -- Type: object -- Default: `{}` - -### Parameter: `baseTime` - -Do not provide a value! This date value is used to generate a registration token. - -- Required: No -- Type: string -- Default: `[utcNow('u')]` - - -## Outputs - -| Output | Type | Description | -| :-- | :-- | :-- | -| `location` | string | The location the resource was deployed into. | -| `name` | string | The name of the VM. | -| `resourceGroupName` | string | The name of the resource group the VM was created in. | -| `resourceId` | string | The resource ID of the VM. | -| `systemAssignedMIPrincipalId` | string | The principal ID of the system assigned identity. | - -## Cross-referenced modules - -This section gives you an overview of all local-referenced module files (i.e., other CARML 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 | -| :-- | :-- | -| `modules/network/network-interface` | Local reference | -| `modules/network/public-ip-address` | Local reference | -| `modules/recovery-services/vault/backup-fabric/protection-container/protected-item` | Local reference | - -## Notes - -### Automanage considerations - -Enabling automanage triggers the creation of additional resources outside of the specific virtual machine deployment, such as: -- an `Automanage-Automate-` in the same Virtual Machine Resource Group and linking to the log analytics workspace leveraged by Azure Security Center. -- a `DefaultResourceGroup-` resource group hosting a recovery services vault `DefaultBackupVault-` where virtual machine backups are stored -For further details on automanage please refer to [Automanage virtual machines](https://learn.microsoft.com/en-us/azure/automanage/automanage-virtual-machines). - -### Parameter Usage: `imageReference` - -#### Marketplace images - -

- -Parameter JSON format - -```json -"imageReference": { - "value": { - "publisher": "MicrosoftWindowsServer", - "offer": "WindowsServer", - "sku": "2022-datacenter-azure-edition", - "version": "latest" - } -} -``` - -
-
- -Bicep format - -```bicep -imageReference: { - publisher: 'MicrosoftWindowsServer' - offer: 'WindowsServer' - sku: '2022-datacenter-azure-edition' - version: 'latest' -} -``` - -
-

- -#### Custom images - -

- -Parameter JSON format - -```json -"imageReference": { - "value": { - "id": "/subscriptions/12345-6789-1011-1213-15161718/resourceGroups/rg-name/providers/Microsoft.Compute/images/imagename" - } -} -``` - -
- -
- -Bicep format - -```bicep -imageReference: { - id: '/subscriptions/12345-6789-1011-1213-15161718/resourceGroups/rg-name/providers/Microsoft.Compute/images/imagename' -} -``` - -
-

- -### Parameter Usage: `plan` - -

- -Parameter JSON format - -```json -"plan": { - "value": { - "name": "qvsa-25", - "product": "qualys-virtual-scanner", - "publisher": "qualysguard" - } -} -``` - -
- -
- -Bicep format - -```bicep -plan: { - name: 'qvsa-25' - product: 'qualys-virtual-scanner' - publisher: 'qualysguard' -} -``` - -
-

- -### Parameter Usage: `osDisk` - -

- -Parameter JSON format - -```json -"osDisk": { - "value": { - "createOption": "fromImage", - "deleteOption": "Delete", // Optional. Can be 'Delete' or 'Detach' - "diskSizeGB": "128", - "managedDisk": { - "storageAccountType": "Premium_LRS", - "diskEncryptionSet": { // Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. - "id": "/subscriptions//resourceGroups//providers/Microsoft.Compute/diskEncryptionSets/" - } - } - } -} -``` - -
- -
- -Bicep format - -```bicep -osDisk: { - createOption: 'fromImage' - deleteOption: 'Delete' // Optional. Can be 'Delete' or 'Detach' - diskSizeGB: '128' - managedDisk: { - storageAccountType: 'Premium_LRS' - diskEncryptionSet: { // Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. - id: '/subscriptions//resourceGroups//providers/Microsoft.Compute/diskEncryptionSets/' - } - } -} -``` - -
-

- -### Parameter Usage: `dataDisks` - -

- -Parameter JSON format - -```json -"dataDisks": { - "value": [ - { - "caching": "ReadOnly", - "createOption": "Empty", - "deleteOption": "Delete", // Optional. Can be 'Delete' or 'Detach' - "diskSizeGB": "256", - "managedDisk": { - "storageAccountType": "Premium_LRS", - "diskEncryptionSet": { // Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. - "id": "/subscriptions//resourceGroups//providers/Microsoft.Compute/diskEncryptionSets/" - } - } - }, - { - "caching": "ReadOnly", - "createOption": "Empty", - "diskSizeGB": "128", - "managedDisk": { - "storageAccountType": "Premium_LRS", - "diskEncryptionSet": { // Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. - "id": "/subscriptions//resourceGroups//providers/Microsoft.Compute/diskEncryptionSets/" - } - } - } - ] -} -``` - -
- -
- -Bicep format - -```bicep -dataDisks: [ - { - caching: 'ReadOnly' - createOption: 'Empty' - deleteOption: 'Delete' // Optional. Can be 'Delete' or 'Detach' - diskSizeGB: '256' - managedDisk: { - storageAccountType: 'Premium_LRS' - diskEncryptionSet: { // Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. - id: '/subscriptions//resourceGroups//providers/Microsoft.Compute/diskEncryptionSets/' - } - } - } - { - caching: 'ReadOnly' - createOption: 'Empty' - diskSizeGB: '128' - managedDisk: { - storageAccountType: 'Premium_LRS' - diskEncryptionSet: { // Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. - id: '/subscriptions//resourceGroups//providers/Microsoft.Compute/diskEncryptionSets/' - } - } - } -] -``` - -
-

- -### Parameter Usage: `nicConfigurations` - -Comments: -- The field `nicSuffix` and `subnetResourceId` are mandatory. -- If `enablePublicIP` is set to true, then `publicIpNameSuffix` is also mandatory. -- Each IP config needs to have the mandatory field `name`. -- If not disabled, `enableAcceleratedNetworking` is considered `true` by default and requires the VM to be deployed with a supported OS and VM size. - -

- -Parameter JSON format - -```json -"nicConfigurations": { - "value": [ - { - "nicSuffix": "-nic-01", - "deleteOption": "Delete", // Optional. Can be 'Delete' or 'Detach' - "ipConfigurations": [ - { - "name": "ipconfig1", - "subnetResourceId": "/subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/", - "pipConfiguration": { - "publicIpNameSuffix": "-pip-01", - "roleAssignments": [ - { - "roleDefinitionIdOrName": "Reader", - "principalIds": [ - "" - ] - } - ] - } - }, - { - "name": "ipconfig2", - "subnetResourceId": "/subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/", - } - ], - "nsgId": "/subscriptions//resourceGroups//providers/Microsoft.Network/networkSecurityGroups/", - "roleAssignments": [ - { - "roleDefinitionIdOrName": "Reader", - "principalIds": [ - "" - ] - } - ] - }, - { - "nicSuffix": "-nic-02", - "ipConfigurations": [ - { - "name": "ipconfig1", - "subnetResourceId": "/subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/", - "pipConfiguration": { - "publicIpNameSuffix": "-pip-02" - } - }, - { - "name": "ipconfig2", - "subnetResourceId": "/subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/", - "privateIPAllocationMethod": "Static", - "privateIPAddress": "10.0.0.9" - } - ] - } - ] -} -``` - -
- -
- -Bicep format - -```bicep -nicConfigurations: { - value: [ - { - nicSuffix: '-nic-01' - deleteOption: 'Delete' // Optional. Can be 'Delete' or 'Detach' - ipConfigurations: [ - { - name: 'ipconfig1' - subnetResourceId: '/subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/' - pipConfiguration: { - publicIpNameSuffix: '-pip-01' - roleAssignments: [ - { - roleDefinitionIdOrName: 'Reader' - principalIds: [ - '' - ] - } - ] - } - } - { - name: 'ipconfig2' - subnetResourceId: '/subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/' - } - ] - nsgId: '/subscriptions//resourceGroups//providers/Microsoft.Network/networkSecurityGroups/' - roleAssignments: [ - { - roleDefinitionIdOrName: 'Reader' - principalIds: [ - '' - ] - } - ] - } - { - nicSuffix: '-nic-02' - ipConfigurations: [ - { - name: 'ipconfig1' - subnetResourceId: '/subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/' - pipConfiguration: { - publicIpNameSuffix: '-pip-02' - } - } - { - name: 'ipconfig2' - subnetResourceId: '/subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/' - privateIPAllocationMethod: 'Static' - privateIPAddress: '10.0.0.9' - } - ] - } - ] -} -``` - -
-

- -### Parameter Usage: `configurationProfileAssignments` - -

- -Parameter JSON format - -```json -"configurationProfileAssignments": { - "value": [ - "/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesProduction", - "/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesDevTest" - ] -} -``` - -
- -
- -Bicep format - -```bicep -configurationProfileAssignments: [ - '/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesProduction' - '/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesDevTest' -] -``` - -
-

- -### Parameter Usage: `extensionDomainJoinConfig` - -

- -Parameter JSON format - -```json -"extensionDomainJoinConfig": { - "value": { - "enabled": true, - "settings": { - "name": "contoso.com", - "user": "test.user@testcompany.com", - "ouPath": "OU=testOU; DC=contoso; DC=com", - "restart": true, - "options": 3 - } - } -}, -"extensionDomainJoinPassword": { - "reference": { - "keyVault": { - "id": "/subscriptions/</resourceGroups/myRG/providers/Microsoft.KeyVault/vaults/myKvlt" - }, - "secretName": "domainJoinUser02-Password" - } -} -``` - -
- -
- -Bicep format - -```bicep -extensionDomainJoinConfig: { - enabled: true - settings: { - name: 'contoso.com' - user: 'test.user@testcompany.com' - ouPath: 'OU=testOU; DC=contoso; DC=com' - restart: true - options: 3 - } -} - -resource kv1 'Microsoft.KeyVault/vaults@2019-09-01' existing = { - name: 'adp-[[namePrefix]]-az-kv-x-001' - scope: resourceGroup('[[subscriptionId]]','validation-rg') -} - -extensionDomainJoinPassword: kv1.getSecret('domainJoinUser02-Password') -``` - -
-

- -### Parameter Usage: `extensionAntiMalwareConfig` - -Only for OSType Windows - -

- -Parameter JSON format - -```json -"extensionAntiMalwareConfig": { - "value": { - "enabled": true, - "settings": { - "AntimalwareEnabled": true, - "Exclusions": { - "Extensions": ".log;.ldf", - "Paths": "D:\\IISlogs;D:\\DatabaseLogs", - "Processes": "mssence.svc" - }, - "RealtimeProtectionEnabled": true, - "ScheduledScanSettings": { - "isEnabled": "true", - "scanType": "Quick", - "day": "7", - "time": "120" - } - } - } -} -``` - -
- -
- -Bicep format - -```bicep -extensionAntiMalwareConfig: { - enabled: true - settings: { - AntimalwareEnabled: true - Exclusions: { - Extensions: '.log;.ldf' - Paths: 'D:\\IISlogs;D:\\DatabaseLogs' - Processes: 'mssence.svc' - } - RealtimeProtectionEnabled: true - ScheduledScanSettings: { - isEnabled: 'true' - scanType: 'Quick' - day: '7' - time: '120' - } - } -} -``` - -
-

- -### Parameter Usage: `extensionAzureDiskEncryptionConfig` - -

- -Parameter JSON format - -```json -"extensionAzureDiskEncryptionConfig": { - // Restrictions: Cannot be enabled on disks that have encryption at host enabled. Managed disks encrypted using Azure Disk Encryption cannot be encrypted using customer-managed keys. - "value": { - "enabled": true, - "settings": { - "EncryptionOperation": "EnableEncryption", - "KeyVaultURL": "https://mykeyvault.vault.azure.net/", - "KeyVaultResourceId": "/subscriptions/[[subscriptionId]]/resourceGroups/validation-rg/providers/Microsoft.KeyVault/vaults/adp-sxx-az-kv-x-001", - "KeyEncryptionKeyURL": "https://mykeyvault.vault.azure.net/keys/keyEncryptionKey/bc3bb46d95c64367975d722f473eeae5", // ID must be updated for new keys - "KekVaultResourceId": "/subscriptions/[[subscriptionId]]/resourceGroups/validation-rg/providers/Microsoft.KeyVault/vaults/adp-sxx-az-kv-x-001", - "KeyEncryptionAlgorithm": "RSA-OAEP", //'RSA-OAEP'/'RSA-OAEP-256'/'RSA1_5' - "VolumeType": "All", //'OS'/'Data'/'All' - "ResizeOSDisk": "false" - } - } -} -``` - -
- -
- -Bicep format - -```bicep -extensionAzureDiskEncryptionConfig: { - // Restrictions: Cannot be enabled on disks that have encryption at host enabled. Managed disks encrypted using Azure Disk Encryption cannot be encrypted using customer-managed keys. - enabled: true - settings: { - EncryptionOperation: 'EnableEncryption' - KeyVaultURL: 'https://mykeyvault.vault.azure.net/' - KeyVaultResourceId: '/subscriptions/[[subscriptionId]]/resourceGroups/validation-rg/providers/Microsoft.KeyVault/vaults/adp-sxx-az-kv-x-001' - KeyEncryptionKeyURL: 'https://mykeyvault.vault.azure.net/keys/keyEncryptionKey/bc3bb46d95c64367975d722f473eeae5' // ID must be updated for new keys - KekVaultResourceId: '/subscriptions/[[subscriptionId]]/resourceGroups/validation-rg/providers/Microsoft.KeyVault/vaults/adp-sxx-az-kv-x-001' - KeyEncryptionAlgorithm: 'RSA-OAEP' //'RSA-OAEP'/'RSA-OAEP-256'/'RSA1_5' - VolumeType: 'All' //'OS'/'Data'/'All' - ResizeOSDisk: 'false' - } -} -``` - -
-

- -### Parameter Usage: `extensionDSCConfig` - -

- -Parameter JSON format - -```json -"extensionDSCConfig": { - "value": { - { - "enabled": true, - "settings": { - "wmfVersion": "latest", - "configuration": { - "url": "http://validURLToConfigLocation", - "script": "ConfigurationScript.ps1", - "function": "ConfigurationFunction" - }, - "configurationArguments": { - "argument1": "Value1", - "argument2": "Value2" - }, - "configurationData": { - "url": "https://foo.psd1" - }, - "privacy": { - "dataCollection": "enable" - }, - "advancedOptions": { - "forcePullAndApply": false, - "downloadMappings": { - "specificDependencyKey": "https://myCustomDependencyLocation" - } - } - }, - "protectedSettings": { - "configurationArguments": { - "mySecret": "MyPlaceholder" - }, - "configurationUrlSasToken": "MyPlaceholder", - "configurationDataUrlSasToken": "MyPlaceholder" - } - } - } -} -``` - -
- -
- -Bicep format - -```bicep -extensionDSCConfig: { - { - enabled: true - settings: { - wmfVersion: 'latest' - configuration: { - url: 'http://validURLToConfigLocation' - script: 'ConfigurationScript.ps1' - function: 'ConfigurationFunction' - } - configurationArguments: { - argument1: 'Value1' - argument2: 'Value2' - } - configurationData: { - url: 'https://foo.psd1' - } - privacy: { - dataCollection: 'enable' - } - advancedOptions: { - forcePullAndApply: false - downloadMappings: { - specificDependencyKey: 'https://myCustomDependencyLocation' - } - } - } - protectedSettings: { - configurationArguments: { - mySecret: 'MyPlaceholder' - } - configurationUrlSasToken: 'MyPlaceholder' - configurationDataUrlSasToken: 'MyPlaceholder' - } - } -} -``` - -
-

- -### Parameter Usage: `extensionCustomScriptConfig` - -

- -Parameter JSON format - -```json -"extensionCustomScriptConfig": { - "value": { - "enabled": true, - "fileData": [ - //storage accounts with SAS token requirement - { - "uri": "https://mystorageaccount.blob.core.windows.net/avdscripts/File1.ps1", - "storageAccountId": "/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/rgName/providers/Microsoft.Storage/storageAccounts/storageAccountName" - }, - { - "uri": "https://mystorageaccount.blob.core.windows.net/avdscripts/File2.ps1", - "storageAccountId": "/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/rgName/providers/Microsoft.Storage/storageAccounts/storageAccountName" - }, - //storage account with public container (no SAS token is required) OR other public URL (not a storage account) - { - "uri": "https://github.com/myProject/File3.ps1", - "storageAccountId": "" - } - ], - "settings": { - "commandToExecute": "powershell -ExecutionPolicy Unrestricted -File testscript.ps1" - } - } -} -``` - -
- -
- -Bicep format - -```bicep -extensionCustomScriptConfig: { - enabled: true - fileData: [ - //storage accounts with SAS token requirement - { - uri: 'https://mystorageaccount.blob.core.windows.net/avdscripts/File1.ps1' - storageAccountId: '/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/rgName/providers/Microsoft.Storage/storageAccounts/storageAccountName' - } - { - uri: 'https://mystorageaccount.blob.core.windows.net/avdscripts/File2.ps1' - storageAccountId: '/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/rgName/providers/Microsoft.Storage/storageAccounts/storageAccountName' - } - //storage account with public container (no SAS token is required) OR other public URL (not a storage account) - { - uri: 'https://github.com/myProject/File3.ps1' - storageAccountId: '' - } - ] - settings: { - commandToExecute: 'powershell -ExecutionPolicy Unrestricted -File testscript.ps1' - } -} -``` - -
-

- -### Parameter Usage: `extensionCustomScriptProtectedSetting` - -This is used if you are going to use secrets or other sensitive information that you don't want to be visible in the deployment and logs. - -

- -Parameter JSON format - -```json -"extensionCustomScriptProtectedSetting": { - "value": [ - { - "commandToExecute": "mycommandToRun -someParam MYSECRET" - } - ] -} -``` - -
- -
- -Bicep format - -```bicep -extensionCustomScriptProtectedSetting: [ - { - commandToExecute: 'mycommandToRun -someParam MYSECRET' - } -] -``` - -
-

diff --git a/modules/compute/virtual-machine/main.json b/modules/compute/virtual-machine/main.json deleted file mode 100644 index cb696cbdcc..0000000000 --- a/modules/compute/virtual-machine/main.json +++ /dev/null @@ -1,4524 +0,0 @@ -{ - "$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": "89939038941992549" - }, - "name": "Virtual Machines", - "description": "This module deploys a Virtual Machine with one or multiple NICs and optionally one or multiple public IPs.", - "owner": "Azure/module-maintainers" - }, - "definitions": { - "managedIdentitiesType": { - "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" - }, - "nullable": true, - "metadata": { - "description": "Optional. The resource ID(s) to assign to the resource." - } - } - }, - "nullable": true - }, - "lockType": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Specify the name of lock." - } - }, - "kind": { - "type": "string", - "allowedValues": [ - "CanNotDelete", - "None", - "ReadOnly" - ], - "nullable": true, - "metadata": { - "description": "Optional. Specify the type of lock." - } - } - }, - "nullable": true - }, - "roleAssignmentType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "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 - }, - "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." - } - } - } - }, - "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." - } - } - } - }, - "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." - } - }, - "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." - } - }, - "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." - } - } - } - }, - "nullable": true - } - }, - "parameters": { - "name": { - "type": "string", - "defaultValue": "[take(toLower(uniqueString(resourceGroup().name)), 10)]", - "metadata": { - "description": "Optional. The name of the virtual machine to be created. You should use a unique prefix to reduce name collisions in Active Directory. If no value is provided, a 10 character long unique string will be generated based on the Resource Group's name." - } - }, - "computerName": { - "type": "string", - "defaultValue": "[parameters('name')]", - "metadata": { - "description": "Optional. Can be used if the computer name needs to be different from the Azure VM resource name. If not used, the resource name will be used as computer name." - } - }, - "vmSize": { - "type": "string", - "metadata": { - "description": "Required. Specifies the size for the VMs." - } - }, - "encryptionAtHost": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. This property can be used by user in the request to enable or disable the Host Encryption for the virtual machine. This will enable the encryption for all the disks including Resource/Temp disk at host itself. For security reasons, it is recommended to set encryptionAtHost to True. Restrictions: Cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs." - } - }, - "securityType": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Specifies the SecurityType of the virtual machine. It is set as TrustedLaunch to enable UefiSettings." - } - }, - "secureBootEnabled": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Specifies whether secure boot should be enabled on the virtual machine. This parameter is part of the UefiSettings. SecurityType should be set to TrustedLaunch to enable UefiSettings." - } - }, - "vTpmEnabled": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Specifies whether vTPM should be enabled on the virtual machine. This parameter is part of the UefiSettings. SecurityType should be set to TrustedLaunch to enable UefiSettings." - } - }, - "imageReference": { - "type": "object", - "metadata": { - "description": "Required. OS image reference. In case of marketplace images, it's the combination of the publisher, offer, sku, version attributes. In case of custom images it's the resource ID of the custom image." - } - }, - "plan": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Optional. Specifies information about the marketplace image used to create the virtual machine. This element is only used for marketplace images. Before you can use a marketplace image from an API, you must enable the image for programmatic use." - } - }, - "osDisk": { - "type": "object", - "metadata": { - "description": "Required. Specifies the OS disk. For security reasons, it is recommended to specify DiskEncryptionSet into the osDisk object. Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs." - } - }, - "dataDisks": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. Specifies the data disks. For security reasons, it is recommended to specify DiskEncryptionSet into the dataDisk object. Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs." - } - }, - "ultraSSDEnabled": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. The flag that enables or disables a capability to have one or more managed data disks with UltraSSD_LRS storage account type on the VM or VMSS. Managed disks with storage account type UltraSSD_LRS can be added to a virtual machine or virtual machine scale set only if this property is enabled." - } - }, - "adminUsername": { - "type": "securestring", - "metadata": { - "description": "Required. Administrator username." - } - }, - "adminPassword": { - "type": "securestring", - "defaultValue": "", - "metadata": { - "description": "Optional. When specifying a Windows Virtual Machine, this value should be passed." - } - }, - "customData": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Custom data associated to the VM, this value will be automatically converted into base64 to account for the expected VM format." - } - }, - "certificatesToBeInstalled": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. Specifies set of certificates that should be installed onto the virtual machine." - } - }, - "priority": { - "type": "string", - "defaultValue": "Regular", - "allowedValues": [ - "Regular", - "Low", - "Spot" - ], - "metadata": { - "description": "Optional. Specifies the priority for the virtual machine." - } - }, - "enableEvictionPolicy": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Specifies the eviction policy for the low priority virtual machine. Will result in 'Deallocate' eviction policy." - } - }, - "maxPriceForLowPriorityVm": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Specifies the maximum price you are willing to pay for a low priority VM/VMSS. This price is in US Dollars." - } - }, - "dedicatedHostId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Specifies resource ID about the dedicated host that the virtual machine resides in." - } - }, - "licenseType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "Windows_Client", - "Windows_Server", - "" - ], - "metadata": { - "description": "Optional. Specifies that the image or disk that is being used was licensed on-premises. This element is only used for images that contain the Windows Server operating system." - } - }, - "publicKeys": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. The list of SSH public keys used to authenticate with linux based VMs." - } - }, - "managedIdentities": { - "$ref": "#/definitions/managedIdentitiesType", - "metadata": { - "description": "Optional. The managed identity definition for this resource. The system-assigned managed identity will automatically be enabled if extensionAadJoinConfig.enabled = \"True\"." - } - }, - "bootDiagnostics": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Whether boot diagnostics should be enabled on the Virtual Machine. Boot diagnostics will be enabled with a managed storage account if no bootDiagnosticsStorageAccountName value is provided. If bootDiagnostics and bootDiagnosticsStorageAccountName values are not provided, boot diagnostics will be disabled." - } - }, - "bootDiagnosticStorageAccountName": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Custom storage account used to store boot diagnostic information. Boot diagnostics will be enabled with a custom storage account if a value is provided." - } - }, - "bootDiagnosticStorageAccountUri": { - "type": "string", - "defaultValue": "[format('.blob.{0}/', environment().suffixes.storage)]", - "metadata": { - "description": "Optional. Storage account boot diagnostic base URI." - } - }, - "proximityPlacementGroupResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Resource ID of a proximity placement group." - } - }, - "availabilitySetResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Resource ID of an availability set. Cannot be used in combination with availability zone nor scale set." - } - }, - "availabilityZone": { - "type": "int", - "defaultValue": 0, - "allowedValues": [ - 0, - 1, - 2, - 3 - ], - "metadata": { - "description": "Optional. If set to 1, 2 or 3, the availability zone for all VMs is hardcoded to that value. If zero, then availability zones is not used. Cannot be used in combination with availability set nor scale set." - } - }, - "nicConfigurations": { - "type": "array", - "metadata": { - "description": "Required. Configures NICs and PIPs." - } - }, - "backupVaultName": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Recovery service vault name to add VMs to backup." - } - }, - "backupVaultResourceGroup": { - "type": "string", - "defaultValue": "[resourceGroup().name]", - "metadata": { - "description": "Optional. Resource group of the backup recovery service vault. If not provided the current resource group name is considered by default." - } - }, - "backupPolicyName": { - "type": "string", - "defaultValue": "DefaultPolicy", - "metadata": { - "description": "Optional. Backup policy the VMs should be using for backup. If not provided, it will use the DefaultPolicy from the backup recovery service vault." - } - }, - "allowExtensionOperations": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Specifies whether extension operations should be allowed on the virtual machine. This may only be set to False when no extensions are present on the virtual machine." - } - }, - "extensionDomainJoinPassword": { - "type": "securestring", - "defaultValue": "", - "metadata": { - "description": "Optional. Required if name is specified. Password of the user specified in user parameter." - } - }, - "extensionDomainJoinConfig": { - "type": "object", - "defaultValue": { - "enabled": false - }, - "metadata": { - "description": "Optional. The configuration for the [Domain Join] extension. Must at least contain the [\"enabled\": true] property to be executed." - } - }, - "extensionAadJoinConfig": { - "type": "object", - "defaultValue": { - "enabled": false - }, - "metadata": { - "description": "Optional. The configuration for the [AAD Join] extension. Must at least contain the [\"enabled\": true] property to be executed." - } - }, - "extensionAntiMalwareConfig": { - "type": "object", - "defaultValue": { - "enabled": false - }, - "metadata": { - "description": "Optional. The configuration for the [Anti Malware] extension. Must at least contain the [\"enabled\": true] property to be executed." - } - }, - "extensionMonitoringAgentConfig": { - "type": "object", - "defaultValue": { - "enabled": false - }, - "metadata": { - "description": "Optional. The configuration for the [Monitoring Agent] extension. Must at least contain the [\"enabled\": true] property to be executed." - } - }, - "monitoringWorkspaceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Resource ID of the monitoring log analytics workspace. Must be set when extensionMonitoringAgentConfig is set to true." - } - }, - "extensionDependencyAgentConfig": { - "type": "object", - "defaultValue": { - "enabled": false - }, - "metadata": { - "description": "Optional. The configuration for the [Dependency Agent] extension. Must at least contain the [\"enabled\": true] property to be executed." - } - }, - "extensionNetworkWatcherAgentConfig": { - "type": "object", - "defaultValue": { - "enabled": false - }, - "metadata": { - "description": "Optional. The configuration for the [Network Watcher Agent] extension. Must at least contain the [\"enabled\": true] property to be executed." - } - }, - "extensionAzureDiskEncryptionConfig": { - "type": "object", - "defaultValue": { - "enabled": false - }, - "metadata": { - "description": "Optional. The configuration for the [Azure Disk Encryption] extension. Must at least contain the [\"enabled\": true] property to be executed. Restrictions: Cannot be enabled on disks that have encryption at host enabled. Managed disks encrypted using Azure Disk Encryption cannot be encrypted using customer-managed keys." - } - }, - "extensionDSCConfig": { - "type": "object", - "defaultValue": { - "enabled": false - }, - "metadata": { - "description": "Optional. The configuration for the [Desired State Configuration] extension. Must at least contain the [\"enabled\": true] property to be executed." - } - }, - "extensionCustomScriptConfig": { - "type": "object", - "defaultValue": { - "enabled": false, - "fileData": [] - }, - "metadata": { - "description": "Optional. The configuration for the [Custom Script] extension. Must at least contain the [\"enabled\": true] property to be executed." - } - }, - "extensionCustomScriptProtectedSetting": { - "type": "secureObject", - "defaultValue": {}, - "metadata": { - "description": "Optional. Any object that contains the extension specific protected settings." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. Location for all resources." - } - }, - "lock": { - "$ref": "#/definitions/lockType", - "metadata": { - "description": "Optional. The lock settings of the service." - } - }, - "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", - "metadata": { - "description": "Optional. Array of role assignments to create." - } - }, - "tags": { - "type": "object", - "nullable": true, - "metadata": { - "description": "Optional. Tags of the resource." - } - }, - "enableDefaultTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." - } - }, - "baseTime": { - "type": "string", - "defaultValue": "[utcNow('u')]", - "metadata": { - "description": "Generated. Do not provide a value! This date value is used to generate a registration token." - } - }, - "sasTokenValidityLength": { - "type": "string", - "defaultValue": "PT8H", - "metadata": { - "description": "Optional. SAS token validity length to use to download files from storage accounts. Usage: 'PT8H' - valid for 8 hours; 'P5D' - valid for 5 days; 'P1Y' - valid for 1 year. When not provided, the SAS token will be valid for 8 hours." - } - }, - "osType": { - "type": "string", - "allowedValues": [ - "Windows", - "Linux" - ], - "metadata": { - "description": "Required. The chosen OS type." - } - }, - "disablePasswordAuthentication": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Specifies whether password authentication should be disabled." - } - }, - "provisionVMAgent": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Indicates whether virtual machine agent should be provisioned on the virtual machine. When this property is not specified in the request body, default behavior is to set it to true. This will ensure that VM Agent is installed on the VM so that extensions can be added to the VM later." - } - }, - "enableAutomaticUpdates": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Indicates whether Automatic Updates is enabled for the Windows virtual machine. Default value is true. When patchMode is set to Manual, this parameter must be set to false. For virtual machine scale sets, this property can be updated and updates will take effect on OS reprovisioning." - } - }, - "patchMode": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "AutomaticByPlatform", - "AutomaticByOS", - "Manual", - "ImageDefault", - "" - ], - "metadata": { - "description": "Optional. VM guest patching orchestration mode. 'AutomaticByOS' & 'Manual' are for Windows only, 'ImageDefault' for Linux only. Refer to 'https://learn.microsoft.com/en-us/azure/virtual-machines/automatic-vm-guest-patching'." - } - }, - "patchAssessmentMode": { - "type": "string", - "defaultValue": "ImageDefault", - "allowedValues": [ - "AutomaticByPlatform", - "ImageDefault" - ], - "metadata": { - "description": "Optional. VM guest patching assessment mode. Set it to 'AutomaticByPlatform' to enable automatically check for updates every 24 hours." - } - }, - "timeZone": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Specifies the time zone of the virtual machine. e.g. 'Pacific Standard Time'. Possible values can be `TimeZoneInfo.id` value from time zones returned by `TimeZoneInfo.GetSystemTimeZones`." - } - }, - "additionalUnattendContent": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. Specifies additional base-64 encoded XML formatted information that can be included in the Unattend.xml file, which is used by Windows Setup. - AdditionalUnattendContent object." - } - }, - "winRM": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Optional. Specifies the Windows Remote Management listeners. This enables remote Windows PowerShell. - WinRMConfiguration object." - } - }, - "configurationProfile": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesProduction", - "/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesDevTest", - "" - ], - "metadata": { - "description": "Required. The configuration profile of automanage." - } - } - }, - "variables": { - "copy": [ - { - "name": "publicKeysFormatted", - "count": "[length(parameters('publicKeys'))]", - "input": { - "path": "[parameters('publicKeys')[copyIndex('publicKeysFormatted')].path]", - "keyData": "[parameters('publicKeys')[copyIndex('publicKeysFormatted')].keyData]" - } - } - ], - "linuxConfiguration": { - "disablePasswordAuthentication": "[parameters('disablePasswordAuthentication')]", - "ssh": { - "publicKeys": "[variables('publicKeysFormatted')]" - }, - "provisionVMAgent": "[parameters('provisionVMAgent')]", - "patchSettings": "[if(and(parameters('provisionVMAgent'), or(equals(toLower(parameters('patchMode')), toLower('AutomaticByPlatform')), equals(toLower(parameters('patchMode')), toLower('ImageDefault')))), createObject('patchMode', parameters('patchMode'), 'assessmentMode', parameters('patchAssessmentMode')), null())]" - }, - "windowsConfiguration": { - "provisionVMAgent": "[parameters('provisionVMAgent')]", - "enableAutomaticUpdates": "[parameters('enableAutomaticUpdates')]", - "patchSettings": "[if(and(parameters('provisionVMAgent'), or(or(equals(toLower(parameters('patchMode')), toLower('AutomaticByPlatform')), equals(toLower(parameters('patchMode')), toLower('AutomaticByOS'))), equals(toLower(parameters('patchMode')), toLower('Manual')))), createObject('patchMode', parameters('patchMode'), 'assessmentMode', parameters('patchAssessmentMode')), null())]", - "timeZone": "[if(empty(parameters('timeZone')), null(), parameters('timeZone'))]", - "additionalUnattendContent": "[if(empty(parameters('additionalUnattendContent')), null(), parameters('additionalUnattendContent'))]", - "winRM": "[if(not(empty(parameters('winRM'))), createObject('listeners', parameters('winRM')), null())]" - }, - "accountSasProperties": { - "signedServices": "b", - "signedPermission": "r", - "signedExpiry": "[dateTimeAdd(parameters('baseTime'), parameters('sasTokenValidityLength'))]", - "signedResourceTypes": "o", - "signedProtocol": "https" - }, - "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]", - "identity": "[if(not(empty(parameters('managedIdentities'))), createObject('type', if(if(parameters('extensionAadJoinConfig').enabled, true(), coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false())), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'SystemAssigned,UserAssigned', 'SystemAssigned'), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'UserAssigned', null())), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]", - "enableReferencedModulesTelemetry": false, - "builtInRoleNames": { - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Data Operator for Managed Disks": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '959f8984-c045-4866-89c7-12bf9737be2e')]", - "Desktop Virtualization Power On Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '489581de-a3bd-480d-9518-53dea7416b33')]", - "Desktop Virtualization Power On Off Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '40c5ff49-9181-41f8-ae61-143b0e78555e')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "Disk Backup Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3e5e47e6-65f7-47ef-90b5-e5dd4d455f24')]", - "Disk Pool Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '60fc6e62-5479-42d4-8bf4-67625fcc2840')]", - "Disk Restore Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b50d9833-a0cb-478e-945f-707fcc997c13')]", - "Disk Snapshot Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7efff54f-a5b4-42b5-a1c5-5411624893ce')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "VM Scanner Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'd24ecba3-c1f4-40fa-a7bb-4588a071e8fd')]" - } - }, - "resources": { - "defaultTelemetry": { - "condition": "[parameters('enableDefaultTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2021-04-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [] - } - } - }, - "vm": { - "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "2022-11-01", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "identity": "[variables('identity')]", - "tags": "[parameters('tags')]", - "zones": "[if(not(equals(parameters('availabilityZone'), 0)), array(parameters('availabilityZone')), null())]", - "plan": "[if(not(empty(parameters('plan'))), parameters('plan'), null())]", - "properties": { - "hardwareProfile": { - "vmSize": "[parameters('vmSize')]" - }, - "securityProfile": { - "encryptionAtHost": "[if(parameters('encryptionAtHost'), parameters('encryptionAtHost'), null())]", - "securityType": "[parameters('securityType')]", - "uefiSettings": "[if(equals(parameters('securityType'), 'TrustedLaunch'), createObject('secureBootEnabled', parameters('secureBootEnabled'), 'vTpmEnabled', parameters('vTpmEnabled')), null())]" - }, - "storageProfile": { - "copy": [ - { - "name": "dataDisks", - "count": "[length(parameters('dataDisks'))]", - "input": { - "lun": "[copyIndex('dataDisks')]", - "name": "[format('{0}-disk-data-{1}', parameters('name'), padLeft(add(copyIndex('dataDisks'), 1), 2, '0'))]", - "diskSizeGB": "[parameters('dataDisks')[copyIndex('dataDisks')].diskSizeGB]", - "createOption": "[if(contains(parameters('dataDisks')[copyIndex('dataDisks')], 'createOption'), parameters('dataDisks')[copyIndex('dataDisks')].createOption, 'Empty')]", - "deleteOption": "[if(contains(parameters('dataDisks')[copyIndex('dataDisks')], 'deleteOption'), parameters('dataDisks')[copyIndex('dataDisks')].deleteOption, 'Delete')]", - "caching": "[if(contains(parameters('dataDisks')[copyIndex('dataDisks')], 'caching'), parameters('dataDisks')[copyIndex('dataDisks')].caching, 'ReadOnly')]", - "managedDisk": { - "storageAccountType": "[parameters('dataDisks')[copyIndex('dataDisks')].managedDisk.storageAccountType]", - "diskEncryptionSet": "[if(contains(parameters('dataDisks')[copyIndex('dataDisks')].managedDisk, 'diskEncryptionSet'), createObject('id', parameters('dataDisks')[copyIndex('dataDisks')].managedDisk.diskEncryptionSet.id), null())]" - } - } - } - ], - "imageReference": "[parameters('imageReference')]", - "osDisk": { - "name": "[format('{0}-disk-os-01', parameters('name'))]", - "createOption": "[if(contains(parameters('osDisk'), 'createOption'), parameters('osDisk').createOption, 'FromImage')]", - "deleteOption": "[if(contains(parameters('osDisk'), 'deleteOption'), parameters('osDisk').deleteOption, 'Delete')]", - "diskSizeGB": "[parameters('osDisk').diskSizeGB]", - "caching": "[if(contains(parameters('osDisk'), 'caching'), parameters('osDisk').caching, 'ReadOnly')]", - "managedDisk": { - "storageAccountType": "[parameters('osDisk').managedDisk.storageAccountType]", - "diskEncryptionSet": "[if(contains(parameters('osDisk').managedDisk, 'diskEncryptionSet'), createObject('id', parameters('osDisk').managedDisk.diskEncryptionSet.id), null())]" - } - } - }, - "additionalCapabilities": { - "ultraSSDEnabled": "[parameters('ultraSSDEnabled')]" - }, - "osProfile": { - "computerName": "[parameters('computerName')]", - "adminUsername": "[parameters('adminUsername')]", - "adminPassword": "[parameters('adminPassword')]", - "customData": "[if(not(empty(parameters('customData'))), base64(parameters('customData')), null())]", - "windowsConfiguration": "[if(equals(parameters('osType'), 'Windows'), variables('windowsConfiguration'), null())]", - "linuxConfiguration": "[if(equals(parameters('osType'), 'Linux'), variables('linuxConfiguration'), null())]", - "secrets": "[parameters('certificatesToBeInstalled')]", - "allowExtensionOperations": "[parameters('allowExtensionOperations')]" - }, - "networkProfile": { - "copy": [ - { - "name": "networkInterfaces", - "count": "[length(parameters('nicConfigurations'))]", - "input": { - "properties": { - "deleteOption": "[if(contains(parameters('nicConfigurations')[copyIndex('networkInterfaces')], 'deleteOption'), parameters('nicConfigurations')[copyIndex('networkInterfaces')].deleteOption, 'Delete')]", - "primary": "[if(equals(copyIndex('networkInterfaces'), 0), true(), false())]" - }, - "id": "[resourceId('Microsoft.Network/networkInterfaces', format('{0}{1}', parameters('name'), parameters('nicConfigurations')[copyIndex('networkInterfaces')].nicSuffix))]" - } - } - ] - }, - "diagnosticsProfile": { - "bootDiagnostics": { - "enabled": "[if(not(empty(parameters('bootDiagnosticStorageAccountName'))), true(), parameters('bootDiagnostics'))]", - "storageUri": "[if(not(empty(parameters('bootDiagnosticStorageAccountName'))), format('https://{0}{1}', parameters('bootDiagnosticStorageAccountName'), parameters('bootDiagnosticStorageAccountUri')), null())]" - } - }, - "availabilitySet": "[if(not(empty(parameters('availabilitySetResourceId'))), createObject('id', parameters('availabilitySetResourceId')), null())]", - "proximityPlacementGroup": "[if(not(empty(parameters('proximityPlacementGroupResourceId'))), createObject('id', parameters('proximityPlacementGroupResourceId')), null())]", - "priority": "[parameters('priority')]", - "evictionPolicy": "[if(parameters('enableEvictionPolicy'), 'Deallocate', null())]", - "billingProfile": "[if(and(not(empty(parameters('priority'))), not(empty(parameters('maxPriceForLowPriorityVm')))), createObject('maxPrice', parameters('maxPriceForLowPriorityVm')), null())]", - "host": "[if(not(empty(parameters('dedicatedHostId'))), createObject('id', parameters('dedicatedHostId')), null())]", - "licenseType": "[if(not(empty(parameters('licenseType'))), parameters('licenseType'), null())]" - }, - "dependsOn": [ - "vm_nic" - ] - }, - "vm_configurationProfileAssignment": { - "condition": "[not(empty(parameters('configurationProfile')))]", - "type": "Microsoft.Automanage/configurationProfileAssignments", - "apiVersion": "2021-04-30-preview", - "scope": "[format('Microsoft.Compute/virtualMachines/{0}', parameters('name'))]", - "name": "default", - "properties": { - "configurationProfile": "[parameters('configurationProfile')]" - }, - "dependsOn": [ - "vm" - ] - }, - "vm_logAnalyticsWorkspace": { - "condition": "[not(empty(parameters('monitoringWorkspaceId')))]", - "existing": true, - "type": "Microsoft.OperationalInsights/workspaces", - "apiVersion": "2021-06-01", - "subscriptionId": "[split(if(not(empty(parameters('monitoringWorkspaceId'))), parameters('monitoringWorkspaceId'), '//'), '/')[2]]", - "resourceGroup": "[split(if(not(empty(parameters('monitoringWorkspaceId'))), parameters('monitoringWorkspaceId'), '////'), '/')[4]]", - "name": "[last(split(if(not(empty(parameters('monitoringWorkspaceId'))), parameters('monitoringWorkspaceId'), 'law'), '/'))]" - }, - "vm_lock": { - "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", - "type": "Microsoft.Authorization/locks", - "apiVersion": "2020-05-01", - "scope": "[format('Microsoft.Compute/virtualMachines/{0}', parameters('name'))]", - "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", - "properties": { - "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", - "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" - }, - "dependsOn": [ - "vm" - ] - }, - "vm_roleAssignments": { - "copy": { - "name": "vm_roleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Compute/virtualMachines/{0}', parameters('name'))]", - "name": "[guid(resourceId('Microsoft.Compute/virtualMachines', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", - "properties": { - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", - "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", - "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", - "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", - "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", - "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", - "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" - }, - "dependsOn": [ - "vm" - ] - }, - "vm_nic": { - "copy": { - "name": "vm_nic", - "count": "[length(parameters('nicConfigurations'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-VM-Nic-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "networkInterfaceName": { - "value": "[format('{0}{1}', parameters('name'), parameters('nicConfigurations')[copyIndex()].nicSuffix)]" - }, - "virtualMachineName": { - "value": "[parameters('name')]" - }, - "location": { - "value": "[parameters('location')]" - }, - "enableIPForwarding": "[if(contains(parameters('nicConfigurations')[copyIndex()], 'enableIPForwarding'), if(not(empty(parameters('nicConfigurations')[copyIndex()].enableIPForwarding)), createObject('value', parameters('nicConfigurations')[copyIndex()].enableIPForwarding), createObject('value', false())), createObject('value', false()))]", - "enableAcceleratedNetworking": "[if(contains(parameters('nicConfigurations')[copyIndex()], 'enableAcceleratedNetworking'), createObject('value', parameters('nicConfigurations')[copyIndex()].enableAcceleratedNetworking), createObject('value', true()))]", - "dnsServers": "[if(contains(parameters('nicConfigurations')[copyIndex()], 'dnsServers'), if(not(empty(parameters('nicConfigurations')[copyIndex()].dnsServers)), createObject('value', parameters('nicConfigurations')[copyIndex()].dnsServers), createObject('value', createArray())), createObject('value', createArray()))]", - "networkSecurityGroupResourceId": "[if(contains(parameters('nicConfigurations')[copyIndex()], 'networkSecurityGroupResourceId'), createObject('value', parameters('nicConfigurations')[copyIndex()].networkSecurityGroupResourceId), createObject('value', ''))]", - "ipConfigurations": { - "value": "[parameters('nicConfigurations')[copyIndex()].ipConfigurations]" - }, - "lock": { - "value": "[coalesce(tryGet(parameters('nicConfigurations')[copyIndex()], 'lock'), parameters('lock'))]" - }, - "tags": { - "value": "[coalesce(tryGet(parameters('nicConfigurations')[copyIndex()], 'tags'), parameters('tags'))]" - }, - "diagnosticSettings": { - "value": "[tryGet(parameters('nicConfigurations')[copyIndex()], 'diagnosticSettings')]" - }, - "roleAssignments": { - "value": "[tryGet(parameters('nicConfigurations')[copyIndex()], 'roleAssignments')]" - } - }, - "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": "11123708724712871468" - } - }, - "definitions": { - "lockType": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Specify the name of lock." - } - }, - "kind": { - "type": "string", - "allowedValues": [ - "CanNotDelete", - "None", - "ReadOnly" - ], - "nullable": true, - "metadata": { - "description": "Optional. Specify the type of lock." - } - } - }, - "nullable": true - }, - "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 \u0007llLogs to collect all logs." - } - } - } - }, - "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." - } - } - } - }, - "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." - } - }, - "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." - } - }, - "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." - } - } - } - }, - "nullable": true - }, - "roleAssignmentType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "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 - } - }, - "parameters": { - "networkInterfaceName": { - "type": "string" - }, - "virtualMachineName": { - "type": "string" - }, - "location": { - "type": "string" - }, - "tags": { - "type": "object", - "nullable": true - }, - "enableIPForwarding": { - "type": "bool", - "defaultValue": false - }, - "enableAcceleratedNetworking": { - "type": "bool", - "defaultValue": false - }, - "dnsServers": { - "type": "array", - "defaultValue": [] - }, - "networkSecurityGroupResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The network security group (NSG) to attach to the network interface." - } - }, - "ipConfigurations": { - "type": "array" - }, - "lock": { - "$ref": "#/definitions/lockType" - }, - "diagnosticSettings": { - "$ref": "#/definitions/diagnosticSettingType", - "metadata": { - "description": "Optional. The diagnostic settings of the Network Interface." - } - }, - "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", - "metadata": { - "description": "Optional. Array of role assignments to create." - } - } - }, - "variables": { - "enableReferencedModulesTelemetry": false - }, - "resources": { - "networkInterface_publicIPAddresses": { - "copy": { - "name": "networkInterface_publicIPAddresses", - "count": "[length(parameters('ipConfigurations'))]" - }, - "condition": "[contains(parameters('ipConfigurations')[copyIndex()], 'pipconfiguration')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-publicIP-{1}', deployment().name, copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "name": { - "value": "[format('{0}{1}', parameters('virtualMachineName'), parameters('ipConfigurations')[copyIndex()].pipconfiguration.publicIpNameSuffix)]" - }, - "diagnosticSettings": { - "value": "[tryGet(parameters('ipConfigurations')[copyIndex()], 'diagnosticSettings')]" - }, - "location": { - "value": "[parameters('location')]" - }, - "lock": { - "value": "[parameters('lock')]" - }, - "publicIPAddressVersion": "[if(contains(parameters('ipConfigurations')[copyIndex()], 'publicIPAddressVersion'), createObject('value', parameters('ipConfigurations')[copyIndex()].publicIPAddressVersion), createObject('value', 'IPv4'))]", - "publicIPAllocationMethod": "[if(contains(parameters('ipConfigurations')[copyIndex()], 'publicIPAllocationMethod'), createObject('value', parameters('ipConfigurations')[copyIndex()].publicIPAllocationMethod), createObject('value', 'Static'))]", - "publicIPPrefixResourceId": "[if(contains(parameters('ipConfigurations')[copyIndex()], 'publicIPPrefixResourceId'), createObject('value', parameters('ipConfigurations')[copyIndex()].publicIPPrefixResourceId), createObject('value', ''))]", - "roleAssignments": "[if(contains(parameters('ipConfigurations')[copyIndex()], 'roleAssignments'), createObject('value', parameters('ipConfigurations')[copyIndex()].roleAssignments), createObject('value', createArray()))]", - "skuName": "[if(contains(parameters('ipConfigurations')[copyIndex()], 'skuName'), createObject('value', parameters('ipConfigurations')[copyIndex()].skuName), createObject('value', 'Standard'))]", - "skuTier": "[if(contains(parameters('ipConfigurations')[copyIndex()], 'skuTier'), createObject('value', parameters('ipConfigurations')[copyIndex()].skuTier), createObject('value', 'Regional'))]", - "tags": { - "value": "[coalesce(tryGet(parameters('ipConfigurations')[copyIndex()], 'tags'), parameters('tags'))]" - }, - "zones": "[if(contains(parameters('ipConfigurations')[copyIndex()], 'zones'), createObject('value', parameters('ipConfigurations')[copyIndex()].zones), createObject('value', createArray()))]" - }, - "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": "15536304828480480757" - }, - "name": "Public IP Addresses", - "description": "This module deploys a Public IP Address.", - "owner": "Azure/module-maintainers" - }, - "definitions": { - "lockType": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Specify the name of lock." - } - }, - "kind": { - "type": "string", - "allowedValues": [ - "CanNotDelete", - "None", - "ReadOnly" - ], - "nullable": true, - "metadata": { - "description": "Optional. Specify the type of lock." - } - } - }, - "nullable": true - }, - "roleAssignmentType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "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 - }, - "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." - } - } - } - }, - "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." - } - } - } - }, - "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." - } - }, - "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." - } - }, - "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." - } - } - } - }, - "nullable": true - } - }, - "parameters": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the Public IP Address." - } - }, - "publicIPPrefixResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Resource ID of the Public IP Prefix object. This is only needed if you want your Public IPs created in a PIP Prefix." - } - }, - "publicIPAllocationMethod": { - "type": "string", - "defaultValue": "Static", - "allowedValues": [ - "Dynamic", - "Static" - ], - "metadata": { - "description": "Optional. The public IP address allocation method." - } - }, - "skuName": { - "type": "string", - "defaultValue": "Standard", - "allowedValues": [ - "Basic", - "Standard" - ], - "metadata": { - "description": "Optional. Name of a public IP address SKU." - } - }, - "skuTier": { - "type": "string", - "defaultValue": "Regional", - "allowedValues": [ - "Global", - "Regional" - ], - "metadata": { - "description": "Optional. Tier of a public IP address SKU." - } - }, - "zones": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. A list of availability zones denoting the IP allocated for the resource needs to come from." - } - }, - "publicIPAddressVersion": { - "type": "string", - "defaultValue": "IPv4", - "allowedValues": [ - "IPv4", - "IPv6" - ], - "metadata": { - "description": "Optional. IP address version." - } - }, - "diagnosticSettings": { - "$ref": "#/definitions/diagnosticSettingType", - "metadata": { - "description": "Optional. The diagnostic settings of the service." - } - }, - "domainNameLabel": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The domain name label. The concatenation of the domain name label and the regionalized DNS zone make up the fully qualified domain name associated with the public IP address. If a domain name label is specified, an A DNS record is created for the public IP in the Microsoft Azure DNS system." - } - }, - "domainNameLabelScope": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "NoReuse", - "ResourceGroupReuse", - "SubscriptionReuse", - "TenantReuse" - ], - "metadata": { - "description": "Optional. The domain name label scope. If a domain name label and a domain name label scope are specified, an A DNS record is created for the public IP in the Microsoft Azure DNS system with a hashed value includes in FQDN." - } - }, - "fqdn": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The Fully Qualified Domain Name of the A DNS record associated with the public IP. This is the concatenation of the domainNameLabel and the regionalized DNS zone." - } - }, - "reverseFqdn": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The reverse FQDN. A user-visible, fully qualified domain name that resolves to this public IP address. If the reverseFqdn is specified, then a PTR DNS record is created pointing from the IP address in the in-addr.arpa domain to the reverse FQDN." - } - }, - "lock": { - "$ref": "#/definitions/lockType", - "metadata": { - "description": "Optional. The lock settings of the service." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. Location for all resources." - } - }, - "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", - "metadata": { - "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." - } - }, - "enableDefaultTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." - } - }, - "tags": { - "type": "object", - "nullable": true, - "metadata": { - "description": "Optional. Tags of the resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" - } - }, - "resources": { - "defaultTelemetry": { - "condition": "[parameters('enableDefaultTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2021-04-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [] - } - } - }, - "publicIpAddress": { - "type": "Microsoft.Network/publicIPAddresses", - "apiVersion": "2023-04-01", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "sku": { - "name": "[parameters('skuName')]", - "tier": "[parameters('skuTier')]" - }, - "zones": "[parameters('zones')]", - "properties": { - "dnsSettings": "[if(not(empty(parameters('domainNameLabel'))), createObject('domainNameLabel', parameters('domainNameLabel'), 'domainNameLabelScope', parameters('domainNameLabelScope'), 'fqdn', parameters('fqdn'), 'reverseFqdn', parameters('reverseFqdn')), null())]", - "publicIPAddressVersion": "[parameters('publicIPAddressVersion')]", - "publicIPAllocationMethod": "[parameters('publicIPAllocationMethod')]", - "publicIPPrefix": "[if(not(empty(parameters('publicIPPrefixResourceId'))), createObject('id', parameters('publicIPPrefixResourceId')), null())]", - "idleTimeoutInMinutes": 4, - "ipTags": [] - } - }, - "publicIpAddress_lock": { - "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", - "type": "Microsoft.Authorization/locks", - "apiVersion": "2020-05-01", - "scope": "[format('Microsoft.Network/publicIPAddresses/{0}', parameters('name'))]", - "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", - "properties": { - "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", - "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" - }, - "dependsOn": [ - "publicIpAddress" - ] - }, - "publicIpAddress_diagnosticSettings": { - "copy": { - "name": "publicIpAddress_diagnosticSettings", - "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" - }, - "type": "Microsoft.Insights/diagnosticSettings", - "apiVersion": "2021-05-01-preview", - "scope": "[format('Microsoft.Network/publicIPAddresses/{0}', parameters('name'))]", - "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", - "properties": { - "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", - "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", - "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", - "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'AllLogs', 'enabled', true())))]", - "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", - "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" - }, - "dependsOn": [ - "publicIpAddress" - ] - }, - "publicIpAddress_roleAssignments": { - "copy": { - "name": "publicIpAddress_roleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "name": "[guid(resourceId('Microsoft.Network/publicIPAddresses', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", - "properties": { - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", - "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", - "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", - "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", - "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", - "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", - "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" - }, - "dependsOn": [ - "publicIpAddress" - ] - } - }, - "outputs": { - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The resource group the public IP address was deployed into." - }, - "value": "[resourceGroup().name]" - }, - "name": { - "type": "string", - "metadata": { - "description": "The name of the public IP address." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the public IP address." - }, - "value": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('name'))]" - }, - "ipAddress": { - "type": "string", - "metadata": { - "description": "The public IP address of the public IP address resource." - }, - "value": "[if(contains(reference('publicIpAddress'), 'ipAddress'), reference('publicIpAddress').ipAddress, '')]" - }, - "location": { - "type": "string", - "metadata": { - "description": "The location the resource was deployed into." - }, - "value": "[reference('publicIpAddress', '2023-04-01', 'full').location]" - } - } - } - } - }, - "networkInterface": { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-NetworkInterface', deployment().name)]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "name": { - "value": "[parameters('networkInterfaceName')]" - }, - "ipConfigurations": { - "copy": [ - { - "name": "value", - "count": "[length(parameters('ipConfigurations'))]", - "input": "[createObject('name', if(not(empty(parameters('ipConfigurations')[copyIndex('value')].name)), parameters('ipConfigurations')[copyIndex('value')].name, null()), 'primary', equals(copyIndex('value'), 0), 'privateIPAllocationMethod', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'privateIPAllocationMethod'), if(not(empty(parameters('ipConfigurations')[copyIndex('value')].privateIPAllocationMethod)), parameters('ipConfigurations')[copyIndex('value')].privateIPAllocationMethod, null()), null()), 'privateIPAddress', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'privateIPAddress'), if(not(empty(parameters('ipConfigurations')[copyIndex('value')].privateIPAddress)), parameters('ipConfigurations')[copyIndex('value')].privateIPAddress, null()), null()), 'publicIPAddressResourceId', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'pipconfiguration'), resourceId('Microsoft.Network/publicIPAddresses', format('{0}{1}', parameters('virtualMachineName'), parameters('ipConfigurations')[copyIndex('value')].pipconfiguration.publicIpNameSuffix)), null()), 'subnetResourceId', parameters('ipConfigurations')[copyIndex('value')].subnetResourceId, 'loadBalancerBackendAddressPools', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'loadBalancerBackendAddressPools'), parameters('ipConfigurations')[copyIndex('value')].loadBalancerBackendAddressPools, null()), 'applicationSecurityGroups', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'applicationSecurityGroups'), parameters('ipConfigurations')[copyIndex('value')].applicationSecurityGroups, null()), 'applicationGatewayBackendAddressPools', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'applicationGatewayBackendAddressPools'), parameters('ipConfigurations')[copyIndex('value')].applicationGatewayBackendAddressPools, null()), 'gatewayLoadBalancer', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'gatewayLoadBalancer'), parameters('ipConfigurations')[copyIndex('value')].gatewayLoadBalancer, null()), 'loadBalancerInboundNatRules', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'loadBalancerInboundNatRules'), parameters('ipConfigurations')[copyIndex('value')].loadBalancerInboundNatRules, null()), 'privateIPAddressVersion', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'privateIPAddressVersion'), parameters('ipConfigurations')[copyIndex('value')].privateIPAddressVersion, null()), 'virtualNetworkTaps', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'virtualNetworkTaps'), parameters('ipConfigurations')[copyIndex('value')].virtualNetworkTaps, null()))]" - } - ] - }, - "location": { - "value": "[parameters('location')]" - }, - "tags": { - "value": "[parameters('tags')]" - }, - "diagnosticSettings": { - "value": "[parameters('diagnosticSettings')]" - }, - "dnsServers": "[if(not(empty(parameters('dnsServers'))), createObject('value', parameters('dnsServers')), createObject('value', createArray()))]", - "enableAcceleratedNetworking": { - "value": "[parameters('enableAcceleratedNetworking')]" - }, - "enableDefaultTelemetry": { - "value": "[variables('enableReferencedModulesTelemetry')]" - }, - "enableIPForwarding": { - "value": "[parameters('enableIPForwarding')]" - }, - "lock": { - "value": "[parameters('lock')]" - }, - "networkSecurityGroupResourceId": "[if(not(empty(parameters('networkSecurityGroupResourceId'))), createObject('value', parameters('networkSecurityGroupResourceId')), createObject('value', ''))]", - "roleAssignments": "[if(not(empty(parameters('roleAssignments'))), createObject('value', parameters('roleAssignments')), createObject('value', createArray()))]" - }, - "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": "2750011165297287068" - }, - "name": "Network Interface", - "description": "This module deploys a Network Interface.", - "owner": "Azure/module-maintainers" - }, - "definitions": { - "lockType": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Specify the name of lock." - } - }, - "kind": { - "type": "string", - "allowedValues": [ - "CanNotDelete", - "None", - "ReadOnly" - ], - "nullable": true, - "metadata": { - "description": "Optional. Specify the type of lock." - } - } - }, - "nullable": true - }, - "roleAssignmentType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "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 - }, - "diagnosticSettingType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name of diagnostic setting." - } - }, - "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." - } - } - } - }, - "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." - } - }, - "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." - } - }, - "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." - } - } - } - }, - "nullable": true - } - }, - "parameters": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the network interface." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. Location for all resources." - } - }, - "tags": { - "type": "object", - "nullable": true, - "metadata": { - "description": "Optional. Tags of the resource." - } - }, - "enableDefaultTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." - } - }, - "enableIPForwarding": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Indicates whether IP forwarding is enabled on this network interface." - } - }, - "enableAcceleratedNetworking": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. If the network interface is accelerated networking enabled." - } - }, - "dnsServers": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. List of DNS servers IP addresses. Use 'AzureProvidedDNS' to switch to azure provided DNS resolution. 'AzureProvidedDNS' value cannot be combined with other IPs, it must be the only value in dnsServers collection." - } - }, - "networkSecurityGroupResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The network security group (NSG) to attach to the network interface." - } - }, - "auxiliaryMode": { - "type": "string", - "defaultValue": "None", - "allowedValues": [ - "Floating", - "MaxConnections", - "None" - ], - "metadata": { - "description": "Optional. Auxiliary mode of Network Interface resource. Not all regions are enabled for Auxiliary Mode Nic." - } - }, - "auxiliarySku": { - "type": "string", - "defaultValue": "None", - "allowedValues": [ - "A1", - "A2", - "A4", - "A8", - "None" - ], - "metadata": { - "description": "Optional. Auxiliary sku of Network Interface resource. Not all regions are enabled for Auxiliary Mode Nic." - } - }, - "disableTcpStateTracking": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Indicates whether to disable tcp state tracking. Subscription must be registered for the Microsoft.Network/AllowDisableTcpStateTracking feature before this property can be set to true." - } - }, - "ipConfigurations": { - "type": "array", - "metadata": { - "description": "Required. A list of IPConfigurations of the network interface." - } - }, - "lock": { - "$ref": "#/definitions/lockType", - "metadata": { - "description": "Optional. The lock settings of the service." - } - }, - "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", - "metadata": { - "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." - } - }, - "diagnosticSettings": { - "$ref": "#/definitions/diagnosticSettingType", - "metadata": { - "description": "Optional. The diagnostic settings of the service." - } - } - }, - "variables": { - "builtInRoleNames": { - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" - } - }, - "resources": { - "defaultTelemetry": { - "condition": "[parameters('enableDefaultTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2021-04-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [] - } - } - }, - "networkInterface": { - "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "2023-04-01", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "properties": { - "copy": [ - { - "name": "ipConfigurations", - "count": "[length(parameters('ipConfigurations'))]", - "input": { - "name": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'name'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].name, format('ipconfig0{0}', add(copyIndex('ipConfigurations'), 1)))]", - "properties": { - "primary": "[if(equals(copyIndex('ipConfigurations'), 0), true(), false())]", - "privateIPAllocationMethod": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'privateIPAllocationMethod'), if(not(empty(parameters('ipConfigurations')[copyIndex('ipConfigurations')].privateIPAllocationMethod)), parameters('ipConfigurations')[copyIndex('ipConfigurations')].privateIPAllocationMethod, null()), null())]", - "privateIPAddress": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'privateIPAddress'), if(not(empty(parameters('ipConfigurations')[copyIndex('ipConfigurations')].privateIPAddress)), parameters('ipConfigurations')[copyIndex('ipConfigurations')].privateIPAddress, null()), null())]", - "publicIPAddress": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'publicIPAddressResourceId'), if(not(equals(parameters('ipConfigurations')[copyIndex('ipConfigurations')].publicIPAddressResourceId, null())), createObject('id', parameters('ipConfigurations')[copyIndex('ipConfigurations')].publicIPAddressResourceId), null()), null())]", - "subnet": { - "id": "[parameters('ipConfigurations')[copyIndex('ipConfigurations')].subnetResourceId]" - }, - "loadBalancerBackendAddressPools": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'loadBalancerBackendAddressPools'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].loadBalancerBackendAddressPools, null())]", - "applicationSecurityGroups": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'applicationSecurityGroups'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].applicationSecurityGroups, null())]", - "applicationGatewayBackendAddressPools": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'applicationGatewayBackendAddressPools'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].applicationGatewayBackendAddressPools, null())]", - "gatewayLoadBalancer": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'gatewayLoadBalancer'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].gatewayLoadBalancer, null())]", - "loadBalancerInboundNatRules": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'loadBalancerInboundNatRules'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].loadBalancerInboundNatRules, null())]", - "privateIPAddressVersion": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'privateIPAddressVersion'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].privateIPAddressVersion, null())]", - "virtualNetworkTaps": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'virtualNetworkTaps'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].virtualNetworkTaps, null())]" - } - } - } - ], - "auxiliaryMode": "[parameters('auxiliaryMode')]", - "auxiliarySku": "[parameters('auxiliarySku')]", - "disableTcpStateTracking": "[parameters('disableTcpStateTracking')]", - "dnsSettings": "[if(not(empty(parameters('dnsServers'))), createObject('dnsServers', parameters('dnsServers')), null())]", - "enableAcceleratedNetworking": "[parameters('enableAcceleratedNetworking')]", - "enableIPForwarding": "[parameters('enableIPForwarding')]", - "networkSecurityGroup": "[if(not(empty(parameters('networkSecurityGroupResourceId'))), createObject('id', parameters('networkSecurityGroupResourceId')), null())]" - } - }, - "networkInterface_diagnosticSettings": { - "copy": { - "name": "networkInterface_diagnosticSettings", - "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" - }, - "type": "Microsoft.Insights/diagnosticSettings", - "apiVersion": "2021-05-01-preview", - "scope": "[format('Microsoft.Network/networkInterfaces/{0}', parameters('name'))]", - "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", - "properties": { - "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", - "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", - "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", - "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", - "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" - }, - "dependsOn": [ - "networkInterface" - ] - }, - "networkInterface_lock": { - "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", - "type": "Microsoft.Authorization/locks", - "apiVersion": "2020-05-01", - "scope": "[format('Microsoft.Network/networkInterfaces/{0}', parameters('name'))]", - "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", - "properties": { - "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", - "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" - }, - "dependsOn": [ - "networkInterface" - ] - }, - "networkInterface_roleAssignments": { - "copy": { - "name": "networkInterface_roleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "name": "[guid(resourceId('Microsoft.Network/networkInterfaces', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", - "properties": { - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", - "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", - "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", - "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", - "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", - "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", - "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" - }, - "dependsOn": [ - "networkInterface" - ] - } - }, - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the deployed resource." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the deployed resource." - }, - "value": "[resourceId('Microsoft.Network/networkInterfaces', parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The resource group of the deployed resource." - }, - "value": "[resourceGroup().name]" - }, - "location": { - "type": "string", - "metadata": { - "description": "The location the resource was deployed into." - }, - "value": "[reference('networkInterface', '2023-04-01', 'full').location]" - } - } - } - }, - "dependsOn": [ - "networkInterface_publicIPAddresses" - ] - } - } - } - } - }, - "vm_aadJoinExtension": { - "condition": "[parameters('extensionAadJoinConfig').enabled]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-VM-AADLogin', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "virtualMachineName": { - "value": "[parameters('name')]" - }, - "name": { - "value": "AADLogin" - }, - "publisher": { - "value": "Microsoft.Azure.ActiveDirectory" - }, - "type": "[if(equals(parameters('osType'), 'Windows'), createObject('value', 'AADLoginForWindows'), createObject('value', 'AADSSHLoginforLinux'))]", - "typeHandlerVersion": "[if(contains(parameters('extensionAadJoinConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionAadJoinConfig').typeHandlerVersion), createObject('value', '1.0'))]", - "autoUpgradeMinorVersion": "[if(contains(parameters('extensionAadJoinConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionAadJoinConfig').autoUpgradeMinorVersion), createObject('value', true()))]", - "enableAutomaticUpgrade": "[if(contains(parameters('extensionAadJoinConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionAadJoinConfig').enableAutomaticUpgrade), createObject('value', false()))]", - "settings": "[if(contains(parameters('extensionAadJoinConfig'), 'settings'), createObject('value', parameters('extensionAadJoinConfig').settings), createObject('value', createObject()))]", - "tags": { - "value": "[coalesce(tryGet(parameters('extensionAadJoinConfig'), 'tags'), parameters('tags'))]" - } - }, - "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": "5421737065579119324" - }, - "name": "Virtual Machine Extensions", - "description": "This module deploys a Virtual Machine Extension.", - "owner": "Azure/module-maintainers" - }, - "parameters": { - "virtualMachineName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment." - } - }, - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the virtual machine extension." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. The location the extension is deployed to." - } - }, - "publisher": { - "type": "string", - "metadata": { - "description": "Required. The name of the extension handler publisher." - } - }, - "type": { - "type": "string", - "metadata": { - "description": "Required. Specifies the type of the extension; an example is \"CustomScriptExtension\"." - } - }, - "typeHandlerVersion": { - "type": "string", - "metadata": { - "description": "Required. Specifies the version of the script handler." - } - }, - "autoUpgradeMinorVersion": { - "type": "bool", - "metadata": { - "description": "Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true." - } - }, - "forceUpdateTag": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." - } - }, - "settings": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Optional. Any object that contains the extension specific settings." - } - }, - "protectedSettings": { - "type": "secureObject", - "defaultValue": {}, - "metadata": { - "description": "Optional. Any object that contains the extension specific protected settings." - } - }, - "supressFailures": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false." - } - }, - "enableAutomaticUpgrade": { - "type": "bool", - "metadata": { - "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." - } - }, - "enableDefaultTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." - } - }, - "tags": { - "type": "object", - "nullable": true, - "metadata": { - "description": "Optional. Tags of the resource." - } - } - }, - "resources": { - "defaultTelemetry": { - "condition": "[parameters('enableDefaultTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2021-04-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [] - } - } - }, - "virtualMachine": { - "existing": true, - "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "2022-11-01", - "name": "[parameters('virtualMachineName')]" - }, - "extension": { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "2022-11-01", - "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "properties": { - "publisher": "[parameters('publisher')]", - "type": "[parameters('type')]", - "typeHandlerVersion": "[parameters('typeHandlerVersion')]", - "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", - "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", - "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", - "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", - "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", - "suppressFailures": "[parameters('supressFailures')]" - }, - "dependsOn": [ - "virtualMachine" - ] - } - }, - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the extension." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the extension." - }, - "value": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the Resource Group the extension was created in." - }, - "value": "[resourceGroup().name]" - }, - "location": { - "type": "string", - "metadata": { - "description": "The location the resource was deployed into." - }, - "value": "[reference('extension', '2022-11-01', 'full').location]" - } - } - } - }, - "dependsOn": [ - "vm" - ] - }, - "vm_domainJoinExtension": { - "condition": "[parameters('extensionDomainJoinConfig').enabled]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-VM-DomainJoin', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "virtualMachineName": { - "value": "[parameters('name')]" - }, - "name": { - "value": "DomainJoin" - }, - "publisher": { - "value": "Microsoft.Compute" - }, - "type": { - "value": "JsonADDomainExtension" - }, - "typeHandlerVersion": "[if(contains(parameters('extensionDomainJoinConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionDomainJoinConfig').typeHandlerVersion), createObject('value', '1.3'))]", - "autoUpgradeMinorVersion": "[if(contains(parameters('extensionDomainJoinConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionDomainJoinConfig').autoUpgradeMinorVersion), createObject('value', true()))]", - "enableAutomaticUpgrade": "[if(contains(parameters('extensionDomainJoinConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionDomainJoinConfig').enableAutomaticUpgrade), createObject('value', false()))]", - "settings": { - "value": "[parameters('extensionDomainJoinConfig').settings]" - }, - "tags": { - "value": "[coalesce(tryGet(parameters('extensionDomainJoinConfig'), 'tags'), parameters('tags'))]" - }, - "protectedSettings": { - "value": { - "Password": "[parameters('extensionDomainJoinPassword')]" - } - }, - "enableDefaultTelemetry": { - "value": "[variables('enableReferencedModulesTelemetry')]" - } - }, - "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": "5421737065579119324" - }, - "name": "Virtual Machine Extensions", - "description": "This module deploys a Virtual Machine Extension.", - "owner": "Azure/module-maintainers" - }, - "parameters": { - "virtualMachineName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment." - } - }, - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the virtual machine extension." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. The location the extension is deployed to." - } - }, - "publisher": { - "type": "string", - "metadata": { - "description": "Required. The name of the extension handler publisher." - } - }, - "type": { - "type": "string", - "metadata": { - "description": "Required. Specifies the type of the extension; an example is \"CustomScriptExtension\"." - } - }, - "typeHandlerVersion": { - "type": "string", - "metadata": { - "description": "Required. Specifies the version of the script handler." - } - }, - "autoUpgradeMinorVersion": { - "type": "bool", - "metadata": { - "description": "Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true." - } - }, - "forceUpdateTag": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." - } - }, - "settings": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Optional. Any object that contains the extension specific settings." - } - }, - "protectedSettings": { - "type": "secureObject", - "defaultValue": {}, - "metadata": { - "description": "Optional. Any object that contains the extension specific protected settings." - } - }, - "supressFailures": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false." - } - }, - "enableAutomaticUpgrade": { - "type": "bool", - "metadata": { - "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." - } - }, - "enableDefaultTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." - } - }, - "tags": { - "type": "object", - "nullable": true, - "metadata": { - "description": "Optional. Tags of the resource." - } - } - }, - "resources": { - "defaultTelemetry": { - "condition": "[parameters('enableDefaultTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2021-04-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [] - } - } - }, - "virtualMachine": { - "existing": true, - "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "2022-11-01", - "name": "[parameters('virtualMachineName')]" - }, - "extension": { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "2022-11-01", - "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "properties": { - "publisher": "[parameters('publisher')]", - "type": "[parameters('type')]", - "typeHandlerVersion": "[parameters('typeHandlerVersion')]", - "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", - "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", - "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", - "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", - "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", - "suppressFailures": "[parameters('supressFailures')]" - }, - "dependsOn": [ - "virtualMachine" - ] - } - }, - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the extension." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the extension." - }, - "value": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the Resource Group the extension was created in." - }, - "value": "[resourceGroup().name]" - }, - "location": { - "type": "string", - "metadata": { - "description": "The location the resource was deployed into." - }, - "value": "[reference('extension', '2022-11-01', 'full').location]" - } - } - } - }, - "dependsOn": [ - "vm" - ] - }, - "vm_microsoftAntiMalwareExtension": { - "condition": "[parameters('extensionAntiMalwareConfig').enabled]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-VM-MicrosoftAntiMalware', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "virtualMachineName": { - "value": "[parameters('name')]" - }, - "name": { - "value": "MicrosoftAntiMalware" - }, - "publisher": { - "value": "Microsoft.Azure.Security" - }, - "type": { - "value": "IaaSAntimalware" - }, - "typeHandlerVersion": "[if(contains(parameters('extensionAntiMalwareConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionAntiMalwareConfig').typeHandlerVersion), createObject('value', '1.3'))]", - "autoUpgradeMinorVersion": "[if(contains(parameters('extensionAntiMalwareConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionAntiMalwareConfig').autoUpgradeMinorVersion), createObject('value', true()))]", - "enableAutomaticUpgrade": "[if(contains(parameters('extensionAntiMalwareConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionAntiMalwareConfig').enableAutomaticUpgrade), createObject('value', false()))]", - "settings": { - "value": "[parameters('extensionAntiMalwareConfig').settings]" - }, - "tags": { - "value": "[coalesce(tryGet(parameters('extensionAntiMalwareConfig'), 'tags'), parameters('tags'))]" - }, - "enableDefaultTelemetry": { - "value": "[variables('enableReferencedModulesTelemetry')]" - } - }, - "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": "5421737065579119324" - }, - "name": "Virtual Machine Extensions", - "description": "This module deploys a Virtual Machine Extension.", - "owner": "Azure/module-maintainers" - }, - "parameters": { - "virtualMachineName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment." - } - }, - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the virtual machine extension." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. The location the extension is deployed to." - } - }, - "publisher": { - "type": "string", - "metadata": { - "description": "Required. The name of the extension handler publisher." - } - }, - "type": { - "type": "string", - "metadata": { - "description": "Required. Specifies the type of the extension; an example is \"CustomScriptExtension\"." - } - }, - "typeHandlerVersion": { - "type": "string", - "metadata": { - "description": "Required. Specifies the version of the script handler." - } - }, - "autoUpgradeMinorVersion": { - "type": "bool", - "metadata": { - "description": "Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true." - } - }, - "forceUpdateTag": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." - } - }, - "settings": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Optional. Any object that contains the extension specific settings." - } - }, - "protectedSettings": { - "type": "secureObject", - "defaultValue": {}, - "metadata": { - "description": "Optional. Any object that contains the extension specific protected settings." - } - }, - "supressFailures": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false." - } - }, - "enableAutomaticUpgrade": { - "type": "bool", - "metadata": { - "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." - } - }, - "enableDefaultTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." - } - }, - "tags": { - "type": "object", - "nullable": true, - "metadata": { - "description": "Optional. Tags of the resource." - } - } - }, - "resources": { - "defaultTelemetry": { - "condition": "[parameters('enableDefaultTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2021-04-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [] - } - } - }, - "virtualMachine": { - "existing": true, - "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "2022-11-01", - "name": "[parameters('virtualMachineName')]" - }, - "extension": { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "2022-11-01", - "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "properties": { - "publisher": "[parameters('publisher')]", - "type": "[parameters('type')]", - "typeHandlerVersion": "[parameters('typeHandlerVersion')]", - "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", - "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", - "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", - "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", - "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", - "suppressFailures": "[parameters('supressFailures')]" - }, - "dependsOn": [ - "virtualMachine" - ] - } - }, - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the extension." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the extension." - }, - "value": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the Resource Group the extension was created in." - }, - "value": "[resourceGroup().name]" - }, - "location": { - "type": "string", - "metadata": { - "description": "The location the resource was deployed into." - }, - "value": "[reference('extension', '2022-11-01', 'full').location]" - } - } - } - }, - "dependsOn": [ - "vm" - ] - }, - "vm_microsoftMonitoringAgentExtension": { - "condition": "[parameters('extensionMonitoringAgentConfig').enabled]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-VM-MicrosoftMonitoringAgent', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "virtualMachineName": { - "value": "[parameters('name')]" - }, - "name": { - "value": "MicrosoftMonitoringAgent" - }, - "publisher": { - "value": "Microsoft.EnterpriseCloud.Monitoring" - }, - "type": "[if(equals(parameters('osType'), 'Windows'), createObject('value', 'MicrosoftMonitoringAgent'), createObject('value', 'OmsAgentForLinux'))]", - "typeHandlerVersion": "[if(contains(parameters('extensionMonitoringAgentConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionMonitoringAgentConfig').typeHandlerVersion), if(equals(parameters('osType'), 'Windows'), createObject('value', '1.0'), createObject('value', '1.7')))]", - "autoUpgradeMinorVersion": "[if(contains(parameters('extensionMonitoringAgentConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionMonitoringAgentConfig').autoUpgradeMinorVersion), createObject('value', true()))]", - "enableAutomaticUpgrade": "[if(contains(parameters('extensionMonitoringAgentConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionMonitoringAgentConfig').enableAutomaticUpgrade), createObject('value', false()))]", - "settings": { - "value": { - "workspaceId": "[if(not(empty(parameters('monitoringWorkspaceId'))), reference('vm_logAnalyticsWorkspace').customerId, '')]" - } - }, - "tags": { - "value": "[coalesce(tryGet(parameters('extensionMonitoringAgentConfig'), 'tags'), parameters('tags'))]" - }, - "protectedSettings": { - "value": { - "workspaceKey": "[if(not(empty(parameters('monitoringWorkspaceId'))), listKeys(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(if(not(empty(parameters('monitoringWorkspaceId'))), parameters('monitoringWorkspaceId'), '//'), '/')[2], split(if(not(empty(parameters('monitoringWorkspaceId'))), parameters('monitoringWorkspaceId'), '////'), '/')[4]), 'Microsoft.OperationalInsights/workspaces', last(split(if(not(empty(parameters('monitoringWorkspaceId'))), parameters('monitoringWorkspaceId'), 'law'), '/'))), '2021-06-01').primarySharedKey, '')]" - } - }, - "enableDefaultTelemetry": { - "value": "[variables('enableReferencedModulesTelemetry')]" - } - }, - "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": "5421737065579119324" - }, - "name": "Virtual Machine Extensions", - "description": "This module deploys a Virtual Machine Extension.", - "owner": "Azure/module-maintainers" - }, - "parameters": { - "virtualMachineName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment." - } - }, - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the virtual machine extension." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. The location the extension is deployed to." - } - }, - "publisher": { - "type": "string", - "metadata": { - "description": "Required. The name of the extension handler publisher." - } - }, - "type": { - "type": "string", - "metadata": { - "description": "Required. Specifies the type of the extension; an example is \"CustomScriptExtension\"." - } - }, - "typeHandlerVersion": { - "type": "string", - "metadata": { - "description": "Required. Specifies the version of the script handler." - } - }, - "autoUpgradeMinorVersion": { - "type": "bool", - "metadata": { - "description": "Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true." - } - }, - "forceUpdateTag": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." - } - }, - "settings": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Optional. Any object that contains the extension specific settings." - } - }, - "protectedSettings": { - "type": "secureObject", - "defaultValue": {}, - "metadata": { - "description": "Optional. Any object that contains the extension specific protected settings." - } - }, - "supressFailures": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false." - } - }, - "enableAutomaticUpgrade": { - "type": "bool", - "metadata": { - "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." - } - }, - "enableDefaultTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." - } - }, - "tags": { - "type": "object", - "nullable": true, - "metadata": { - "description": "Optional. Tags of the resource." - } - } - }, - "resources": { - "defaultTelemetry": { - "condition": "[parameters('enableDefaultTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2021-04-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [] - } - } - }, - "virtualMachine": { - "existing": true, - "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "2022-11-01", - "name": "[parameters('virtualMachineName')]" - }, - "extension": { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "2022-11-01", - "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "properties": { - "publisher": "[parameters('publisher')]", - "type": "[parameters('type')]", - "typeHandlerVersion": "[parameters('typeHandlerVersion')]", - "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", - "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", - "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", - "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", - "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", - "suppressFailures": "[parameters('supressFailures')]" - }, - "dependsOn": [ - "virtualMachine" - ] - } - }, - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the extension." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the extension." - }, - "value": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the Resource Group the extension was created in." - }, - "value": "[resourceGroup().name]" - }, - "location": { - "type": "string", - "metadata": { - "description": "The location the resource was deployed into." - }, - "value": "[reference('extension', '2022-11-01', 'full').location]" - } - } - } - }, - "dependsOn": [ - "vm", - "vm_logAnalyticsWorkspace" - ] - }, - "vm_dependencyAgentExtension": { - "condition": "[parameters('extensionDependencyAgentConfig').enabled]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-VM-DependencyAgent', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "virtualMachineName": { - "value": "[parameters('name')]" - }, - "name": { - "value": "DependencyAgent" - }, - "publisher": { - "value": "Microsoft.Azure.Monitoring.DependencyAgent" - }, - "type": "[if(equals(parameters('osType'), 'Windows'), createObject('value', 'DependencyAgentWindows'), createObject('value', 'DependencyAgentLinux'))]", - "typeHandlerVersion": "[if(contains(parameters('extensionDependencyAgentConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionDependencyAgentConfig').typeHandlerVersion), createObject('value', '9.5'))]", - "autoUpgradeMinorVersion": "[if(contains(parameters('extensionDependencyAgentConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionDependencyAgentConfig').autoUpgradeMinorVersion), createObject('value', true()))]", - "enableAutomaticUpgrade": "[if(contains(parameters('extensionDependencyAgentConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionDependencyAgentConfig').enableAutomaticUpgrade), createObject('value', true()))]", - "enableDefaultTelemetry": { - "value": "[variables('enableReferencedModulesTelemetry')]" - }, - "tags": { - "value": "[coalesce(tryGet(parameters('extensionDependencyAgentConfig'), 'tags'), parameters('tags'))]" - } - }, - "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": "5421737065579119324" - }, - "name": "Virtual Machine Extensions", - "description": "This module deploys a Virtual Machine Extension.", - "owner": "Azure/module-maintainers" - }, - "parameters": { - "virtualMachineName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment." - } - }, - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the virtual machine extension." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. The location the extension is deployed to." - } - }, - "publisher": { - "type": "string", - "metadata": { - "description": "Required. The name of the extension handler publisher." - } - }, - "type": { - "type": "string", - "metadata": { - "description": "Required. Specifies the type of the extension; an example is \"CustomScriptExtension\"." - } - }, - "typeHandlerVersion": { - "type": "string", - "metadata": { - "description": "Required. Specifies the version of the script handler." - } - }, - "autoUpgradeMinorVersion": { - "type": "bool", - "metadata": { - "description": "Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true." - } - }, - "forceUpdateTag": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." - } - }, - "settings": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Optional. Any object that contains the extension specific settings." - } - }, - "protectedSettings": { - "type": "secureObject", - "defaultValue": {}, - "metadata": { - "description": "Optional. Any object that contains the extension specific protected settings." - } - }, - "supressFailures": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false." - } - }, - "enableAutomaticUpgrade": { - "type": "bool", - "metadata": { - "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." - } - }, - "enableDefaultTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." - } - }, - "tags": { - "type": "object", - "nullable": true, - "metadata": { - "description": "Optional. Tags of the resource." - } - } - }, - "resources": { - "defaultTelemetry": { - "condition": "[parameters('enableDefaultTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2021-04-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [] - } - } - }, - "virtualMachine": { - "existing": true, - "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "2022-11-01", - "name": "[parameters('virtualMachineName')]" - }, - "extension": { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "2022-11-01", - "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "properties": { - "publisher": "[parameters('publisher')]", - "type": "[parameters('type')]", - "typeHandlerVersion": "[parameters('typeHandlerVersion')]", - "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", - "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", - "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", - "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", - "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", - "suppressFailures": "[parameters('supressFailures')]" - }, - "dependsOn": [ - "virtualMachine" - ] - } - }, - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the extension." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the extension." - }, - "value": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the Resource Group the extension was created in." - }, - "value": "[resourceGroup().name]" - }, - "location": { - "type": "string", - "metadata": { - "description": "The location the resource was deployed into." - }, - "value": "[reference('extension', '2022-11-01', 'full').location]" - } - } - } - }, - "dependsOn": [ - "vm" - ] - }, - "vm_networkWatcherAgentExtension": { - "condition": "[parameters('extensionNetworkWatcherAgentConfig').enabled]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-VM-NetworkWatcherAgent', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "virtualMachineName": { - "value": "[parameters('name')]" - }, - "name": { - "value": "NetworkWatcherAgent" - }, - "publisher": { - "value": "Microsoft.Azure.NetworkWatcher" - }, - "type": "[if(equals(parameters('osType'), 'Windows'), createObject('value', 'NetworkWatcherAgentWindows'), createObject('value', 'NetworkWatcherAgentLinux'))]", - "typeHandlerVersion": "[if(contains(parameters('extensionNetworkWatcherAgentConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionNetworkWatcherAgentConfig').typeHandlerVersion), createObject('value', '1.4'))]", - "autoUpgradeMinorVersion": "[if(contains(parameters('extensionNetworkWatcherAgentConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionNetworkWatcherAgentConfig').autoUpgradeMinorVersion), createObject('value', true()))]", - "enableAutomaticUpgrade": "[if(contains(parameters('extensionNetworkWatcherAgentConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionNetworkWatcherAgentConfig').enableAutomaticUpgrade), createObject('value', false()))]", - "enableDefaultTelemetry": { - "value": "[variables('enableReferencedModulesTelemetry')]" - }, - "tags": { - "value": "[coalesce(tryGet(parameters('extensionNetworkWatcherAgentConfig'), 'tags'), parameters('tags'))]" - } - }, - "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": "5421737065579119324" - }, - "name": "Virtual Machine Extensions", - "description": "This module deploys a Virtual Machine Extension.", - "owner": "Azure/module-maintainers" - }, - "parameters": { - "virtualMachineName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment." - } - }, - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the virtual machine extension." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. The location the extension is deployed to." - } - }, - "publisher": { - "type": "string", - "metadata": { - "description": "Required. The name of the extension handler publisher." - } - }, - "type": { - "type": "string", - "metadata": { - "description": "Required. Specifies the type of the extension; an example is \"CustomScriptExtension\"." - } - }, - "typeHandlerVersion": { - "type": "string", - "metadata": { - "description": "Required. Specifies the version of the script handler." - } - }, - "autoUpgradeMinorVersion": { - "type": "bool", - "metadata": { - "description": "Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true." - } - }, - "forceUpdateTag": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." - } - }, - "settings": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Optional. Any object that contains the extension specific settings." - } - }, - "protectedSettings": { - "type": "secureObject", - "defaultValue": {}, - "metadata": { - "description": "Optional. Any object that contains the extension specific protected settings." - } - }, - "supressFailures": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false." - } - }, - "enableAutomaticUpgrade": { - "type": "bool", - "metadata": { - "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." - } - }, - "enableDefaultTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." - } - }, - "tags": { - "type": "object", - "nullable": true, - "metadata": { - "description": "Optional. Tags of the resource." - } - } - }, - "resources": { - "defaultTelemetry": { - "condition": "[parameters('enableDefaultTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2021-04-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [] - } - } - }, - "virtualMachine": { - "existing": true, - "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "2022-11-01", - "name": "[parameters('virtualMachineName')]" - }, - "extension": { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "2022-11-01", - "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "properties": { - "publisher": "[parameters('publisher')]", - "type": "[parameters('type')]", - "typeHandlerVersion": "[parameters('typeHandlerVersion')]", - "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", - "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", - "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", - "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", - "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", - "suppressFailures": "[parameters('supressFailures')]" - }, - "dependsOn": [ - "virtualMachine" - ] - } - }, - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the extension." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the extension." - }, - "value": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the Resource Group the extension was created in." - }, - "value": "[resourceGroup().name]" - }, - "location": { - "type": "string", - "metadata": { - "description": "The location the resource was deployed into." - }, - "value": "[reference('extension', '2022-11-01', 'full').location]" - } - } - } - }, - "dependsOn": [ - "vm" - ] - }, - "vm_desiredStateConfigurationExtension": { - "condition": "[parameters('extensionDSCConfig').enabled]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-VM-DesiredStateConfiguration', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "virtualMachineName": { - "value": "[parameters('name')]" - }, - "name": { - "value": "DesiredStateConfiguration" - }, - "publisher": { - "value": "Microsoft.Powershell" - }, - "type": { - "value": "DSC" - }, - "typeHandlerVersion": "[if(contains(parameters('extensionDSCConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionDSCConfig').typeHandlerVersion), createObject('value', '2.77'))]", - "autoUpgradeMinorVersion": "[if(contains(parameters('extensionDSCConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionDSCConfig').autoUpgradeMinorVersion), createObject('value', true()))]", - "enableAutomaticUpgrade": "[if(contains(parameters('extensionDSCConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionDSCConfig').enableAutomaticUpgrade), createObject('value', false()))]", - "settings": "[if(contains(parameters('extensionDSCConfig'), 'settings'), createObject('value', parameters('extensionDSCConfig').settings), createObject('value', createObject()))]", - "tags": { - "value": "[coalesce(tryGet(parameters('extensionDSCConfig'), 'tags'), parameters('tags'))]" - }, - "protectedSettings": "[if(contains(parameters('extensionDSCConfig'), 'protectedSettings'), createObject('value', parameters('extensionDSCConfig').protectedSettings), createObject('value', createObject()))]", - "enableDefaultTelemetry": { - "value": "[variables('enableReferencedModulesTelemetry')]" - } - }, - "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": "5421737065579119324" - }, - "name": "Virtual Machine Extensions", - "description": "This module deploys a Virtual Machine Extension.", - "owner": "Azure/module-maintainers" - }, - "parameters": { - "virtualMachineName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment." - } - }, - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the virtual machine extension." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. The location the extension is deployed to." - } - }, - "publisher": { - "type": "string", - "metadata": { - "description": "Required. The name of the extension handler publisher." - } - }, - "type": { - "type": "string", - "metadata": { - "description": "Required. Specifies the type of the extension; an example is \"CustomScriptExtension\"." - } - }, - "typeHandlerVersion": { - "type": "string", - "metadata": { - "description": "Required. Specifies the version of the script handler." - } - }, - "autoUpgradeMinorVersion": { - "type": "bool", - "metadata": { - "description": "Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true." - } - }, - "forceUpdateTag": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." - } - }, - "settings": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Optional. Any object that contains the extension specific settings." - } - }, - "protectedSettings": { - "type": "secureObject", - "defaultValue": {}, - "metadata": { - "description": "Optional. Any object that contains the extension specific protected settings." - } - }, - "supressFailures": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false." - } - }, - "enableAutomaticUpgrade": { - "type": "bool", - "metadata": { - "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." - } - }, - "enableDefaultTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." - } - }, - "tags": { - "type": "object", - "nullable": true, - "metadata": { - "description": "Optional. Tags of the resource." - } - } - }, - "resources": { - "defaultTelemetry": { - "condition": "[parameters('enableDefaultTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2021-04-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [] - } - } - }, - "virtualMachine": { - "existing": true, - "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "2022-11-01", - "name": "[parameters('virtualMachineName')]" - }, - "extension": { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "2022-11-01", - "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "properties": { - "publisher": "[parameters('publisher')]", - "type": "[parameters('type')]", - "typeHandlerVersion": "[parameters('typeHandlerVersion')]", - "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", - "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", - "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", - "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", - "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", - "suppressFailures": "[parameters('supressFailures')]" - }, - "dependsOn": [ - "virtualMachine" - ] - } - }, - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the extension." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the extension." - }, - "value": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the Resource Group the extension was created in." - }, - "value": "[resourceGroup().name]" - }, - "location": { - "type": "string", - "metadata": { - "description": "The location the resource was deployed into." - }, - "value": "[reference('extension', '2022-11-01', 'full').location]" - } - } - } - }, - "dependsOn": [ - "vm" - ] - }, - "vm_customScriptExtension": { - "condition": "[parameters('extensionCustomScriptConfig').enabled]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-VM-CustomScriptExtension', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "virtualMachineName": { - "value": "[parameters('name')]" - }, - "name": { - "value": "CustomScriptExtension" - }, - "publisher": "[if(equals(parameters('osType'), 'Windows'), createObject('value', 'Microsoft.Compute'), createObject('value', 'Microsoft.Azure.Extensions'))]", - "type": "[if(equals(parameters('osType'), 'Windows'), createObject('value', 'CustomScriptExtension'), createObject('value', 'CustomScript'))]", - "typeHandlerVersion": "[if(contains(parameters('extensionCustomScriptConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionCustomScriptConfig').typeHandlerVersion), if(equals(parameters('osType'), 'Windows'), createObject('value', '1.10'), createObject('value', '2.1')))]", - "autoUpgradeMinorVersion": "[if(contains(parameters('extensionCustomScriptConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionCustomScriptConfig').autoUpgradeMinorVersion), createObject('value', true()))]", - "enableAutomaticUpgrade": "[if(contains(parameters('extensionCustomScriptConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionCustomScriptConfig').enableAutomaticUpgrade), createObject('value', false()))]", - "settings": { - "value": { - "copy": [ - { - "name": "fileUris", - "count": "[length(parameters('extensionCustomScriptConfig').fileData)]", - "input": "[if(contains(parameters('extensionCustomScriptConfig').fileData[copyIndex('fileUris')], 'storageAccountId'), format('{0}?{1}', parameters('extensionCustomScriptConfig').fileData[copyIndex('fileUris')].uri, listAccountSas(parameters('extensionCustomScriptConfig').fileData[copyIndex('fileUris')].storageAccountId, '2019-04-01', variables('accountSasProperties')).accountSasToken), parameters('extensionCustomScriptConfig').fileData[copyIndex('fileUris')].uri)]" - } - ] - } - }, - "tags": { - "value": "[coalesce(tryGet(parameters('extensionCustomScriptConfig'), 'tags'), parameters('tags'))]" - }, - "protectedSettings": { - "value": "[parameters('extensionCustomScriptProtectedSetting')]" - }, - "enableDefaultTelemetry": { - "value": "[variables('enableReferencedModulesTelemetry')]" - } - }, - "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": "5421737065579119324" - }, - "name": "Virtual Machine Extensions", - "description": "This module deploys a Virtual Machine Extension.", - "owner": "Azure/module-maintainers" - }, - "parameters": { - "virtualMachineName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment." - } - }, - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the virtual machine extension." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. The location the extension is deployed to." - } - }, - "publisher": { - "type": "string", - "metadata": { - "description": "Required. The name of the extension handler publisher." - } - }, - "type": { - "type": "string", - "metadata": { - "description": "Required. Specifies the type of the extension; an example is \"CustomScriptExtension\"." - } - }, - "typeHandlerVersion": { - "type": "string", - "metadata": { - "description": "Required. Specifies the version of the script handler." - } - }, - "autoUpgradeMinorVersion": { - "type": "bool", - "metadata": { - "description": "Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true." - } - }, - "forceUpdateTag": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." - } - }, - "settings": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Optional. Any object that contains the extension specific settings." - } - }, - "protectedSettings": { - "type": "secureObject", - "defaultValue": {}, - "metadata": { - "description": "Optional. Any object that contains the extension specific protected settings." - } - }, - "supressFailures": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false." - } - }, - "enableAutomaticUpgrade": { - "type": "bool", - "metadata": { - "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." - } - }, - "enableDefaultTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." - } - }, - "tags": { - "type": "object", - "nullable": true, - "metadata": { - "description": "Optional. Tags of the resource." - } - } - }, - "resources": { - "defaultTelemetry": { - "condition": "[parameters('enableDefaultTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2021-04-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [] - } - } - }, - "virtualMachine": { - "existing": true, - "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "2022-11-01", - "name": "[parameters('virtualMachineName')]" - }, - "extension": { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "2022-11-01", - "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "properties": { - "publisher": "[parameters('publisher')]", - "type": "[parameters('type')]", - "typeHandlerVersion": "[parameters('typeHandlerVersion')]", - "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", - "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", - "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", - "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", - "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", - "suppressFailures": "[parameters('supressFailures')]" - }, - "dependsOn": [ - "virtualMachine" - ] - } - }, - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the extension." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the extension." - }, - "value": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the Resource Group the extension was created in." - }, - "value": "[resourceGroup().name]" - }, - "location": { - "type": "string", - "metadata": { - "description": "The location the resource was deployed into." - }, - "value": "[reference('extension', '2022-11-01', 'full').location]" - } - } - } - }, - "dependsOn": [ - "vm", - "vm_desiredStateConfigurationExtension" - ] - }, - "vm_azureDiskEncryptionExtension": { - "condition": "[parameters('extensionAzureDiskEncryptionConfig').enabled]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-VM-AzureDiskEncryption', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "virtualMachineName": { - "value": "[parameters('name')]" - }, - "name": { - "value": "AzureDiskEncryption" - }, - "publisher": { - "value": "Microsoft.Azure.Security" - }, - "type": "[if(equals(parameters('osType'), 'Windows'), createObject('value', 'AzureDiskEncryption'), createObject('value', 'AzureDiskEncryptionForLinux'))]", - "typeHandlerVersion": "[if(contains(parameters('extensionAzureDiskEncryptionConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionAzureDiskEncryptionConfig').typeHandlerVersion), if(equals(parameters('osType'), 'Windows'), createObject('value', '2.2'), createObject('value', '1.1')))]", - "autoUpgradeMinorVersion": "[if(contains(parameters('extensionAzureDiskEncryptionConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionAzureDiskEncryptionConfig').autoUpgradeMinorVersion), createObject('value', true()))]", - "enableAutomaticUpgrade": "[if(contains(parameters('extensionAzureDiskEncryptionConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionAzureDiskEncryptionConfig').enableAutomaticUpgrade), createObject('value', false()))]", - "forceUpdateTag": "[if(contains(parameters('extensionAzureDiskEncryptionConfig'), 'forceUpdateTag'), createObject('value', parameters('extensionAzureDiskEncryptionConfig').forceUpdateTag), createObject('value', '1.0'))]", - "settings": { - "value": "[parameters('extensionAzureDiskEncryptionConfig').settings]" - }, - "tags": { - "value": "[coalesce(tryGet(parameters('extensionAzureDiskEncryptionConfig'), 'tags'), parameters('tags'))]" - }, - "enableDefaultTelemetry": { - "value": "[variables('enableReferencedModulesTelemetry')]" - } - }, - "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": "5421737065579119324" - }, - "name": "Virtual Machine Extensions", - "description": "This module deploys a Virtual Machine Extension.", - "owner": "Azure/module-maintainers" - }, - "parameters": { - "virtualMachineName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment." - } - }, - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the virtual machine extension." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. The location the extension is deployed to." - } - }, - "publisher": { - "type": "string", - "metadata": { - "description": "Required. The name of the extension handler publisher." - } - }, - "type": { - "type": "string", - "metadata": { - "description": "Required. Specifies the type of the extension; an example is \"CustomScriptExtension\"." - } - }, - "typeHandlerVersion": { - "type": "string", - "metadata": { - "description": "Required. Specifies the version of the script handler." - } - }, - "autoUpgradeMinorVersion": { - "type": "bool", - "metadata": { - "description": "Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true." - } - }, - "forceUpdateTag": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." - } - }, - "settings": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Optional. Any object that contains the extension specific settings." - } - }, - "protectedSettings": { - "type": "secureObject", - "defaultValue": {}, - "metadata": { - "description": "Optional. Any object that contains the extension specific protected settings." - } - }, - "supressFailures": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false." - } - }, - "enableAutomaticUpgrade": { - "type": "bool", - "metadata": { - "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." - } - }, - "enableDefaultTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." - } - }, - "tags": { - "type": "object", - "nullable": true, - "metadata": { - "description": "Optional. Tags of the resource." - } - } - }, - "resources": { - "defaultTelemetry": { - "condition": "[parameters('enableDefaultTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2021-04-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [] - } - } - }, - "virtualMachine": { - "existing": true, - "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "2022-11-01", - "name": "[parameters('virtualMachineName')]" - }, - "extension": { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "2022-11-01", - "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "properties": { - "publisher": "[parameters('publisher')]", - "type": "[parameters('type')]", - "typeHandlerVersion": "[parameters('typeHandlerVersion')]", - "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", - "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", - "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", - "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", - "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", - "suppressFailures": "[parameters('supressFailures')]" - }, - "dependsOn": [ - "virtualMachine" - ] - } - }, - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the extension." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the extension." - }, - "value": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the Resource Group the extension was created in." - }, - "value": "[resourceGroup().name]" - }, - "location": { - "type": "string", - "metadata": { - "description": "The location the resource was deployed into." - }, - "value": "[reference('extension', '2022-11-01', 'full').location]" - } - } - } - }, - "dependsOn": [ - "vm", - "vm_customScriptExtension", - "vm_microsoftMonitoringAgentExtension" - ] - }, - "vm_backup": { - "condition": "[not(empty(parameters('backupVaultName')))]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-VM-Backup', uniqueString(deployment().name, parameters('location')))]", - "resourceGroup": "[parameters('backupVaultResourceGroup')]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "name": { - "value": "[format('vm;iaasvmcontainerv2;{0};{1}', resourceGroup().name, parameters('name'))]" - }, - "policyId": { - "value": "[resourceId('Microsoft.RecoveryServices/vaults/backupPolicies', parameters('backupVaultName'), parameters('backupPolicyName'))]" - }, - "protectedItemType": { - "value": "Microsoft.Compute/virtualMachines" - }, - "protectionContainerName": { - "value": "[format('iaasvmcontainer;iaasvmcontainerv2;{0};{1}', resourceGroup().name, parameters('name'))]" - }, - "recoveryVaultName": { - "value": "[parameters('backupVaultName')]" - }, - "sourceResourceId": { - "value": "[resourceId('Microsoft.Compute/virtualMachines', parameters('name'))]" - }, - "enableDefaultTelemetry": { - "value": "[variables('enableReferencedModulesTelemetry')]" - } - }, - "template": { - "$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": "9921011786088905122" - }, - "name": "Recovery Service Vaults Protection Container Protected Item", - "description": "This module deploys a Recovery Services Vault Protection Container Protected Item.", - "owner": "Azure/module-maintainers" - }, - "parameters": { - "name": { - "type": "string", - "metadata": { - "description": "Required. Name of the resource." - } - }, - "protectionContainerName": { - "type": "string", - "metadata": { - "description": "Conditional. Name of the Azure Recovery Service Vault Protection Container. Required if the template is used in a standalone deployment." - } - }, - "recoveryVaultName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent Azure Recovery Service Vault. Required if the template is used in a standalone deployment." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. Location for all resources." - } - }, - "protectedItemType": { - "type": "string", - "allowedValues": [ - "AzureFileShareProtectedItem", - "AzureVmWorkloadSAPAseDatabase", - "AzureVmWorkloadSAPHanaDatabase", - "AzureVmWorkloadSQLDatabase", - "DPMProtectedItem", - "GenericProtectedItem", - "MabFileFolderProtectedItem", - "Microsoft.ClassicCompute/virtualMachines", - "Microsoft.Compute/virtualMachines", - "Microsoft.Sql/servers/databases" - ], - "metadata": { - "description": "Required. The backup item type." - } - }, - "policyId": { - "type": "string", - "metadata": { - "description": "Required. ID of the backup policy with which this item is backed up." - } - }, - "sourceResourceId": { - "type": "string", - "metadata": { - "description": "Required. Resource ID of the resource to back up." - } - }, - "enableDefaultTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." - } - } - }, - "resources": [ - { - "condition": "[parameters('enableDefaultTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2021-04-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [] - } - } - }, - { - "type": "Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems", - "apiVersion": "2023-01-01", - "name": "[format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name'))]", - "location": "[parameters('location')]", - "properties": { - "protectedItemType": "[parameters('protectedItemType')]", - "policyId": "[parameters('policyId')]", - "sourceResourceId": "[parameters('sourceResourceId')]" - } - } - ], - "outputs": { - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the Resource Group the protected item was created in." - }, - "value": "[resourceGroup().name]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the protected item." - }, - "value": "[resourceId('Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems', split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[0], split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[1], split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[2], split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[3])]" - }, - "name": { - "type": "string", - "metadata": { - "description": "The Name of the protected item." - }, - "value": "[format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name'))]" - } - } - } - }, - "dependsOn": [ - "vm", - "vm_aadJoinExtension", - "vm_customScriptExtension", - "vm_dependencyAgentExtension", - "vm_desiredStateConfigurationExtension", - "vm_domainJoinExtension", - "vm_microsoftAntiMalwareExtension", - "vm_microsoftMonitoringAgentExtension", - "vm_networkWatcherAgentExtension" - ] - } - }, - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the VM." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the VM." - }, - "value": "[resourceId('Microsoft.Compute/virtualMachines', parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the resource group the VM was created in." - }, - "value": "[resourceGroup().name]" - }, - "systemAssignedMIPrincipalId": { - "type": "string", - "metadata": { - "description": "The principal ID of the system assigned identity." - }, - "value": "[if(and(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), contains(reference('vm', '2022-11-01', 'full').identity, 'principalId')), reference('vm', '2022-11-01', 'full').identity.principalId, '')]" - }, - "location": { - "type": "string", - "metadata": { - "description": "The location the resource was deployed into." - }, - "value": "[reference('vm', '2022-11-01', 'full').location]" - } - } -} \ No newline at end of file From 3458ba0aca0596acf0cbbe1ab84c9f24e994e4bb Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Wed, 6 Dec 2023 11:19:58 +0100 Subject: [PATCH 04/96] rename test folders --- .../virtual-machine/extension/README.md | 165 ------------------ .../virtual-machine/extension/version.json | 10 +- .../tests/e2e/linux.atmg/main.test.bicep | 9 +- .../dependencies.bicep | 0 .../main.test.bicep | 9 +- .../tests/e2e/linux/main.test.bicep | 11 +- .../tests/e2e/windows.atmg/main.test.bicep | 9 +- .../dependencies.bicep | 0 .../main.test.bicep | 9 +- .../tests/e2e/windows.ssecmk/main.test.bicep | 9 +- .../tests/e2e/windows/main.test.bicep | 11 +- avm/res/compute/virtual-machine/version.json | 10 +- 12 files changed, 33 insertions(+), 219 deletions(-) delete mode 100644 avm/res/compute/virtual-machine/extension/README.md rename avm/res/compute/virtual-machine/tests/e2e/{linux.min => linux.defaults}/dependencies.bicep (100%) rename avm/res/compute/virtual-machine/tests/e2e/{linux.min => linux.defaults}/main.test.bicep (92%) rename avm/res/compute/virtual-machine/tests/e2e/{windows.min => windows.defaults}/dependencies.bicep (100%) rename avm/res/compute/virtual-machine/tests/e2e/{windows.min => windows.defaults}/main.test.bicep (90%) diff --git a/avm/res/compute/virtual-machine/extension/README.md b/avm/res/compute/virtual-machine/extension/README.md deleted file mode 100644 index 324ebc8179..0000000000 --- a/avm/res/compute/virtual-machine/extension/README.md +++ /dev/null @@ -1,165 +0,0 @@ -# Virtual Machine Extensions `[Microsoft.Compute/virtualMachines/extensions]` - -This module deploys a Virtual Machine Extension. - -## Navigation - -- [Resource Types](#Resource-Types) -- [Parameters](#Parameters) -- [Outputs](#Outputs) -- [Cross-referenced modules](#Cross-referenced-modules) - -## Resource Types - -| Resource Type | API Version | -| :-- | :-- | -| `Microsoft.Compute/virtualMachines/extensions` | [2022-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Compute/2022-11-01/virtualMachines/extensions) | - -## Parameters - -**Required parameters** - -| Parameter | Type | Description | -| :-- | :-- | :-- | -| [`autoUpgradeMinorVersion`](#parameter-autoupgrademinorversion) | bool | Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true. | -| [`enableAutomaticUpgrade`](#parameter-enableautomaticupgrade) | bool | Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available. | -| [`name`](#parameter-name) | string | The name of the virtual machine extension. | -| [`publisher`](#parameter-publisher) | string | The name of the extension handler publisher. | -| [`type`](#parameter-type) | string | Specifies the type of the extension; an example is "CustomScriptExtension". | -| [`typeHandlerVersion`](#parameter-typehandlerversion) | string | Specifies the version of the script handler. | - -**Conditional parameters** - -| Parameter | Type | Description | -| :-- | :-- | :-- | -| [`virtualMachineName`](#parameter-virtualmachinename) | string | The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment. | - -**Optional parameters** - -| Parameter | Type | Description | -| :-- | :-- | :-- | -| [`enableDefaultTelemetry`](#parameter-enabledefaulttelemetry) | bool | Enable telemetry via a Globally Unique Identifier (GUID). | -| [`forceUpdateTag`](#parameter-forceupdatetag) | string | How the extension handler should be forced to update even if the extension configuration has not changed. | -| [`location`](#parameter-location) | string | The location the extension is deployed to. | -| [`protectedSettings`](#parameter-protectedsettings) | secureObject | Any object that contains the extension specific protected settings. | -| [`settings`](#parameter-settings) | object | Any object that contains the extension specific settings. | -| [`supressFailures`](#parameter-supressfailures) | bool | Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false. | -| [`tags`](#parameter-tags) | object | Tags of the resource. | - -### Parameter: `autoUpgradeMinorVersion` - -Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true. - -- Required: Yes -- Type: bool - -### Parameter: `enableAutomaticUpgrade` - -Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available. - -- Required: Yes -- Type: bool - -### Parameter: `name` - -The name of the virtual machine extension. - -- Required: Yes -- Type: string - -### Parameter: `publisher` - -The name of the extension handler publisher. - -- Required: Yes -- Type: string - -### Parameter: `type` - -Specifies the type of the extension; an example is "CustomScriptExtension". - -- Required: Yes -- Type: string - -### Parameter: `typeHandlerVersion` - -Specifies the version of the script handler. - -- Required: Yes -- Type: string - -### Parameter: `virtualMachineName` - -The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment. - -- Required: Yes -- Type: string - -### Parameter: `enableDefaultTelemetry` - -Enable telemetry via a Globally Unique Identifier (GUID). - -- Required: No -- Type: bool -- Default: `True` - -### Parameter: `forceUpdateTag` - -How the extension handler should be forced to update even if the extension configuration has not changed. - -- Required: No -- Type: string -- Default: `''` - -### Parameter: `location` - -The location the extension is deployed to. - -- Required: No -- Type: string -- Default: `[resourceGroup().location]` - -### Parameter: `protectedSettings` - -Any object that contains the extension specific protected settings. - -- Required: No -- Type: secureObject -- Default: `{}` - -### Parameter: `settings` - -Any object that contains the extension specific settings. - -- Required: No -- Type: object -- Default: `{}` - -### Parameter: `supressFailures` - -Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false. - -- Required: No -- Type: bool -- Default: `False` - -### Parameter: `tags` - -Tags of the resource. - -- Required: No -- Type: object - - -## Outputs - -| Output | Type | Description | -| :-- | :-- | :-- | -| `location` | string | The location the resource was deployed into. | -| `name` | string | The name of the extension. | -| `resourceGroupName` | string | The name of the Resource Group the extension was created in. | -| `resourceId` | string | The resource ID of the extension. | - -## Cross-referenced modules - -_None_ diff --git a/avm/res/compute/virtual-machine/extension/version.json b/avm/res/compute/virtual-machine/extension/version.json index 96236a61ba..8def869ede 100644 --- a/avm/res/compute/virtual-machine/extension/version.json +++ b/avm/res/compute/virtual-machine/extension/version.json @@ -1,7 +1,7 @@ { - "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.4", - "pathFilters": [ - "./main.json" - ] + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.1", + "pathFilters": [ + "./main.json" + ] } diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux.atmg/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.atmg/main.test.bicep index 4e53732a23..30d62270aa 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/linux.atmg/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/linux.atmg/main.test.bicep @@ -14,11 +14,8 @@ 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 = 'cvmlinatmg' -@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') -param enableDefaultTelemetry bool = true - @description('Optional. A token to inject into the name of each resource.') -param namePrefix string = '[[namePrefix]]' +param namePrefix string = '#_namePrefix_#' // ============ // // Dependencies // @@ -54,9 +51,8 @@ module nestedDependencies 'dependencies.bicep' = { module testDeployment '../../../main.bicep' = { scope: resourceGroup - name: '${uniqueString(deployment().name, location)}-test-${serviceShort}' + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' params: { - enableDefaultTelemetry: enableDefaultTelemetry location: location name: '${namePrefix}${serviceShort}' adminUsername: 'localAdminUser' @@ -121,3 +117,4 @@ module testDeployment '../../../main.bicep' = { nestedDependencies // Required to leverage `existing` SSH key reference ] } + diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux.min/dependencies.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/dependencies.bicep similarity index 100% rename from avm/res/compute/virtual-machine/tests/e2e/linux.min/dependencies.bicep rename to avm/res/compute/virtual-machine/tests/e2e/linux.defaults/dependencies.bicep diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux.min/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep similarity index 92% rename from avm/res/compute/virtual-machine/tests/e2e/linux.min/main.test.bicep rename to avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep index 4c3fffb43d..ed72917bfe 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/linux.min/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep @@ -14,11 +14,8 @@ 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 = 'cvmlinmin' -@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') -param enableDefaultTelemetry bool = true - @description('Optional. A token to inject into the name of each resource.') -param namePrefix string = '[[namePrefix]]' +param namePrefix string = '#_namePrefix_#' // ============ // // Dependencies // @@ -54,9 +51,8 @@ module nestedDependencies 'dependencies.bicep' = { module testDeployment '../../../main.bicep' = { scope: resourceGroup - name: '${uniqueString(deployment().name, location)}-test-${serviceShort}' + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' params: { - enableDefaultTelemetry: enableDefaultTelemetry location: location name: '${namePrefix}${serviceShort}' adminUsername: 'localAdminUser' @@ -100,3 +96,4 @@ module testDeployment '../../../main.bicep' = { nestedDependencies // Required to leverage `existing` SSH key reference ] } + diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux/main.test.bicep index b4b5e7ba57..7e883b74a5 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/linux/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/linux/main.test.bicep @@ -14,11 +14,8 @@ 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 = 'cvmlincom' -@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') -param enableDefaultTelemetry bool = true - @description('Optional. A token to inject into the name of each resource.') -param namePrefix string = '[[namePrefix]]' +param namePrefix string = '#_namePrefix_#' // ============ // // Dependencies // @@ -51,7 +48,7 @@ module nestedDependencies 'dependencies.bicep' = { // Diagnostics // =========== -module diagnosticDependencies '../../../../../.shared/.templates/diagnostic.dependencies.bicep' = { +module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/templates/diagnostic.dependencies.bicep' = { scope: resourceGroup name: '${uniqueString(deployment().name, location)}-diagnosticDependencies' params: { @@ -69,9 +66,8 @@ module diagnosticDependencies '../../../../../.shared/.templates/diagnostic.depe module testDeployment '../../../main.bicep' = { scope: resourceGroup - name: '${uniqueString(deployment().name, location)}-test-${serviceShort}' + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' params: { - enableDefaultTelemetry: enableDefaultTelemetry name: '${namePrefix}${serviceShort}' computerName: '${namePrefix}linvm1' location: location @@ -312,3 +308,4 @@ module testDeployment '../../../main.bicep' = { nestedDependencies // Required to leverage `existing` SSH key reference ] } + diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows.atmg/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.atmg/main.test.bicep index b1314bce14..e7d07330bf 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/windows.atmg/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/windows.atmg/main.test.bicep @@ -18,11 +18,8 @@ param serviceShort string = 'cvmwinatmg' @secure() param password string = newGuid() -@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') -param enableDefaultTelemetry bool = true - @description('Optional. A token to inject into the name of each resource.') -param namePrefix string = '[[namePrefix]]' +param namePrefix string = '#_namePrefix_#' // ============ // // Dependencies // @@ -50,9 +47,8 @@ module nestedDependencies 'dependencies.bicep' = { module testDeployment '../../../main.bicep' = { scope: resourceGroup - name: '${uniqueString(deployment().name, location)}-test-${serviceShort}' + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' params: { - enableDefaultTelemetry: enableDefaultTelemetry location: location name: '${namePrefix}${serviceShort}' adminUsername: 'localAdministrator' @@ -90,3 +86,4 @@ module testDeployment '../../../main.bicep' = { } } } + diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows.min/dependencies.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.defaults/dependencies.bicep similarity index 100% rename from avm/res/compute/virtual-machine/tests/e2e/windows.min/dependencies.bicep rename to avm/res/compute/virtual-machine/tests/e2e/windows.defaults/dependencies.bicep diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows.min/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.defaults/main.test.bicep similarity index 90% rename from avm/res/compute/virtual-machine/tests/e2e/windows.min/main.test.bicep rename to avm/res/compute/virtual-machine/tests/e2e/windows.defaults/main.test.bicep index 68c34d8494..57e5b468dd 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/windows.min/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/windows.defaults/main.test.bicep @@ -18,11 +18,8 @@ param serviceShort string = 'cvmwinmin' @secure() param password string = newGuid() -@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') -param enableDefaultTelemetry bool = true - @description('Optional. A token to inject into the name of each resource.') -param namePrefix string = '[[namePrefix]]' +param namePrefix string = '#_namePrefix_#' // ============ // // Dependencies // @@ -49,9 +46,8 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // module testDeployment '../../../main.bicep' = { scope: resourceGroup - name: '${uniqueString(deployment().name, location)}-test-${serviceShort}' + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' params: { - enableDefaultTelemetry: enableDefaultTelemetry location: location name: '${namePrefix}${serviceShort}' adminUsername: 'localAdminUser' @@ -83,3 +79,4 @@ module testDeployment '../../../main.bicep' = { adminPassword: password } } + diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows.ssecmk/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.ssecmk/main.test.bicep index ff7c06d244..f3bca018e3 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/windows.ssecmk/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/windows.ssecmk/main.test.bicep @@ -21,11 +21,8 @@ param password string = newGuid() @description('Generated. Used as a basis for unique resource names.') param baseTime string = utcNow('u') -@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') -param enableDefaultTelemetry bool = true - @description('Optional. A token to inject into the name of each resource.') -param namePrefix string = '[[namePrefix]]' +param namePrefix string = '#_namePrefix_#' // ============ // // Dependencies // @@ -55,9 +52,8 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // module testDeployment '../../../main.bicep' = { scope: resourceGroup - name: '${uniqueString(deployment().name, location)}-test-${serviceShort}' + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' params: { - enableDefaultTelemetry: enableDefaultTelemetry location: location name: '${namePrefix}${serviceShort}' adminUsername: 'VMAdministrator' @@ -108,3 +104,4 @@ module testDeployment '../../../main.bicep' = { } } } + diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows/main.test.bicep index 7bc8a2c00f..c83d294103 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/windows/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/windows/main.test.bicep @@ -18,11 +18,8 @@ param serviceShort string = 'cvmwincom' @secure() param password string = newGuid() -@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') -param enableDefaultTelemetry bool = true - @description('Optional. A token to inject into the name of each resource.') -param namePrefix string = '[[namePrefix]]' +param namePrefix string = '#_namePrefix_#' // ============ // // Dependencies // @@ -54,7 +51,7 @@ module nestedDependencies 'dependencies.bicep' = { // Diagnostics // =========== -module diagnosticDependencies '../../../../../.shared/.templates/diagnostic.dependencies.bicep' = { +module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/templates/diagnostic.dependencies.bicep' = { scope: resourceGroup name: '${uniqueString(deployment().name, location)}-diagnosticDependencies' params: { @@ -72,9 +69,8 @@ module diagnosticDependencies '../../../../../.shared/.templates/diagnostic.depe module testDeployment '../../../main.bicep' = { scope: resourceGroup - name: '${uniqueString(deployment().name, location)}-test-${serviceShort}' + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' params: { - enableDefaultTelemetry: enableDefaultTelemetry location: location name: '${namePrefix}${serviceShort}' computerName: '${namePrefix}winvm1' @@ -330,3 +326,4 @@ module testDeployment '../../../main.bicep' = { } } } + diff --git a/avm/res/compute/virtual-machine/version.json b/avm/res/compute/virtual-machine/version.json index 9ed3662aba..8def869ede 100644 --- a/avm/res/compute/virtual-machine/version.json +++ b/avm/res/compute/virtual-machine/version.json @@ -1,7 +1,7 @@ { - "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.6", - "pathFilters": [ - "./main.json" - ] + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.1", + "pathFilters": [ + "./main.json" + ] } From 3a740acd1a9621be2e574728b717c80447967882 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Wed, 6 Dec 2023 11:36:58 +0100 Subject: [PATCH 05/96] update folders and service name --- .../tests/e2e/linux.defaults/main.test.bicep | 3 +- .../{linux => linux.max}/dependencies.bicep | 0 .../e2e/{linux => linux.max}/main.test.bicep | 3 +- .../dependencies.bicep | 0 .../{windows => waf-aligned}/main.test.bicep | 3 +- .../e2e/windows.defaults/main.test.bicep | 3 +- .../tests/e2e/windows.max/dependencies.bicep | 310 +++++++++++++++++ .../tests/e2e/windows.max/main.test.bicep | 328 ++++++++++++++++++ 8 files changed, 642 insertions(+), 8 deletions(-) rename avm/res/compute/virtual-machine/tests/e2e/{linux => linux.max}/dependencies.bicep (100%) rename avm/res/compute/virtual-machine/tests/e2e/{linux => linux.max}/main.test.bicep (99%) rename avm/res/compute/virtual-machine/tests/e2e/{windows => waf-aligned}/dependencies.bicep (100%) rename avm/res/compute/virtual-machine/tests/e2e/{windows => waf-aligned}/main.test.bicep (99%) create mode 100644 avm/res/compute/virtual-machine/tests/e2e/windows.max/dependencies.bicep create mode 100644 avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep index ed72917bfe..512584def0 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep @@ -12,7 +12,7 @@ param resourceGroupName string = 'dep-${namePrefix}-compute.virtualMachines-${se 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 = 'cvmlinmin' +param serviceShort string = 'cvmlindef' @description('Optional. A token to inject into the name of each resource.') param namePrefix string = '#_namePrefix_#' @@ -96,4 +96,3 @@ module testDeployment '../../../main.bicep' = { nestedDependencies // Required to leverage `existing` SSH key reference ] } - diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux/dependencies.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.max/dependencies.bicep similarity index 100% rename from avm/res/compute/virtual-machine/tests/e2e/linux/dependencies.bicep rename to avm/res/compute/virtual-machine/tests/e2e/linux.max/dependencies.bicep diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep similarity index 99% rename from avm/res/compute/virtual-machine/tests/e2e/linux/main.test.bicep rename to avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep index 7e883b74a5..b0f05bf96c 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/linux/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep @@ -12,7 +12,7 @@ param resourceGroupName string = 'dep-${namePrefix}-compute.virtualMachines-${se 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 = 'cvmlincom' +param serviceShort string = 'cvmlinmax' @description('Optional. A token to inject into the name of each resource.') param namePrefix string = '#_namePrefix_#' @@ -308,4 +308,3 @@ module testDeployment '../../../main.bicep' = { nestedDependencies // Required to leverage `existing` SSH key reference ] } - diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows/dependencies.bicep b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/dependencies.bicep similarity index 100% rename from avm/res/compute/virtual-machine/tests/e2e/windows/dependencies.bicep rename to avm/res/compute/virtual-machine/tests/e2e/waf-aligned/dependencies.bicep diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep similarity index 99% rename from avm/res/compute/virtual-machine/tests/e2e/windows/main.test.bicep rename to avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep index c83d294103..8878339bfc 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/windows/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep @@ -12,7 +12,7 @@ param resourceGroupName string = 'dep-${namePrefix}-compute.virtualMachines-${se 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 = 'cvmwincom' +param serviceShort string = 'cvmwinwaf' @description('Optional. The password to leverage for the login.') @secure() @@ -326,4 +326,3 @@ module testDeployment '../../../main.bicep' = { } } } - diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows.defaults/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.defaults/main.test.bicep index 57e5b468dd..b3ba0e594f 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/windows.defaults/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/windows.defaults/main.test.bicep @@ -12,7 +12,7 @@ param resourceGroupName string = 'dep-${namePrefix}-compute.virtualMachines-${se 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 = 'cvmwinmin' +param serviceShort string = 'cvmwindef' @description('Optional. The password to leverage for the login.') @secure() @@ -79,4 +79,3 @@ module testDeployment '../../../main.bicep' = { adminPassword: password } } - diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows.max/dependencies.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.max/dependencies.bicep new file mode 100644 index 0000000000..6a1f5fcc13 --- /dev/null +++ b/avm/res/compute/virtual-machine/tests/e2e/windows.max/dependencies.bicep @@ -0,0 +1,310 @@ +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +@description('Required. The name of the Application Security Group to create.') +param applicationSecurityGroupName string + +@description('Required. The name of the Managed Identity to create.') +param managedIdentityName string + +@description('Required. The name of the Load Balancer to create.') +param loadBalancerName string + +@description('Required. The name of the Recovery Services Vault to create.') +param recoveryServicesVaultName string + +@description('Required. The name of the Key Vault to create.') +param keyVaultName string + +@description('Required. The name of the Storage Account to create.') +param storageAccountName string + +@description('Required. The name of the Deployment Script used to upload data to the Storage Account.') +param storageUploadDeploymentScriptName string + +@description('Required. The name of the Proximity Placement Group to create.') +param proximityPlacementGroupName string + +@description('Optional. The location to deploy resources to.') +param location string = resourceGroup().location + +var storageAccountCSEFileName = 'scriptExtensionMasterInstaller.ps1' +var addressPrefix = '10.0.0.0/16' + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + } + } + ] + } +} + +resource applicationSecurityGroup 'Microsoft.Network/applicationSecurityGroups@2023-04-01' = { + name: applicationSecurityGroupName + location: location +} + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: location +} + +resource msiRGContrRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(resourceGroup().id, 'Contributor', managedIdentity.id) + scope: resourceGroup() + properties: { + principalId: managedIdentity.properties.principalId + roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor + principalType: 'ServicePrincipal' + } +} + +resource loadBalancer 'Microsoft.Network/loadBalancers@2023-04-01' = { + name: loadBalancerName + location: location + sku: { + name: 'Standard' + } + properties: { + frontendIPConfigurations: [ + { + name: 'privateIPConfig1' + properties: { + subnet: virtualNetwork.properties.subnets[0] + } + } + ] + backendAddressPools: [ + { + name: 'servers' + } + ] + } +} + +resource recoveryServicesVault 'Microsoft.RecoveryServices/vaults@2022-04-01' = { + name: recoveryServicesVaultName + location: location + sku: { + name: 'RS0' + tier: 'Standard' + } + properties: {} + + resource backupPolicy 'backupPolicies@2022-03-01' = { + name: 'backupPolicy' + properties: { + backupManagementType: 'AzureIaasVM' + instantRPDetails: {} + schedulePolicy: { + schedulePolicyType: 'SimpleSchedulePolicy' + scheduleRunFrequency: 'Daily' + scheduleRunTimes: [ + '2019-11-07T07:00:00Z' + ] + scheduleWeeklyFrequency: 0 + } + retentionPolicy: { + retentionPolicyType: 'LongTermRetentionPolicy' + dailySchedule: { + retentionTimes: [ + '2019-11-07T07:00:00Z' + ] + retentionDuration: { + count: 180 + durationType: 'Days' + } + } + weeklySchedule: { + daysOfTheWeek: [ + 'Sunday' + ] + retentionTimes: [ + '2019-11-07T07:00:00Z' + ] + retentionDuration: { + count: 12 + durationType: 'Weeks' + } + } + monthlySchedule: { + retentionScheduleFormatType: 'Weekly' + retentionScheduleWeekly: { + daysOfTheWeek: [ + 'Sunday' + ] + weeksOfTheMonth: [ + 'First' + ] + } + retentionTimes: [ + '2019-11-07T07:00:00Z' + ] + retentionDuration: { + count: 60 + durationType: 'Months' + } + } + yearlySchedule: { + retentionScheduleFormatType: 'Weekly' + monthsOfYear: [ + 'January' + ] + retentionScheduleWeekly: { + daysOfTheWeek: [ + 'Sunday' + ] + weeksOfTheMonth: [ + 'First' + ] + } + retentionTimes: [ + '2019-11-07T07:00:00Z' + ] + retentionDuration: { + count: 10 + durationType: 'Years' + } + } + } + instantRpRetentionRangeInDays: 2 + timeZone: 'UTC' + protectedItemsCount: 0 + } + } +} + +resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = { + name: keyVaultName + location: location + properties: { + sku: { + family: 'A' + name: 'standard' + } + tenantId: tenant().tenantId + enablePurgeProtection: null + enabledForTemplateDeployment: true + enabledForDiskEncryption: true + enabledForDeployment: true + enableRbacAuthorization: true + accessPolicies: [] + } + + resource key 'keys@2022-07-01' = { + name: 'encryptionKey' + properties: { + kty: 'RSA' + } + } +} + +resource msiKVReadRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid('msi-${keyVault::key.id}-${location}-${managedIdentity.id}-KeyVault-Key-Read-RoleAssignment') + scope: keyVault::key + properties: { + principalId: managedIdentity.properties.principalId + roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') // Key Vault Crypto User + principalType: 'ServicePrincipal' + } +} + +resource storageAccount 'Microsoft.Storage/storageAccounts@2021-09-01' = { + name: storageAccountName + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' + + resource blobService 'blobServices@2021-09-01' = { + name: 'default' + + resource container 'containers@2021-09-01' = { + name: 'scripts' + } + } +} + +resource storageUpload 'Microsoft.Resources/deploymentScripts@2020-10-01' = { + name: storageUploadDeploymentScriptName + location: location + kind: 'AzurePowerShell' + identity: { + type: 'UserAssigned' + userAssignedIdentities: { + '${managedIdentity.id}': {} + } + } + properties: { + azPowerShellVersion: '9.0' + retentionInterval: 'P1D' + arguments: '-StorageAccountName "${storageAccount.name}" -ResourceGroupName "${resourceGroup().name}" -ContainerName "${storageAccount::blobService::container.name}" -FileName "${storageAccountCSEFileName}"' + scriptContent: loadTextContent('../../../../../.shared/.scripts/Set-BlobContent.ps1') + } + dependsOn: [ + msiRGContrRoleAssignment + ] +} + +resource proximityPlacementGroup 'Microsoft.Compute/proximityPlacementGroups@2022-03-01' = { + name: proximityPlacementGroupName + location: location +} + +@description('The resource ID of the created Virtual Network Subnet.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id + +@description('The resource ID of the created Application Security Group.') +output applicationSecurityGroupResourceId string = applicationSecurityGroup.id + +@description('The principal ID of the created Managed Identity.') +output managedIdentityPrincipalId string = managedIdentity.properties.principalId + +@description('The resource ID of the created Managed Identity.') +output managedIdentityResourceId string = managedIdentity.id + +@description('The resource ID of the created Load Balancer Backend Pool.') +output loadBalancerBackendPoolResourceId string = loadBalancer.properties.backendAddressPools[0].id + +@description('The name of the created Recovery Services Vault.') +output recoveryServicesVaultName string = recoveryServicesVault.name + +@description('The name of the Resource Group, the Recovery Services Vault was created in.') +output recoveryServicesVaultResourceGroupName string = resourceGroup().name + +@description('The name of the Backup Policy created in the Backup Recovery Vault.') +output recoveryServicesVaultBackupPolicyName string = recoveryServicesVault::backupPolicy.name + +@description('The resource ID of the created Key Vault.') +output keyVaultResourceId string = keyVault.id + +@description('The URL of the created Key Vault.') +output keyVaultUrl string = keyVault.properties.vaultUri + +@description('The URL of the created Key Vault Encryption Key.') +output keyVaultEncryptionKeyUrl string = keyVault::key.properties.keyUriWithVersion + +@description('The resource ID of the created Storage Account.') +output storageAccountResourceId string = storageAccount.id + +@description('The name of the Custom Script Extension in the created Storage Account.') +output storageAccountCSEFileName string = storageAccountCSEFileName + +@description('The URL of the Custom Script Extension in the created Storage Account') +output storageAccountCSEFileUrl string = '${storageAccount.properties.primaryEndpoints.blob}${storageAccount::blobService::container.name}/${storageAccountCSEFileName}' + +@description('The resource ID of the created Proximity Placement Group.') +output proximityPlacementGroupResourceId string = proximityPlacementGroup.id diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep new file mode 100644 index 0000000000..89ae07105b --- /dev/null +++ b/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep @@ -0,0 +1,328 @@ +targetScope = 'subscription' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-compute.virtualMachines-${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 = 'cvmwinmax' + +@description('Optional. The password to leverage for the login.') +@secure() +param password string = newGuid() + +@description('Optional. A token to inject into the name of each resource.') +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: { + location: location + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + applicationSecurityGroupName: 'dep-${namePrefix}-asg-${serviceShort}' + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}' + loadBalancerName: 'dep-${namePrefix}-lb-${serviceShort}' + recoveryServicesVaultName: 'dep-${namePrefix}-rsv-${serviceShort}' + storageAccountName: 'dep${namePrefix}sa${serviceShort}01' + storageUploadDeploymentScriptName: 'dep-${namePrefix}-sads-${serviceShort}' + proximityPlacementGroupName: 'dep-${namePrefix}-ppg-${serviceShort}' + } +} + +// Diagnostics +// =========== +module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/templates/diagnostic.dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-diagnosticDependencies' + params: { + storageAccountName: 'dep${namePrefix}diasa${serviceShort}01' + logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' + eventHubNamespaceEventHubName: 'dep-${namePrefix}-evh-${serviceShort}' + eventHubNamespaceName: 'dep-${namePrefix}-evhns-${serviceShort}' + location: location + } +} + +// ============== // +// Test Execution // +// ============== // + +module testDeployment '../../../main.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' + params: { + location: location + name: '${namePrefix}${serviceShort}' + computerName: '${namePrefix}winvm1' + adminUsername: 'VMAdmin' + imageReference: { + publisher: 'MicrosoftWindowsServer' + offer: 'WindowsServer' + sku: '2019-datacenter' + version: 'latest' + } + nicConfigurations: [ + { + deleteOption: 'Delete' + ipConfigurations: [ + { + applicationSecurityGroups: [ + { + id: nestedDependencies.outputs.applicationSecurityGroupResourceId + } + ] + loadBalancerBackendAddressPools: [ + { + id: nestedDependencies.outputs.loadBalancerBackendPoolResourceId + } + ] + name: 'ipconfig01' + pipConfiguration: { + publicIpNameSuffix: '-pip-01' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + } + zones: [ + '1' + '2' + '3' + ] + subnetResourceId: nestedDependencies.outputs.subnetResourceId + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + } + ] + nicSuffix: '-nic-01' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + } + ] + osDisk: { + caching: 'None' + createOption: 'fromImage' + deleteOption: 'Delete' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + osType: 'Windows' + vmSize: 'Standard_DS2_v2' + adminPassword: password + availabilityZone: 2 + backupPolicyName: nestedDependencies.outputs.recoveryServicesVaultBackupPolicyName + backupVaultName: nestedDependencies.outputs.recoveryServicesVaultName + backupVaultResourceGroup: nestedDependencies.outputs.recoveryServicesVaultResourceGroupName + dataDisks: [ + { + caching: 'None' + createOption: 'Empty' + deleteOption: 'Delete' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + { + caching: 'None' + createOption: 'Empty' + deleteOption: 'Delete' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + ] + enableAutomaticUpdates: true + patchMode: 'AutomaticByPlatform' + encryptionAtHost: false + extensionAntiMalwareConfig: { + enabled: true + settings: { + AntimalwareEnabled: 'true' + Exclusions: { + Extensions: '.ext1;.ext2' + Paths: 'c:\\excluded-path-1;c:\\excluded-path-2' + Processes: 'excludedproc1.exe;excludedproc2.exe' + } + RealtimeProtectionEnabled: 'true' + ScheduledScanSettings: { + day: '7' + isEnabled: 'true' + scanType: 'Quick' + time: '120' + } + } + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + extensionCustomScriptConfig: { + enabled: true + fileData: [ + { + storageAccountId: nestedDependencies.outputs.storageAccountResourceId + uri: nestedDependencies.outputs.storageAccountCSEFileUrl + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + extensionCustomScriptProtectedSetting: { + commandToExecute: 'powershell -ExecutionPolicy Unrestricted -Command "& ./${nestedDependencies.outputs.storageAccountCSEFileName}"' + } + extensionDependencyAgentConfig: { + enabled: true + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + extensionAzureDiskEncryptionConfig: { + enabled: true + settings: { + EncryptionOperation: 'EnableEncryption' + KekVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + KeyEncryptionAlgorithm: 'RSA-OAEP' + KeyEncryptionKeyURL: nestedDependencies.outputs.keyVaultEncryptionKeyUrl + KeyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + KeyVaultURL: nestedDependencies.outputs.keyVaultUrl + ResizeOSDisk: 'false' + VolumeType: 'All' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + } + extensionAadJoinConfig: { + enabled: true + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + extensionDSCConfig: { + enabled: true + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + extensionMonitoringAgentConfig: { + enabled: true + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + extensionNetworkWatcherAgentConfig: { + enabled: true + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + monitoringWorkspaceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + proximityPlacementGroupResourceId: nestedDependencies.outputs.proximityPlacementGroupResourceId + roleAssignments: [ + { + roleDefinitionIdOrName: 'Owner' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] + } + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } +} From 048ebd0fa485102b2330437ec222f87a42e9ff93 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Wed, 6 Dec 2023 14:08:44 +0100 Subject: [PATCH 06/96] fix path --- .../virtual-machine/tests/e2e/linux.atmg/dependencies.bicep | 2 +- .../virtual-machine/tests/e2e/linux.defaults/dependencies.bicep | 2 +- .../virtual-machine/tests/e2e/linux.max/dependencies.bicep | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux.atmg/dependencies.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.atmg/dependencies.bicep index d8b2e100e0..fe37b069fa 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/linux.atmg/dependencies.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/linux.atmg/dependencies.bicep @@ -64,7 +64,7 @@ resource sshDeploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' azPowerShellVersion: '9.0' retentionInterval: 'P1D' arguments: ' -SSHKeyName "${sshKeyName}" -ResourceGroupName "${resourceGroup().name}"' - scriptContent: loadTextContent('../../../../../.shared/.scripts/New-SSHKey.ps1') + scriptContent: loadTextContent('../../../../../../utilities/e2e-template-assets/scripts/New-SSHKey.ps1') } dependsOn: [ msiRGContrRoleAssignment diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/dependencies.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/dependencies.bicep index c88f2b1230..023a59cca3 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/dependencies.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/dependencies.bicep @@ -64,7 +64,7 @@ resource sshDeploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' azPowerShellVersion: '9.0' retentionInterval: 'P1D' arguments: '-SSHKeyName "${sshKeyName}" -ResourceGroupName "${resourceGroup().name}"' - scriptContent: loadTextContent('../../../../../.shared/.scripts/New-SSHKey.ps1') + scriptContent: loadTextContent('../../../../../../utilities/e2e-template-assets/scripts/New-SSHKey.ps1') } dependsOn: [ msiRGContrRoleAssignment diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux.max/dependencies.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.max/dependencies.bicep index 4dbd74b07b..08611161cb 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/linux.max/dependencies.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/linux.max/dependencies.bicep @@ -276,7 +276,7 @@ resource sshDeploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' azPowerShellVersion: '9.0' retentionInterval: 'P1D' arguments: '-SSHKeyName "${sshKeyName}" -ResourceGroupName "${resourceGroup().name}"' - scriptContent: loadTextContent('../../../../../.shared/.scripts/New-SSHKey.ps1') + scriptContent: loadTextContent('../../../../../../utilities/e2e-template-assets/scripts/New-SSHKey.ps1') } dependsOn: [ msiRGContrRoleAssignment From 99ce15358db819b0e975df3dca040312b60d42fa Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Wed, 6 Dec 2023 14:33:31 +0100 Subject: [PATCH 07/96] fix path --- .../virtual-machine/tests/e2e/linux.max/dependencies.bicep | 2 +- .../virtual-machine/tests/e2e/waf-aligned/dependencies.bicep | 2 +- .../virtual-machine/tests/e2e/windows.max/dependencies.bicep | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux.max/dependencies.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.max/dependencies.bicep index 08611161cb..f748f995d5 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/linux.max/dependencies.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/linux.max/dependencies.bicep @@ -255,7 +255,7 @@ resource storageUpload 'Microsoft.Resources/deploymentScripts@2020-10-01' = { azPowerShellVersion: '9.0' retentionInterval: 'P1D' arguments: '-StorageAccountName "${storageAccount.name}" -ResourceGroupName "${resourceGroup().name}" -ContainerName "${storageAccount::blobService::container.name}" -FileName "${storageAccountCSEFileName}"' - scriptContent: loadTextContent('../../../../../.shared/.scripts/Set-BlobContent.ps1') + scriptContent: loadTextContent('../../../../../../utilities/e2e-template-assets/scripts/Set-BlobContent.ps1') } dependsOn: [ msiRGContrRoleAssignment diff --git a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/dependencies.bicep index 6a1f5fcc13..e198bcd227 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/dependencies.bicep @@ -252,7 +252,7 @@ resource storageUpload 'Microsoft.Resources/deploymentScripts@2020-10-01' = { azPowerShellVersion: '9.0' retentionInterval: 'P1D' arguments: '-StorageAccountName "${storageAccount.name}" -ResourceGroupName "${resourceGroup().name}" -ContainerName "${storageAccount::blobService::container.name}" -FileName "${storageAccountCSEFileName}"' - scriptContent: loadTextContent('../../../../../.shared/.scripts/Set-BlobContent.ps1') + scriptContent: loadTextContent('../../../../../../utilities/e2e-template-assets/scripts/Set-BlobContent.ps1') } dependsOn: [ msiRGContrRoleAssignment diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows.max/dependencies.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.max/dependencies.bicep index 6a1f5fcc13..e198bcd227 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/windows.max/dependencies.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/windows.max/dependencies.bicep @@ -252,7 +252,7 @@ resource storageUpload 'Microsoft.Resources/deploymentScripts@2020-10-01' = { azPowerShellVersion: '9.0' retentionInterval: 'P1D' arguments: '-StorageAccountName "${storageAccount.name}" -ResourceGroupName "${resourceGroup().name}" -ContainerName "${storageAccount::blobService::container.name}" -FileName "${storageAccountCSEFileName}"' - scriptContent: loadTextContent('../../../../../.shared/.scripts/Set-BlobContent.ps1') + scriptContent: loadTextContent('../../../../../../utilities/e2e-template-assets/scripts/Set-BlobContent.ps1') } dependsOn: [ msiRGContrRoleAssignment From 6585221dbd04b88413597664e3981578fff46561 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Wed, 6 Dec 2023 14:54:44 +0100 Subject: [PATCH 08/96] add iteration --- .../virtual-machine/tests/e2e/linux.atmg/main.test.bicep | 6 +++--- .../tests/e2e/linux.defaults/main.test.bicep | 5 +++-- .../virtual-machine/tests/e2e/linux.max/main.test.bicep | 5 +++-- .../virtual-machine/tests/e2e/waf-aligned/main.test.bicep | 5 +++-- .../virtual-machine/tests/e2e/windows.atmg/main.test.bicep | 6 +++--- .../tests/e2e/windows.defaults/main.test.bicep | 5 +++-- .../virtual-machine/tests/e2e/windows.max/main.test.bicep | 5 +++-- .../tests/e2e/windows.ssecmk/main.test.bicep | 6 +++--- 8 files changed, 24 insertions(+), 19 deletions(-) diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux.atmg/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.atmg/main.test.bicep index 30d62270aa..38b372c561 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/linux.atmg/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/linux.atmg/main.test.bicep @@ -49,7 +49,8 @@ module nestedDependencies 'dependencies.bicep' = { // scope: resourceGroup // } -module testDeployment '../../../main.bicep' = { +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { scope: resourceGroup name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' params: { @@ -116,5 +117,4 @@ module testDeployment '../../../main.bicep' = { dependsOn: [ nestedDependencies // Required to leverage `existing` SSH key reference ] -} - +}] diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep index 512584def0..0c29de18d5 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep @@ -49,7 +49,8 @@ module nestedDependencies 'dependencies.bicep' = { // scope: resourceGroup // } -module testDeployment '../../../main.bicep' = { +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { scope: resourceGroup name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' params: { @@ -95,4 +96,4 @@ module testDeployment '../../../main.bicep' = { dependsOn: [ nestedDependencies // Required to leverage `existing` SSH key reference ] -} +}] diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep index b0f05bf96c..6d3230629b 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep @@ -64,7 +64,8 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // Test Execution // // ============== // -module testDeployment '../../../main.bicep' = { +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { scope: resourceGroup name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' params: { @@ -307,4 +308,4 @@ module testDeployment '../../../main.bicep' = { dependsOn: [ nestedDependencies // Required to leverage `existing` SSH key reference ] -} +}] diff --git a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep index 8878339bfc..f5eeab7b8a 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep @@ -67,7 +67,8 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // Test Execution // // ============== // -module testDeployment '../../../main.bicep' = { +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { scope: resourceGroup name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' params: { @@ -325,4 +326,4 @@ module testDeployment '../../../main.bicep' = { Role: 'DeploymentValidation' } } -} +}] diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows.atmg/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.atmg/main.test.bicep index e7d07330bf..d246dc04ba 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/windows.atmg/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/windows.atmg/main.test.bicep @@ -45,7 +45,8 @@ module nestedDependencies 'dependencies.bicep' = { // Test Execution // // ============== // -module testDeployment '../../../main.bicep' = { +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { scope: resourceGroup name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' params: { @@ -85,5 +86,4 @@ module testDeployment '../../../main.bicep' = { Role: 'DeploymentValidation' } } -} - +}] diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows.defaults/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.defaults/main.test.bicep index b3ba0e594f..60c2365479 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/windows.defaults/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/windows.defaults/main.test.bicep @@ -44,7 +44,8 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // // Test Execution // // ============== // -module testDeployment '../../../main.bicep' = { +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { scope: resourceGroup name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' params: { @@ -78,4 +79,4 @@ module testDeployment '../../../main.bicep' = { vmSize: 'Standard_DS2_v2' adminPassword: password } -} +}] diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep index 89ae07105b..cb89e67798 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep @@ -67,7 +67,8 @@ module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/t // Test Execution // // ============== // -module testDeployment '../../../main.bicep' = { +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { scope: resourceGroup name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' params: { @@ -325,4 +326,4 @@ module testDeployment '../../../main.bicep' = { Role: 'DeploymentValidation' } } -} +}] diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows.ssecmk/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.ssecmk/main.test.bicep index f3bca018e3..41cced4df4 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/windows.ssecmk/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/windows.ssecmk/main.test.bicep @@ -50,7 +50,8 @@ module nestedDependencies 'dependencies.bicep' = { // ============== // // Test Execution // // ============== // -module testDeployment '../../../main.bicep' = { +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { scope: resourceGroup name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' params: { @@ -103,5 +104,4 @@ module testDeployment '../../../main.bicep' = { Role: 'DeploymentValidation' } } -} - +}] From 44e61356a22a943619a8bf1cf385ef8791dfdec1 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Wed, 6 Dec 2023 15:07:37 +0100 Subject: [PATCH 09/96] add metadata to tests --- .../virtual-machine/tests/e2e/linux.defaults/main.test.bicep | 3 +++ .../virtual-machine/tests/e2e/linux.max/main.test.bicep | 3 +++ .../virtual-machine/tests/e2e/waf-aligned/main.test.bicep | 3 +++ .../virtual-machine/tests/e2e/windows.defaults/main.test.bicep | 3 +++ .../virtual-machine/tests/e2e/windows.max/main.test.bicep | 3 +++ 5 files changed, 15 insertions(+) diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep index 0c29de18d5..9009f7baaa 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep @@ -1,5 +1,8 @@ targetScope = 'subscription' +metadata name = 'Using only defaults' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' + // ========== // // Parameters // // ========== // diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep index 6d3230629b..1ab524b9f3 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep @@ -1,5 +1,8 @@ targetScope = 'subscription' +metadata name = 'Using large parameter set' +metadata description = 'This instance deploys the module with most of its features enabled.' + // ========== // // Parameters // // ========== // diff --git a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep index f5eeab7b8a..80cff1e036 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep @@ -1,5 +1,8 @@ targetScope = 'subscription' +metadata name = 'WAF-aligned' +metadata description = 'This instance deploys the module in alignment with the best-practices of the Well-Architected Framework.' + // ========== // // Parameters // // ========== // diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows.defaults/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.defaults/main.test.bicep index 60c2365479..59a9c66b6a 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/windows.defaults/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/windows.defaults/main.test.bicep @@ -1,5 +1,8 @@ targetScope = 'subscription' +metadata name = 'Using only defaults' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' + // ========== // // Parameters // // ========== // diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep index cb89e67798..1b012ebcab 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep @@ -1,5 +1,8 @@ targetScope = 'subscription' +metadata name = 'Using large parameter set' +metadata description = 'This instance deploys the module with most of its features enabled.' + // ========== // // Parameters // // ========== // From fc15f60b8ce15573fa534cfeaba8419cacb6ec70 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Wed, 6 Dec 2023 15:21:34 +0100 Subject: [PATCH 10/96] use NIC module --- avm/res/compute/virtual-machine/main.bicep | 51 +++--- .../modules/nested_networkInterface.bicep | 147 ------------------ 2 files changed, 25 insertions(+), 173 deletions(-) delete mode 100644 avm/res/compute/virtual-machine/modules/nested_networkInterface.bicep diff --git a/avm/res/compute/virtual-machine/main.bicep b/avm/res/compute/virtual-machine/main.bicep index f908e4b473..5e0fad537a 100644 --- a/avm/res/compute/virtual-machine/main.bicep +++ b/avm/res/compute/virtual-machine/main.bicep @@ -337,11 +337,10 @@ resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (ena } } -module vm_nic 'modules/nested_networkInterface.bicep' = [for (nicConfiguration, index) in nicConfigurations: { +module vm_nic '../../network/network-interface/main.bicep' = [for (nicConfiguration, index) in nicConfigurations: { name: '${uniqueString(deployment().name, location)}-VM-Nic-${index}' params: { - networkInterfaceName: '${name}${nicConfiguration.nicSuffix}' - virtualMachineName: name + name: '${name}${nicConfiguration.nicSuffix}' location: location enableIPForwarding: contains(nicConfiguration, 'enableIPForwarding') ? (!empty(nicConfiguration.enableIPForwarding) ? nicConfiguration.enableIPForwarding : false) : false enableAcceleratedNetworking: contains(nicConfiguration, 'enableAcceleratedNetworking') ? nicConfiguration.enableAcceleratedNetworking : true @@ -627,29 +626,29 @@ module vm_azureDiskEncryptionExtension 'extension/main.bicep' = if (extensionAzu ] } -module vm_backup '../../recovery-services/vault/backup-fabric/protection-container/protected-item/main.bicep' = if (!empty(backupVaultName)) { - name: '${uniqueString(deployment().name, location)}-VM-Backup' - params: { - name: 'vm;iaasvmcontainerv2;${resourceGroup().name};${vm.name}' - policyId: az.resourceId('Microsoft.RecoveryServices/vaults/backupPolicies', backupVaultName, backupPolicyName) - protectedItemType: 'Microsoft.Compute/virtualMachines' - protectionContainerName: 'iaasvmcontainer;iaasvmcontainerv2;${resourceGroup().name};${vm.name}' - recoveryVaultName: backupVaultName - sourceResourceId: vm.id - enableDefaultTelemetry: enableReferencedModulesTelemetry - } - scope: az.resourceGroup(backupVaultResourceGroup) - dependsOn: [ - vm_aadJoinExtension - vm_domainJoinExtension - vm_microsoftMonitoringAgentExtension - vm_microsoftAntiMalwareExtension - vm_networkWatcherAgentExtension - vm_dependencyAgentExtension - vm_desiredStateConfigurationExtension - vm_customScriptExtension - ] -} +// module vm_backup '../../recovery-services/vault/backup-fabric/protection-container/protected-item/main.bicep' = if (!empty(backupVaultName)) { +// name: '${uniqueString(deployment().name, location)}-VM-Backup' +// params: { +// name: 'vm;iaasvmcontainerv2;${resourceGroup().name};${vm.name}' +// policyId: az.resourceId('Microsoft.RecoveryServices/vaults/backupPolicies', backupVaultName, backupPolicyName) +// protectedItemType: 'Microsoft.Compute/virtualMachines' +// protectionContainerName: 'iaasvmcontainer;iaasvmcontainerv2;${resourceGroup().name};${vm.name}' +// recoveryVaultName: backupVaultName +// sourceResourceId: vm.id +// enableDefaultTelemetry: enableReferencedModulesTelemetry +// } +// scope: az.resourceGroup(backupVaultResourceGroup) +// dependsOn: [ +// vm_aadJoinExtension +// vm_domainJoinExtension +// vm_microsoftMonitoringAgentExtension +// vm_microsoftAntiMalwareExtension +// vm_networkWatcherAgentExtension +// vm_dependencyAgentExtension +// vm_desiredStateConfigurationExtension +// vm_customScriptExtension +// ] +// } resource vm_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock ?? {}) && lock.?kind != 'None') { name: lock.?name ?? 'lock-${name}' diff --git a/avm/res/compute/virtual-machine/modules/nested_networkInterface.bicep b/avm/res/compute/virtual-machine/modules/nested_networkInterface.bicep deleted file mode 100644 index a7e44aaf79..0000000000 --- a/avm/res/compute/virtual-machine/modules/nested_networkInterface.bicep +++ /dev/null @@ -1,147 +0,0 @@ -param networkInterfaceName string -param virtualMachineName string -param location string -param tags object? -param enableIPForwarding bool = false -param enableAcceleratedNetworking bool = false -param dnsServers array = [] - -@description('Optional. The network security group (NSG) to attach to the network interface.') -param networkSecurityGroupResourceId string = '' - -param ipConfigurations array -param lock lockType - -@description('Optional. The diagnostic settings of the Network Interface.') -param diagnosticSettings diagnosticSettingType - -@description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType - -var enableReferencedModulesTelemetry = false - -module networkInterface_publicIPAddresses '../../../network/public-ip-address/main.bicep' = [for (ipConfiguration, index) in ipConfigurations: if (contains(ipConfiguration, 'pipconfiguration')) { - name: '${deployment().name}-publicIP-${index}' - params: { - name: '${virtualMachineName}${ipConfiguration.pipconfiguration.publicIpNameSuffix}' - diagnosticSettings: ipConfiguration.?diagnosticSettings - location: location - lock: lock - publicIPAddressVersion: contains(ipConfiguration, 'publicIPAddressVersion') ? ipConfiguration.publicIPAddressVersion : 'IPv4' - publicIPAllocationMethod: contains(ipConfiguration, 'publicIPAllocationMethod') ? ipConfiguration.publicIPAllocationMethod : 'Static' - publicIPPrefixResourceId: contains(ipConfiguration, 'publicIPPrefixResourceId') ? ipConfiguration.publicIPPrefixResourceId : '' - roleAssignments: contains(ipConfiguration, 'roleAssignments') ? ipConfiguration.roleAssignments : [] - skuName: contains(ipConfiguration, 'skuName') ? ipConfiguration.skuName : 'Standard' - skuTier: contains(ipConfiguration, 'skuTier') ? ipConfiguration.skuTier : 'Regional' - tags: ipConfiguration.?tags ?? tags - zones: contains(ipConfiguration, 'zones') ? ipConfiguration.zones : [] - } -}] - -module networkInterface '../../../network/network-interface/main.bicep' = { - name: '${deployment().name}-NetworkInterface' - params: { - name: networkInterfaceName - ipConfigurations: [for (ipConfiguration, index) in ipConfigurations: { - name: !empty(ipConfiguration.name) ? ipConfiguration.name : null - primary: index == 0 - privateIPAllocationMethod: contains(ipConfiguration, 'privateIPAllocationMethod') ? (!empty(ipConfiguration.privateIPAllocationMethod) ? ipConfiguration.privateIPAllocationMethod : null) : null - privateIPAddress: contains(ipConfiguration, 'privateIPAddress') ? (!empty(ipConfiguration.privateIPAddress) ? ipConfiguration.privateIPAddress : null) : null - publicIPAddressResourceId: contains(ipConfiguration, 'pipconfiguration') ? resourceId('Microsoft.Network/publicIPAddresses', '${virtualMachineName}${ipConfiguration.pipconfiguration.publicIpNameSuffix}') : null - subnetResourceId: ipConfiguration.subnetResourceId - loadBalancerBackendAddressPools: contains(ipConfiguration, 'loadBalancerBackendAddressPools') ? ipConfiguration.loadBalancerBackendAddressPools : null - applicationSecurityGroups: contains(ipConfiguration, 'applicationSecurityGroups') ? ipConfiguration.applicationSecurityGroups : null - applicationGatewayBackendAddressPools: contains(ipConfiguration, 'applicationGatewayBackendAddressPools') ? ipConfiguration.applicationGatewayBackendAddressPools : null - gatewayLoadBalancer: contains(ipConfiguration, 'gatewayLoadBalancer') ? ipConfiguration.gatewayLoadBalancer : null - loadBalancerInboundNatRules: contains(ipConfiguration, 'loadBalancerInboundNatRules') ? ipConfiguration.loadBalancerInboundNatRules : null - privateIPAddressVersion: contains(ipConfiguration, 'privateIPAddressVersion') ? ipConfiguration.privateIPAddressVersion : null - virtualNetworkTaps: contains(ipConfiguration, 'virtualNetworkTaps') ? ipConfiguration.virtualNetworkTaps : null - }] - location: location - tags: tags - diagnosticSettings: diagnosticSettings - dnsServers: !empty(dnsServers) ? dnsServers : [] - enableAcceleratedNetworking: enableAcceleratedNetworking - enableDefaultTelemetry: enableReferencedModulesTelemetry - enableIPForwarding: enableIPForwarding - lock: lock - networkSecurityGroupResourceId: !empty(networkSecurityGroupResourceId) ? networkSecurityGroupResourceId : '' - roleAssignments: !empty(roleAssignments) ? roleAssignments : [] - } - dependsOn: [ - networkInterface_publicIPAddresses - ] -} - -// =============== // -// Definitions // -// =============== // - -type lockType = { - @description('Optional. Specify the name of lock.') - name: string? - - @description('Optional. Specify the type of lock.') - kind: ('CanNotDelete' | 'ReadOnly' | 'None')? -}? - -type diagnosticSettingType = { - @description('Optional. The name of diagnostic setting.') - name: string? - - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') - logCategoriesAndGroups: { - @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') - category: string? - - @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to llLogs to collect all logs.') - categoryGroup: string? - }[]? - - @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: { - @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to AllMetrics to collect all metrics.') - category: string - }[]? - - @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.') - logAnalyticsDestinationType: ('Dedicated' | 'AzureDiagnostics')? - - @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.') - workspaceResourceId: string? - - @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.') - storageAccountResourceId: string? - - @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.') - eventHubAuthorizationRuleResourceId: string? - - @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.') - eventHubName: string? - - @description('Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs.') - marketplacePartnerResourceId: string? -}[]? - -type roleAssignmentType = { - @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? -}[]? From adf84ef7ce00a80f2192fab399d89eda7e916cdc Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Wed, 6 Dec 2023 15:22:45 +0100 Subject: [PATCH 11/96] update location for extensions --- avm/res/compute/virtual-machine/main.bicep | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/avm/res/compute/virtual-machine/main.bicep b/avm/res/compute/virtual-machine/main.bicep index 5e0fad537a..308c636d7b 100644 --- a/avm/res/compute/virtual-machine/main.bicep +++ b/avm/res/compute/virtual-machine/main.bicep @@ -465,6 +465,7 @@ module vm_aadJoinExtension 'extension/main.bicep' = if (extensionAadJoinConfig.e params: { virtualMachineName: vm.name name: 'AADLogin' + location: location publisher: 'Microsoft.Azure.ActiveDirectory' type: osType == 'Windows' ? 'AADLoginForWindows' : 'AADSSHLoginforLinux' typeHandlerVersion: contains(extensionAadJoinConfig, 'typeHandlerVersion') ? extensionAadJoinConfig.typeHandlerVersion : '1.0' @@ -480,6 +481,7 @@ module vm_domainJoinExtension 'extension/main.bicep' = if (extensionDomainJoinCo params: { virtualMachineName: vm.name name: 'DomainJoin' + location: location publisher: 'Microsoft.Compute' type: 'JsonADDomainExtension' typeHandlerVersion: contains(extensionDomainJoinConfig, 'typeHandlerVersion') ? extensionDomainJoinConfig.typeHandlerVersion : '1.3' @@ -499,6 +501,7 @@ module vm_microsoftAntiMalwareExtension 'extension/main.bicep' = if (extensionAn params: { virtualMachineName: vm.name name: 'MicrosoftAntiMalware' + location: location publisher: 'Microsoft.Azure.Security' type: 'IaaSAntimalware' typeHandlerVersion: contains(extensionAntiMalwareConfig, 'typeHandlerVersion') ? extensionAntiMalwareConfig.typeHandlerVersion : '1.3' @@ -520,6 +523,7 @@ module vm_microsoftMonitoringAgentExtension 'extension/main.bicep' = if (extensi params: { virtualMachineName: vm.name name: 'MicrosoftMonitoringAgent' + location: location publisher: 'Microsoft.EnterpriseCloud.Monitoring' type: osType == 'Windows' ? 'MicrosoftMonitoringAgent' : 'OmsAgentForLinux' typeHandlerVersion: contains(extensionMonitoringAgentConfig, 'typeHandlerVersion') ? extensionMonitoringAgentConfig.typeHandlerVersion : (osType == 'Windows' ? '1.0' : '1.7') @@ -541,6 +545,7 @@ module vm_dependencyAgentExtension 'extension/main.bicep' = if (extensionDepende params: { virtualMachineName: vm.name name: 'DependencyAgent' + location: location publisher: 'Microsoft.Azure.Monitoring.DependencyAgent' type: osType == 'Windows' ? 'DependencyAgentWindows' : 'DependencyAgentLinux' typeHandlerVersion: contains(extensionDependencyAgentConfig, 'typeHandlerVersion') ? extensionDependencyAgentConfig.typeHandlerVersion : '9.5' @@ -556,6 +561,7 @@ module vm_networkWatcherAgentExtension 'extension/main.bicep' = if (extensionNet params: { virtualMachineName: vm.name name: 'NetworkWatcherAgent' + location: location publisher: 'Microsoft.Azure.NetworkWatcher' type: osType == 'Windows' ? 'NetworkWatcherAgentWindows' : 'NetworkWatcherAgentLinux' typeHandlerVersion: contains(extensionNetworkWatcherAgentConfig, 'typeHandlerVersion') ? extensionNetworkWatcherAgentConfig.typeHandlerVersion : '1.4' @@ -571,6 +577,7 @@ module vm_desiredStateConfigurationExtension 'extension/main.bicep' = if (extens params: { virtualMachineName: vm.name name: 'DesiredStateConfiguration' + location: location publisher: 'Microsoft.Powershell' type: 'DSC' typeHandlerVersion: contains(extensionDSCConfig, 'typeHandlerVersion') ? extensionDSCConfig.typeHandlerVersion : '2.77' @@ -588,6 +595,7 @@ module vm_customScriptExtension 'extension/main.bicep' = if (extensionCustomScri params: { virtualMachineName: vm.name name: 'CustomScriptExtension' + location: location publisher: osType == 'Windows' ? 'Microsoft.Compute' : 'Microsoft.Azure.Extensions' type: osType == 'Windows' ? 'CustomScriptExtension' : 'CustomScript' typeHandlerVersion: contains(extensionCustomScriptConfig, 'typeHandlerVersion') ? extensionCustomScriptConfig.typeHandlerVersion : (osType == 'Windows' ? '1.10' : '2.1') @@ -610,6 +618,7 @@ module vm_azureDiskEncryptionExtension 'extension/main.bicep' = if (extensionAzu params: { virtualMachineName: vm.name name: 'AzureDiskEncryption' + location: location publisher: 'Microsoft.Azure.Security' type: osType == 'Windows' ? 'AzureDiskEncryption' : 'AzureDiskEncryptionForLinux' typeHandlerVersion: contains(extensionAzureDiskEncryptionConfig, 'typeHandlerVersion') ? extensionAzureDiskEncryptionConfig.typeHandlerVersion : (osType == 'Windows' ? '2.2' : '1.1') From 058d7aa405461472d518c812f255f7352b9c834b Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Wed, 6 Dec 2023 15:50:08 +0100 Subject: [PATCH 12/96] remove .scripts folder --- .../.scripts/Copy-VhdToStorageAccount.ps1 | 123 ------------------ .../scripts/.scripts/Get-PairedRegion.ps1 | 32 ----- .../scripts/.scripts/New-SSHKey.ps1 | 40 ------ .../scripts/.scripts/Set-BlobContent.ps1 | 46 ------- .../.scripts/Set-CertificateInKeyVault.ps1 | 67 ---------- .../.scripts/Set-PfxCertificateInKeyVault.ps1 | 62 --------- .../scripts/.scripts/Start-ImageTemplate.ps1 | 79 ----------- 7 files changed, 449 deletions(-) delete mode 100644 avm/utilities/e2e-template-assets/scripts/.scripts/Copy-VhdToStorageAccount.ps1 delete mode 100644 avm/utilities/e2e-template-assets/scripts/.scripts/Get-PairedRegion.ps1 delete mode 100644 avm/utilities/e2e-template-assets/scripts/.scripts/New-SSHKey.ps1 delete mode 100644 avm/utilities/e2e-template-assets/scripts/.scripts/Set-BlobContent.ps1 delete mode 100644 avm/utilities/e2e-template-assets/scripts/.scripts/Set-CertificateInKeyVault.ps1 delete mode 100644 avm/utilities/e2e-template-assets/scripts/.scripts/Set-PfxCertificateInKeyVault.ps1 delete mode 100644 avm/utilities/e2e-template-assets/scripts/.scripts/Start-ImageTemplate.ps1 diff --git a/avm/utilities/e2e-template-assets/scripts/.scripts/Copy-VhdToStorageAccount.ps1 b/avm/utilities/e2e-template-assets/scripts/.scripts/Copy-VhdToStorageAccount.ps1 deleted file mode 100644 index 2a353dd74f..0000000000 --- a/avm/utilities/e2e-template-assets/scripts/.scripts/Copy-VhdToStorageAccount.ps1 +++ /dev/null @@ -1,123 +0,0 @@ -<# -.SYNOPSIS -Copy a VHD baked from a given Image Template to a given destination storage account blob container - -.DESCRIPTION -Copy a VHD baked from a given Image Template to a given destination storage account blob container - -.PARAMETER ImageTemplateName -Mandatory. The name of the Image Template - -.PARAMETER ImageTemplateResourceGroup -Mandatory. The resource group name of the Image Template - -.PARAMETER DestinationStorageAccountName -Mandatory. The name of the destination storage account - -.PARAMETER DestinationContainerName -Optional. The name of the existing destination blob container - -.PARAMETER VhdName -Optional. Specify a different name for the destination VHD file - -.PARAMETER WaitForComplete -Optional. Run the command synchronously. Wait for the completion of the copy. - -.EXAMPLE -./Copy-VhdToStorageAccount -ImageTemplateName 'vhd-img-template-001-2022-07-29-15-54-01' -ImageTemplateResourceGroup 'validation-rg' -DestinationStorageAccountName 'vhdstorage001' - -Copy a VHD created by Image Template 'vhd-img-template-001-2022-07-29-15-54-01' in resource group 'validation-rg' to destination storage account 'vhdstorage001' in blob container named 'vhds'. Save the VHD file as 'vhd-img-template-001-2022-07-29-15-54-01.vhd'. - -.EXAMPLE -./Copy-VhdToStorageAccount -ImageTemplateName 'vhd-img-template-001-2022-07-29-15-54-01' -ImageTemplateResourceGroup 'validation-rg' -DestinationStorageAccountName 'vhdstorage001' -VhdName 'vhd-img-template-001' -WaitForComplete - -Copy a VHD baked by Image Template 'vhd-img-template-001-2022-07-29-15-54-01' in resource group 'validation-rg' to destination storage account 'vhdstorage001' in a blob container named 'vhds' and wait for the completion of the copy. Save the VHD file as 'vhd-img-template-001.vhd'. -#> - -[CmdletBinding(SupportsShouldProcess)] -param ( - [Parameter(Mandatory = $true)] - [string] $ImageTemplateName, - - [Parameter(Mandatory = $true)] - [string] $ImageTemplateResourceGroup, - - [Parameter(Mandatory = $true)] - [string] $DestinationStorageAccountName, - - [Parameter(Mandatory = $false)] - [string] $DestinationContainerName = 'vhds', - - [Parameter(Mandatory = $false)] - [string] $VhdName = $ImageTemplateName, - - [Parameter(Mandatory = $false)] - [switch] $WaitForComplete -) - -begin { - Write-Debug ('{0} entered' -f $MyInvocation.MyCommand) - - # Install required modules - $currentVerbosePreference = $VerbosePreference - $VerbosePreference = 'SilentlyContinue' - $requiredModules = @( - 'Az.ImageBuilder', - 'Az.Storage' - ) - foreach ($moduleName in $requiredModules) { - if (-not ($installedModule = Get-Module $moduleName -ListAvailable)) { - Install-Module $moduleName -Repository 'PSGallery' -Force -Scope 'CurrentUser' - if ($installed = Get-Module -Name $moduleName -ListAvailable) { - Write-Verbose ('Installed module [{0}] with version [{1}]' -f $installed.Name, $installed.Version) -Verbose - } - } else { - Write-Verbose ('Module [{0}] already installed in version [{1}]' -f $installedModule[0].Name, $installedModule[0].Version) -Verbose - } - } - $VerbosePreference = $currentVerbosePreference -} - -process { - # Retrieving and initializing parameters before the blob copy - Write-Verbose 'Initializing source storage account parameters before the blob copy' -Verbose - Write-Verbose ('Retrieving source storage account from Image Template [{0}] in resource group [{1}]' -f $imageTemplateName, $imageTemplateResourceGroup) -Verbose - Get-InstalledModule - $imgtRunOutput = Get-AzImageBuilderTemplateRunOutput -ImageTemplateName $imageTemplateName -ResourceGroupName $imageTemplateResourceGroup | Where-Object ArtifactUri -NE $null - $sourceUri = $imgtRunOutput.ArtifactUri - $sourceStorageAccountName = $sourceUri.Split('//')[1].Split('.')[0] - $storageAccountList = Get-AzStorageAccount - $sourceStorageAccount = $storageAccountList | Where-Object StorageAccountName -EQ $sourceStorageAccountName - $sourceStorageAccountContext = $sourceStorageAccount.Context - $sourceStorageAccountRGName = $sourceStorageAccount.ResourceGroupName - Write-Verbose ('Retrieving artifact uri [{0}] stored in resource group [{1}]' -f $sourceUri, $sourceStorageAccountRGName) -Verbose - - Write-Verbose 'Initializing destination storage account parameters before the blob copy' -Verbose - $destinationStorageAccount = $storageAccountList | Where-Object StorageAccountName -EQ $destinationStorageAccountName - $destinationStorageAccountContext = $destinationStorageAccount.Context - $destinationBlobName = "$vhdName.vhd" - Write-Verbose ('Planning for destination blob name [{0}] in container [{1}] and storage account [{2}]' -f $destinationBlobName, $destinationContainerName, $destinationStorageAccountName) -Verbose - - # Copying the VHD to a destination blob container - $resourceActionInputObject = @{ - AbsoluteUri = $sourceUri - Context = $sourceStorageAccountContext - DestContext = $destinationStorageAccountContext - DestBlob = $destinationBlobName - DestContainer = $destinationContainerName - Force = $true - } - - if ($PSCmdlet.ShouldProcess('Storage blob copy of VHD [{0}]' -f $destinationBlobName, 'Start')) { - $destBlob = Start-AzStorageBlobCopy @resourceActionInputObject - Write-Verbose ('Copied/initialized copy of VHD from URI [{0}] to container [{1}] in storage account [{2}]' -f $sourceUri, $destinationContainerName, $destinationStorageAccountName) -Verbose - } - - if ($WaitForComplete) { - $destBlob | Get-AzStorageBlobCopyState -WaitForComplete - } -} - -end { - Write-Debug ('{0} exited' -f $MyInvocation.MyCommand) -} diff --git a/avm/utilities/e2e-template-assets/scripts/.scripts/Get-PairedRegion.ps1 b/avm/utilities/e2e-template-assets/scripts/.scripts/Get-PairedRegion.ps1 deleted file mode 100644 index 839bd27995..0000000000 --- a/avm/utilities/e2e-template-assets/scripts/.scripts/Get-PairedRegion.ps1 +++ /dev/null @@ -1,32 +0,0 @@ -<# -.SYNOPSIS -Gets the paired region (location) for a particular Azure region. - -.DESCRIPTION -Gets the paired region (location) for a particular Azure region. - -.PARAMETER Location -Mandatory. The name of the Azure region (i.e. AustraliaEast, australiaeast, Australia East) - -.EXAMPLE -./Get-PairedRegion.ps1 -Location 'australiaeast' - -Output will be 'australiasoutheast'. -#> - -param( - [string] $Location -) - -# Sleep for role assignment propagation -Start-Sleep -Seconds 10 - -$PairedRegionName = Get-AzLocation | - Where-Object -FilterScript { $Location -in @($PSItem.Location, $PSItem.DisplayName) } | - Select-Object -ExpandProperty PairedRegion | - Select-Object -ExpandProperty Name - -# Write into Deployment Script output stream -$DeploymentScriptOutputs = @{ - pairedRegionName = $PairedRegionName -} diff --git a/avm/utilities/e2e-template-assets/scripts/.scripts/New-SSHKey.ps1 b/avm/utilities/e2e-template-assets/scripts/.scripts/New-SSHKey.ps1 deleted file mode 100644 index 3e5c532388..0000000000 --- a/avm/utilities/e2e-template-assets/scripts/.scripts/New-SSHKey.ps1 +++ /dev/null @@ -1,40 +0,0 @@ -<# -.SYNOPSIS -Generate a new Public SSH Key or fetch it from an existing Public SSH Key resource. - -.DESCRIPTION -Generate a new Public SSH Key or fetch it from an existing Public SSH Key resource. - -.PARAMETER SSHKeyName -Mandatory. The name of the Public SSH Key Resource as it would be deployed in Azure - -.PARAMETER ResourceGroupName -Mandatory. The resource group name of the Public SSH Key Resource as it would be deployed in Azure - -.EXAMPLE -./New-SSHKey.ps1 -SSHKeyName 'myKeyResource' -ResourceGroupName 'ssh-rg' - -Generate a new Public SSH Key or fetch it from an existing Public SSH Key resource 'myKeyResource' in Resource Group 'ssh-rg' -#> -param( - [Parameter(Mandatory = $true)] - [string] $SSHKeyName, - - [Parameter(Mandatory = $true)] - [string] $ResourceGroupName -) - -if (-not ($sshKey = Get-AzSshKey -ResourceGroupName $ResourceGroupName | Where-Object { $_.Name -eq $SSHKeyName })) { - Write-Verbose "No SSH key [$SSHKeyName] found in Resource Group [$ResourceGroupName]. Generating new." -Verbose - $null = ssh-keygen -f generated -N (Get-Random -Maximum 99999) - $publicKey = Get-Content 'generated.pub' -Raw - # $privateKey = cat generated | Out-String -} else { - Write-Verbose "SSH key [$SSHKeyName] found in Resource Group [$ResourceGroupName]. Returning." -Verbose - $publicKey = $sshKey.publicKey -} -# Write into Deployment Script output stream -$DeploymentScriptOutputs = @{ - # Requires conversion as the script otherwise returns an object instead of the plain public key string - publicKey = $publicKey | Out-String -} diff --git a/avm/utilities/e2e-template-assets/scripts/.scripts/Set-BlobContent.ps1 b/avm/utilities/e2e-template-assets/scripts/.scripts/Set-BlobContent.ps1 deleted file mode 100644 index 394bbd6b38..0000000000 --- a/avm/utilities/e2e-template-assets/scripts/.scripts/Set-BlobContent.ps1 +++ /dev/null @@ -1,46 +0,0 @@ -<# -.SYNOPSIS -Upload a test file to the given Storage Account Container. - -.DESCRIPTION -Upload a test file to the given Storage Account Container. - -.PARAMETER StorageAccountName -Mandatory. The name of the Storage Account to upload the file to - -.PARAMETER ResourceGroupName -Mandatory. The name of the Resource Group containing the Storage Account to upload the file to - -.PARAMETER ContainerName -Mandatory. The name of the Storage Account Container to upload the file to - -.PARAMETER FileName -Mandatory. The name of the file of the file to create in the container - -.EXAMPLE -./Set-BlobContent.ps1 -StorageAccountName 'mystorage' -ResourceGroupName 'storage-rg' -ContainerName 'mycontainer' -FileName 'testCSE.ps1' - -Generate a dummy file 'testCSE.ps1' to the Storage Account 'mystorage' Container 'mycontainer' in Resource Group 'storage-rg' -#> -param( - [Parameter(Mandatory = $true)] - [string] $StorageAccountName, - - [Parameter(Mandatory = $true)] - [string] $ResourceGroupName, - - [Parameter(Mandatory = $true)] - [string] $ContainerName, - - [Parameter(Mandatory = $true)] - [string] $FileName -) - -Write-Verbose "Create file [$FileName]" -Verbose -$file = New-Item -Value "Write-Host 'I am content'" -Path $FileName -Force - -Write-Verbose "Getting storage account [$StorageAccountName|$ResourceGroupName] context." -Verbose -$storageAccount = Get-AzStorageAccount -ResourceGroupName $ResourceGroupName -StorageAccountName $StorageAccountName -ErrorAction 'Stop' - -Write-Verbose 'Uploading file [$fileName]' -Verbose -Set-AzStorageBlobContent -File $file.FullName -Container $ContainerName -Context $storageAccount.Context -Force -ErrorAction 'Stop' | Out-Null diff --git a/avm/utilities/e2e-template-assets/scripts/.scripts/Set-CertificateInKeyVault.ps1 b/avm/utilities/e2e-template-assets/scripts/.scripts/Set-CertificateInKeyVault.ps1 deleted file mode 100644 index 5f9bafaef5..0000000000 --- a/avm/utilities/e2e-template-assets/scripts/.scripts/Set-CertificateInKeyVault.ps1 +++ /dev/null @@ -1,67 +0,0 @@ -<# -.SYNOPSIS -Generate a new Key Vault Certificate or fetch its secret reference if already existing. - -.DESCRIPTION -Generate a new Key Vault Certificate or fetch its secret reference if already existing. - -.PARAMETER KeyVaultName -Mandatory. The name of the Key Vault to add a new certificate to, or fetch the secret reference it from - -.PARAMETER CertName -Mandatory. The name of the certificate to generate or fetch the secret reference from - -.PARAMETER CertSubjectName -Optional. The subject distinguished name is the name of the user of the certificate. The distinguished name for the certificate is a textual representation of the subject or issuer of the certificate. Default name is "CN=fabrikam.com" - -.EXAMPLE -./Set-CertificateInKeyVault.ps1 -KeyVaultName 'myVault' -CertName 'myCert' -CertSubjectName 'CN=fabrikam.com' - -Generate a new Key Vault Certificate with the default or provided subject name, or fetch its secret reference if already existing as 'myCert' in Key Vault 'myVault' -#> -param( - [Parameter(Mandatory = $true)] - [string] $KeyVaultName, - - [Parameter(Mandatory = $true)] - [string] $CertName, - - [Parameter(Mandatory = $false)] - [string] $CertSubjectName = 'CN=fabrikam.com' -) - -$certificate = Get-AzKeyVaultCertificate -VaultName $KeyVaultName -Name $CertName -ErrorAction 'SilentlyContinue' - -if (-not $certificate) { - $policyInputObject = @{ - SecretContentType = 'application/x-pkcs12' - SubjectName = $CertSubjectName - IssuerName = 'Self' - ValidityInMonths = 12 - ReuseKeyOnRenewal = $true - } - $certPolicy = New-AzKeyVaultCertificatePolicy @policyInputObject - - $null = Add-AzKeyVaultCertificate -VaultName $KeyVaultName -Name $CertName -CertificatePolicy $certPolicy - Write-Verbose ('Initiated creation of certificate [{0}] in key vault [{1}]' -f $CertName, $KeyVaultName) -Verbose - - while (-not (Get-AzKeyVaultCertificateOperation -VaultName $KeyVaultName -Name $CertName).Status -eq 'completed') { - Write-Verbose 'Waiting 10 seconds for certificate creation' -Verbose - Start-Sleep 10 - } - - Write-Verbose 'Certificate created' -Verbose -} - -$secretId = $certificate.SecretId -while ([String]::IsNullOrEmpty($secretId)) { - Write-Verbose 'Waiting 10 seconds until certificate can be fetched' -Verbose - Start-Sleep 10 - $certificate = Get-AzKeyVaultCertificate -VaultName $KeyVaultName -Name $CertName -ErrorAction 'Stop' - $secretId = $certificate.SecretId -} - -# Write into Deployment Script output stream -$DeploymentScriptOutputs = @{ - secretUrl = $secretId -} diff --git a/avm/utilities/e2e-template-assets/scripts/.scripts/Set-PfxCertificateInKeyVault.ps1 b/avm/utilities/e2e-template-assets/scripts/.scripts/Set-PfxCertificateInKeyVault.ps1 deleted file mode 100644 index fd88a2243e..0000000000 --- a/avm/utilities/e2e-template-assets/scripts/.scripts/Set-PfxCertificateInKeyVault.ps1 +++ /dev/null @@ -1,62 +0,0 @@ -<# -.SYNOPSIS -Generate a new PFX Certificate and store it alongside its password as Secrets in the given Key Vault. - -.DESCRIPTION -Generate a new PFX Certificate and store it alongside its password as Secrets in the given Key Vault. - -.PARAMETER KeyVaultName -Mandatory. The name of the Key Vault to store the Certificate & Password in - -.PARAMETER ResourceGroupName -Mandatory. The name of the Resource Group containing the Key Vault to store the Certificate & Password in - -.PARAMETER CertPWSecretName -Mandatory. The name of the Secret to store the Certificate's password in - -.PARAMETER CertSecretName -Mandatory. The name of the Secret to store the Secret in - -.EXAMPLE -./Set-PfxCertificateInKeyVault.ps1 -KeyVaultName 'myVault' -ResourceGroupName 'vault-rg' -CertPWSecretName 'pfxCertificatePassword' -CertSecretName 'pfxBase64Certificate' - -Generate a Certificate and store it as the Secret 'pfxCertificatePassword' in the Key Vault 'vault-rg' of Resource Group 'storage-rg' alongside its password as the Secret 'pfxCertificatePassword' -#> -param( - [Parameter(Mandatory = $true)] - [string] $KeyVaultName, - - [Parameter(Mandatory = $true)] - [string] $ResourceGroupName, - - [Parameter(Mandatory = $true)] - [string] $CertPWSecretName, - - [Parameter(Mandatory = $true)] - [string] $CertSecretName -) - -$password = ConvertTo-SecureString -String "$ResourceGroupName/$KeyVaultName/$CertSecretName" -AsPlainText -Force - -# Install open-ssl if not available -apt-get install openssl - -# Generate certificate -openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout './privateKey.key' -out './certificate.crt' -subj '/CN=*.contoso.onmicrosoft.com/O=contoso/C=US' - -# Sign certificate -openssl pkcs12 -export -out 'aadds.pfx' -inkey './privateKey.key' -in './certificate.crt' -passout pass:$password - -# Convert certificate to string -$rawCertByteStream = Get-Content './aadds.pfx' -AsByteStream -Write-Verbose 'Convert to secure string' -Verbose -$pfxCertificate = ConvertTo-SecureString -String ([System.Convert]::ToBase64String($rawCertByteStream)) -AsPlainText -Force - -# Set values -@( - @{ name = $CertPWSecretName; secretValue = $password } - @{ name = $CertSecretName; secretValue = $pfxCertificate } -) | ForEach-Object { - $null = Set-AzKeyVaultSecret -VaultName $KeyVaultName -Name $_.name -SecretValue $_.secretValue - Write-Verbose ('Added secret [{0}] to key vault [{1}]' -f $_.name, $keyVaultName) -Verbose -} diff --git a/avm/utilities/e2e-template-assets/scripts/.scripts/Start-ImageTemplate.ps1 b/avm/utilities/e2e-template-assets/scripts/.scripts/Start-ImageTemplate.ps1 deleted file mode 100644 index 798f799a75..0000000000 --- a/avm/utilities/e2e-template-assets/scripts/.scripts/Start-ImageTemplate.ps1 +++ /dev/null @@ -1,79 +0,0 @@ -<# -.SYNOPSIS -Create image artifacts from a given image template - -.DESCRIPTION -Create image artifacts from a given image template - -.PARAMETER ImageTemplateName -Mandatory. The name of the image template - -.PARAMETER ImageTemplateResourceGroup -Mandatory. The resource group name of the image template - -.PARAMETER NoWait -Optional. Run the command asynchronously - -.EXAMPLE -./Start-ImageTemplate -ImageTemplateName 'vhd-img-template-001-2022-07-29-15-54-01' -ImageTemplateResourceGroup 'validation-rg' - -Create image artifacts from image template 'vhd-img-template-001-2022-07-29-15-54-01' in resource group 'validation-rg' and wait for their completion - -.EXAMPLE -./Start-ImageTemplate -ImageTemplateName 'vhd-img-template-001-2022-07-29-15-54-01' -ImageTemplateResourceGroup 'validation-rg' -NoWait - -Start the creation of artifacts from image template 'vhd-img-template-001-2022-07-29-15-54-01' in resource group 'validation-rg' and do not wait for their completion -#> - -[CmdletBinding(SupportsShouldProcess)] -param ( - [Parameter(Mandatory = $true)] - [string] $ImageTemplateName, - - [Parameter(Mandatory = $true)] - [string] $ImageTemplateResourceGroup, - - [Parameter(Mandatory = $false)] - [switch] $NoWait -) - -begin { - Write-Debug ('{0} entered' -f $MyInvocation.MyCommand) - - # Install required modules - $currentVerbosePreference = $VerbosePreference - $VerbosePreference = 'SilentlyContinue' - $requiredModules = @( - 'Az.ImageBuilder' - ) - foreach ($moduleName in $requiredModules) { - if (-not ($installedModule = Get-Module $moduleName -ListAvailable)) { - Install-Module $moduleName -Repository 'PSGallery' -Force -Scope 'CurrentUser' - if ($installed = Get-Module -Name $moduleName -ListAvailable) { - Write-Verbose ('Installed module [{0}] with version [{1}]' -f $installed.Name, $installed.Version) -Verbose - } - } else { - Write-Verbose ('Module [{0}] already installed in version [{1}]' -f $installedModule[0].Name, $installedModule[0].Version) -Verbose - } - } - $VerbosePreference = $currentVerbosePreference -} - -process { - # Create image artifacts from existing image template - $resourceActionInputObject = @{ - ImageTemplateName = $imageTemplateName - ResourceGroupName = $imageTemplateResourceGroup - } - if ($NoWait) { - $resourceActionInputObject['NoWait'] = $true - } - if ($PSCmdlet.ShouldProcess('Image template [{0}]' -f $imageTemplateName, 'Start')) { - $null = Start-AzImageBuilderTemplate @resourceActionInputObject - Write-Verbose ('Created/initialized creation of image artifacts from image template [{0}] in resource group [{1}]' -f $imageTemplateName, $imageTemplateResourceGroup) -Verbose - } -} - -end { - Write-Debug ('{0} exited' -f $MyInvocation.MyCommand) -} From f91b0a6d493c06f477458dc57a5a5c6993dfdce1 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Wed, 6 Dec 2023 16:23:44 +0100 Subject: [PATCH 13/96] reference NIC from BRM --- avm/res/compute/virtual-machine/main.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/res/compute/virtual-machine/main.bicep b/avm/res/compute/virtual-machine/main.bicep index 308c636d7b..04dd654def 100644 --- a/avm/res/compute/virtual-machine/main.bicep +++ b/avm/res/compute/virtual-machine/main.bicep @@ -337,7 +337,7 @@ resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (ena } } -module vm_nic '../../network/network-interface/main.bicep' = [for (nicConfiguration, index) in nicConfigurations: { +module vm_nic 'br/public:avm/res/network/network-interface:0.2.2' = [for (nicConfiguration, index) in nicConfigurations: { name: '${uniqueString(deployment().name, location)}-VM-Nic-${index}' params: { name: '${name}${nicConfiguration.nicSuffix}' From 1e376055208532b836ba84adb3fcea4aabf635bb Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 7 Dec 2023 11:33:21 +0100 Subject: [PATCH 14/96] add protected item --- avm/res/compute/virtual-machine/main.bicep | 47 +++---- .../virtual-machine/protected-item/main.bicep | 70 ++++++++++ .../virtual-machine/protected-item/main.json | 128 ++++++++++++++++++ .../protected-item/version.json | 7 + 4 files changed, 229 insertions(+), 23 deletions(-) create mode 100644 avm/res/compute/virtual-machine/protected-item/main.bicep create mode 100644 avm/res/compute/virtual-machine/protected-item/main.json create mode 100644 avm/res/compute/virtual-machine/protected-item/version.json diff --git a/avm/res/compute/virtual-machine/main.bicep b/avm/res/compute/virtual-machine/main.bicep index 04dd654def..d02256a8f3 100644 --- a/avm/res/compute/virtual-machine/main.bicep +++ b/avm/res/compute/virtual-machine/main.bicep @@ -635,29 +635,30 @@ module vm_azureDiskEncryptionExtension 'extension/main.bicep' = if (extensionAzu ] } -// module vm_backup '../../recovery-services/vault/backup-fabric/protection-container/protected-item/main.bicep' = if (!empty(backupVaultName)) { -// name: '${uniqueString(deployment().name, location)}-VM-Backup' -// params: { -// name: 'vm;iaasvmcontainerv2;${resourceGroup().name};${vm.name}' -// policyId: az.resourceId('Microsoft.RecoveryServices/vaults/backupPolicies', backupVaultName, backupPolicyName) -// protectedItemType: 'Microsoft.Compute/virtualMachines' -// protectionContainerName: 'iaasvmcontainer;iaasvmcontainerv2;${resourceGroup().name};${vm.name}' -// recoveryVaultName: backupVaultName -// sourceResourceId: vm.id -// enableDefaultTelemetry: enableReferencedModulesTelemetry -// } -// scope: az.resourceGroup(backupVaultResourceGroup) -// dependsOn: [ -// vm_aadJoinExtension -// vm_domainJoinExtension -// vm_microsoftMonitoringAgentExtension -// vm_microsoftAntiMalwareExtension -// vm_networkWatcherAgentExtension -// vm_dependencyAgentExtension -// vm_desiredStateConfigurationExtension -// vm_customScriptExtension -// ] -// } +module vm_backup 'protected-item/main.bicep' = if (!empty(backupVaultName)) { + name: '${uniqueString(deployment().name, location)}-VM-Backup' + params: { + name: 'vm;iaasvmcontainerv2;${resourceGroup().name};${vm.name}' + location: location + policyId: az.resourceId('Microsoft.RecoveryServices/vaults/backupPolicies', backupVaultName, backupPolicyName) + protectedItemType: 'Microsoft.Compute/virtualMachines' + protectionContainerName: 'iaasvmcontainer;iaasvmcontainerv2;${resourceGroup().name};${vm.name}' + recoveryVaultName: backupVaultName + sourceResourceId: vm.id + enableDefaultTelemetry: enableReferencedModulesTelemetry + } + scope: az.resourceGroup(backupVaultResourceGroup) + dependsOn: [ + vm_aadJoinExtension + vm_domainJoinExtension + vm_microsoftMonitoringAgentExtension + vm_microsoftAntiMalwareExtension + vm_networkWatcherAgentExtension + vm_dependencyAgentExtension + vm_desiredStateConfigurationExtension + vm_customScriptExtension + ] +} resource vm_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock ?? {}) && lock.?kind != 'None') { name: lock.?name ?? 'lock-${name}' diff --git a/avm/res/compute/virtual-machine/protected-item/main.bicep b/avm/res/compute/virtual-machine/protected-item/main.bicep new file mode 100644 index 0000000000..7631577c89 --- /dev/null +++ b/avm/res/compute/virtual-machine/protected-item/main.bicep @@ -0,0 +1,70 @@ +metadata name = 'Recovery Service Vaults Protection Container Protected Item' +metadata description = 'This module deploys a Recovery Services Vault Protection Container Protected Item.' +metadata owner = 'Azure/module-maintainers' + +@description('Required. Name of the resource.') +param name string + +@description('Conditional. Name of the Azure Recovery Service Vault Protection Container. Required if the template is used in a standalone deployment.') +param protectionContainerName string + +@description('Conditional. The name of the parent Azure Recovery Service Vault. Required if the template is used in a standalone deployment.') +param recoveryVaultName string + +@description('Optional. Location for all resources.') +param location string = resourceGroup().location + +@allowed([ + 'AzureFileShareProtectedItem' + 'AzureVmWorkloadSAPAseDatabase' + 'AzureVmWorkloadSAPHanaDatabase' + 'AzureVmWorkloadSQLDatabase' + 'DPMProtectedItem' + 'GenericProtectedItem' + 'MabFileFolderProtectedItem' + 'Microsoft.ClassicCompute/virtualMachines' + 'Microsoft.Compute/virtualMachines' + 'Microsoft.Sql/servers/databases' +]) +@description('Required. The backup item type.') +param protectedItemType string + +@description('Required. ID of the backup policy with which this item is backed up.') +param policyId string + +@description('Required. Resource ID of the resource to back up.') +param sourceResourceId string + +@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') +param enableDefaultTelemetry bool = true + +resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (enableDefaultTelemetry) { + name: 'pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-${uniqueString(deployment().name, location)}' + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + } + } +} + +resource protectedItem 'Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems@2023-01-01' = { + name: '${recoveryVaultName}/Azure/${protectionContainerName}/${name}' + location: location + properties: { + protectedItemType: any(protectedItemType) + policyId: policyId + sourceResourceId: sourceResourceId + } +} + +@description('The name of the Resource Group the protected item was created in.') +output resourceGroupName string = resourceGroup().name + +@description('The resource ID of the protected item.') +output resourceId string = protectedItem.id + +@description('The Name of the protected item.') +output name string = protectedItem.name diff --git a/avm/res/compute/virtual-machine/protected-item/main.json b/avm/res/compute/virtual-machine/protected-item/main.json new file mode 100644 index 0000000000..232937bb2a --- /dev/null +++ b/avm/res/compute/virtual-machine/protected-item/main.json @@ -0,0 +1,128 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.22.6.54827", + "templateHash": "7148492251760573310" + }, + "name": "Recovery Service Vaults Protection Container Protected Item", + "description": "This module deploys a Recovery Services Vault Protection Container Protected Item.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the resource." + } + }, + "protectionContainerName": { + "type": "string", + "metadata": { + "description": "Conditional. Name of the Azure Recovery Service Vault Protection Container. Required if the template is used in a standalone deployment." + } + }, + "recoveryVaultName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Azure Recovery Service Vault. Required if the template is used in a standalone deployment." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "protectedItemType": { + "type": "string", + "allowedValues": [ + "AzureFileShareProtectedItem", + "AzureVmWorkloadSAPAseDatabase", + "AzureVmWorkloadSAPHanaDatabase", + "AzureVmWorkloadSQLDatabase", + "DPMProtectedItem", + "GenericProtectedItem", + "MabFileFolderProtectedItem", + "Microsoft.ClassicCompute/virtualMachines", + "Microsoft.Compute/virtualMachines", + "Microsoft.Sql/servers/databases" + ], + "metadata": { + "description": "Required. The backup item type." + } + }, + "policyId": { + "type": "string", + "metadata": { + "description": "Required. ID of the backup policy with which this item is backed up." + } + }, + "sourceResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the resource to back up." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + } + }, + "resources": [ + { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + { + "type": "Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems", + "apiVersion": "2023-01-01", + "name": "[format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name'))]", + "location": "[parameters('location')]", + "properties": { + "protectedItemType": "[parameters('protectedItemType')]", + "policyId": "[parameters('policyId')]", + "sourceResourceId": "[parameters('sourceResourceId')]" + } + } + ], + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the protected item was created in." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the protected item." + }, + "value": "[resourceId('Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems', split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[0], split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[1], split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[2], split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[3])]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The Name of the protected item." + }, + "value": "[format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name'))]" + } + } +} \ No newline at end of file diff --git a/avm/res/compute/virtual-machine/protected-item/version.json b/avm/res/compute/virtual-machine/protected-item/version.json new file mode 100644 index 0000000000..96236a61ba --- /dev/null +++ b/avm/res/compute/virtual-machine/protected-item/version.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.4", + "pathFilters": [ + "./main.json" + ] +} From 5e31ff4a47d52b3753ac83423ea579f016116d93 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 7 Dec 2023 11:41:38 +0100 Subject: [PATCH 15/96] add readme --- avm/res/compute/virtual-machine/README.md | 3384 +++++++++++++++++++ avm/res/compute/virtual-machine/main.json | 3729 +++++++++++++++++++++ 2 files changed, 7113 insertions(+) create mode 100644 avm/res/compute/virtual-machine/README.md create mode 100644 avm/res/compute/virtual-machine/main.json diff --git a/avm/res/compute/virtual-machine/README.md b/avm/res/compute/virtual-machine/README.md new file mode 100644 index 0000000000..2c008c1f3a --- /dev/null +++ b/avm/res/compute/virtual-machine/README.md @@ -0,0 +1,3384 @@ +# Virtual Machines `[Microsoft.Compute/virtualMachines]` + +This module deploys a Virtual Machine with one or multiple NICs and optionally one or multiple public IPs. + +## 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.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | +| `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | +| `Microsoft.Automanage/configurationProfileAssignments` | [2021-04-30-preview](https://learn.microsoft.com/en-us/azure/templates) | +| `Microsoft.Compute/virtualMachines` | [2022-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Compute/2022-11-01/virtualMachines) | +| `Microsoft.Compute/virtualMachines/extensions` | [2022-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Compute/2022-11-01/virtualMachines/extensions) | +| `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | +| `Microsoft.Network/networkInterfaces` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/networkInterfaces) | +| `Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems` | [2023-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.RecoveryServices/2023-01-01/vaults/backupFabrics/protectionContainers/protectedItems) | + +## 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/compute/virtual-machine:`. + +- [Linux.Atmg](#example-1-linuxatmg) +- [Using only defaults](#example-2-using-only-defaults) +- [Using large parameter set](#example-3-using-large-parameter-set) +- [WAF-aligned](#example-4-waf-aligned) +- [Windows.Atmg](#example-5-windowsatmg) +- [Using only defaults](#example-6-using-only-defaults) +- [Using large parameter set](#example-7-using-large-parameter-set) +- [Windows.Ssecmk](#example-8-windowsssecmk) + + +### Example 1: _Linux.Atmg_ + +

+ +via Bicep module + +```bicep +module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { + name: '${uniqueString(deployment().name, location)}-test-cvmlinatmg' + params: { + // Required parameters + adminUsername: 'localAdminUser' + imageReference: { + offer: '0001-com-ubuntu-server-jammy' + publisher: 'Canonical' + sku: '22_04-lts-gen2' + version: 'latest' + } + nicConfigurations: [ + { + ipConfigurations: [ + { + name: 'ipconfig01' + pipConfiguration: { + publicIpNameSuffix: '-pip-01' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + subnetResourceId: '' + zones: [ + '1' + '2' + '3' + ] + } + ] + nicSuffix: '-nic-01' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + ] + osDisk: { + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + osType: 'Linux' + vmSize: 'Standard_DS2_v2' + // Non-required parameters + configurationProfile: '/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesProduction' + disablePasswordAuthentication: true + location: '' + name: 'cvmlinatmg' + publicKeys: [ + { + keyData: '' + path: '/home/localAdminUser/.ssh/authorized_keys' + } + ] + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } +} +``` + +
+

+ +

+ +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 + "adminUsername": { + "value": "localAdminUser" + }, + "imageReference": { + "value": { + "offer": "0001-com-ubuntu-server-jammy", + "publisher": "Canonical", + "sku": "22_04-lts-gen2", + "version": "latest" + } + }, + "nicConfigurations": { + "value": [ + { + "ipConfigurations": [ + { + "name": "ipconfig01", + "pipConfiguration": { + "publicIpNameSuffix": "-pip-01", + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + }, + "subnetResourceId": "", + "zones": [ + "1", + "2", + "3" + ] + } + ], + "nicSuffix": "-nic-01", + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + ] + }, + "osDisk": { + "value": { + "diskSizeGB": "128", + "managedDisk": { + "storageAccountType": "Premium_LRS" + } + } + }, + "osType": { + "value": "Linux" + }, + "vmSize": { + "value": "Standard_DS2_v2" + }, + // Non-required parameters + "configurationProfile": { + "value": "/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesProduction" + }, + "disablePasswordAuthentication": { + "value": true + }, + "location": { + "value": "" + }, + "name": { + "value": "cvmlinatmg" + }, + "publicKeys": { + "value": [ + { + "keyData": "", + "path": "/home/localAdminUser/.ssh/authorized_keys" + } + ] + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + } +} +``` + +
+

+ +### Example 2: _Using only defaults_ + +This instance deploys the module with the minimum set of required parameters. + + +

+ +via Bicep module + +```bicep +module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { + name: '${uniqueString(deployment().name, location)}-test-cvmlindef' + params: { + // Required parameters + adminUsername: 'localAdminUser' + imageReference: { + offer: '0001-com-ubuntu-server-jammy' + publisher: 'Canonical' + sku: '22_04-lts-gen2' + version: 'latest' + } + nicConfigurations: [ + { + ipConfigurations: [ + { + name: 'ipconfig01' + pipConfiguration: { + publicIpNameSuffix: '-pip-01' + } + subnetResourceId: '' + } + ] + nicSuffix: '-nic-01' + } + ] + osDisk: { + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + osType: 'Linux' + vmSize: 'Standard_DS2_v2' + // Non-required parameters + disablePasswordAuthentication: true + location: '' + name: 'cvmlindef' + publicKeys: [ + { + keyData: '' + path: '/home/localAdminUser/.ssh/authorized_keys' + } + ] + } +} +``` + +
+

+ +

+ +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 + "adminUsername": { + "value": "localAdminUser" + }, + "imageReference": { + "value": { + "offer": "0001-com-ubuntu-server-jammy", + "publisher": "Canonical", + "sku": "22_04-lts-gen2", + "version": "latest" + } + }, + "nicConfigurations": { + "value": [ + { + "ipConfigurations": [ + { + "name": "ipconfig01", + "pipConfiguration": { + "publicIpNameSuffix": "-pip-01" + }, + "subnetResourceId": "" + } + ], + "nicSuffix": "-nic-01" + } + ] + }, + "osDisk": { + "value": { + "diskSizeGB": "128", + "managedDisk": { + "storageAccountType": "Premium_LRS" + } + } + }, + "osType": { + "value": "Linux" + }, + "vmSize": { + "value": "Standard_DS2_v2" + }, + // Non-required parameters + "disablePasswordAuthentication": { + "value": true + }, + "location": { + "value": "" + }, + "name": { + "value": "cvmlindef" + }, + "publicKeys": { + "value": [ + { + "keyData": "", + "path": "/home/localAdminUser/.ssh/authorized_keys" + } + ] + } + } +} +``` + +
+

+ +### Example 3: _Using large parameter set_ + +This instance deploys the module with most of its features enabled. + + +

+ +via Bicep module + +```bicep +module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { + name: '${uniqueString(deployment().name, location)}-test-cvmlinmax' + params: { + // Required parameters + adminUsername: 'localAdministrator' + imageReference: { + offer: '0001-com-ubuntu-server-focal' + publisher: 'Canonical' + sku: '' + version: 'latest' + } + nicConfigurations: [ + { + deleteOption: 'Delete' + diagnosticSettings: [ + { + eventHubAuthorizationRuleResourceId: '' + eventHubName: '' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + name: 'customSetting' + storageAccountResourceId: '' + workspaceResourceId: '' + } + ] + ipConfigurations: [ + { + applicationSecurityGroups: [ + { + id: '' + } + ] + diagnosticSettings: [ + { + eventHubAuthorizationRuleResourceId: '' + eventHubName: '' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + name: 'customSetting' + storageAccountResourceId: '' + workspaceResourceId: '' + } + ] + loadBalancerBackendAddressPools: [ + { + id: '' + } + ] + name: 'ipconfig01' + pipConfiguration: { + publicIpNameSuffix: '-pip-01' + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Reader' + } + ] + } + subnetResourceId: '' + zones: [ + '1' + '2' + '3' + ] + } + ] + nicSuffix: '-nic-01' + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Reader' + } + ] + } + ] + osDisk: { + caching: 'ReadOnly' + createOption: 'fromImage' + deleteOption: 'Delete' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + osType: 'Linux' + vmSize: 'Standard_DS2_v2' + // Non-required parameters + availabilityZone: 1 + backupPolicyName: '' + backupVaultName: '' + backupVaultResourceGroup: '' + computerName: 'linvm1' + dataDisks: [ + { + caching: 'ReadWrite' + createOption: 'Empty' + deleteOption: 'Delete' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + { + caching: 'ReadWrite' + createOption: 'Empty' + deleteOption: 'Delete' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + ] + disablePasswordAuthentication: true + enableAutomaticUpdates: true + encryptionAtHost: false + extensionAadJoinConfig: { + enabled: true + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionAzureDiskEncryptionConfig: { + enabled: true + settings: { + EncryptionOperation: 'EnableEncryption' + KekVaultResourceId: '' + KeyEncryptionAlgorithm: 'RSA-OAEP' + KeyEncryptionKeyURL: '' + KeyVaultResourceId: '' + KeyVaultURL: '' + ResizeOSDisk: 'false' + VolumeType: 'All' + } + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionCustomScriptConfig: { + enabled: true + fileData: [ + { + storageAccountId: '' + uri: '' + } + ] + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionCustomScriptProtectedSetting: { + commandToExecute: '' + } + extensionDependencyAgentConfig: { + enabled: true + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionDSCConfig: { + enabled: false + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionMonitoringAgentConfig: { + enabled: true + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionNetworkWatcherAgentConfig: { + enabled: true + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + location: '' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + '' + ] + } + monitoringWorkspaceId: '' + name: 'cvmlinmax' + patchMode: 'AutomaticByPlatform' + publicKeys: [ + { + keyData: '' + path: '/home/localAdministrator/.ssh/authorized_keys' + } + ] + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Owner' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: '' + } + ] + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } +} +``` + +
+

+ +

+ +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 + "adminUsername": { + "value": "localAdministrator" + }, + "imageReference": { + "value": { + "offer": "0001-com-ubuntu-server-focal", + "publisher": "Canonical", + "sku": "", + "version": "latest" + } + }, + "nicConfigurations": { + "value": [ + { + "deleteOption": "Delete", + "diagnosticSettings": [ + { + "eventHubAuthorizationRuleResourceId": "", + "eventHubName": "", + "metricCategories": [ + { + "category": "AllMetrics" + } + ], + "name": "customSetting", + "storageAccountResourceId": "", + "workspaceResourceId": "" + } + ], + "ipConfigurations": [ + { + "applicationSecurityGroups": [ + { + "id": "" + } + ], + "diagnosticSettings": [ + { + "eventHubAuthorizationRuleResourceId": "", + "eventHubName": "", + "metricCategories": [ + { + "category": "AllMetrics" + } + ], + "name": "customSetting", + "storageAccountResourceId": "", + "workspaceResourceId": "" + } + ], + "loadBalancerBackendAddressPools": [ + { + "id": "" + } + ], + "name": "ipconfig01", + "pipConfiguration": { + "publicIpNameSuffix": "-pip-01", + "roleAssignments": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Reader" + } + ] + }, + "subnetResourceId": "", + "zones": [ + "1", + "2", + "3" + ] + } + ], + "nicSuffix": "-nic-01", + "roleAssignments": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Reader" + } + ] + } + ] + }, + "osDisk": { + "value": { + "caching": "ReadOnly", + "createOption": "fromImage", + "deleteOption": "Delete", + "diskSizeGB": "128", + "managedDisk": { + "storageAccountType": "Premium_LRS" + } + } + }, + "osType": { + "value": "Linux" + }, + "vmSize": { + "value": "Standard_DS2_v2" + }, + // Non-required parameters + "availabilityZone": { + "value": 1 + }, + "backupPolicyName": { + "value": "" + }, + "backupVaultName": { + "value": "" + }, + "backupVaultResourceGroup": { + "value": "" + }, + "computerName": { + "value": "linvm1" + }, + "dataDisks": { + "value": [ + { + "caching": "ReadWrite", + "createOption": "Empty", + "deleteOption": "Delete", + "diskSizeGB": "128", + "managedDisk": { + "storageAccountType": "Premium_LRS" + } + }, + { + "caching": "ReadWrite", + "createOption": "Empty", + "deleteOption": "Delete", + "diskSizeGB": "128", + "managedDisk": { + "storageAccountType": "Premium_LRS" + } + } + ] + }, + "disablePasswordAuthentication": { + "value": true + }, + "enableAutomaticUpdates": { + "value": true + }, + "encryptionAtHost": { + "value": false + }, + "extensionAadJoinConfig": { + "value": { + "enabled": true, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionAzureDiskEncryptionConfig": { + "value": { + "enabled": true, + "settings": { + "EncryptionOperation": "EnableEncryption", + "KekVaultResourceId": "", + "KeyEncryptionAlgorithm": "RSA-OAEP", + "KeyEncryptionKeyURL": "", + "KeyVaultResourceId": "", + "KeyVaultURL": "", + "ResizeOSDisk": "false", + "VolumeType": "All" + }, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionCustomScriptConfig": { + "value": { + "enabled": true, + "fileData": [ + { + "storageAccountId": "", + "uri": "" + } + ], + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionCustomScriptProtectedSetting": { + "value": { + "commandToExecute": "" + } + }, + "extensionDependencyAgentConfig": { + "value": { + "enabled": true, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionDSCConfig": { + "value": { + "enabled": false, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionMonitoringAgentConfig": { + "value": { + "enabled": true, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionNetworkWatcherAgentConfig": { + "value": { + "enabled": true, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "location": { + "value": "" + }, + "lock": { + "value": { + "kind": "CanNotDelete", + "name": "myCustomLockName" + } + }, + "managedIdentities": { + "value": { + "systemAssigned": true, + "userAssignedResourceIds": [ + "" + ] + } + }, + "monitoringWorkspaceId": { + "value": "" + }, + "name": { + "value": "cvmlinmax" + }, + "patchMode": { + "value": "AutomaticByPlatform" + }, + "publicKeys": { + "value": [ + { + "keyData": "", + "path": "/home/localAdministrator/.ssh/authorized_keys" + } + ] + }, + "roleAssignments": { + "value": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Owner" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "" + } + ] + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + } +} +``` + +
+

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

+ +via Bicep module + +```bicep +module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { + name: '${uniqueString(deployment().name, location)}-test-cvmwinwaf' + params: { + // Required parameters + adminUsername: 'VMAdmin' + imageReference: { + offer: 'WindowsServer' + publisher: 'MicrosoftWindowsServer' + sku: '2019-datacenter' + version: 'latest' + } + nicConfigurations: [ + { + deleteOption: 'Delete' + diagnosticSettings: [ + { + eventHubAuthorizationRuleResourceId: '' + eventHubName: '' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + name: 'customSetting' + storageAccountResourceId: '' + workspaceResourceId: '' + } + ] + ipConfigurations: [ + { + applicationSecurityGroups: [ + { + id: '' + } + ] + diagnosticSettings: [ + { + eventHubAuthorizationRuleResourceId: '' + eventHubName: '' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + name: 'customSetting' + storageAccountResourceId: '' + workspaceResourceId: '' + } + ] + loadBalancerBackendAddressPools: [ + { + id: '' + } + ] + name: 'ipconfig01' + pipConfiguration: { + publicIpNameSuffix: '-pip-01' + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Reader' + } + ] + } + subnetResourceId: '' + zones: [ + '1' + '2' + '3' + ] + } + ] + nicSuffix: '-nic-01' + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Reader' + } + ] + } + ] + osDisk: { + caching: 'None' + createOption: 'fromImage' + deleteOption: 'Delete' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + osType: 'Windows' + vmSize: 'Standard_DS2_v2' + // Non-required parameters + adminPassword: '' + availabilityZone: 2 + backupPolicyName: '' + backupVaultName: '' + backupVaultResourceGroup: '' + computerName: 'winvm1' + dataDisks: [ + { + caching: 'None' + createOption: 'Empty' + deleteOption: 'Delete' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + { + caching: 'None' + createOption: 'Empty' + deleteOption: 'Delete' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + ] + enableAutomaticUpdates: true + encryptionAtHost: false + extensionAadJoinConfig: { + enabled: true + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionAntiMalwareConfig: { + enabled: true + settings: { + AntimalwareEnabled: 'true' + Exclusions: { + Extensions: '.ext1;.ext2' + Paths: 'c:\\excluded-path-1;c:\\excluded-path-2' + Processes: 'excludedproc1.exe;excludedproc2.exe' + } + RealtimeProtectionEnabled: 'true' + ScheduledScanSettings: { + day: '7' + isEnabled: 'true' + scanType: 'Quick' + time: '120' + } + } + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionAzureDiskEncryptionConfig: { + enabled: true + settings: { + EncryptionOperation: 'EnableEncryption' + KekVaultResourceId: '' + KeyEncryptionAlgorithm: 'RSA-OAEP' + KeyEncryptionKeyURL: '' + KeyVaultResourceId: '' + KeyVaultURL: '' + ResizeOSDisk: 'false' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + VolumeType: 'All' + } + } + extensionCustomScriptConfig: { + enabled: true + fileData: [ + { + storageAccountId: '' + uri: '' + } + ] + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionCustomScriptProtectedSetting: { + commandToExecute: '' + } + extensionDependencyAgentConfig: { + enabled: true + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionDSCConfig: { + enabled: true + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionMonitoringAgentConfig: { + enabled: true + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionNetworkWatcherAgentConfig: { + enabled: true + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + location: '' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + '' + ] + } + monitoringWorkspaceId: '' + name: 'cvmwinwaf' + patchMode: 'AutomaticByPlatform' + proximityPlacementGroupResourceId: '' + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Owner' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: '' + } + ] + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } +} +``` + +
+

+ +

+ +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 + "adminUsername": { + "value": "VMAdmin" + }, + "imageReference": { + "value": { + "offer": "WindowsServer", + "publisher": "MicrosoftWindowsServer", + "sku": "2019-datacenter", + "version": "latest" + } + }, + "nicConfigurations": { + "value": [ + { + "deleteOption": "Delete", + "diagnosticSettings": [ + { + "eventHubAuthorizationRuleResourceId": "", + "eventHubName": "", + "metricCategories": [ + { + "category": "AllMetrics" + } + ], + "name": "customSetting", + "storageAccountResourceId": "", + "workspaceResourceId": "" + } + ], + "ipConfigurations": [ + { + "applicationSecurityGroups": [ + { + "id": "" + } + ], + "diagnosticSettings": [ + { + "eventHubAuthorizationRuleResourceId": "", + "eventHubName": "", + "metricCategories": [ + { + "category": "AllMetrics" + } + ], + "name": "customSetting", + "storageAccountResourceId": "", + "workspaceResourceId": "" + } + ], + "loadBalancerBackendAddressPools": [ + { + "id": "" + } + ], + "name": "ipconfig01", + "pipConfiguration": { + "publicIpNameSuffix": "-pip-01", + "roleAssignments": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Reader" + } + ] + }, + "subnetResourceId": "", + "zones": [ + "1", + "2", + "3" + ] + } + ], + "nicSuffix": "-nic-01", + "roleAssignments": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Reader" + } + ] + } + ] + }, + "osDisk": { + "value": { + "caching": "None", + "createOption": "fromImage", + "deleteOption": "Delete", + "diskSizeGB": "128", + "managedDisk": { + "storageAccountType": "Premium_LRS" + } + } + }, + "osType": { + "value": "Windows" + }, + "vmSize": { + "value": "Standard_DS2_v2" + }, + // Non-required parameters + "adminPassword": { + "value": "" + }, + "availabilityZone": { + "value": 2 + }, + "backupPolicyName": { + "value": "" + }, + "backupVaultName": { + "value": "" + }, + "backupVaultResourceGroup": { + "value": "" + }, + "computerName": { + "value": "winvm1" + }, + "dataDisks": { + "value": [ + { + "caching": "None", + "createOption": "Empty", + "deleteOption": "Delete", + "diskSizeGB": "128", + "managedDisk": { + "storageAccountType": "Premium_LRS" + } + }, + { + "caching": "None", + "createOption": "Empty", + "deleteOption": "Delete", + "diskSizeGB": "128", + "managedDisk": { + "storageAccountType": "Premium_LRS" + } + } + ] + }, + "enableAutomaticUpdates": { + "value": true + }, + "encryptionAtHost": { + "value": false + }, + "extensionAadJoinConfig": { + "value": { + "enabled": true, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionAntiMalwareConfig": { + "value": { + "enabled": true, + "settings": { + "AntimalwareEnabled": "true", + "Exclusions": { + "Extensions": ".ext1;.ext2", + "Paths": "c:\\excluded-path-1;c:\\excluded-path-2", + "Processes": "excludedproc1.exe;excludedproc2.exe" + }, + "RealtimeProtectionEnabled": "true", + "ScheduledScanSettings": { + "day": "7", + "isEnabled": "true", + "scanType": "Quick", + "time": "120" + } + }, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionAzureDiskEncryptionConfig": { + "value": { + "enabled": true, + "settings": { + "EncryptionOperation": "EnableEncryption", + "KekVaultResourceId": "", + "KeyEncryptionAlgorithm": "RSA-OAEP", + "KeyEncryptionKeyURL": "", + "KeyVaultResourceId": "", + "KeyVaultURL": "", + "ResizeOSDisk": "false", + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + }, + "VolumeType": "All" + } + } + }, + "extensionCustomScriptConfig": { + "value": { + "enabled": true, + "fileData": [ + { + "storageAccountId": "", + "uri": "" + } + ], + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionCustomScriptProtectedSetting": { + "value": { + "commandToExecute": "" + } + }, + "extensionDependencyAgentConfig": { + "value": { + "enabled": true, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionDSCConfig": { + "value": { + "enabled": true, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionMonitoringAgentConfig": { + "value": { + "enabled": true, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionNetworkWatcherAgentConfig": { + "value": { + "enabled": true, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "location": { + "value": "" + }, + "lock": { + "value": { + "kind": "CanNotDelete", + "name": "myCustomLockName" + } + }, + "managedIdentities": { + "value": { + "systemAssigned": true, + "userAssignedResourceIds": [ + "" + ] + } + }, + "monitoringWorkspaceId": { + "value": "" + }, + "name": { + "value": "cvmwinwaf" + }, + "patchMode": { + "value": "AutomaticByPlatform" + }, + "proximityPlacementGroupResourceId": { + "value": "" + }, + "roleAssignments": { + "value": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Owner" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "" + } + ] + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + } +} +``` + +
+

+ +### Example 5: _Windows.Atmg_ + +

+ +via Bicep module + +```bicep +module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { + name: '${uniqueString(deployment().name, location)}-test-cvmwinatmg' + params: { + // Required parameters + adminUsername: 'localAdministrator' + imageReference: { + offer: 'WindowsServer' + publisher: 'MicrosoftWindowsServer' + sku: '2022-datacenter-azure-edition' + version: 'latest' + } + nicConfigurations: [ + { + ipConfigurations: [ + { + name: 'ipconfig01' + subnetResourceId: '' + } + ] + nicSuffix: '-nic-01' + } + ] + osDisk: { + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + osType: 'Windows' + vmSize: 'Standard_DS2_v2' + // Non-required parameters + adminPassword: '' + configurationProfile: '/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesProduction' + location: '' + name: 'cvmwinatmg' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } +} +``` + +
+

+ +

+ +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 + "adminUsername": { + "value": "localAdministrator" + }, + "imageReference": { + "value": { + "offer": "WindowsServer", + "publisher": "MicrosoftWindowsServer", + "sku": "2022-datacenter-azure-edition", + "version": "latest" + } + }, + "nicConfigurations": { + "value": [ + { + "ipConfigurations": [ + { + "name": "ipconfig01", + "subnetResourceId": "" + } + ], + "nicSuffix": "-nic-01" + } + ] + }, + "osDisk": { + "value": { + "diskSizeGB": "128", + "managedDisk": { + "storageAccountType": "Premium_LRS" + } + } + }, + "osType": { + "value": "Windows" + }, + "vmSize": { + "value": "Standard_DS2_v2" + }, + // Non-required parameters + "adminPassword": { + "value": "" + }, + "configurationProfile": { + "value": "/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesProduction" + }, + "location": { + "value": "" + }, + "name": { + "value": "cvmwinatmg" + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + } +} +``` + +
+

+ +### Example 6: _Using only defaults_ + +This instance deploys the module with the minimum set of required parameters. + + +

+ +via Bicep module + +```bicep +module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { + name: '${uniqueString(deployment().name, location)}-test-cvmwindef' + params: { + // Required parameters + adminUsername: 'localAdminUser' + imageReference: { + offer: 'WindowsServer' + publisher: 'MicrosoftWindowsServer' + sku: '2022-datacenter-azure-edition' + version: 'latest' + } + nicConfigurations: [ + { + ipConfigurations: [ + { + name: 'ipconfig01' + subnetResourceId: '' + } + ] + nicSuffix: '-nic-01' + } + ] + osDisk: { + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + osType: 'Windows' + vmSize: 'Standard_DS2_v2' + // Non-required parameters + adminPassword: '' + location: '' + name: 'cvmwindef' + } +} +``` + +
+

+ +

+ +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 + "adminUsername": { + "value": "localAdminUser" + }, + "imageReference": { + "value": { + "offer": "WindowsServer", + "publisher": "MicrosoftWindowsServer", + "sku": "2022-datacenter-azure-edition", + "version": "latest" + } + }, + "nicConfigurations": { + "value": [ + { + "ipConfigurations": [ + { + "name": "ipconfig01", + "subnetResourceId": "" + } + ], + "nicSuffix": "-nic-01" + } + ] + }, + "osDisk": { + "value": { + "diskSizeGB": "128", + "managedDisk": { + "storageAccountType": "Premium_LRS" + } + } + }, + "osType": { + "value": "Windows" + }, + "vmSize": { + "value": "Standard_DS2_v2" + }, + // Non-required parameters + "adminPassword": { + "value": "" + }, + "location": { + "value": "" + }, + "name": { + "value": "cvmwindef" + } + } +} +``` + +
+

+ +### Example 7: _Using large parameter set_ + +This instance deploys the module with most of its features enabled. + + +

+ +via Bicep module + +```bicep +module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { + name: '${uniqueString(deployment().name, location)}-test-cvmwinmax' + params: { + // Required parameters + adminUsername: 'VMAdmin' + imageReference: { + offer: 'WindowsServer' + publisher: 'MicrosoftWindowsServer' + sku: '2019-datacenter' + version: 'latest' + } + nicConfigurations: [ + { + deleteOption: 'Delete' + diagnosticSettings: [ + { + eventHubAuthorizationRuleResourceId: '' + eventHubName: '' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + name: 'customSetting' + storageAccountResourceId: '' + workspaceResourceId: '' + } + ] + ipConfigurations: [ + { + applicationSecurityGroups: [ + { + id: '' + } + ] + diagnosticSettings: [ + { + eventHubAuthorizationRuleResourceId: '' + eventHubName: '' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + name: 'customSetting' + storageAccountResourceId: '' + workspaceResourceId: '' + } + ] + loadBalancerBackendAddressPools: [ + { + id: '' + } + ] + name: 'ipconfig01' + pipConfiguration: { + publicIpNameSuffix: '-pip-01' + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Reader' + } + ] + } + subnetResourceId: '' + zones: [ + '1' + '2' + '3' + ] + } + ] + nicSuffix: '-nic-01' + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Reader' + } + ] + } + ] + osDisk: { + caching: 'None' + createOption: 'fromImage' + deleteOption: 'Delete' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + osType: 'Windows' + vmSize: 'Standard_DS2_v2' + // Non-required parameters + adminPassword: '' + availabilityZone: 2 + backupPolicyName: '' + backupVaultName: '' + backupVaultResourceGroup: '' + computerName: 'winvm1' + dataDisks: [ + { + caching: 'None' + createOption: 'Empty' + deleteOption: 'Delete' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + { + caching: 'None' + createOption: 'Empty' + deleteOption: 'Delete' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Premium_LRS' + } + } + ] + enableAutomaticUpdates: true + encryptionAtHost: false + extensionAadJoinConfig: { + enabled: true + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionAntiMalwareConfig: { + enabled: true + settings: { + AntimalwareEnabled: 'true' + Exclusions: { + Extensions: '.ext1;.ext2' + Paths: 'c:\\excluded-path-1;c:\\excluded-path-2' + Processes: 'excludedproc1.exe;excludedproc2.exe' + } + RealtimeProtectionEnabled: 'true' + ScheduledScanSettings: { + day: '7' + isEnabled: 'true' + scanType: 'Quick' + time: '120' + } + } + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionAzureDiskEncryptionConfig: { + enabled: true + settings: { + EncryptionOperation: 'EnableEncryption' + KekVaultResourceId: '' + KeyEncryptionAlgorithm: 'RSA-OAEP' + KeyEncryptionKeyURL: '' + KeyVaultResourceId: '' + KeyVaultURL: '' + ResizeOSDisk: 'false' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + VolumeType: 'All' + } + } + extensionCustomScriptConfig: { + enabled: true + fileData: [ + { + storageAccountId: '' + uri: '' + } + ] + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionCustomScriptProtectedSetting: { + commandToExecute: '' + } + extensionDependencyAgentConfig: { + enabled: true + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionDSCConfig: { + enabled: true + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionMonitoringAgentConfig: { + enabled: true + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + extensionNetworkWatcherAgentConfig: { + enabled: true + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + location: '' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + '' + ] + } + monitoringWorkspaceId: '' + name: 'cvmwinmax' + patchMode: 'AutomaticByPlatform' + proximityPlacementGroupResourceId: '' + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Owner' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: '' + } + ] + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } +} +``` + +
+

+ +

+ +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 + "adminUsername": { + "value": "VMAdmin" + }, + "imageReference": { + "value": { + "offer": "WindowsServer", + "publisher": "MicrosoftWindowsServer", + "sku": "2019-datacenter", + "version": "latest" + } + }, + "nicConfigurations": { + "value": [ + { + "deleteOption": "Delete", + "diagnosticSettings": [ + { + "eventHubAuthorizationRuleResourceId": "", + "eventHubName": "", + "metricCategories": [ + { + "category": "AllMetrics" + } + ], + "name": "customSetting", + "storageAccountResourceId": "", + "workspaceResourceId": "" + } + ], + "ipConfigurations": [ + { + "applicationSecurityGroups": [ + { + "id": "" + } + ], + "diagnosticSettings": [ + { + "eventHubAuthorizationRuleResourceId": "", + "eventHubName": "", + "metricCategories": [ + { + "category": "AllMetrics" + } + ], + "name": "customSetting", + "storageAccountResourceId": "", + "workspaceResourceId": "" + } + ], + "loadBalancerBackendAddressPools": [ + { + "id": "" + } + ], + "name": "ipconfig01", + "pipConfiguration": { + "publicIpNameSuffix": "-pip-01", + "roleAssignments": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Reader" + } + ] + }, + "subnetResourceId": "", + "zones": [ + "1", + "2", + "3" + ] + } + ], + "nicSuffix": "-nic-01", + "roleAssignments": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Reader" + } + ] + } + ] + }, + "osDisk": { + "value": { + "caching": "None", + "createOption": "fromImage", + "deleteOption": "Delete", + "diskSizeGB": "128", + "managedDisk": { + "storageAccountType": "Premium_LRS" + } + } + }, + "osType": { + "value": "Windows" + }, + "vmSize": { + "value": "Standard_DS2_v2" + }, + // Non-required parameters + "adminPassword": { + "value": "" + }, + "availabilityZone": { + "value": 2 + }, + "backupPolicyName": { + "value": "" + }, + "backupVaultName": { + "value": "" + }, + "backupVaultResourceGroup": { + "value": "" + }, + "computerName": { + "value": "winvm1" + }, + "dataDisks": { + "value": [ + { + "caching": "None", + "createOption": "Empty", + "deleteOption": "Delete", + "diskSizeGB": "128", + "managedDisk": { + "storageAccountType": "Premium_LRS" + } + }, + { + "caching": "None", + "createOption": "Empty", + "deleteOption": "Delete", + "diskSizeGB": "128", + "managedDisk": { + "storageAccountType": "Premium_LRS" + } + } + ] + }, + "enableAutomaticUpdates": { + "value": true + }, + "encryptionAtHost": { + "value": false + }, + "extensionAadJoinConfig": { + "value": { + "enabled": true, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionAntiMalwareConfig": { + "value": { + "enabled": true, + "settings": { + "AntimalwareEnabled": "true", + "Exclusions": { + "Extensions": ".ext1;.ext2", + "Paths": "c:\\excluded-path-1;c:\\excluded-path-2", + "Processes": "excludedproc1.exe;excludedproc2.exe" + }, + "RealtimeProtectionEnabled": "true", + "ScheduledScanSettings": { + "day": "7", + "isEnabled": "true", + "scanType": "Quick", + "time": "120" + } + }, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionAzureDiskEncryptionConfig": { + "value": { + "enabled": true, + "settings": { + "EncryptionOperation": "EnableEncryption", + "KekVaultResourceId": "", + "KeyEncryptionAlgorithm": "RSA-OAEP", + "KeyEncryptionKeyURL": "", + "KeyVaultResourceId": "", + "KeyVaultURL": "", + "ResizeOSDisk": "false", + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + }, + "VolumeType": "All" + } + } + }, + "extensionCustomScriptConfig": { + "value": { + "enabled": true, + "fileData": [ + { + "storageAccountId": "", + "uri": "" + } + ], + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionCustomScriptProtectedSetting": { + "value": { + "commandToExecute": "" + } + }, + "extensionDependencyAgentConfig": { + "value": { + "enabled": true, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionDSCConfig": { + "value": { + "enabled": true, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionMonitoringAgentConfig": { + "value": { + "enabled": true, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "extensionNetworkWatcherAgentConfig": { + "value": { + "enabled": true, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, + "location": { + "value": "" + }, + "lock": { + "value": { + "kind": "CanNotDelete", + "name": "myCustomLockName" + } + }, + "managedIdentities": { + "value": { + "systemAssigned": true, + "userAssignedResourceIds": [ + "" + ] + } + }, + "monitoringWorkspaceId": { + "value": "" + }, + "name": { + "value": "cvmwinmax" + }, + "patchMode": { + "value": "AutomaticByPlatform" + }, + "proximityPlacementGroupResourceId": { + "value": "" + }, + "roleAssignments": { + "value": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Owner" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "" + } + ] + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + } +} +``` + +
+

+ +### Example 8: _Windows.Ssecmk_ + +

+ +via Bicep module + +```bicep +module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { + name: '${uniqueString(deployment().name, location)}-test-cvmwincmk' + params: { + // Required parameters + adminUsername: 'VMAdministrator' + imageReference: { + offer: 'WindowsServer' + publisher: 'MicrosoftWindowsServer' + sku: '2019-datacenter' + version: 'latest' + } + nicConfigurations: [ + { + ipConfigurations: [ + { + name: 'ipconfig01' + subnetResourceId: '' + } + ] + nicSuffix: '-nic-01' + } + ] + osDisk: { + diskSizeGB: '128' + managedDisk: { + diskEncryptionSet: { + id: '' + } + storageAccountType: 'Premium_LRS' + } + } + osType: 'Windows' + vmSize: 'Standard_DS2_v2' + // Non-required parameters + adminPassword: '' + dataDisks: [ + { + diskSizeGB: '128' + managedDisk: { + diskEncryptionSet: { + id: '' + } + storageAccountType: 'Premium_LRS' + } + } + ] + location: '' + name: 'cvmwincmk' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } +} +``` + +
+

+ +

+ +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 + "adminUsername": { + "value": "VMAdministrator" + }, + "imageReference": { + "value": { + "offer": "WindowsServer", + "publisher": "MicrosoftWindowsServer", + "sku": "2019-datacenter", + "version": "latest" + } + }, + "nicConfigurations": { + "value": [ + { + "ipConfigurations": [ + { + "name": "ipconfig01", + "subnetResourceId": "" + } + ], + "nicSuffix": "-nic-01" + } + ] + }, + "osDisk": { + "value": { + "diskSizeGB": "128", + "managedDisk": { + "diskEncryptionSet": { + "id": "" + }, + "storageAccountType": "Premium_LRS" + } + } + }, + "osType": { + "value": "Windows" + }, + "vmSize": { + "value": "Standard_DS2_v2" + }, + // Non-required parameters + "adminPassword": { + "value": "" + }, + "dataDisks": { + "value": [ + { + "diskSizeGB": "128", + "managedDisk": { + "diskEncryptionSet": { + "id": "" + }, + "storageAccountType": "Premium_LRS" + } + } + ] + }, + "location": { + "value": "" + }, + "name": { + "value": "cvmwincmk" + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + } +} +``` + +
+

+ + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`adminUsername`](#parameter-adminusername) | securestring | Administrator username. | +| [`configurationProfile`](#parameter-configurationprofile) | string | The configuration profile of automanage. | +| [`imageReference`](#parameter-imagereference) | object | OS image reference. In case of marketplace images, it's the combination of the publisher, offer, sku, version attributes. In case of custom images it's the resource ID of the custom image. | +| [`nicConfigurations`](#parameter-nicconfigurations) | array | Configures NICs and PIPs. | +| [`osDisk`](#parameter-osdisk) | object | Specifies the OS disk. For security reasons, it is recommended to specify DiskEncryptionSet into the osDisk object. Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. | +| [`osType`](#parameter-ostype) | string | The chosen OS type. | +| [`vmSize`](#parameter-vmsize) | string | Specifies the size for the VMs. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`additionalUnattendContent`](#parameter-additionalunattendcontent) | array | Specifies additional base-64 encoded XML formatted information that can be included in the Unattend.xml file, which is used by Windows Setup. - AdditionalUnattendContent object. | +| [`adminPassword`](#parameter-adminpassword) | securestring | When specifying a Windows Virtual Machine, this value should be passed. | +| [`allowExtensionOperations`](#parameter-allowextensionoperations) | bool | Specifies whether extension operations should be allowed on the virtual machine. This may only be set to False when no extensions are present on the virtual machine. | +| [`availabilitySetResourceId`](#parameter-availabilitysetresourceid) | string | Resource ID of an availability set. Cannot be used in combination with availability zone nor scale set. | +| [`availabilityZone`](#parameter-availabilityzone) | int | If set to 1, 2 or 3, the availability zone for all VMs is hardcoded to that value. If zero, then availability zones is not used. Cannot be used in combination with availability set nor scale set. | +| [`backupPolicyName`](#parameter-backuppolicyname) | string | Backup policy the VMs should be using for backup. If not provided, it will use the DefaultPolicy from the backup recovery service vault. | +| [`backupVaultName`](#parameter-backupvaultname) | string | Recovery service vault name to add VMs to backup. | +| [`backupVaultResourceGroup`](#parameter-backupvaultresourcegroup) | string | Resource group of the backup recovery service vault. If not provided the current resource group name is considered by default. | +| [`bootDiagnostics`](#parameter-bootdiagnostics) | bool | Whether boot diagnostics should be enabled on the Virtual Machine. Boot diagnostics will be enabled with a managed storage account if no bootDiagnosticsStorageAccountName value is provided. If bootDiagnostics and bootDiagnosticsStorageAccountName values are not provided, boot diagnostics will be disabled. | +| [`bootDiagnosticStorageAccountName`](#parameter-bootdiagnosticstorageaccountname) | string | Custom storage account used to store boot diagnostic information. Boot diagnostics will be enabled with a custom storage account if a value is provided. | +| [`bootDiagnosticStorageAccountUri`](#parameter-bootdiagnosticstorageaccounturi) | string | Storage account boot diagnostic base URI. | +| [`certificatesToBeInstalled`](#parameter-certificatestobeinstalled) | array | Specifies set of certificates that should be installed onto the virtual machine. | +| [`computerName`](#parameter-computername) | string | Can be used if the computer name needs to be different from the Azure VM resource name. If not used, the resource name will be used as computer name. | +| [`customData`](#parameter-customdata) | string | Custom data associated to the VM, this value will be automatically converted into base64 to account for the expected VM format. | +| [`dataDisks`](#parameter-datadisks) | array | Specifies the data disks. For security reasons, it is recommended to specify DiskEncryptionSet into the dataDisk object. Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. | +| [`dedicatedHostId`](#parameter-dedicatedhostid) | string | Specifies resource ID about the dedicated host that the virtual machine resides in. | +| [`disablePasswordAuthentication`](#parameter-disablepasswordauthentication) | bool | Specifies whether password authentication should be disabled. | +| [`enableAutomaticUpdates`](#parameter-enableautomaticupdates) | bool | Indicates whether Automatic Updates is enabled for the Windows virtual machine. Default value is true. When patchMode is set to Manual, this parameter must be set to false. For virtual machine scale sets, this property can be updated and updates will take effect on OS reprovisioning. | +| [`enableDefaultTelemetry`](#parameter-enabledefaulttelemetry) | bool | Enable telemetry via a Globally Unique Identifier (GUID). | +| [`enableEvictionPolicy`](#parameter-enableevictionpolicy) | bool | Specifies the eviction policy for the low priority virtual machine. Will result in 'Deallocate' eviction policy. | +| [`encryptionAtHost`](#parameter-encryptionathost) | bool | This property can be used by user in the request to enable or disable the Host Encryption for the virtual machine. This will enable the encryption for all the disks including Resource/Temp disk at host itself. For security reasons, it is recommended to set encryptionAtHost to True. Restrictions: Cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. | +| [`extensionAadJoinConfig`](#parameter-extensionaadjoinconfig) | object | The configuration for the [AAD Join] extension. Must at least contain the ["enabled": true] property to be executed. | +| [`extensionAntiMalwareConfig`](#parameter-extensionantimalwareconfig) | object | The configuration for the [Anti Malware] extension. Must at least contain the ["enabled": true] property to be executed. | +| [`extensionAzureDiskEncryptionConfig`](#parameter-extensionazurediskencryptionconfig) | object | The configuration for the [Azure Disk Encryption] extension. Must at least contain the ["enabled": true] property to be executed. Restrictions: Cannot be enabled on disks that have encryption at host enabled. Managed disks encrypted using Azure Disk Encryption cannot be encrypted using customer-managed keys. | +| [`extensionCustomScriptConfig`](#parameter-extensioncustomscriptconfig) | object | The configuration for the [Custom Script] extension. Must at least contain the ["enabled": true] property to be executed. | +| [`extensionCustomScriptProtectedSetting`](#parameter-extensioncustomscriptprotectedsetting) | secureObject | Any object that contains the extension specific protected settings. | +| [`extensionDependencyAgentConfig`](#parameter-extensiondependencyagentconfig) | object | The configuration for the [Dependency Agent] extension. Must at least contain the ["enabled": true] property to be executed. | +| [`extensionDomainJoinConfig`](#parameter-extensiondomainjoinconfig) | object | The configuration for the [Domain Join] extension. Must at least contain the ["enabled": true] property to be executed. | +| [`extensionDomainJoinPassword`](#parameter-extensiondomainjoinpassword) | securestring | Required if name is specified. Password of the user specified in user parameter. | +| [`extensionDSCConfig`](#parameter-extensiondscconfig) | object | The configuration for the [Desired State Configuration] extension. Must at least contain the ["enabled": true] property to be executed. | +| [`extensionMonitoringAgentConfig`](#parameter-extensionmonitoringagentconfig) | object | The configuration for the [Monitoring Agent] extension. Must at least contain the ["enabled": true] property to be executed. | +| [`extensionNetworkWatcherAgentConfig`](#parameter-extensionnetworkwatcheragentconfig) | object | The configuration for the [Network Watcher Agent] extension. Must at least contain the ["enabled": true] property to be executed. | +| [`licenseType`](#parameter-licensetype) | string | Specifies that the image or disk that is being used was licensed on-premises. This element is only used for images that contain the Windows Server operating system. | +| [`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. The system-assigned managed identity will automatically be enabled if extensionAadJoinConfig.enabled = "True". | +| [`maxPriceForLowPriorityVm`](#parameter-maxpriceforlowpriorityvm) | string | Specifies the maximum price you are willing to pay for a low priority VM/VMSS. This price is in US Dollars. | +| [`monitoringWorkspaceId`](#parameter-monitoringworkspaceid) | string | Resource ID of the monitoring log analytics workspace. Must be set when extensionMonitoringAgentConfig is set to true. | +| [`name`](#parameter-name) | string | The name of the virtual machine to be created. You should use a unique prefix to reduce name collisions in Active Directory. If no value is provided, a 10 character long unique string will be generated based on the Resource Group's name. | +| [`patchAssessmentMode`](#parameter-patchassessmentmode) | string | VM guest patching assessment mode. Set it to 'AutomaticByPlatform' to enable automatically check for updates every 24 hours. | +| [`patchMode`](#parameter-patchmode) | string | VM guest patching orchestration mode. 'AutomaticByOS' & 'Manual' are for Windows only, 'ImageDefault' for Linux only. Refer to 'https://learn.microsoft.com/en-us/azure/virtual-machines/automatic-vm-guest-patching'. | +| [`plan`](#parameter-plan) | object | Specifies information about the marketplace image used to create the virtual machine. This element is only used for marketplace images. Before you can use a marketplace image from an API, you must enable the image for programmatic use. | +| [`priority`](#parameter-priority) | string | Specifies the priority for the virtual machine. | +| [`provisionVMAgent`](#parameter-provisionvmagent) | bool | Indicates whether virtual machine agent should be provisioned on the virtual machine. When this property is not specified in the request body, default behavior is to set it to true. This will ensure that VM Agent is installed on the VM so that extensions can be added to the VM later. | +| [`proximityPlacementGroupResourceId`](#parameter-proximityplacementgroupresourceid) | string | Resource ID of a proximity placement group. | +| [`publicKeys`](#parameter-publickeys) | array | The list of SSH public keys used to authenticate with linux based VMs. | +| [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | +| [`sasTokenValidityLength`](#parameter-sastokenvaliditylength) | string | SAS token validity length to use to download files from storage accounts. Usage: 'PT8H' - valid for 8 hours; 'P5D' - valid for 5 days; 'P1Y' - valid for 1 year. When not provided, the SAS token will be valid for 8 hours. | +| [`secureBootEnabled`](#parameter-securebootenabled) | bool | Specifies whether secure boot should be enabled on the virtual machine. This parameter is part of the UefiSettings. SecurityType should be set to TrustedLaunch to enable UefiSettings. | +| [`securityType`](#parameter-securitytype) | string | Specifies the SecurityType of the virtual machine. It is set as TrustedLaunch to enable UefiSettings. | +| [`tags`](#parameter-tags) | object | Tags of the resource. | +| [`timeZone`](#parameter-timezone) | string | Specifies the time zone of the virtual machine. e.g. 'Pacific Standard Time'. Possible values can be `TimeZoneInfo.id` value from time zones returned by `TimeZoneInfo.GetSystemTimeZones`. | +| [`ultraSSDEnabled`](#parameter-ultrassdenabled) | bool | The flag that enables or disables a capability to have one or more managed data disks with UltraSSD_LRS storage account type on the VM or VMSS. Managed disks with storage account type UltraSSD_LRS can be added to a virtual machine or virtual machine scale set only if this property is enabled. | +| [`vTpmEnabled`](#parameter-vtpmenabled) | bool | Specifies whether vTPM should be enabled on the virtual machine. This parameter is part of the UefiSettings. SecurityType should be set to TrustedLaunch to enable UefiSettings. | +| [`winRM`](#parameter-winrm) | object | Specifies the Windows Remote Management listeners. This enables remote Windows PowerShell. - WinRMConfiguration object. | + +**Generated parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`baseTime`](#parameter-basetime) | string | Do not provide a value! This date value is used to generate a registration token. | + +### Parameter: `adminUsername` + +Administrator username. + +- Required: Yes +- Type: securestring + +### Parameter: `configurationProfile` + +The configuration profile of automanage. + +- Required: No +- Type: string +- Default: `''` +- Allowed: + ```Bicep + [ + '' + '/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesDevTest' + '/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesProduction' + ] + ``` + +### Parameter: `imageReference` + +OS image reference. In case of marketplace images, it's the combination of the publisher, offer, sku, version attributes. In case of custom images it's the resource ID of the custom image. + +- Required: Yes +- Type: object + +### Parameter: `nicConfigurations` + +Configures NICs and PIPs. + +- Required: Yes +- Type: array + +### Parameter: `osDisk` + +Specifies the OS disk. For security reasons, it is recommended to specify DiskEncryptionSet into the osDisk object. Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. + +- Required: Yes +- Type: object + +### Parameter: `osType` + +The chosen OS type. + +- Required: Yes +- Type: string +- Allowed: + ```Bicep + [ + 'Linux' + 'Windows' + ] + ``` + +### Parameter: `vmSize` + +Specifies the size for the VMs. + +- Required: Yes +- Type: string + +### Parameter: `additionalUnattendContent` + +Specifies additional base-64 encoded XML formatted information that can be included in the Unattend.xml file, which is used by Windows Setup. - AdditionalUnattendContent object. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `adminPassword` + +When specifying a Windows Virtual Machine, this value should be passed. + +- Required: No +- Type: securestring +- Default: `''` + +### Parameter: `allowExtensionOperations` + +Specifies whether extension operations should be allowed on the virtual machine. This may only be set to False when no extensions are present on the virtual machine. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `availabilitySetResourceId` + +Resource ID of an availability set. Cannot be used in combination with availability zone nor scale set. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `availabilityZone` + +If set to 1, 2 or 3, the availability zone for all VMs is hardcoded to that value. If zero, then availability zones is not used. Cannot be used in combination with availability set nor scale set. + +- Required: No +- Type: int +- Default: `0` +- Allowed: + ```Bicep + [ + 0 + 1 + 2 + 3 + ] + ``` + +### Parameter: `backupPolicyName` + +Backup policy the VMs should be using for backup. If not provided, it will use the DefaultPolicy from the backup recovery service vault. + +- Required: No +- Type: string +- Default: `'DefaultPolicy'` + +### Parameter: `backupVaultName` + +Recovery service vault name to add VMs to backup. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `backupVaultResourceGroup` + +Resource group of the backup recovery service vault. If not provided the current resource group name is considered by default. + +- Required: No +- Type: string +- Default: `[resourceGroup().name]` + +### Parameter: `bootDiagnostics` + +Whether boot diagnostics should be enabled on the Virtual Machine. Boot diagnostics will be enabled with a managed storage account if no bootDiagnosticsStorageAccountName value is provided. If bootDiagnostics and bootDiagnosticsStorageAccountName values are not provided, boot diagnostics will be disabled. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `bootDiagnosticStorageAccountName` + +Custom storage account used to store boot diagnostic information. Boot diagnostics will be enabled with a custom storage account if a value is provided. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `bootDiagnosticStorageAccountUri` + +Storage account boot diagnostic base URI. + +- Required: No +- Type: string +- Default: `[format('.blob.{0}/', environment().suffixes.storage)]` + +### Parameter: `certificatesToBeInstalled` + +Specifies set of certificates that should be installed onto the virtual machine. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `computerName` + +Can be used if the computer name needs to be different from the Azure VM resource name. If not used, the resource name will be used as computer name. + +- Required: No +- Type: string +- Default: `[parameters('name')]` + +### Parameter: `customData` + +Custom data associated to the VM, this value will be automatically converted into base64 to account for the expected VM format. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `dataDisks` + +Specifies the data disks. For security reasons, it is recommended to specify DiskEncryptionSet into the dataDisk object. Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `dedicatedHostId` + +Specifies resource ID about the dedicated host that the virtual machine resides in. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `disablePasswordAuthentication` + +Specifies whether password authentication should be disabled. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `enableAutomaticUpdates` + +Indicates whether Automatic Updates is enabled for the Windows virtual machine. Default value is true. When patchMode is set to Manual, this parameter must be set to false. For virtual machine scale sets, this property can be updated and updates will take effect on OS reprovisioning. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `enableDefaultTelemetry` + +Enable telemetry via a Globally Unique Identifier (GUID). + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `enableEvictionPolicy` + +Specifies the eviction policy for the low priority virtual machine. Will result in 'Deallocate' eviction policy. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `encryptionAtHost` + +This property can be used by user in the request to enable or disable the Host Encryption for the virtual machine. This will enable the encryption for all the disks including Resource/Temp disk at host itself. For security reasons, it is recommended to set encryptionAtHost to True. Restrictions: Cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `extensionAadJoinConfig` + +The configuration for the [AAD Join] extension. Must at least contain the ["enabled": true] property to be executed. + +- Required: No +- Type: object +- Default: + ```Bicep + { + enabled: false + } + ``` + +### Parameter: `extensionAntiMalwareConfig` + +The configuration for the [Anti Malware] extension. Must at least contain the ["enabled": true] property to be executed. + +- Required: No +- Type: object +- Default: + ```Bicep + { + enabled: false + } + ``` + +### Parameter: `extensionAzureDiskEncryptionConfig` + +The configuration for the [Azure Disk Encryption] extension. Must at least contain the ["enabled": true] property to be executed. Restrictions: Cannot be enabled on disks that have encryption at host enabled. Managed disks encrypted using Azure Disk Encryption cannot be encrypted using customer-managed keys. + +- Required: No +- Type: object +- Default: + ```Bicep + { + enabled: false + } + ``` + +### Parameter: `extensionCustomScriptConfig` + +The configuration for the [Custom Script] extension. Must at least contain the ["enabled": true] property to be executed. + +- Required: No +- Type: object +- Default: + ```Bicep + { + enabled: false + fileData: [] + } + ``` + +### Parameter: `extensionCustomScriptProtectedSetting` + +Any object that contains the extension specific protected settings. + +- Required: No +- Type: secureObject +- Default: `{}` + +### Parameter: `extensionDependencyAgentConfig` + +The configuration for the [Dependency Agent] extension. Must at least contain the ["enabled": true] property to be executed. + +- Required: No +- Type: object +- Default: + ```Bicep + { + enabled: false + } + ``` + +### Parameter: `extensionDomainJoinConfig` + +The configuration for the [Domain Join] extension. Must at least contain the ["enabled": true] property to be executed. + +- Required: No +- Type: object +- Default: + ```Bicep + { + enabled: false + } + ``` + +### Parameter: `extensionDomainJoinPassword` + +Required if name is specified. Password of the user specified in user parameter. + +- Required: No +- Type: securestring +- Default: `''` + +### Parameter: `extensionDSCConfig` + +The configuration for the [Desired State Configuration] extension. Must at least contain the ["enabled": true] property to be executed. + +- Required: No +- Type: object +- Default: + ```Bicep + { + enabled: false + } + ``` + +### Parameter: `extensionMonitoringAgentConfig` + +The configuration for the [Monitoring Agent] extension. Must at least contain the ["enabled": true] property to be executed. + +- Required: No +- Type: object +- Default: + ```Bicep + { + enabled: false + } + ``` + +### Parameter: `extensionNetworkWatcherAgentConfig` + +The configuration for the [Network Watcher Agent] extension. Must at least contain the ["enabled": true] property to be executed. + +- Required: No +- Type: object +- Default: + ```Bicep + { + enabled: false + } + ``` + +### Parameter: `licenseType` + +Specifies that the image or disk that is being used was licensed on-premises. This element is only used for images that contain the Windows Server operating system. + +- Required: No +- Type: string +- Default: `''` +- Allowed: + ```Bicep + [ + '' + 'Windows_Client' + 'Windows_Server' + ] + ``` + +### Parameter: `location` + +Location for all resources. + +- Required: No +- Type: string +- Default: `[resourceGroup().location]` + +### Parameter: `lock` + +The lock settings of the service. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`kind`](#parameter-lockkind) | string | Specify the type of lock. | +| [`name`](#parameter-lockname) | string | Specify the name of lock. | + +### Parameter: `lock.kind` + +Specify the type of lock. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'CanNotDelete' + 'None' + 'ReadOnly' + ] + ``` + +### Parameter: `lock.name` + +Specify the name of lock. + +- Required: No +- Type: string + +### Parameter: `managedIdentities` + +The managed identity definition for this resource. The system-assigned managed identity will automatically be enabled if extensionAadJoinConfig.enabled = "True". + +- Required: No +- Type: object + +**Optional parameters** + +| 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. | + +### Parameter: `managedIdentities.systemAssigned` + +Enables system assigned managed identity on the resource. + +- Required: No +- Type: bool + +### Parameter: `managedIdentities.userAssignedResourceIds` + +The resource ID(s) to assign to the resource. + +- Required: No +- Type: array + +### Parameter: `maxPriceForLowPriorityVm` + +Specifies the maximum price you are willing to pay for a low priority VM/VMSS. This price is in US Dollars. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `monitoringWorkspaceId` + +Resource ID of the monitoring log analytics workspace. Must be set when extensionMonitoringAgentConfig is set to true. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `name` + +The name of the virtual machine to be created. You should use a unique prefix to reduce name collisions in Active Directory. If no value is provided, a 10 character long unique string will be generated based on the Resource Group's name. + +- Required: No +- Type: string +- Default: `[take(toLower(uniqueString(resourceGroup().name)), 10)]` + +### Parameter: `patchAssessmentMode` + +VM guest patching assessment mode. Set it to 'AutomaticByPlatform' to enable automatically check for updates every 24 hours. + +- Required: No +- Type: string +- Default: `'ImageDefault'` +- Allowed: + ```Bicep + [ + 'AutomaticByPlatform' + 'ImageDefault' + ] + ``` + +### Parameter: `patchMode` + +VM guest patching orchestration mode. 'AutomaticByOS' & 'Manual' are for Windows only, 'ImageDefault' for Linux only. Refer to 'https://learn.microsoft.com/en-us/azure/virtual-machines/automatic-vm-guest-patching'. + +- Required: No +- Type: string +- Default: `''` +- Allowed: + ```Bicep + [ + '' + 'AutomaticByOS' + 'AutomaticByPlatform' + 'ImageDefault' + 'Manual' + ] + ``` + +### Parameter: `plan` + +Specifies information about the marketplace image used to create the virtual machine. This element is only used for marketplace images. Before you can use a marketplace image from an API, you must enable the image for programmatic use. + +- Required: No +- Type: object +- Default: `{}` + +### Parameter: `priority` + +Specifies the priority for the virtual machine. + +- Required: No +- Type: string +- Default: `'Regular'` +- Allowed: + ```Bicep + [ + 'Low' + 'Regular' + 'Spot' + ] + ``` + +### Parameter: `provisionVMAgent` + +Indicates whether virtual machine agent should be provisioned on the virtual machine. When this property is not specified in the request body, default behavior is to set it to true. This will ensure that VM Agent is installed on the VM so that extensions can be added to the VM later. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `proximityPlacementGroupResourceId` + +Resource ID of a proximity placement group. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `publicKeys` + +The list of SSH public keys used to authenticate with linux based VMs. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `roleAssignments` + +Array of role assignments to create. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`principalId`](#parameter-roleassignmentsprincipalid) | string | The principal ID of the principal (user/group/identity) to assign the role to. | +| [`roleDefinitionIdOrName`](#parameter-roleassignmentsroledefinitionidorname) | string | 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'. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`condition`](#parameter-roleassignmentscondition) | string | 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`](#parameter-roleassignmentsconditionversion) | string | Version of the condition. | +| [`delegatedManagedIdentityResourceId`](#parameter-roleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | +| [`description`](#parameter-roleassignmentsdescription) | string | The description of the role assignment. | +| [`principalType`](#parameter-roleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. | + +### Parameter: `roleAssignments.principalId` + +The principal ID of the principal (user/group/identity) to assign the role to. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.roleDefinitionIdOrName` + +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'. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.condition` + +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" + +- Required: No +- Type: string + +### Parameter: `roleAssignments.conditionVersion` + +Version of the condition. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + '2.0' + ] + ``` + +### Parameter: `roleAssignments.delegatedManagedIdentityResourceId` + +The Resource Id of the delegated managed identity resource. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.description` + +The description of the role assignment. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.principalType` + +The principal type of the assigned principal ID. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Device' + 'ForeignGroup' + 'Group' + 'ServicePrincipal' + 'User' + ] + ``` + +### Parameter: `sasTokenValidityLength` + +SAS token validity length to use to download files from storage accounts. Usage: 'PT8H' - valid for 8 hours; 'P5D' - valid for 5 days; 'P1Y' - valid for 1 year. When not provided, the SAS token will be valid for 8 hours. + +- Required: No +- Type: string +- Default: `'PT8H'` + +### Parameter: `secureBootEnabled` + +Specifies whether secure boot should be enabled on the virtual machine. This parameter is part of the UefiSettings. SecurityType should be set to TrustedLaunch to enable UefiSettings. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `securityType` + +Specifies the SecurityType of the virtual machine. It is set as TrustedLaunch to enable UefiSettings. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `tags` + +Tags of the resource. + +- Required: No +- Type: object + +### Parameter: `timeZone` + +Specifies the time zone of the virtual machine. e.g. 'Pacific Standard Time'. Possible values can be `TimeZoneInfo.id` value from time zones returned by `TimeZoneInfo.GetSystemTimeZones`. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `ultraSSDEnabled` + +The flag that enables or disables a capability to have one or more managed data disks with UltraSSD_LRS storage account type on the VM or VMSS. Managed disks with storage account type UltraSSD_LRS can be added to a virtual machine or virtual machine scale set only if this property is enabled. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `vTpmEnabled` + +Specifies whether vTPM should be enabled on the virtual machine. This parameter is part of the UefiSettings. SecurityType should be set to TrustedLaunch to enable UefiSettings. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `winRM` + +Specifies the Windows Remote Management listeners. This enables remote Windows PowerShell. - WinRMConfiguration object. + +- Required: No +- Type: object +- Default: `{}` + +### Parameter: `baseTime` + +Do not provide a value! This date value is used to generate a registration token. + +- Required: No +- Type: string +- Default: `[utcNow('u')]` + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `location` | string | The location the resource was deployed into. | +| `name` | string | The name of the VM. | +| `resourceGroupName` | string | The name of the resource group the VM was created in. | +| `resourceId` | string | The resource ID of the VM. | +| `systemAssignedMIPrincipalId` | string | The principal ID of the system assigned identity. | + +## Cross-referenced modules + +This section gives you an overview of all local-referenced module files (i.e., other CARML 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/res/network/network-interface:0.2.2` | Remote reference | diff --git a/avm/res/compute/virtual-machine/main.json b/avm/res/compute/virtual-machine/main.json new file mode 100644 index 0000000000..f890008468 --- /dev/null +++ b/avm/res/compute/virtual-machine/main.json @@ -0,0 +1,3729 @@ +{ + "$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": "18084273995093499059" + }, + "name": "Virtual Machines", + "description": "This module deploys a Virtual Machine with one or multiple NICs and optionally one or multiple public IPs.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "managedIdentitiesType": { + "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" + }, + "nullable": true, + "metadata": { + "description": "Optional. The resource ID(s) to assign to the resource." + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "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 + }, + "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." + } + } + } + }, + "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." + } + } + } + }, + "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." + } + }, + "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." + } + }, + "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." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "defaultValue": "[take(toLower(uniqueString(resourceGroup().name)), 10)]", + "metadata": { + "description": "Optional. The name of the virtual machine to be created. You should use a unique prefix to reduce name collisions in Active Directory. If no value is provided, a 10 character long unique string will be generated based on the Resource Group's name." + } + }, + "computerName": { + "type": "string", + "defaultValue": "[parameters('name')]", + "metadata": { + "description": "Optional. Can be used if the computer name needs to be different from the Azure VM resource name. If not used, the resource name will be used as computer name." + } + }, + "vmSize": { + "type": "string", + "metadata": { + "description": "Required. Specifies the size for the VMs." + } + }, + "encryptionAtHost": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. This property can be used by user in the request to enable or disable the Host Encryption for the virtual machine. This will enable the encryption for all the disks including Resource/Temp disk at host itself. For security reasons, it is recommended to set encryptionAtHost to True. Restrictions: Cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs." + } + }, + "securityType": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Specifies the SecurityType of the virtual machine. It is set as TrustedLaunch to enable UefiSettings." + } + }, + "secureBootEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Specifies whether secure boot should be enabled on the virtual machine. This parameter is part of the UefiSettings. SecurityType should be set to TrustedLaunch to enable UefiSettings." + } + }, + "vTpmEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Specifies whether vTPM should be enabled on the virtual machine. This parameter is part of the UefiSettings. SecurityType should be set to TrustedLaunch to enable UefiSettings." + } + }, + "imageReference": { + "type": "object", + "metadata": { + "description": "Required. OS image reference. In case of marketplace images, it's the combination of the publisher, offer, sku, version attributes. In case of custom images it's the resource ID of the custom image." + } + }, + "plan": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Specifies information about the marketplace image used to create the virtual machine. This element is only used for marketplace images. Before you can use a marketplace image from an API, you must enable the image for programmatic use." + } + }, + "osDisk": { + "type": "object", + "metadata": { + "description": "Required. Specifies the OS disk. For security reasons, it is recommended to specify DiskEncryptionSet into the osDisk object. Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs." + } + }, + "dataDisks": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Specifies the data disks. For security reasons, it is recommended to specify DiskEncryptionSet into the dataDisk object. Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs." + } + }, + "ultraSSDEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. The flag that enables or disables a capability to have one or more managed data disks with UltraSSD_LRS storage account type on the VM or VMSS. Managed disks with storage account type UltraSSD_LRS can be added to a virtual machine or virtual machine scale set only if this property is enabled." + } + }, + "adminUsername": { + "type": "securestring", + "metadata": { + "description": "Required. Administrator username." + } + }, + "adminPassword": { + "type": "securestring", + "defaultValue": "", + "metadata": { + "description": "Optional. When specifying a Windows Virtual Machine, this value should be passed." + } + }, + "customData": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Custom data associated to the VM, this value will be automatically converted into base64 to account for the expected VM format." + } + }, + "certificatesToBeInstalled": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Specifies set of certificates that should be installed onto the virtual machine." + } + }, + "priority": { + "type": "string", + "defaultValue": "Regular", + "allowedValues": [ + "Regular", + "Low", + "Spot" + ], + "metadata": { + "description": "Optional. Specifies the priority for the virtual machine." + } + }, + "enableEvictionPolicy": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Specifies the eviction policy for the low priority virtual machine. Will result in 'Deallocate' eviction policy." + } + }, + "maxPriceForLowPriorityVm": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Specifies the maximum price you are willing to pay for a low priority VM/VMSS. This price is in US Dollars." + } + }, + "dedicatedHostId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Specifies resource ID about the dedicated host that the virtual machine resides in." + } + }, + "licenseType": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "Windows_Client", + "Windows_Server", + "" + ], + "metadata": { + "description": "Optional. Specifies that the image or disk that is being used was licensed on-premises. This element is only used for images that contain the Windows Server operating system." + } + }, + "publicKeys": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. The list of SSH public keys used to authenticate with linux based VMs." + } + }, + "managedIdentities": { + "$ref": "#/definitions/managedIdentitiesType", + "metadata": { + "description": "Optional. The managed identity definition for this resource. The system-assigned managed identity will automatically be enabled if extensionAadJoinConfig.enabled = \"True\"." + } + }, + "bootDiagnostics": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Whether boot diagnostics should be enabled on the Virtual Machine. Boot diagnostics will be enabled with a managed storage account if no bootDiagnosticsStorageAccountName value is provided. If bootDiagnostics and bootDiagnosticsStorageAccountName values are not provided, boot diagnostics will be disabled." + } + }, + "bootDiagnosticStorageAccountName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Custom storage account used to store boot diagnostic information. Boot diagnostics will be enabled with a custom storage account if a value is provided." + } + }, + "bootDiagnosticStorageAccountUri": { + "type": "string", + "defaultValue": "[format('.blob.{0}/', environment().suffixes.storage)]", + "metadata": { + "description": "Optional. Storage account boot diagnostic base URI." + } + }, + "proximityPlacementGroupResourceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of a proximity placement group." + } + }, + "availabilitySetResourceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of an availability set. Cannot be used in combination with availability zone nor scale set." + } + }, + "availabilityZone": { + "type": "int", + "defaultValue": 0, + "allowedValues": [ + 0, + 1, + 2, + 3 + ], + "metadata": { + "description": "Optional. If set to 1, 2 or 3, the availability zone for all VMs is hardcoded to that value. If zero, then availability zones is not used. Cannot be used in combination with availability set nor scale set." + } + }, + "nicConfigurations": { + "type": "array", + "metadata": { + "description": "Required. Configures NICs and PIPs." + } + }, + "backupVaultName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Recovery service vault name to add VMs to backup." + } + }, + "backupVaultResourceGroup": { + "type": "string", + "defaultValue": "[resourceGroup().name]", + "metadata": { + "description": "Optional. Resource group of the backup recovery service vault. If not provided the current resource group name is considered by default." + } + }, + "backupPolicyName": { + "type": "string", + "defaultValue": "DefaultPolicy", + "metadata": { + "description": "Optional. Backup policy the VMs should be using for backup. If not provided, it will use the DefaultPolicy from the backup recovery service vault." + } + }, + "allowExtensionOperations": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Specifies whether extension operations should be allowed on the virtual machine. This may only be set to False when no extensions are present on the virtual machine." + } + }, + "extensionDomainJoinPassword": { + "type": "securestring", + "defaultValue": "", + "metadata": { + "description": "Optional. Required if name is specified. Password of the user specified in user parameter." + } + }, + "extensionDomainJoinConfig": { + "type": "object", + "defaultValue": { + "enabled": false + }, + "metadata": { + "description": "Optional. The configuration for the [Domain Join] extension. Must at least contain the [\"enabled\": true] property to be executed." + } + }, + "extensionAadJoinConfig": { + "type": "object", + "defaultValue": { + "enabled": false + }, + "metadata": { + "description": "Optional. The configuration for the [AAD Join] extension. Must at least contain the [\"enabled\": true] property to be executed." + } + }, + "extensionAntiMalwareConfig": { + "type": "object", + "defaultValue": { + "enabled": false + }, + "metadata": { + "description": "Optional. The configuration for the [Anti Malware] extension. Must at least contain the [\"enabled\": true] property to be executed." + } + }, + "extensionMonitoringAgentConfig": { + "type": "object", + "defaultValue": { + "enabled": false + }, + "metadata": { + "description": "Optional. The configuration for the [Monitoring Agent] extension. Must at least contain the [\"enabled\": true] property to be executed." + } + }, + "monitoringWorkspaceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of the monitoring log analytics workspace. Must be set when extensionMonitoringAgentConfig is set to true." + } + }, + "extensionDependencyAgentConfig": { + "type": "object", + "defaultValue": { + "enabled": false + }, + "metadata": { + "description": "Optional. The configuration for the [Dependency Agent] extension. Must at least contain the [\"enabled\": true] property to be executed." + } + }, + "extensionNetworkWatcherAgentConfig": { + "type": "object", + "defaultValue": { + "enabled": false + }, + "metadata": { + "description": "Optional. The configuration for the [Network Watcher Agent] extension. Must at least contain the [\"enabled\": true] property to be executed." + } + }, + "extensionAzureDiskEncryptionConfig": { + "type": "object", + "defaultValue": { + "enabled": false + }, + "metadata": { + "description": "Optional. The configuration for the [Azure Disk Encryption] extension. Must at least contain the [\"enabled\": true] property to be executed. Restrictions: Cannot be enabled on disks that have encryption at host enabled. Managed disks encrypted using Azure Disk Encryption cannot be encrypted using customer-managed keys." + } + }, + "extensionDSCConfig": { + "type": "object", + "defaultValue": { + "enabled": false + }, + "metadata": { + "description": "Optional. The configuration for the [Desired State Configuration] extension. Must at least contain the [\"enabled\": true] property to be executed." + } + }, + "extensionCustomScriptConfig": { + "type": "object", + "defaultValue": { + "enabled": false, + "fileData": [] + }, + "metadata": { + "description": "Optional. The configuration for the [Custom Script] extension. Must at least contain the [\"enabled\": true] property to be executed." + } + }, + "extensionCustomScriptProtectedSetting": { + "type": "secureObject", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific protected settings." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + }, + "baseTime": { + "type": "string", + "defaultValue": "[utcNow('u')]", + "metadata": { + "description": "Generated. Do not provide a value! This date value is used to generate a registration token." + } + }, + "sasTokenValidityLength": { + "type": "string", + "defaultValue": "PT8H", + "metadata": { + "description": "Optional. SAS token validity length to use to download files from storage accounts. Usage: 'PT8H' - valid for 8 hours; 'P5D' - valid for 5 days; 'P1Y' - valid for 1 year. When not provided, the SAS token will be valid for 8 hours." + } + }, + "osType": { + "type": "string", + "allowedValues": [ + "Windows", + "Linux" + ], + "metadata": { + "description": "Required. The chosen OS type." + } + }, + "disablePasswordAuthentication": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Specifies whether password authentication should be disabled." + } + }, + "provisionVMAgent": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Indicates whether virtual machine agent should be provisioned on the virtual machine. When this property is not specified in the request body, default behavior is to set it to true. This will ensure that VM Agent is installed on the VM so that extensions can be added to the VM later." + } + }, + "enableAutomaticUpdates": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Indicates whether Automatic Updates is enabled for the Windows virtual machine. Default value is true. When patchMode is set to Manual, this parameter must be set to false. For virtual machine scale sets, this property can be updated and updates will take effect on OS reprovisioning." + } + }, + "patchMode": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "AutomaticByPlatform", + "AutomaticByOS", + "Manual", + "ImageDefault", + "" + ], + "metadata": { + "description": "Optional. VM guest patching orchestration mode. 'AutomaticByOS' & 'Manual' are for Windows only, 'ImageDefault' for Linux only. Refer to 'https://learn.microsoft.com/en-us/azure/virtual-machines/automatic-vm-guest-patching'." + } + }, + "patchAssessmentMode": { + "type": "string", + "defaultValue": "ImageDefault", + "allowedValues": [ + "AutomaticByPlatform", + "ImageDefault" + ], + "metadata": { + "description": "Optional. VM guest patching assessment mode. Set it to 'AutomaticByPlatform' to enable automatically check for updates every 24 hours." + } + }, + "timeZone": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Specifies the time zone of the virtual machine. e.g. 'Pacific Standard Time'. Possible values can be `TimeZoneInfo.id` value from time zones returned by `TimeZoneInfo.GetSystemTimeZones`." + } + }, + "additionalUnattendContent": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Specifies additional base-64 encoded XML formatted information that can be included in the Unattend.xml file, which is used by Windows Setup. - AdditionalUnattendContent object." + } + }, + "winRM": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Specifies the Windows Remote Management listeners. This enables remote Windows PowerShell. - WinRMConfiguration object." + } + }, + "configurationProfile": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesProduction", + "/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesDevTest", + "" + ], + "metadata": { + "description": "Required. The configuration profile of automanage." + } + } + }, + "variables": { + "copy": [ + { + "name": "publicKeysFormatted", + "count": "[length(parameters('publicKeys'))]", + "input": { + "path": "[parameters('publicKeys')[copyIndex('publicKeysFormatted')].path]", + "keyData": "[parameters('publicKeys')[copyIndex('publicKeysFormatted')].keyData]" + } + } + ], + "linuxConfiguration": { + "disablePasswordAuthentication": "[parameters('disablePasswordAuthentication')]", + "ssh": { + "publicKeys": "[variables('publicKeysFormatted')]" + }, + "provisionVMAgent": "[parameters('provisionVMAgent')]", + "patchSettings": "[if(and(parameters('provisionVMAgent'), or(equals(toLower(parameters('patchMode')), toLower('AutomaticByPlatform')), equals(toLower(parameters('patchMode')), toLower('ImageDefault')))), createObject('patchMode', parameters('patchMode'), 'assessmentMode', parameters('patchAssessmentMode')), null())]" + }, + "windowsConfiguration": { + "provisionVMAgent": "[parameters('provisionVMAgent')]", + "enableAutomaticUpdates": "[parameters('enableAutomaticUpdates')]", + "patchSettings": "[if(and(parameters('provisionVMAgent'), or(or(equals(toLower(parameters('patchMode')), toLower('AutomaticByPlatform')), equals(toLower(parameters('patchMode')), toLower('AutomaticByOS'))), equals(toLower(parameters('patchMode')), toLower('Manual')))), createObject('patchMode', parameters('patchMode'), 'assessmentMode', parameters('patchAssessmentMode')), null())]", + "timeZone": "[if(empty(parameters('timeZone')), null(), parameters('timeZone'))]", + "additionalUnattendContent": "[if(empty(parameters('additionalUnattendContent')), null(), parameters('additionalUnattendContent'))]", + "winRM": "[if(not(empty(parameters('winRM'))), createObject('listeners', parameters('winRM')), null())]" + }, + "accountSasProperties": { + "signedServices": "b", + "signedPermission": "r", + "signedExpiry": "[dateTimeAdd(parameters('baseTime'), parameters('sasTokenValidityLength'))]", + "signedResourceTypes": "o", + "signedProtocol": "https" + }, + "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]", + "identity": "[if(not(empty(parameters('managedIdentities'))), createObject('type', if(if(parameters('extensionAadJoinConfig').enabled, true(), coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false())), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'SystemAssigned,UserAssigned', 'SystemAssigned'), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'UserAssigned', null())), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]", + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Data Operator for Managed Disks": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '959f8984-c045-4866-89c7-12bf9737be2e')]", + "Desktop Virtualization Power On Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '489581de-a3bd-480d-9518-53dea7416b33')]", + "Desktop Virtualization Power On Off Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '40c5ff49-9181-41f8-ae61-143b0e78555e')]", + "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", + "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", + "Disk Backup Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3e5e47e6-65f7-47ef-90b5-e5dd4d455f24')]", + "Disk Pool Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '60fc6e62-5479-42d4-8bf4-67625fcc2840')]", + "Disk Restore Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b50d9833-a0cb-478e-945f-707fcc997c13')]", + "Disk Snapshot Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7efff54f-a5b4-42b5-a1c5-5411624893ce')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", + "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", + "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", + "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", + "VM Scanner Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'd24ecba3-c1f4-40fa-a7bb-4588a071e8fd')]" + } + }, + "resources": { + "defaultTelemetry": { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + "vm": { + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2022-11-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "identity": "[variables('identity')]", + "tags": "[parameters('tags')]", + "zones": "[if(not(equals(parameters('availabilityZone'), 0)), array(parameters('availabilityZone')), null())]", + "plan": "[if(not(empty(parameters('plan'))), parameters('plan'), null())]", + "properties": { + "hardwareProfile": { + "vmSize": "[parameters('vmSize')]" + }, + "securityProfile": { + "encryptionAtHost": "[if(parameters('encryptionAtHost'), parameters('encryptionAtHost'), null())]", + "securityType": "[parameters('securityType')]", + "uefiSettings": "[if(equals(parameters('securityType'), 'TrustedLaunch'), createObject('secureBootEnabled', parameters('secureBootEnabled'), 'vTpmEnabled', parameters('vTpmEnabled')), null())]" + }, + "storageProfile": { + "copy": [ + { + "name": "dataDisks", + "count": "[length(parameters('dataDisks'))]", + "input": { + "lun": "[copyIndex('dataDisks')]", + "name": "[format('{0}-disk-data-{1}', parameters('name'), padLeft(add(copyIndex('dataDisks'), 1), 2, '0'))]", + "diskSizeGB": "[parameters('dataDisks')[copyIndex('dataDisks')].diskSizeGB]", + "createOption": "[if(contains(parameters('dataDisks')[copyIndex('dataDisks')], 'createOption'), parameters('dataDisks')[copyIndex('dataDisks')].createOption, 'Empty')]", + "deleteOption": "[if(contains(parameters('dataDisks')[copyIndex('dataDisks')], 'deleteOption'), parameters('dataDisks')[copyIndex('dataDisks')].deleteOption, 'Delete')]", + "caching": "[if(contains(parameters('dataDisks')[copyIndex('dataDisks')], 'caching'), parameters('dataDisks')[copyIndex('dataDisks')].caching, 'ReadOnly')]", + "managedDisk": { + "storageAccountType": "[parameters('dataDisks')[copyIndex('dataDisks')].managedDisk.storageAccountType]", + "diskEncryptionSet": "[if(contains(parameters('dataDisks')[copyIndex('dataDisks')].managedDisk, 'diskEncryptionSet'), createObject('id', parameters('dataDisks')[copyIndex('dataDisks')].managedDisk.diskEncryptionSet.id), null())]" + } + } + } + ], + "imageReference": "[parameters('imageReference')]", + "osDisk": { + "name": "[format('{0}-disk-os-01', parameters('name'))]", + "createOption": "[if(contains(parameters('osDisk'), 'createOption'), parameters('osDisk').createOption, 'FromImage')]", + "deleteOption": "[if(contains(parameters('osDisk'), 'deleteOption'), parameters('osDisk').deleteOption, 'Delete')]", + "diskSizeGB": "[parameters('osDisk').diskSizeGB]", + "caching": "[if(contains(parameters('osDisk'), 'caching'), parameters('osDisk').caching, 'ReadOnly')]", + "managedDisk": { + "storageAccountType": "[parameters('osDisk').managedDisk.storageAccountType]", + "diskEncryptionSet": "[if(contains(parameters('osDisk').managedDisk, 'diskEncryptionSet'), createObject('id', parameters('osDisk').managedDisk.diskEncryptionSet.id), null())]" + } + } + }, + "additionalCapabilities": { + "ultraSSDEnabled": "[parameters('ultraSSDEnabled')]" + }, + "osProfile": { + "computerName": "[parameters('computerName')]", + "adminUsername": "[parameters('adminUsername')]", + "adminPassword": "[parameters('adminPassword')]", + "customData": "[if(not(empty(parameters('customData'))), base64(parameters('customData')), null())]", + "windowsConfiguration": "[if(equals(parameters('osType'), 'Windows'), variables('windowsConfiguration'), null())]", + "linuxConfiguration": "[if(equals(parameters('osType'), 'Linux'), variables('linuxConfiguration'), null())]", + "secrets": "[parameters('certificatesToBeInstalled')]", + "allowExtensionOperations": "[parameters('allowExtensionOperations')]" + }, + "networkProfile": { + "copy": [ + { + "name": "networkInterfaces", + "count": "[length(parameters('nicConfigurations'))]", + "input": { + "properties": { + "deleteOption": "[if(contains(parameters('nicConfigurations')[copyIndex('networkInterfaces')], 'deleteOption'), parameters('nicConfigurations')[copyIndex('networkInterfaces')].deleteOption, 'Delete')]", + "primary": "[if(equals(copyIndex('networkInterfaces'), 0), true(), false())]" + }, + "id": "[resourceId('Microsoft.Network/networkInterfaces', format('{0}{1}', parameters('name'), parameters('nicConfigurations')[copyIndex('networkInterfaces')].nicSuffix))]" + } + } + ] + }, + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": "[if(not(empty(parameters('bootDiagnosticStorageAccountName'))), true(), parameters('bootDiagnostics'))]", + "storageUri": "[if(not(empty(parameters('bootDiagnosticStorageAccountName'))), format('https://{0}{1}', parameters('bootDiagnosticStorageAccountName'), parameters('bootDiagnosticStorageAccountUri')), null())]" + } + }, + "availabilitySet": "[if(not(empty(parameters('availabilitySetResourceId'))), createObject('id', parameters('availabilitySetResourceId')), null())]", + "proximityPlacementGroup": "[if(not(empty(parameters('proximityPlacementGroupResourceId'))), createObject('id', parameters('proximityPlacementGroupResourceId')), null())]", + "priority": "[parameters('priority')]", + "evictionPolicy": "[if(parameters('enableEvictionPolicy'), 'Deallocate', null())]", + "billingProfile": "[if(and(not(empty(parameters('priority'))), not(empty(parameters('maxPriceForLowPriorityVm')))), createObject('maxPrice', parameters('maxPriceForLowPriorityVm')), null())]", + "host": "[if(not(empty(parameters('dedicatedHostId'))), createObject('id', parameters('dedicatedHostId')), null())]", + "licenseType": "[if(not(empty(parameters('licenseType'))), parameters('licenseType'), null())]" + }, + "dependsOn": [ + "vm_nic" + ] + }, + "vm_configurationProfileAssignment": { + "condition": "[not(empty(parameters('configurationProfile')))]", + "type": "Microsoft.Automanage/configurationProfileAssignments", + "apiVersion": "2021-04-30-preview", + "scope": "[format('Microsoft.Compute/virtualMachines/{0}', parameters('name'))]", + "name": "default", + "properties": { + "configurationProfile": "[parameters('configurationProfile')]" + }, + "dependsOn": [ + "vm" + ] + }, + "vm_logAnalyticsWorkspace": { + "condition": "[not(empty(parameters('monitoringWorkspaceId')))]", + "existing": true, + "type": "Microsoft.OperationalInsights/workspaces", + "apiVersion": "2021-06-01", + "subscriptionId": "[split(if(not(empty(parameters('monitoringWorkspaceId'))), parameters('monitoringWorkspaceId'), '//'), '/')[2]]", + "resourceGroup": "[split(if(not(empty(parameters('monitoringWorkspaceId'))), parameters('monitoringWorkspaceId'), '////'), '/')[4]]", + "name": "[last(split(if(not(empty(parameters('monitoringWorkspaceId'))), parameters('monitoringWorkspaceId'), 'law'), '/'))]" + }, + "vm_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Compute/virtualMachines/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "vm" + ] + }, + "vm_roleAssignments": { + "copy": { + "name": "vm_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Compute/virtualMachines/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Compute/virtualMachines', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "vm" + ] + }, + "vm_nic": { + "copy": { + "name": "vm_nic", + "count": "[length(parameters('nicConfigurations'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-VM-Nic-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[format('{0}{1}', parameters('name'), parameters('nicConfigurations')[copyIndex()].nicSuffix)]" + }, + "location": { + "value": "[parameters('location')]" + }, + "enableIPForwarding": "[if(contains(parameters('nicConfigurations')[copyIndex()], 'enableIPForwarding'), if(not(empty(parameters('nicConfigurations')[copyIndex()].enableIPForwarding)), createObject('value', parameters('nicConfigurations')[copyIndex()].enableIPForwarding), createObject('value', false())), createObject('value', false()))]", + "enableAcceleratedNetworking": "[if(contains(parameters('nicConfigurations')[copyIndex()], 'enableAcceleratedNetworking'), createObject('value', parameters('nicConfigurations')[copyIndex()].enableAcceleratedNetworking), createObject('value', true()))]", + "dnsServers": "[if(contains(parameters('nicConfigurations')[copyIndex()], 'dnsServers'), if(not(empty(parameters('nicConfigurations')[copyIndex()].dnsServers)), createObject('value', parameters('nicConfigurations')[copyIndex()].dnsServers), createObject('value', createArray())), createObject('value', createArray()))]", + "networkSecurityGroupResourceId": "[if(contains(parameters('nicConfigurations')[copyIndex()], 'networkSecurityGroupResourceId'), createObject('value', parameters('nicConfigurations')[copyIndex()].networkSecurityGroupResourceId), createObject('value', ''))]", + "ipConfigurations": { + "value": "[parameters('nicConfigurations')[copyIndex()].ipConfigurations]" + }, + "lock": { + "value": "[coalesce(tryGet(parameters('nicConfigurations')[copyIndex()], 'lock'), parameters('lock'))]" + }, + "tags": { + "value": "[coalesce(tryGet(parameters('nicConfigurations')[copyIndex()], 'tags'), parameters('tags'))]" + }, + "diagnosticSettings": { + "value": "[tryGet(parameters('nicConfigurations')[copyIndex()], 'diagnosticSettings')]" + }, + "roleAssignments": { + "value": "[tryGet(parameters('nicConfigurations')[copyIndex()], 'roleAssignments')]" + } + }, + "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": "14617314094453038306" + }, + "name": "Network Interface", + "description": "This module deploys a Network Interface.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "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." + } + } + } + }, + "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." + } + } + } + }, + "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." + } + }, + "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." + } + }, + "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." + } + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "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 + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the network interface." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Resource tags." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "enableIPForwarding": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether IP forwarding is enabled on this network interface." + } + }, + "enableAcceleratedNetworking": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. If the network interface is accelerated networking enabled." + } + }, + "dnsServers": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. List of DNS servers IP addresses. Use 'AzureProvidedDNS' to switch to azure provided DNS resolution. 'AzureProvidedDNS' value cannot be combined with other IPs, it must be the only value in dnsServers collection." + } + }, + "networkSecurityGroupResourceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The network security group (NSG) to attach to the network interface." + } + }, + "auxiliaryMode": { + "type": "string", + "defaultValue": "None", + "allowedValues": [ + "Floating", + "MaxConnections", + "None" + ], + "metadata": { + "description": "Optional. Auxiliary mode of Network Interface resource. Not all regions are enabled for Auxiliary Mode Nic." + } + }, + "auxiliarySku": { + "type": "string", + "defaultValue": "None", + "allowedValues": [ + "A1", + "A2", + "A4", + "A8", + "None" + ], + "metadata": { + "description": "Optional. Auxiliary sku of Network Interface resource. Not all regions are enabled for Auxiliary Mode Nic." + } + }, + "disableTcpStateTracking": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether to disable tcp state tracking. Subscription must be registered for the Microsoft.Network/AllowDisableTcpStateTracking feature before this property can be set to true." + } + }, + "ipConfigurations": { + "type": "array", + "metadata": { + "description": "Required. A list of IPConfigurations of the network interface." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.network-networkinterface.{0}.{1}', replace('0.2.2', '.', '-'), 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" + } + } + } + } + }, + "networkInterface": { + "type": "Microsoft.Network/networkInterfaces", + "apiVersion": "2023-04-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "copy": [ + { + "name": "ipConfigurations", + "count": "[length(parameters('ipConfigurations'))]", + "input": { + "name": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'name'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].name, format('ipconfig0{0}', add(copyIndex('ipConfigurations'), 1)))]", + "properties": { + "primary": "[if(equals(copyIndex('ipConfigurations'), 0), true(), false())]", + "privateIPAllocationMethod": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'privateIPAllocationMethod'), if(not(empty(parameters('ipConfigurations')[copyIndex('ipConfigurations')].privateIPAllocationMethod)), parameters('ipConfigurations')[copyIndex('ipConfigurations')].privateIPAllocationMethod, null()), null())]", + "privateIPAddress": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'privateIPAddress'), if(not(empty(parameters('ipConfigurations')[copyIndex('ipConfigurations')].privateIPAddress)), parameters('ipConfigurations')[copyIndex('ipConfigurations')].privateIPAddress, null()), null())]", + "publicIPAddress": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'publicIPAddressResourceId'), if(not(equals(parameters('ipConfigurations')[copyIndex('ipConfigurations')].publicIPAddressResourceId, null())), createObject('id', parameters('ipConfigurations')[copyIndex('ipConfigurations')].publicIPAddressResourceId), null()), null())]", + "subnet": { + "id": "[parameters('ipConfigurations')[copyIndex('ipConfigurations')].subnetResourceId]" + }, + "loadBalancerBackendAddressPools": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'loadBalancerBackendAddressPools'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].loadBalancerBackendAddressPools, null())]", + "applicationSecurityGroups": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'applicationSecurityGroups'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].applicationSecurityGroups, null())]", + "applicationGatewayBackendAddressPools": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'applicationGatewayBackendAddressPools'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].applicationGatewayBackendAddressPools, null())]", + "gatewayLoadBalancer": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'gatewayLoadBalancer'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].gatewayLoadBalancer, null())]", + "loadBalancerInboundNatRules": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'loadBalancerInboundNatRules'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].loadBalancerInboundNatRules, null())]", + "privateIPAddressVersion": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'privateIPAddressVersion'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].privateIPAddressVersion, null())]", + "virtualNetworkTaps": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'virtualNetworkTaps'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].virtualNetworkTaps, null())]" + } + } + } + ], + "auxiliaryMode": "[parameters('auxiliaryMode')]", + "auxiliarySku": "[parameters('auxiliarySku')]", + "disableTcpStateTracking": "[parameters('disableTcpStateTracking')]", + "dnsSettings": "[if(not(empty(parameters('dnsServers'))), createObject('dnsServers', parameters('dnsServers')), null())]", + "enableAcceleratedNetworking": "[parameters('enableAcceleratedNetworking')]", + "enableIPForwarding": "[parameters('enableIPForwarding')]", + "networkSecurityGroup": "[if(not(empty(parameters('networkSecurityGroupResourceId'))), createObject('id', parameters('networkSecurityGroupResourceId')), null())]" + } + }, + "networkInterface_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Network/networkInterfaces/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "networkInterface" + ] + }, + "networkInterface_diagnosticSettings": { + "copy": { + "name": "networkInterface_diagnosticSettings", + "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + }, + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.Network/networkInterfaces/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", + "properties": { + "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", + "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", + "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", + "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", + "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", + "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", + "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + }, + "dependsOn": [ + "networkInterface" + ] + }, + "networkInterface_roleAssignments": { + "copy": { + "name": "networkInterface_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/networkInterfaces/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/networkInterfaces', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "networkInterface" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed resource." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed resource." + }, + "value": "[resourceId('Microsoft.Network/networkInterfaces', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed resource." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('networkInterface', '2023-04-01', 'full').location]" + } + } + } + } + }, + "vm_aadJoinExtension": { + "condition": "[parameters('extensionAadJoinConfig').enabled]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-VM-AADLogin', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "virtualMachineName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "AADLogin" + }, + "location": { + "value": "[parameters('location')]" + }, + "publisher": { + "value": "Microsoft.Azure.ActiveDirectory" + }, + "type": "[if(equals(parameters('osType'), 'Windows'), createObject('value', 'AADLoginForWindows'), createObject('value', 'AADSSHLoginforLinux'))]", + "typeHandlerVersion": "[if(contains(parameters('extensionAadJoinConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionAadJoinConfig').typeHandlerVersion), createObject('value', '1.0'))]", + "autoUpgradeMinorVersion": "[if(contains(parameters('extensionAadJoinConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionAadJoinConfig').autoUpgradeMinorVersion), createObject('value', true()))]", + "enableAutomaticUpgrade": "[if(contains(parameters('extensionAadJoinConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionAadJoinConfig').enableAutomaticUpgrade), createObject('value', false()))]", + "settings": "[if(contains(parameters('extensionAadJoinConfig'), 'settings'), createObject('value', parameters('extensionAadJoinConfig').settings), createObject('value', createObject()))]", + "tags": { + "value": "[coalesce(tryGet(parameters('extensionAadJoinConfig'), 'tags'), parameters('tags'))]" + } + }, + "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": "5421737065579119324" + }, + "name": "Virtual Machine Extensions", + "description": "This module deploys a Virtual Machine Extension.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "virtualMachineName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the virtual machine extension." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. The location the extension is deployed to." + } + }, + "publisher": { + "type": "string", + "metadata": { + "description": "Required. The name of the extension handler publisher." + } + }, + "type": { + "type": "string", + "metadata": { + "description": "Required. Specifies the type of the extension; an example is \"CustomScriptExtension\"." + } + }, + "typeHandlerVersion": { + "type": "string", + "metadata": { + "description": "Required. Specifies the version of the script handler." + } + }, + "autoUpgradeMinorVersion": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true." + } + }, + "forceUpdateTag": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." + } + }, + "settings": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific settings." + } + }, + "protectedSettings": { + "type": "secureObject", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific protected settings." + } + }, + "supressFailures": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false." + } + }, + "enableAutomaticUpgrade": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + } + }, + "resources": { + "defaultTelemetry": { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + "virtualMachine": { + "existing": true, + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2022-11-01", + "name": "[parameters('virtualMachineName')]" + }, + "extension": { + "type": "Microsoft.Compute/virtualMachines/extensions", + "apiVersion": "2022-11-01", + "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "publisher": "[parameters('publisher')]", + "type": "[parameters('type')]", + "typeHandlerVersion": "[parameters('typeHandlerVersion')]", + "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", + "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", + "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", + "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", + "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", + "suppressFailures": "[parameters('supressFailures')]" + }, + "dependsOn": [ + "virtualMachine" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the extension." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the extension." + }, + "value": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the extension was created in." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('extension', '2022-11-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "vm" + ] + }, + "vm_domainJoinExtension": { + "condition": "[parameters('extensionDomainJoinConfig').enabled]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-VM-DomainJoin', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "virtualMachineName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "DomainJoin" + }, + "location": { + "value": "[parameters('location')]" + }, + "publisher": { + "value": "Microsoft.Compute" + }, + "type": { + "value": "JsonADDomainExtension" + }, + "typeHandlerVersion": "[if(contains(parameters('extensionDomainJoinConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionDomainJoinConfig').typeHandlerVersion), createObject('value', '1.3'))]", + "autoUpgradeMinorVersion": "[if(contains(parameters('extensionDomainJoinConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionDomainJoinConfig').autoUpgradeMinorVersion), createObject('value', true()))]", + "enableAutomaticUpgrade": "[if(contains(parameters('extensionDomainJoinConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionDomainJoinConfig').enableAutomaticUpgrade), createObject('value', false()))]", + "settings": { + "value": "[parameters('extensionDomainJoinConfig').settings]" + }, + "tags": { + "value": "[coalesce(tryGet(parameters('extensionDomainJoinConfig'), 'tags'), parameters('tags'))]" + }, + "protectedSettings": { + "value": { + "Password": "[parameters('extensionDomainJoinPassword')]" + } + }, + "enableDefaultTelemetry": { + "value": "[variables('enableReferencedModulesTelemetry')]" + } + }, + "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": "5421737065579119324" + }, + "name": "Virtual Machine Extensions", + "description": "This module deploys a Virtual Machine Extension.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "virtualMachineName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the virtual machine extension." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. The location the extension is deployed to." + } + }, + "publisher": { + "type": "string", + "metadata": { + "description": "Required. The name of the extension handler publisher." + } + }, + "type": { + "type": "string", + "metadata": { + "description": "Required. Specifies the type of the extension; an example is \"CustomScriptExtension\"." + } + }, + "typeHandlerVersion": { + "type": "string", + "metadata": { + "description": "Required. Specifies the version of the script handler." + } + }, + "autoUpgradeMinorVersion": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true." + } + }, + "forceUpdateTag": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." + } + }, + "settings": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific settings." + } + }, + "protectedSettings": { + "type": "secureObject", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific protected settings." + } + }, + "supressFailures": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false." + } + }, + "enableAutomaticUpgrade": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + } + }, + "resources": { + "defaultTelemetry": { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + "virtualMachine": { + "existing": true, + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2022-11-01", + "name": "[parameters('virtualMachineName')]" + }, + "extension": { + "type": "Microsoft.Compute/virtualMachines/extensions", + "apiVersion": "2022-11-01", + "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "publisher": "[parameters('publisher')]", + "type": "[parameters('type')]", + "typeHandlerVersion": "[parameters('typeHandlerVersion')]", + "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", + "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", + "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", + "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", + "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", + "suppressFailures": "[parameters('supressFailures')]" + }, + "dependsOn": [ + "virtualMachine" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the extension." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the extension." + }, + "value": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the extension was created in." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('extension', '2022-11-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "vm" + ] + }, + "vm_microsoftAntiMalwareExtension": { + "condition": "[parameters('extensionAntiMalwareConfig').enabled]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-VM-MicrosoftAntiMalware', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "virtualMachineName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "MicrosoftAntiMalware" + }, + "location": { + "value": "[parameters('location')]" + }, + "publisher": { + "value": "Microsoft.Azure.Security" + }, + "type": { + "value": "IaaSAntimalware" + }, + "typeHandlerVersion": "[if(contains(parameters('extensionAntiMalwareConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionAntiMalwareConfig').typeHandlerVersion), createObject('value', '1.3'))]", + "autoUpgradeMinorVersion": "[if(contains(parameters('extensionAntiMalwareConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionAntiMalwareConfig').autoUpgradeMinorVersion), createObject('value', true()))]", + "enableAutomaticUpgrade": "[if(contains(parameters('extensionAntiMalwareConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionAntiMalwareConfig').enableAutomaticUpgrade), createObject('value', false()))]", + "settings": { + "value": "[parameters('extensionAntiMalwareConfig').settings]" + }, + "tags": { + "value": "[coalesce(tryGet(parameters('extensionAntiMalwareConfig'), 'tags'), parameters('tags'))]" + }, + "enableDefaultTelemetry": { + "value": "[variables('enableReferencedModulesTelemetry')]" + } + }, + "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": "5421737065579119324" + }, + "name": "Virtual Machine Extensions", + "description": "This module deploys a Virtual Machine Extension.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "virtualMachineName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the virtual machine extension." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. The location the extension is deployed to." + } + }, + "publisher": { + "type": "string", + "metadata": { + "description": "Required. The name of the extension handler publisher." + } + }, + "type": { + "type": "string", + "metadata": { + "description": "Required. Specifies the type of the extension; an example is \"CustomScriptExtension\"." + } + }, + "typeHandlerVersion": { + "type": "string", + "metadata": { + "description": "Required. Specifies the version of the script handler." + } + }, + "autoUpgradeMinorVersion": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true." + } + }, + "forceUpdateTag": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." + } + }, + "settings": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific settings." + } + }, + "protectedSettings": { + "type": "secureObject", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific protected settings." + } + }, + "supressFailures": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false." + } + }, + "enableAutomaticUpgrade": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + } + }, + "resources": { + "defaultTelemetry": { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + "virtualMachine": { + "existing": true, + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2022-11-01", + "name": "[parameters('virtualMachineName')]" + }, + "extension": { + "type": "Microsoft.Compute/virtualMachines/extensions", + "apiVersion": "2022-11-01", + "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "publisher": "[parameters('publisher')]", + "type": "[parameters('type')]", + "typeHandlerVersion": "[parameters('typeHandlerVersion')]", + "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", + "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", + "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", + "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", + "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", + "suppressFailures": "[parameters('supressFailures')]" + }, + "dependsOn": [ + "virtualMachine" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the extension." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the extension." + }, + "value": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the extension was created in." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('extension', '2022-11-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "vm" + ] + }, + "vm_microsoftMonitoringAgentExtension": { + "condition": "[parameters('extensionMonitoringAgentConfig').enabled]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-VM-MicrosoftMonitoringAgent', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "virtualMachineName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "MicrosoftMonitoringAgent" + }, + "location": { + "value": "[parameters('location')]" + }, + "publisher": { + "value": "Microsoft.EnterpriseCloud.Monitoring" + }, + "type": "[if(equals(parameters('osType'), 'Windows'), createObject('value', 'MicrosoftMonitoringAgent'), createObject('value', 'OmsAgentForLinux'))]", + "typeHandlerVersion": "[if(contains(parameters('extensionMonitoringAgentConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionMonitoringAgentConfig').typeHandlerVersion), if(equals(parameters('osType'), 'Windows'), createObject('value', '1.0'), createObject('value', '1.7')))]", + "autoUpgradeMinorVersion": "[if(contains(parameters('extensionMonitoringAgentConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionMonitoringAgentConfig').autoUpgradeMinorVersion), createObject('value', true()))]", + "enableAutomaticUpgrade": "[if(contains(parameters('extensionMonitoringAgentConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionMonitoringAgentConfig').enableAutomaticUpgrade), createObject('value', false()))]", + "settings": { + "value": { + "workspaceId": "[if(not(empty(parameters('monitoringWorkspaceId'))), reference('vm_logAnalyticsWorkspace').customerId, '')]" + } + }, + "tags": { + "value": "[coalesce(tryGet(parameters('extensionMonitoringAgentConfig'), 'tags'), parameters('tags'))]" + }, + "protectedSettings": { + "value": { + "workspaceKey": "[if(not(empty(parameters('monitoringWorkspaceId'))), listKeys(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(if(not(empty(parameters('monitoringWorkspaceId'))), parameters('monitoringWorkspaceId'), '//'), '/')[2], split(if(not(empty(parameters('monitoringWorkspaceId'))), parameters('monitoringWorkspaceId'), '////'), '/')[4]), 'Microsoft.OperationalInsights/workspaces', last(split(if(not(empty(parameters('monitoringWorkspaceId'))), parameters('monitoringWorkspaceId'), 'law'), '/'))), '2021-06-01').primarySharedKey, '')]" + } + }, + "enableDefaultTelemetry": { + "value": "[variables('enableReferencedModulesTelemetry')]" + } + }, + "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": "5421737065579119324" + }, + "name": "Virtual Machine Extensions", + "description": "This module deploys a Virtual Machine Extension.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "virtualMachineName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the virtual machine extension." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. The location the extension is deployed to." + } + }, + "publisher": { + "type": "string", + "metadata": { + "description": "Required. The name of the extension handler publisher." + } + }, + "type": { + "type": "string", + "metadata": { + "description": "Required. Specifies the type of the extension; an example is \"CustomScriptExtension\"." + } + }, + "typeHandlerVersion": { + "type": "string", + "metadata": { + "description": "Required. Specifies the version of the script handler." + } + }, + "autoUpgradeMinorVersion": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true." + } + }, + "forceUpdateTag": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." + } + }, + "settings": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific settings." + } + }, + "protectedSettings": { + "type": "secureObject", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific protected settings." + } + }, + "supressFailures": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false." + } + }, + "enableAutomaticUpgrade": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + } + }, + "resources": { + "defaultTelemetry": { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + "virtualMachine": { + "existing": true, + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2022-11-01", + "name": "[parameters('virtualMachineName')]" + }, + "extension": { + "type": "Microsoft.Compute/virtualMachines/extensions", + "apiVersion": "2022-11-01", + "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "publisher": "[parameters('publisher')]", + "type": "[parameters('type')]", + "typeHandlerVersion": "[parameters('typeHandlerVersion')]", + "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", + "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", + "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", + "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", + "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", + "suppressFailures": "[parameters('supressFailures')]" + }, + "dependsOn": [ + "virtualMachine" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the extension." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the extension." + }, + "value": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the extension was created in." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('extension', '2022-11-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "vm", + "vm_logAnalyticsWorkspace" + ] + }, + "vm_dependencyAgentExtension": { + "condition": "[parameters('extensionDependencyAgentConfig').enabled]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-VM-DependencyAgent', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "virtualMachineName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "DependencyAgent" + }, + "location": { + "value": "[parameters('location')]" + }, + "publisher": { + "value": "Microsoft.Azure.Monitoring.DependencyAgent" + }, + "type": "[if(equals(parameters('osType'), 'Windows'), createObject('value', 'DependencyAgentWindows'), createObject('value', 'DependencyAgentLinux'))]", + "typeHandlerVersion": "[if(contains(parameters('extensionDependencyAgentConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionDependencyAgentConfig').typeHandlerVersion), createObject('value', '9.5'))]", + "autoUpgradeMinorVersion": "[if(contains(parameters('extensionDependencyAgentConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionDependencyAgentConfig').autoUpgradeMinorVersion), createObject('value', true()))]", + "enableAutomaticUpgrade": "[if(contains(parameters('extensionDependencyAgentConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionDependencyAgentConfig').enableAutomaticUpgrade), createObject('value', true()))]", + "enableDefaultTelemetry": { + "value": "[variables('enableReferencedModulesTelemetry')]" + }, + "tags": { + "value": "[coalesce(tryGet(parameters('extensionDependencyAgentConfig'), 'tags'), parameters('tags'))]" + } + }, + "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": "5421737065579119324" + }, + "name": "Virtual Machine Extensions", + "description": "This module deploys a Virtual Machine Extension.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "virtualMachineName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the virtual machine extension." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. The location the extension is deployed to." + } + }, + "publisher": { + "type": "string", + "metadata": { + "description": "Required. The name of the extension handler publisher." + } + }, + "type": { + "type": "string", + "metadata": { + "description": "Required. Specifies the type of the extension; an example is \"CustomScriptExtension\"." + } + }, + "typeHandlerVersion": { + "type": "string", + "metadata": { + "description": "Required. Specifies the version of the script handler." + } + }, + "autoUpgradeMinorVersion": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true." + } + }, + "forceUpdateTag": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." + } + }, + "settings": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific settings." + } + }, + "protectedSettings": { + "type": "secureObject", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific protected settings." + } + }, + "supressFailures": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false." + } + }, + "enableAutomaticUpgrade": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + } + }, + "resources": { + "defaultTelemetry": { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + "virtualMachine": { + "existing": true, + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2022-11-01", + "name": "[parameters('virtualMachineName')]" + }, + "extension": { + "type": "Microsoft.Compute/virtualMachines/extensions", + "apiVersion": "2022-11-01", + "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "publisher": "[parameters('publisher')]", + "type": "[parameters('type')]", + "typeHandlerVersion": "[parameters('typeHandlerVersion')]", + "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", + "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", + "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", + "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", + "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", + "suppressFailures": "[parameters('supressFailures')]" + }, + "dependsOn": [ + "virtualMachine" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the extension." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the extension." + }, + "value": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the extension was created in." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('extension', '2022-11-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "vm" + ] + }, + "vm_networkWatcherAgentExtension": { + "condition": "[parameters('extensionNetworkWatcherAgentConfig').enabled]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-VM-NetworkWatcherAgent', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "virtualMachineName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "NetworkWatcherAgent" + }, + "location": { + "value": "[parameters('location')]" + }, + "publisher": { + "value": "Microsoft.Azure.NetworkWatcher" + }, + "type": "[if(equals(parameters('osType'), 'Windows'), createObject('value', 'NetworkWatcherAgentWindows'), createObject('value', 'NetworkWatcherAgentLinux'))]", + "typeHandlerVersion": "[if(contains(parameters('extensionNetworkWatcherAgentConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionNetworkWatcherAgentConfig').typeHandlerVersion), createObject('value', '1.4'))]", + "autoUpgradeMinorVersion": "[if(contains(parameters('extensionNetworkWatcherAgentConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionNetworkWatcherAgentConfig').autoUpgradeMinorVersion), createObject('value', true()))]", + "enableAutomaticUpgrade": "[if(contains(parameters('extensionNetworkWatcherAgentConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionNetworkWatcherAgentConfig').enableAutomaticUpgrade), createObject('value', false()))]", + "enableDefaultTelemetry": { + "value": "[variables('enableReferencedModulesTelemetry')]" + }, + "tags": { + "value": "[coalesce(tryGet(parameters('extensionNetworkWatcherAgentConfig'), 'tags'), parameters('tags'))]" + } + }, + "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": "5421737065579119324" + }, + "name": "Virtual Machine Extensions", + "description": "This module deploys a Virtual Machine Extension.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "virtualMachineName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the virtual machine extension." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. The location the extension is deployed to." + } + }, + "publisher": { + "type": "string", + "metadata": { + "description": "Required. The name of the extension handler publisher." + } + }, + "type": { + "type": "string", + "metadata": { + "description": "Required. Specifies the type of the extension; an example is \"CustomScriptExtension\"." + } + }, + "typeHandlerVersion": { + "type": "string", + "metadata": { + "description": "Required. Specifies the version of the script handler." + } + }, + "autoUpgradeMinorVersion": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true." + } + }, + "forceUpdateTag": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." + } + }, + "settings": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific settings." + } + }, + "protectedSettings": { + "type": "secureObject", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific protected settings." + } + }, + "supressFailures": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false." + } + }, + "enableAutomaticUpgrade": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + } + }, + "resources": { + "defaultTelemetry": { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + "virtualMachine": { + "existing": true, + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2022-11-01", + "name": "[parameters('virtualMachineName')]" + }, + "extension": { + "type": "Microsoft.Compute/virtualMachines/extensions", + "apiVersion": "2022-11-01", + "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "publisher": "[parameters('publisher')]", + "type": "[parameters('type')]", + "typeHandlerVersion": "[parameters('typeHandlerVersion')]", + "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", + "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", + "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", + "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", + "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", + "suppressFailures": "[parameters('supressFailures')]" + }, + "dependsOn": [ + "virtualMachine" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the extension." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the extension." + }, + "value": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the extension was created in." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('extension', '2022-11-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "vm" + ] + }, + "vm_desiredStateConfigurationExtension": { + "condition": "[parameters('extensionDSCConfig').enabled]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-VM-DesiredStateConfiguration', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "virtualMachineName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "DesiredStateConfiguration" + }, + "location": { + "value": "[parameters('location')]" + }, + "publisher": { + "value": "Microsoft.Powershell" + }, + "type": { + "value": "DSC" + }, + "typeHandlerVersion": "[if(contains(parameters('extensionDSCConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionDSCConfig').typeHandlerVersion), createObject('value', '2.77'))]", + "autoUpgradeMinorVersion": "[if(contains(parameters('extensionDSCConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionDSCConfig').autoUpgradeMinorVersion), createObject('value', true()))]", + "enableAutomaticUpgrade": "[if(contains(parameters('extensionDSCConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionDSCConfig').enableAutomaticUpgrade), createObject('value', false()))]", + "settings": "[if(contains(parameters('extensionDSCConfig'), 'settings'), createObject('value', parameters('extensionDSCConfig').settings), createObject('value', createObject()))]", + "tags": { + "value": "[coalesce(tryGet(parameters('extensionDSCConfig'), 'tags'), parameters('tags'))]" + }, + "protectedSettings": "[if(contains(parameters('extensionDSCConfig'), 'protectedSettings'), createObject('value', parameters('extensionDSCConfig').protectedSettings), createObject('value', createObject()))]", + "enableDefaultTelemetry": { + "value": "[variables('enableReferencedModulesTelemetry')]" + } + }, + "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": "5421737065579119324" + }, + "name": "Virtual Machine Extensions", + "description": "This module deploys a Virtual Machine Extension.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "virtualMachineName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the virtual machine extension." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. The location the extension is deployed to." + } + }, + "publisher": { + "type": "string", + "metadata": { + "description": "Required. The name of the extension handler publisher." + } + }, + "type": { + "type": "string", + "metadata": { + "description": "Required. Specifies the type of the extension; an example is \"CustomScriptExtension\"." + } + }, + "typeHandlerVersion": { + "type": "string", + "metadata": { + "description": "Required. Specifies the version of the script handler." + } + }, + "autoUpgradeMinorVersion": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true." + } + }, + "forceUpdateTag": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." + } + }, + "settings": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific settings." + } + }, + "protectedSettings": { + "type": "secureObject", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific protected settings." + } + }, + "supressFailures": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false." + } + }, + "enableAutomaticUpgrade": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + } + }, + "resources": { + "defaultTelemetry": { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + "virtualMachine": { + "existing": true, + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2022-11-01", + "name": "[parameters('virtualMachineName')]" + }, + "extension": { + "type": "Microsoft.Compute/virtualMachines/extensions", + "apiVersion": "2022-11-01", + "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "publisher": "[parameters('publisher')]", + "type": "[parameters('type')]", + "typeHandlerVersion": "[parameters('typeHandlerVersion')]", + "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", + "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", + "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", + "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", + "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", + "suppressFailures": "[parameters('supressFailures')]" + }, + "dependsOn": [ + "virtualMachine" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the extension." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the extension." + }, + "value": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the extension was created in." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('extension', '2022-11-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "vm" + ] + }, + "vm_customScriptExtension": { + "condition": "[parameters('extensionCustomScriptConfig').enabled]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-VM-CustomScriptExtension', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "virtualMachineName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "CustomScriptExtension" + }, + "location": { + "value": "[parameters('location')]" + }, + "publisher": "[if(equals(parameters('osType'), 'Windows'), createObject('value', 'Microsoft.Compute'), createObject('value', 'Microsoft.Azure.Extensions'))]", + "type": "[if(equals(parameters('osType'), 'Windows'), createObject('value', 'CustomScriptExtension'), createObject('value', 'CustomScript'))]", + "typeHandlerVersion": "[if(contains(parameters('extensionCustomScriptConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionCustomScriptConfig').typeHandlerVersion), if(equals(parameters('osType'), 'Windows'), createObject('value', '1.10'), createObject('value', '2.1')))]", + "autoUpgradeMinorVersion": "[if(contains(parameters('extensionCustomScriptConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionCustomScriptConfig').autoUpgradeMinorVersion), createObject('value', true()))]", + "enableAutomaticUpgrade": "[if(contains(parameters('extensionCustomScriptConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionCustomScriptConfig').enableAutomaticUpgrade), createObject('value', false()))]", + "settings": { + "value": { + "copy": [ + { + "name": "fileUris", + "count": "[length(parameters('extensionCustomScriptConfig').fileData)]", + "input": "[if(contains(parameters('extensionCustomScriptConfig').fileData[copyIndex('fileUris')], 'storageAccountId'), format('{0}?{1}', parameters('extensionCustomScriptConfig').fileData[copyIndex('fileUris')].uri, listAccountSas(parameters('extensionCustomScriptConfig').fileData[copyIndex('fileUris')].storageAccountId, '2019-04-01', variables('accountSasProperties')).accountSasToken), parameters('extensionCustomScriptConfig').fileData[copyIndex('fileUris')].uri)]" + } + ] + } + }, + "tags": { + "value": "[coalesce(tryGet(parameters('extensionCustomScriptConfig'), 'tags'), parameters('tags'))]" + }, + "protectedSettings": { + "value": "[parameters('extensionCustomScriptProtectedSetting')]" + }, + "enableDefaultTelemetry": { + "value": "[variables('enableReferencedModulesTelemetry')]" + } + }, + "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": "5421737065579119324" + }, + "name": "Virtual Machine Extensions", + "description": "This module deploys a Virtual Machine Extension.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "virtualMachineName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the virtual machine extension." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. The location the extension is deployed to." + } + }, + "publisher": { + "type": "string", + "metadata": { + "description": "Required. The name of the extension handler publisher." + } + }, + "type": { + "type": "string", + "metadata": { + "description": "Required. Specifies the type of the extension; an example is \"CustomScriptExtension\"." + } + }, + "typeHandlerVersion": { + "type": "string", + "metadata": { + "description": "Required. Specifies the version of the script handler." + } + }, + "autoUpgradeMinorVersion": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true." + } + }, + "forceUpdateTag": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." + } + }, + "settings": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific settings." + } + }, + "protectedSettings": { + "type": "secureObject", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific protected settings." + } + }, + "supressFailures": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false." + } + }, + "enableAutomaticUpgrade": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + } + }, + "resources": { + "defaultTelemetry": { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + "virtualMachine": { + "existing": true, + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2022-11-01", + "name": "[parameters('virtualMachineName')]" + }, + "extension": { + "type": "Microsoft.Compute/virtualMachines/extensions", + "apiVersion": "2022-11-01", + "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "publisher": "[parameters('publisher')]", + "type": "[parameters('type')]", + "typeHandlerVersion": "[parameters('typeHandlerVersion')]", + "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", + "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", + "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", + "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", + "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", + "suppressFailures": "[parameters('supressFailures')]" + }, + "dependsOn": [ + "virtualMachine" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the extension." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the extension." + }, + "value": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the extension was created in." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('extension', '2022-11-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "vm", + "vm_desiredStateConfigurationExtension" + ] + }, + "vm_azureDiskEncryptionExtension": { + "condition": "[parameters('extensionAzureDiskEncryptionConfig').enabled]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-VM-AzureDiskEncryption', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "virtualMachineName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "AzureDiskEncryption" + }, + "location": { + "value": "[parameters('location')]" + }, + "publisher": { + "value": "Microsoft.Azure.Security" + }, + "type": "[if(equals(parameters('osType'), 'Windows'), createObject('value', 'AzureDiskEncryption'), createObject('value', 'AzureDiskEncryptionForLinux'))]", + "typeHandlerVersion": "[if(contains(parameters('extensionAzureDiskEncryptionConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionAzureDiskEncryptionConfig').typeHandlerVersion), if(equals(parameters('osType'), 'Windows'), createObject('value', '2.2'), createObject('value', '1.1')))]", + "autoUpgradeMinorVersion": "[if(contains(parameters('extensionAzureDiskEncryptionConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionAzureDiskEncryptionConfig').autoUpgradeMinorVersion), createObject('value', true()))]", + "enableAutomaticUpgrade": "[if(contains(parameters('extensionAzureDiskEncryptionConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionAzureDiskEncryptionConfig').enableAutomaticUpgrade), createObject('value', false()))]", + "forceUpdateTag": "[if(contains(parameters('extensionAzureDiskEncryptionConfig'), 'forceUpdateTag'), createObject('value', parameters('extensionAzureDiskEncryptionConfig').forceUpdateTag), createObject('value', '1.0'))]", + "settings": { + "value": "[parameters('extensionAzureDiskEncryptionConfig').settings]" + }, + "tags": { + "value": "[coalesce(tryGet(parameters('extensionAzureDiskEncryptionConfig'), 'tags'), parameters('tags'))]" + }, + "enableDefaultTelemetry": { + "value": "[variables('enableReferencedModulesTelemetry')]" + } + }, + "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": "5421737065579119324" + }, + "name": "Virtual Machine Extensions", + "description": "This module deploys a Virtual Machine Extension.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "virtualMachineName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the virtual machine extension." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. The location the extension is deployed to." + } + }, + "publisher": { + "type": "string", + "metadata": { + "description": "Required. The name of the extension handler publisher." + } + }, + "type": { + "type": "string", + "metadata": { + "description": "Required. Specifies the type of the extension; an example is \"CustomScriptExtension\"." + } + }, + "typeHandlerVersion": { + "type": "string", + "metadata": { + "description": "Required. Specifies the version of the script handler." + } + }, + "autoUpgradeMinorVersion": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true." + } + }, + "forceUpdateTag": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." + } + }, + "settings": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific settings." + } + }, + "protectedSettings": { + "type": "secureObject", + "defaultValue": {}, + "metadata": { + "description": "Optional. Any object that contains the extension specific protected settings." + } + }, + "supressFailures": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false." + } + }, + "enableAutomaticUpgrade": { + "type": "bool", + "metadata": { + "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + } + }, + "resources": { + "defaultTelemetry": { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + "virtualMachine": { + "existing": true, + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2022-11-01", + "name": "[parameters('virtualMachineName')]" + }, + "extension": { + "type": "Microsoft.Compute/virtualMachines/extensions", + "apiVersion": "2022-11-01", + "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "publisher": "[parameters('publisher')]", + "type": "[parameters('type')]", + "typeHandlerVersion": "[parameters('typeHandlerVersion')]", + "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", + "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", + "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", + "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", + "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", + "suppressFailures": "[parameters('supressFailures')]" + }, + "dependsOn": [ + "virtualMachine" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the extension." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the extension." + }, + "value": "[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the extension was created in." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('extension', '2022-11-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "vm", + "vm_customScriptExtension", + "vm_microsoftMonitoringAgentExtension" + ] + }, + "vm_backup": { + "condition": "[not(empty(parameters('backupVaultName')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-VM-Backup', uniqueString(deployment().name, parameters('location')))]", + "resourceGroup": "[parameters('backupVaultResourceGroup')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[format('vm;iaasvmcontainerv2;{0};{1}', resourceGroup().name, parameters('name'))]" + }, + "location": { + "value": "[parameters('location')]" + }, + "policyId": { + "value": "[resourceId('Microsoft.RecoveryServices/vaults/backupPolicies', parameters('backupVaultName'), parameters('backupPolicyName'))]" + }, + "protectedItemType": { + "value": "Microsoft.Compute/virtualMachines" + }, + "protectionContainerName": { + "value": "[format('iaasvmcontainer;iaasvmcontainerv2;{0};{1}', resourceGroup().name, parameters('name'))]" + }, + "recoveryVaultName": { + "value": "[parameters('backupVaultName')]" + }, + "sourceResourceId": { + "value": "[resourceId('Microsoft.Compute/virtualMachines', parameters('name'))]" + }, + "enableDefaultTelemetry": { + "value": "[variables('enableReferencedModulesTelemetry')]" + } + }, + "template": { + "$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": "9921011786088905122" + }, + "name": "Recovery Service Vaults Protection Container Protected Item", + "description": "This module deploys a Recovery Services Vault Protection Container Protected Item.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the resource." + } + }, + "protectionContainerName": { + "type": "string", + "metadata": { + "description": "Conditional. Name of the Azure Recovery Service Vault Protection Container. Required if the template is used in a standalone deployment." + } + }, + "recoveryVaultName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Azure Recovery Service Vault. Required if the template is used in a standalone deployment." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "protectedItemType": { + "type": "string", + "allowedValues": [ + "AzureFileShareProtectedItem", + "AzureVmWorkloadSAPAseDatabase", + "AzureVmWorkloadSAPHanaDatabase", + "AzureVmWorkloadSQLDatabase", + "DPMProtectedItem", + "GenericProtectedItem", + "MabFileFolderProtectedItem", + "Microsoft.ClassicCompute/virtualMachines", + "Microsoft.Compute/virtualMachines", + "Microsoft.Sql/servers/databases" + ], + "metadata": { + "description": "Required. The backup item type." + } + }, + "policyId": { + "type": "string", + "metadata": { + "description": "Required. ID of the backup policy with which this item is backed up." + } + }, + "sourceResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the resource to back up." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + } + }, + "resources": [ + { + "condition": "[parameters('enableDefaultTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2021-04-01", + "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + { + "type": "Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems", + "apiVersion": "2023-01-01", + "name": "[format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name'))]", + "location": "[parameters('location')]", + "properties": { + "protectedItemType": "[parameters('protectedItemType')]", + "policyId": "[parameters('policyId')]", + "sourceResourceId": "[parameters('sourceResourceId')]" + } + } + ], + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the protected item was created in." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the protected item." + }, + "value": "[resourceId('Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems', split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[0], split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[1], split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[2], split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[3])]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The Name of the protected item." + }, + "value": "[format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name'))]" + } + } + } + }, + "dependsOn": [ + "vm", + "vm_aadJoinExtension", + "vm_customScriptExtension", + "vm_dependencyAgentExtension", + "vm_desiredStateConfigurationExtension", + "vm_domainJoinExtension", + "vm_microsoftAntiMalwareExtension", + "vm_microsoftMonitoringAgentExtension", + "vm_networkWatcherAgentExtension" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the VM." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the VM." + }, + "value": "[resourceId('Microsoft.Compute/virtualMachines', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the VM was created in." + }, + "value": "[resourceGroup().name]" + }, + "systemAssignedMIPrincipalId": { + "type": "string", + "metadata": { + "description": "The principal ID of the system assigned identity." + }, + "value": "[if(and(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), contains(reference('vm', '2022-11-01', 'full').identity, 'principalId')), reference('vm', '2022-11-01', 'full').identity.principalId, '')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('vm', '2022-11-01', 'full').location]" + } + } +} \ No newline at end of file From 7d31c6947e78084a8c61393c8377636a45d5817d Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 7 Dec 2023 11:43:22 +0100 Subject: [PATCH 16/96] add pipeline --- .../avm.res.compute.virtual-machine.yml | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 .github/workflows/avm.res.compute.virtual-machine.yml diff --git a/.github/workflows/avm.res.compute.virtual-machine.yml b/.github/workflows/avm.res.compute.virtual-machine.yml new file mode 100644 index 0000000000..fb238043a1 --- /dev/null +++ b/.github/workflows/avm.res.compute.virtual-machine.yml @@ -0,0 +1,83 @@ +name: "avm.res.compute.virtual-machine" + +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.compute.virtual-machine.yml" + - "avm/res/compute/virtual-machine/**" + - "avm/utilities/pipelines/**" + - "!*/**/README.md" + +env: + modulePath: "avm/res/compute/virtual-machine" + workflowPath: ".github/workflows/avm.res.compute.virtual-machine.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 module test 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 }} + psRuleModuleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.psRuleModuleTestFilePaths }} + 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 }}" + psRuleModuleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.psRuleModuleTestFilePaths }}" + modulePath: "${{ needs.job_initialize_pipeline.outputs.modulePath}}" + secrets: inherit From 6a1cdfcf581d5593d663c514100ef6d2b4440ac4 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 7 Dec 2023 11:44:31 +0100 Subject: [PATCH 17/96] add pipeline for testing --- .../avm.res.compute.virtual-machine.yml | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 .github/workflows/avm.res.compute.virtual-machine.yml diff --git a/.github/workflows/avm.res.compute.virtual-machine.yml b/.github/workflows/avm.res.compute.virtual-machine.yml new file mode 100644 index 0000000000..fb238043a1 --- /dev/null +++ b/.github/workflows/avm.res.compute.virtual-machine.yml @@ -0,0 +1,83 @@ +name: "avm.res.compute.virtual-machine" + +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.compute.virtual-machine.yml" + - "avm/res/compute/virtual-machine/**" + - "avm/utilities/pipelines/**" + - "!*/**/README.md" + +env: + modulePath: "avm/res/compute/virtual-machine" + workflowPath: ".github/workflows/avm.res.compute.virtual-machine.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 module test 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 }} + psRuleModuleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.psRuleModuleTestFilePaths }} + 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 }}" + psRuleModuleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.psRuleModuleTestFilePaths }}" + modulePath: "${{ needs.job_initialize_pipeline.outputs.modulePath}}" + secrets: inherit From 77246eb39c6e732ff6ca432677d3d3738e60165f Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 7 Dec 2023 13:43:52 +0100 Subject: [PATCH 18/96] test --- .../compliance/module.tests.ps1 | 95 +++++++++++++------ 1 file changed, 64 insertions(+), 31 deletions(-) diff --git a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 index 097acbce2a..2c2bededb0 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 @@ -43,7 +43,9 @@ foreach ($moduleFolderPath in $moduleFolderPaths) { # building paths $builtTestFileMap = [System.Collections.Concurrent.ConcurrentDictionary[string, object]]::new() +# $pathsToBuild | ForEach-Object -Parallel { $pathsToBuild | ForEach-Object -Parallel { + # $dict = $using:builtTestFileMap $dict = $using:builtTestFileMap $builtTemplate = bicep build $_ --stdout | ConvertFrom-Json -AsHashtable $null = $dict.TryAdd($_, $builtTemplate) @@ -108,7 +110,8 @@ Describe 'File/folder tests' -Tag 'Modules' { # ========= try { $rawData = Invoke-WebRequest -Uri $telemetryCsvLink - } catch { + } + catch { $errorMessage = "Failed to download telemetry CSV file from [$telemetryCsvLink] due to [{0}]." -f $_.Exception.Message Write-Error $errorMessage Set-ItResult -Skipped -Because $errorMessage @@ -131,7 +134,8 @@ Describe 'File/folder tests' -Tag 'Modules' { if ($isOrphaned) { $pathExisting = Test-Path $orphanedFilePath $pathExisting | Should -Be $true -Because 'The module is orphaned.' - } else { + } + else { $pathExisting = Test-Path $orphanedFilePath $pathExisting | Should -Be $false -Because ('The module is not orphaned but owned by [{0}].' -f $relevantCSVRow.PrimaryModuleOwnerGHHandle) } @@ -423,13 +427,17 @@ Describe 'Module tests' -Tag 'Module' { $SchemaArray = @() if ($Schemaverion -eq $RgDeploymentSchema) { $SchemaOutput = $true - } elseIf ($Schemaverion -eq $SubscriptionDeploymentSchema) { + } + elseIf ($Schemaverion -eq $SubscriptionDeploymentSchema) { $SchemaOutput = $true - } elseIf ($Schemaverion -eq $MgDeploymentSchema) { + } + elseIf ($Schemaverion -eq $MgDeploymentSchema) { $SchemaOutput = $true - } elseIf ($Schemaverion -eq $TenantDeploymentSchema) { + } + elseIf ($Schemaverion -eq $TenantDeploymentSchema) { $SchemaOutput = $true - } else { + } + else { $SchemaOutput = $false } $SchemaArray += $SchemaOutput @@ -492,7 +500,8 @@ Describe 'Module tests' -Tag 'Module' { foreach ($Param in $Parameter) { if ($Param.substring(0, 1) -cnotmatch '[a-z]' -or $Param -match '-' -or $Param -match '_') { $CamelCasingFlag += $false - } else { + } + else { $CamelCasingFlag += $true } } @@ -517,7 +526,8 @@ Describe 'Module tests' -Tag 'Module' { foreach ($Variab in $Variable) { if ($Variab.substring(0, 1) -cnotmatch '[a-z]' -or $Variab -match '-') { $CamelCasingFlag += $false - } else { + } + else { $CamelCasingFlag += $true } } @@ -536,7 +546,8 @@ Describe 'Module tests' -Tag 'Module' { foreach ($Output in $Outputs) { if ($Output.substring(0, 1) -cnotmatch '[a-z]' -or $Output -match '-' -or $Output -match '_') { $CamelCasingFlag += $false - } else { + } + else { $CamelCasingFlag += $true } } @@ -553,7 +564,8 @@ Describe 'Module tests' -Tag 'Module' { # With the introduction of user defined types, the way resources are configured in the schema slightly changed. We have to account for that. if ($templateContent.resources.GetType().Name -eq 'Object[]') { $templateResources = $templateContent.resources - } else { + } + else { $templateResources = $templateContent.resources.Keys | ForEach-Object { $templateContent.resources[$_] } } @@ -571,7 +583,8 @@ Describe 'Module tests' -Tag 'Module' { # With the introduction of user defined types, the way resources are configured in the schema slightly changed. We have to account for that. if ($templateContent.resources.GetType().Name -eq 'Object[]') { $templateResources = $templateContent.resources - } else { + } + else { $templateResources = $templateContent.resources.Keys | ForEach-Object { $templateContent.resources[$_] } } @@ -595,7 +608,8 @@ Describe 'Module tests' -Tag 'Module' { # With the introduction of user defined types, the way resources are configured in the schema slightly changed. We have to account for that. if ($templateContent.resources.GetType().Name -eq 'Object[]') { $templateResources = $templateContent.resources - } else { + } + else { $templateResources = $templateContent.resources.Keys | ForEach-Object { $templateContent.resources[$_] } } @@ -624,7 +638,8 @@ Describe 'Module tests' -Tag 'Module' { # ========= try { $rawData = Invoke-WebRequest -Uri $telemetryCsvLink - } catch { + } + catch { $errorMessage = "Failed to download telemetry CSV file from [$telemetryCsvLink] due to [{0}]." -f $_.Exception.Message Write-Error $errorMessage Set-ItResult -Skipped -Because $errorMessage @@ -650,7 +665,8 @@ Describe 'Module tests' -Tag 'Module' { # With the introduction of user defined types, the way resources are configured in the schema slightly changed. We have to account for that. if ($templateContent.resources.GetType().Name -eq 'Object[]') { $templateResources = $templateContent.resources - } else { + } + else { $templateResources = $templateContent.resources.Keys | ForEach-Object { $templateContent.resources[$_] } } $telemetryDeploymentName = ($templateResources | Where-Object { $_.condition -like "*telemetry*" }).name # The AVM telemetry prefix @@ -671,7 +687,8 @@ Describe 'Module tests' -Tag 'Module' { if ($Locationparamoutput -contains 'Location') { if ($Locationparamoutputvalue -eq '[resourceGroup().Location]' -or $Locationparamoutputvalue -eq 'global') { $LocationFlag = $true - } else { + } + else { $LocationFlag = $false } @@ -732,7 +749,8 @@ Describe 'Module tests' -Tag 'Module' { $readMeFileContentHeader = (Get-Content -Path $readMeFilePath)[0] if ($readMeFileContentHeader -match '^.*`\[(.+)\]`.*') { $primaryResourceType = $matches[1] - } else { + } + else { Write-Error "Cannot identity primary resource type in readme header [$readMeFileContentHeader] and cannot execute the test." return } @@ -740,7 +758,8 @@ Describe 'Module tests' -Tag 'Module' { # With the introduction of user defined types, the way resources are configured in the schema slightly changed. We have to account for that. if ($templateContent.resources.GetType().Name -eq 'Object[]') { $templateResources = $templateContent.resources - } else { + } + else { $templateResources = $templateContent.resources.Keys | ForEach-Object { $templateContent.resources[$_] } } @@ -766,7 +785,8 @@ Describe 'Module tests' -Tag 'Module' { $readMeFileContentHeader = (Get-Content -Path $readMeFilePath)[0] if ($readMeFileContentHeader -match '^.*`\[(.+)\]`.*') { $primaryResourceType = $matches[1] - } else { + } + else { Write-Error "Cannot identity primary resource type in readme header [$readMeFileContentHeader] and cannot execute the test." return } @@ -774,7 +794,8 @@ Describe 'Module tests' -Tag 'Module' { # With the introduction of user defined types, the way resources are configured in the schema slightly changed. We have to account for that. if ($templateContent.resources.GetType().Name -eq 'Object[]') { $templateResources = $templateContent.resources - } else { + } + else { $templateResources = $templateContent.resources.Keys | ForEach-Object { $templateContent.resources[$_] } } @@ -1055,10 +1076,12 @@ Describe 'Module tests' -Tag 'Module' { $rawReponse = Invoke-WebRequest -Uri $expectedUdtUrl if (($rawReponse.Headers['Content-Type'] | Out-String) -like "*text/plain*") { $expectedSchemaFull = $rawReponse.Content -split '\n' - } else { + } + else { throw "Failed to fetch schema from [$expectedUdtUrl]. Skipping schema check" } - } catch { + } + catch { Write-Warning "Failed to fetch schema from [$expectedUdtUrl]. Skipping schema check" return } @@ -1077,7 +1100,8 @@ Describe 'Module tests' -Tag 'Module' { foreach ($finding in (Compare-Object $implementedSchema $expectedSchema)) { if ($finding.SideIndicator -eq '=>') { $formattedDiff += ('+ {0}' -f $finding.InputObject) - } elseif ($finding.SideIndicator -eq '<=') { + } + elseif ($finding.SideIndicator -eq '<=') { $formattedDiff += ('- {0}' -f $finding.InputObject) } } @@ -1094,7 +1118,8 @@ Describe 'Module tests' -Tag 'Module' { } } } - } else { + } + else { Set-ItResult -Skipped -Because "the module template has no [$parameterName] parameter." } } @@ -1107,7 +1132,8 @@ Describe 'Module tests' -Tag 'Module' { if ($templateFileContent.definitions.Keys -contains 'managedIdentitiesType' -and $templateFileContent.definitions.managedIdentitiesType.properties.keys -contains 'systemAssigned') { $templateFileContent.outputs.Keys | Should -Contain 'systemAssignedMIPrincipalId' -Because 'The AVM specs require a this output. For information please review the [AVM Specs](https://aka.ms/avm/interfaces/managed-identities).' - } else { + } + else { Set-ItResult -Skipped -Because 'the module template has no [managedIdentitiesType] UDT definition or does not support system-assigned-identities.' } } @@ -1120,7 +1146,8 @@ Describe 'Module tests' -Tag 'Module' { if ($templateFileContent.parameters.Keys -contains 'tags') { $templateFileContent.parameters.tags.nullable | Should -Be $true -Because 'The AVM specs require a specific format. For information please review the [AVM Specs](https://aka.ms/avm/interfaces/tags).' - } else { + } + else { Set-ItResult -Skipped -Because 'the module template has no [tags] parameter.' } } @@ -1166,7 +1193,8 @@ Describe 'Test file tests' -Tag 'TestTemplate' { if (($testFileContent | Out-String) -match "param serviceShort string = '(.*)'") { $Matches[1] | Should -BeLike '*min' - } else { + } + else { Set-ItResult -Skipped -Because 'the module test deployment file should contain a parameter [serviceShort] using the syntax [param serviceShort string = ''*min''] but it doesn''t.' } } @@ -1179,7 +1207,8 @@ Describe 'Test file tests' -Tag 'TestTemplate' { if (($testFileContent | Out-String) -match "param serviceShort string = '(.*)'") { $Matches[1] | Should -BeLike '*max' - } else { + } + else { Set-ItResult -Skipped -Because 'the module test deployment file should contain a parameter [serviceShort] using the syntax [param serviceShort string = ''*max''] but it doesn''t.' } } @@ -1192,7 +1221,8 @@ Describe 'Test file tests' -Tag 'TestTemplate' { if (($testFileContent | Out-String) -match "param serviceShort string = '(.*)'") { $Matches[1] | Should -BeLike '*waf' - } else { + } + else { Set-ItResult -Skipped -Because 'the module test deployment file should contain a parameter [serviceShort] using the syntax [param serviceShort string = ''*waf''] but it doesn''t.' } } @@ -1265,7 +1295,8 @@ Describe 'API version tests' -Tag 'ApiCheck' { try { $apiSpecs = Invoke-WebRequest -Uri $ApiSpecsFileUri $ApiVersions = ConvertFrom-Json $apiSpecs.Content -AsHashtable - } catch { + } + catch { Write-Warning "Failed to download API specs file from [$ApiSpecsFileUri]. Skipping API tests" Set-ItResult -Skipped -Because "Failed to download API specs file from [$ApiSpecsFileUri]. Skipping API tests." return @@ -1378,7 +1409,8 @@ Describe 'API version tests' -Tag 'ApiCheck' { # We allow the latest 5 including previews (in case somebody wants to use preview), or the latest 3 non-preview $approvedApiVersions += $resourceTypeApiVersions | Select-Object -Last 5 $approvedApiVersions += $resourceTypeApiVersions | Where-Object { $_ -notlike '*-preview' } | Select-Object -Last 5 - } else { + } + else { # We allow the latest 5 non-preview preview $approvedApiVersions += $resourceTypeApiVersions | Where-Object { $_ -notlike '*-preview' } | Select-Object -Last 5 } @@ -1391,7 +1423,8 @@ Describe 'API version tests' -Tag 'ApiCheck' { # The original failed test was # $approvedApiVersions | Should -Contain $TargetApi - } else { + } + else { # Provide a warning if an API version is second to next to expire. $indexOfVersion = $approvedApiVersions.IndexOf($TargetApi) From fdfadc05b1ec1b248247c266c8acf756b81d2b03 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 7 Dec 2023 13:47:56 +0100 Subject: [PATCH 19/96] test --- .../pipelines/staticValidation/compliance/module.tests.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 index 2c2bededb0..0421139a23 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 @@ -44,9 +44,9 @@ foreach ($moduleFolderPath in $moduleFolderPaths) { # building paths $builtTestFileMap = [System.Collections.Concurrent.ConcurrentDictionary[string, object]]::new() # $pathsToBuild | ForEach-Object -Parallel { -$pathsToBuild | ForEach-Object -Parallel { +$pathsToBuild | ForEach-Object { # $dict = $using:builtTestFileMap - $dict = $using:builtTestFileMap + $dict = $builtTestFileMap $builtTemplate = bicep build $_ --stdout | ConvertFrom-Json -AsHashtable $null = $dict.TryAdd($_, $builtTemplate) } From a5e687e67063de195e12bb960436da9bc67d5f32 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 7 Dec 2023 14:13:30 +0100 Subject: [PATCH 20/96] move children --- .../virtual-machine/extension/README.md | 165 ++++++++++++++++++ .../virtual-machine/extension/main.json | 4 +- .../virtual-machine/extension/version.json | 7 - avm/res/compute/virtual-machine/main.bicep | 3 +- .../protected-item.bicep} | 15 -- .../virtual-machine/protected-item/main.json | 128 -------------- .../protected-item/version.json | 7 - 7 files changed, 168 insertions(+), 161 deletions(-) create mode 100644 avm/res/compute/virtual-machine/extension/README.md delete mode 100644 avm/res/compute/virtual-machine/extension/version.json rename avm/res/compute/virtual-machine/{protected-item/main.bicep => modules/protected-item.bicep} (79%) delete mode 100644 avm/res/compute/virtual-machine/protected-item/main.json delete mode 100644 avm/res/compute/virtual-machine/protected-item/version.json diff --git a/avm/res/compute/virtual-machine/extension/README.md b/avm/res/compute/virtual-machine/extension/README.md new file mode 100644 index 0000000000..324ebc8179 --- /dev/null +++ b/avm/res/compute/virtual-machine/extension/README.md @@ -0,0 +1,165 @@ +# Virtual Machine Extensions `[Microsoft.Compute/virtualMachines/extensions]` + +This module deploys a Virtual Machine Extension. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Compute/virtualMachines/extensions` | [2022-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Compute/2022-11-01/virtualMachines/extensions) | + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`autoUpgradeMinorVersion`](#parameter-autoupgrademinorversion) | bool | Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true. | +| [`enableAutomaticUpgrade`](#parameter-enableautomaticupgrade) | bool | Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available. | +| [`name`](#parameter-name) | string | The name of the virtual machine extension. | +| [`publisher`](#parameter-publisher) | string | The name of the extension handler publisher. | +| [`type`](#parameter-type) | string | Specifies the type of the extension; an example is "CustomScriptExtension". | +| [`typeHandlerVersion`](#parameter-typehandlerversion) | string | Specifies the version of the script handler. | + +**Conditional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`virtualMachineName`](#parameter-virtualmachinename) | string | The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enableDefaultTelemetry`](#parameter-enabledefaulttelemetry) | bool | Enable telemetry via a Globally Unique Identifier (GUID). | +| [`forceUpdateTag`](#parameter-forceupdatetag) | string | How the extension handler should be forced to update even if the extension configuration has not changed. | +| [`location`](#parameter-location) | string | The location the extension is deployed to. | +| [`protectedSettings`](#parameter-protectedsettings) | secureObject | Any object that contains the extension specific protected settings. | +| [`settings`](#parameter-settings) | object | Any object that contains the extension specific settings. | +| [`supressFailures`](#parameter-supressfailures) | bool | Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false. | +| [`tags`](#parameter-tags) | object | Tags of the resource. | + +### Parameter: `autoUpgradeMinorVersion` + +Indicates whether the extension should use a newer minor version if one is available at deployment time. Once deployed, however, the extension will not upgrade minor versions unless redeployed, even with this property set to true. + +- Required: Yes +- Type: bool + +### Parameter: `enableAutomaticUpgrade` + +Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available. + +- Required: Yes +- Type: bool + +### Parameter: `name` + +The name of the virtual machine extension. + +- Required: Yes +- Type: string + +### Parameter: `publisher` + +The name of the extension handler publisher. + +- Required: Yes +- Type: string + +### Parameter: `type` + +Specifies the type of the extension; an example is "CustomScriptExtension". + +- Required: Yes +- Type: string + +### Parameter: `typeHandlerVersion` + +Specifies the version of the script handler. + +- Required: Yes +- Type: string + +### Parameter: `virtualMachineName` + +The name of the parent virtual machine that extension is provisioned for. Required if the template is used in a standalone deployment. + +- Required: Yes +- Type: string + +### Parameter: `enableDefaultTelemetry` + +Enable telemetry via a Globally Unique Identifier (GUID). + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `forceUpdateTag` + +How the extension handler should be forced to update even if the extension configuration has not changed. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `location` + +The location the extension is deployed to. + +- Required: No +- Type: string +- Default: `[resourceGroup().location]` + +### Parameter: `protectedSettings` + +Any object that contains the extension specific protected settings. + +- Required: No +- Type: secureObject +- Default: `{}` + +### Parameter: `settings` + +Any object that contains the extension specific settings. + +- Required: No +- Type: object +- Default: `{}` + +### Parameter: `supressFailures` + +Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `tags` + +Tags of the resource. + +- Required: No +- Type: object + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `location` | string | The location the resource was deployed into. | +| `name` | string | The name of the extension. | +| `resourceGroupName` | string | The name of the Resource Group the extension was created in. | +| `resourceId` | string | The resource ID of the extension. | + +## Cross-referenced modules + +_None_ diff --git a/avm/res/compute/virtual-machine/extension/main.json b/avm/res/compute/virtual-machine/extension/main.json index 50534220f0..5ddd571641 100644 --- a/avm/res/compute/virtual-machine/extension/main.json +++ b/avm/res/compute/virtual-machine/extension/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "9638144716839375831" + "version": "0.23.1.45101", + "templateHash": "5421737065579119324" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", diff --git a/avm/res/compute/virtual-machine/extension/version.json b/avm/res/compute/virtual-machine/extension/version.json deleted file mode 100644 index 8def869ede..0000000000 --- a/avm/res/compute/virtual-machine/extension/version.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.1", - "pathFilters": [ - "./main.json" - ] -} diff --git a/avm/res/compute/virtual-machine/main.bicep b/avm/res/compute/virtual-machine/main.bicep index d02256a8f3..a57788f3ed 100644 --- a/avm/res/compute/virtual-machine/main.bicep +++ b/avm/res/compute/virtual-machine/main.bicep @@ -635,7 +635,7 @@ module vm_azureDiskEncryptionExtension 'extension/main.bicep' = if (extensionAzu ] } -module vm_backup 'protected-item/main.bicep' = if (!empty(backupVaultName)) { +module vm_backup 'modules/protected-item.bicep' = if (!empty(backupVaultName)) { name: '${uniqueString(deployment().name, location)}-VM-Backup' params: { name: 'vm;iaasvmcontainerv2;${resourceGroup().name};${vm.name}' @@ -645,7 +645,6 @@ module vm_backup 'protected-item/main.bicep' = if (!empty(backupVaultName)) { protectionContainerName: 'iaasvmcontainer;iaasvmcontainerv2;${resourceGroup().name};${vm.name}' recoveryVaultName: backupVaultName sourceResourceId: vm.id - enableDefaultTelemetry: enableReferencedModulesTelemetry } scope: az.resourceGroup(backupVaultResourceGroup) dependsOn: [ diff --git a/avm/res/compute/virtual-machine/protected-item/main.bicep b/avm/res/compute/virtual-machine/modules/protected-item.bicep similarity index 79% rename from avm/res/compute/virtual-machine/protected-item/main.bicep rename to avm/res/compute/virtual-machine/modules/protected-item.bicep index 7631577c89..dbba0616ac 100644 --- a/avm/res/compute/virtual-machine/protected-item/main.bicep +++ b/avm/res/compute/virtual-machine/modules/protected-item.bicep @@ -35,21 +35,6 @@ param policyId string @description('Required. Resource ID of the resource to back up.') param sourceResourceId string -@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') -param enableDefaultTelemetry bool = true - -resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (enableDefaultTelemetry) { - name: 'pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-${uniqueString(deployment().name, location)}' - properties: { - mode: 'Incremental' - template: { - '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' - contentVersion: '1.0.0.0' - resources: [] - } - } -} - resource protectedItem 'Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems@2023-01-01' = { name: '${recoveryVaultName}/Azure/${protectionContainerName}/${name}' location: location diff --git a/avm/res/compute/virtual-machine/protected-item/main.json b/avm/res/compute/virtual-machine/protected-item/main.json deleted file mode 100644 index 232937bb2a..0000000000 --- a/avm/res/compute/virtual-machine/protected-item/main.json +++ /dev/null @@ -1,128 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "7148492251760573310" - }, - "name": "Recovery Service Vaults Protection Container Protected Item", - "description": "This module deploys a Recovery Services Vault Protection Container Protected Item.", - "owner": "Azure/module-maintainers" - }, - "parameters": { - "name": { - "type": "string", - "metadata": { - "description": "Required. Name of the resource." - } - }, - "protectionContainerName": { - "type": "string", - "metadata": { - "description": "Conditional. Name of the Azure Recovery Service Vault Protection Container. Required if the template is used in a standalone deployment." - } - }, - "recoveryVaultName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent Azure Recovery Service Vault. Required if the template is used in a standalone deployment." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. Location for all resources." - } - }, - "protectedItemType": { - "type": "string", - "allowedValues": [ - "AzureFileShareProtectedItem", - "AzureVmWorkloadSAPAseDatabase", - "AzureVmWorkloadSAPHanaDatabase", - "AzureVmWorkloadSQLDatabase", - "DPMProtectedItem", - "GenericProtectedItem", - "MabFileFolderProtectedItem", - "Microsoft.ClassicCompute/virtualMachines", - "Microsoft.Compute/virtualMachines", - "Microsoft.Sql/servers/databases" - ], - "metadata": { - "description": "Required. The backup item type." - } - }, - "policyId": { - "type": "string", - "metadata": { - "description": "Required. ID of the backup policy with which this item is backed up." - } - }, - "sourceResourceId": { - "type": "string", - "metadata": { - "description": "Required. Resource ID of the resource to back up." - } - }, - "enableDefaultTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." - } - } - }, - "resources": [ - { - "condition": "[parameters('enableDefaultTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2021-04-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [] - } - } - }, - { - "type": "Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems", - "apiVersion": "2023-01-01", - "name": "[format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name'))]", - "location": "[parameters('location')]", - "properties": { - "protectedItemType": "[parameters('protectedItemType')]", - "policyId": "[parameters('policyId')]", - "sourceResourceId": "[parameters('sourceResourceId')]" - } - } - ], - "outputs": { - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the Resource Group the protected item was created in." - }, - "value": "[resourceGroup().name]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the protected item." - }, - "value": "[resourceId('Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems', split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[0], split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[1], split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[2], split(format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name')), '/')[3])]" - }, - "name": { - "type": "string", - "metadata": { - "description": "The Name of the protected item." - }, - "value": "[format('{0}/Azure/{1}/{2}', parameters('recoveryVaultName'), parameters('protectionContainerName'), parameters('name'))]" - } - } -} \ No newline at end of file diff --git a/avm/res/compute/virtual-machine/protected-item/version.json b/avm/res/compute/virtual-machine/protected-item/version.json deleted file mode 100644 index 96236a61ba..0000000000 --- a/avm/res/compute/virtual-machine/protected-item/version.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.4", - "pathFilters": [ - "./main.json" - ] -} From 85b99dd8faf3cd436727f6c1dc911862c3e84a2d Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 7 Dec 2023 14:31:11 +0100 Subject: [PATCH 21/96] change enableTelemetry --- avm/res/compute/virtual-machine/main.bicep | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/avm/res/compute/virtual-machine/main.bicep b/avm/res/compute/virtual-machine/main.bicep index a57788f3ed..280682d0c9 100644 --- a/avm/res/compute/virtual-machine/main.bicep +++ b/avm/res/compute/virtual-machine/main.bicep @@ -196,7 +196,7 @@ param roleAssignments roleAssignmentType param tags object? @description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') -param enableDefaultTelemetry bool = true +param enableTelemetry bool = true @description('Generated. Do not provide a value! This date value is used to generate a registration token.') param baseTime string = utcNow('u') @@ -325,7 +325,7 @@ var builtInRoleNames = { 'VM Scanner Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'd24ecba3-c1f4-40fa-a7bb-4588a071e8fd') } -resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (enableDefaultTelemetry) { +resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (enableTelemetry) { name: 'pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-${uniqueString(deployment().name, location)}' properties: { mode: 'Incremental' @@ -492,7 +492,7 @@ module vm_domainJoinExtension 'extension/main.bicep' = if (extensionDomainJoinCo protectedSettings: { Password: extensionDomainJoinPassword } - enableDefaultTelemetry: enableReferencedModulesTelemetry + enableTelemetry: enableReferencedModulesTelemetry } } @@ -509,7 +509,7 @@ module vm_microsoftAntiMalwareExtension 'extension/main.bicep' = if (extensionAn enableAutomaticUpgrade: contains(extensionAntiMalwareConfig, 'enableAutomaticUpgrade') ? extensionAntiMalwareConfig.enableAutomaticUpgrade : false settings: extensionAntiMalwareConfig.settings tags: extensionAntiMalwareConfig.?tags ?? tags - enableDefaultTelemetry: enableReferencedModulesTelemetry + enableTelemetry: enableReferencedModulesTelemetry } } @@ -536,7 +536,7 @@ module vm_microsoftMonitoringAgentExtension 'extension/main.bicep' = if (extensi protectedSettings: { workspaceKey: !empty(monitoringWorkspaceId) ? vm_logAnalyticsWorkspace.listKeys().primarySharedKey : '' } - enableDefaultTelemetry: enableReferencedModulesTelemetry + enableTelemetry: enableReferencedModulesTelemetry } } @@ -551,7 +551,7 @@ module vm_dependencyAgentExtension 'extension/main.bicep' = if (extensionDepende typeHandlerVersion: contains(extensionDependencyAgentConfig, 'typeHandlerVersion') ? extensionDependencyAgentConfig.typeHandlerVersion : '9.5' autoUpgradeMinorVersion: contains(extensionDependencyAgentConfig, 'autoUpgradeMinorVersion') ? extensionDependencyAgentConfig.autoUpgradeMinorVersion : true enableAutomaticUpgrade: contains(extensionDependencyAgentConfig, 'enableAutomaticUpgrade') ? extensionDependencyAgentConfig.enableAutomaticUpgrade : true - enableDefaultTelemetry: enableReferencedModulesTelemetry + enableTelemetry: enableReferencedModulesTelemetry tags: extensionDependencyAgentConfig.?tags ?? tags } } @@ -567,7 +567,7 @@ module vm_networkWatcherAgentExtension 'extension/main.bicep' = if (extensionNet typeHandlerVersion: contains(extensionNetworkWatcherAgentConfig, 'typeHandlerVersion') ? extensionNetworkWatcherAgentConfig.typeHandlerVersion : '1.4' autoUpgradeMinorVersion: contains(extensionNetworkWatcherAgentConfig, 'autoUpgradeMinorVersion') ? extensionNetworkWatcherAgentConfig.autoUpgradeMinorVersion : true enableAutomaticUpgrade: contains(extensionNetworkWatcherAgentConfig, 'enableAutomaticUpgrade') ? extensionNetworkWatcherAgentConfig.enableAutomaticUpgrade : false - enableDefaultTelemetry: enableReferencedModulesTelemetry + enableTelemetry: enableReferencedModulesTelemetry tags: extensionNetworkWatcherAgentConfig.?tags ?? tags } } @@ -586,7 +586,7 @@ module vm_desiredStateConfigurationExtension 'extension/main.bicep' = if (extens settings: contains(extensionDSCConfig, 'settings') ? extensionDSCConfig.settings : {} tags: extensionDSCConfig.?tags ?? tags protectedSettings: contains(extensionDSCConfig, 'protectedSettings') ? extensionDSCConfig.protectedSettings : {} - enableDefaultTelemetry: enableReferencedModulesTelemetry + enableTelemetry: enableReferencedModulesTelemetry } } @@ -606,7 +606,7 @@ module vm_customScriptExtension 'extension/main.bicep' = if (extensionCustomScri } tags: extensionCustomScriptConfig.?tags ?? tags protectedSettings: extensionCustomScriptProtectedSetting - enableDefaultTelemetry: enableReferencedModulesTelemetry + enableTelemetry: enableReferencedModulesTelemetry } dependsOn: [ vm_desiredStateConfigurationExtension @@ -627,7 +627,7 @@ module vm_azureDiskEncryptionExtension 'extension/main.bicep' = if (extensionAzu forceUpdateTag: contains(extensionAzureDiskEncryptionConfig, 'forceUpdateTag') ? extensionAzureDiskEncryptionConfig.forceUpdateTag : '1.0' settings: extensionAzureDiskEncryptionConfig.settings tags: extensionAzureDiskEncryptionConfig.?tags ?? tags - enableDefaultTelemetry: enableReferencedModulesTelemetry + enableTelemetry: enableReferencedModulesTelemetry } dependsOn: [ vm_customScriptExtension From 839ec998f0303196a09290be16fd8529a44a29aa Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 7 Dec 2023 15:11:56 +0100 Subject: [PATCH 22/96] small fixes --- avm/res/compute/virtual-machine/README.md | 15 +- .../virtual-machine/extension/main.bicep | 15 - avm/res/compute/virtual-machine/main.bicep | 10 - avm/res/compute/virtual-machine/main.json | 266 +----------------- 4 files changed, 21 insertions(+), 285 deletions(-) diff --git a/avm/res/compute/virtual-machine/README.md b/avm/res/compute/virtual-machine/README.md index 2c008c1f3a..be80e21bf8 100644 --- a/avm/res/compute/virtual-machine/README.md +++ b/avm/res/compute/virtual-machine/README.md @@ -40,7 +40,6 @@ The following section provides usage examples for the module, which were used to - [Using large parameter set](#example-7-using-large-parameter-set) - [Windows.Ssecmk](#example-8-windowsssecmk) - ### Example 1: _Linux.Atmg_

@@ -2591,8 +2590,8 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { | [`dedicatedHostId`](#parameter-dedicatedhostid) | string | Specifies resource ID about the dedicated host that the virtual machine resides in. | | [`disablePasswordAuthentication`](#parameter-disablepasswordauthentication) | bool | Specifies whether password authentication should be disabled. | | [`enableAutomaticUpdates`](#parameter-enableautomaticupdates) | bool | Indicates whether Automatic Updates is enabled for the Windows virtual machine. Default value is true. When patchMode is set to Manual, this parameter must be set to false. For virtual machine scale sets, this property can be updated and updates will take effect on OS reprovisioning. | -| [`enableDefaultTelemetry`](#parameter-enabledefaulttelemetry) | bool | Enable telemetry via a Globally Unique Identifier (GUID). | | [`enableEvictionPolicy`](#parameter-enableevictionpolicy) | bool | Specifies the eviction policy for the low priority virtual machine. Will result in 'Deallocate' eviction policy. | +| [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable telemetry via a Globally Unique Identifier (GUID). | | [`encryptionAtHost`](#parameter-encryptionathost) | bool | This property can be used by user in the request to enable or disable the Host Encryption for the virtual machine. This will enable the encryption for all the disks including Resource/Temp disk at host itself. For security reasons, it is recommended to set encryptionAtHost to True. Restrictions: Cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. | | [`extensionAadJoinConfig`](#parameter-extensionaadjoinconfig) | object | The configuration for the [AAD Join] extension. Must at least contain the ["enabled": true] property to be executed. | | [`extensionAntiMalwareConfig`](#parameter-extensionantimalwareconfig) | object | The configuration for the [Anti Malware] extension. Must at least contain the ["enabled": true] property to be executed. | @@ -2853,21 +2852,21 @@ Indicates whether Automatic Updates is enabled for the Windows virtual machine. - Type: bool - Default: `True` -### Parameter: `enableDefaultTelemetry` +### Parameter: `enableEvictionPolicy` -Enable telemetry via a Globally Unique Identifier (GUID). +Specifies the eviction policy for the low priority virtual machine. Will result in 'Deallocate' eviction policy. - Required: No - Type: bool -- Default: `True` +- Default: `False` -### Parameter: `enableEvictionPolicy` +### Parameter: `enableTelemetry` -Specifies the eviction policy for the low priority virtual machine. Will result in 'Deallocate' eviction policy. +Enable telemetry via a Globally Unique Identifier (GUID). - Required: No - Type: bool -- Default: `False` +- Default: `True` ### Parameter: `encryptionAtHost` diff --git a/avm/res/compute/virtual-machine/extension/main.bicep b/avm/res/compute/virtual-machine/extension/main.bicep index 909805fe1c..51e12982c7 100644 --- a/avm/res/compute/virtual-machine/extension/main.bicep +++ b/avm/res/compute/virtual-machine/extension/main.bicep @@ -39,24 +39,9 @@ param supressFailures bool = false @description('Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available.') param enableAutomaticUpgrade bool -@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') -param enableDefaultTelemetry bool = true - @description('Optional. Tags of the resource.') param tags object? -resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (enableDefaultTelemetry) { - name: 'pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-${uniqueString(deployment().name, location)}' - properties: { - mode: 'Incremental' - template: { - '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' - contentVersion: '1.0.0.0' - resources: [] - } - } -} - resource virtualMachine 'Microsoft.Compute/virtualMachines@2022-11-01' existing = { name: virtualMachineName } diff --git a/avm/res/compute/virtual-machine/main.bicep b/avm/res/compute/virtual-machine/main.bicep index 280682d0c9..47e3495ee3 100644 --- a/avm/res/compute/virtual-machine/main.bicep +++ b/avm/res/compute/virtual-machine/main.bicep @@ -302,8 +302,6 @@ var identity = !empty(managedIdentities) ? { userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null } : null -var enableReferencedModulesTelemetry = false - var builtInRoleNames = { Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') 'Data Operator for Managed Disks': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '959f8984-c045-4866-89c7-12bf9737be2e') @@ -492,7 +490,6 @@ module vm_domainJoinExtension 'extension/main.bicep' = if (extensionDomainJoinCo protectedSettings: { Password: extensionDomainJoinPassword } - enableTelemetry: enableReferencedModulesTelemetry } } @@ -509,7 +506,6 @@ module vm_microsoftAntiMalwareExtension 'extension/main.bicep' = if (extensionAn enableAutomaticUpgrade: contains(extensionAntiMalwareConfig, 'enableAutomaticUpgrade') ? extensionAntiMalwareConfig.enableAutomaticUpgrade : false settings: extensionAntiMalwareConfig.settings tags: extensionAntiMalwareConfig.?tags ?? tags - enableTelemetry: enableReferencedModulesTelemetry } } @@ -536,7 +532,6 @@ module vm_microsoftMonitoringAgentExtension 'extension/main.bicep' = if (extensi protectedSettings: { workspaceKey: !empty(monitoringWorkspaceId) ? vm_logAnalyticsWorkspace.listKeys().primarySharedKey : '' } - enableTelemetry: enableReferencedModulesTelemetry } } @@ -551,7 +546,6 @@ module vm_dependencyAgentExtension 'extension/main.bicep' = if (extensionDepende typeHandlerVersion: contains(extensionDependencyAgentConfig, 'typeHandlerVersion') ? extensionDependencyAgentConfig.typeHandlerVersion : '9.5' autoUpgradeMinorVersion: contains(extensionDependencyAgentConfig, 'autoUpgradeMinorVersion') ? extensionDependencyAgentConfig.autoUpgradeMinorVersion : true enableAutomaticUpgrade: contains(extensionDependencyAgentConfig, 'enableAutomaticUpgrade') ? extensionDependencyAgentConfig.enableAutomaticUpgrade : true - enableTelemetry: enableReferencedModulesTelemetry tags: extensionDependencyAgentConfig.?tags ?? tags } } @@ -567,7 +561,6 @@ module vm_networkWatcherAgentExtension 'extension/main.bicep' = if (extensionNet typeHandlerVersion: contains(extensionNetworkWatcherAgentConfig, 'typeHandlerVersion') ? extensionNetworkWatcherAgentConfig.typeHandlerVersion : '1.4' autoUpgradeMinorVersion: contains(extensionNetworkWatcherAgentConfig, 'autoUpgradeMinorVersion') ? extensionNetworkWatcherAgentConfig.autoUpgradeMinorVersion : true enableAutomaticUpgrade: contains(extensionNetworkWatcherAgentConfig, 'enableAutomaticUpgrade') ? extensionNetworkWatcherAgentConfig.enableAutomaticUpgrade : false - enableTelemetry: enableReferencedModulesTelemetry tags: extensionNetworkWatcherAgentConfig.?tags ?? tags } } @@ -586,7 +579,6 @@ module vm_desiredStateConfigurationExtension 'extension/main.bicep' = if (extens settings: contains(extensionDSCConfig, 'settings') ? extensionDSCConfig.settings : {} tags: extensionDSCConfig.?tags ?? tags protectedSettings: contains(extensionDSCConfig, 'protectedSettings') ? extensionDSCConfig.protectedSettings : {} - enableTelemetry: enableReferencedModulesTelemetry } } @@ -606,7 +598,6 @@ module vm_customScriptExtension 'extension/main.bicep' = if (extensionCustomScri } tags: extensionCustomScriptConfig.?tags ?? tags protectedSettings: extensionCustomScriptProtectedSetting - enableTelemetry: enableReferencedModulesTelemetry } dependsOn: [ vm_desiredStateConfigurationExtension @@ -627,7 +618,6 @@ module vm_azureDiskEncryptionExtension 'extension/main.bicep' = if (extensionAzu forceUpdateTag: contains(extensionAzureDiskEncryptionConfig, 'forceUpdateTag') ? extensionAzureDiskEncryptionConfig.forceUpdateTag : '1.0' settings: extensionAzureDiskEncryptionConfig.settings tags: extensionAzureDiskEncryptionConfig.?tags ?? tags - enableTelemetry: enableReferencedModulesTelemetry } dependsOn: [ vm_customScriptExtension diff --git a/avm/res/compute/virtual-machine/main.json b/avm/res/compute/virtual-machine/main.json index f890008468..06e1030f6b 100644 --- a/avm/res/compute/virtual-machine/main.json +++ b/avm/res/compute/virtual-machine/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "18084273995093499059" + "templateHash": "14776084147478527075" }, "name": "Virtual Machines", "description": "This module deploys a Virtual Machine with one or multiple NICs and optionally one or multiple public IPs.", @@ -612,7 +612,7 @@ "description": "Optional. Tags of the resource." } }, - "enableDefaultTelemetry": { + "enableTelemetry": { "type": "bool", "defaultValue": true, "metadata": { @@ -759,7 +759,6 @@ }, "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]", "identity": "[if(not(empty(parameters('managedIdentities'))), createObject('type', if(if(parameters('extensionAadJoinConfig').enabled, true(), coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false())), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'SystemAssigned,UserAssigned', 'SystemAssigned'), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'UserAssigned', null())), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]", - "enableReferencedModulesTelemetry": false, "builtInRoleNames": { "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", "Data Operator for Managed Disks": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '959f8984-c045-4866-89c7-12bf9737be2e')]", @@ -783,7 +782,7 @@ }, "resources": { "defaultTelemetry": { - "condition": "[parameters('enableDefaultTelemetry')]", + "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", @@ -1523,7 +1522,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "5421737065579119324" + "templateHash": "9445653680126696241" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -1607,13 +1606,6 @@ "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." } }, - "enableDefaultTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." - } - }, "tags": { "type": "object", "nullable": true, @@ -1623,20 +1615,6 @@ } }, "resources": { - "defaultTelemetry": { - "condition": "[parameters('enableDefaultTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2021-04-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [] - } - } - }, "virtualMachine": { "existing": true, "type": "Microsoft.Compute/virtualMachines", @@ -1740,9 +1718,6 @@ "value": { "Password": "[parameters('extensionDomainJoinPassword')]" } - }, - "enableDefaultTelemetry": { - "value": "[variables('enableReferencedModulesTelemetry')]" } }, "template": { @@ -1753,7 +1728,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "5421737065579119324" + "templateHash": "9445653680126696241" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -1837,13 +1812,6 @@ "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." } }, - "enableDefaultTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." - } - }, "tags": { "type": "object", "nullable": true, @@ -1853,20 +1821,6 @@ } }, "resources": { - "defaultTelemetry": { - "condition": "[parameters('enableDefaultTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2021-04-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [] - } - } - }, "virtualMachine": { "existing": true, "type": "Microsoft.Compute/virtualMachines", @@ -1965,9 +1919,6 @@ }, "tags": { "value": "[coalesce(tryGet(parameters('extensionAntiMalwareConfig'), 'tags'), parameters('tags'))]" - }, - "enableDefaultTelemetry": { - "value": "[variables('enableReferencedModulesTelemetry')]" } }, "template": { @@ -1978,7 +1929,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "5421737065579119324" + "templateHash": "9445653680126696241" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -2062,13 +2013,6 @@ "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." } }, - "enableDefaultTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." - } - }, "tags": { "type": "object", "nullable": true, @@ -2078,20 +2022,6 @@ } }, "resources": { - "defaultTelemetry": { - "condition": "[parameters('enableDefaultTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2021-04-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [] - } - } - }, "virtualMachine": { "existing": true, "type": "Microsoft.Compute/virtualMachines", @@ -2195,9 +2125,6 @@ "value": { "workspaceKey": "[if(not(empty(parameters('monitoringWorkspaceId'))), listKeys(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(if(not(empty(parameters('monitoringWorkspaceId'))), parameters('monitoringWorkspaceId'), '//'), '/')[2], split(if(not(empty(parameters('monitoringWorkspaceId'))), parameters('monitoringWorkspaceId'), '////'), '/')[4]), 'Microsoft.OperationalInsights/workspaces', last(split(if(not(empty(parameters('monitoringWorkspaceId'))), parameters('monitoringWorkspaceId'), 'law'), '/'))), '2021-06-01').primarySharedKey, '')]" } - }, - "enableDefaultTelemetry": { - "value": "[variables('enableReferencedModulesTelemetry')]" } }, "template": { @@ -2208,7 +2135,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "5421737065579119324" + "templateHash": "9445653680126696241" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -2292,13 +2219,6 @@ "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." } }, - "enableDefaultTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." - } - }, "tags": { "type": "object", "nullable": true, @@ -2308,20 +2228,6 @@ } }, "resources": { - "defaultTelemetry": { - "condition": "[parameters('enableDefaultTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2021-04-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [] - } - } - }, "virtualMachine": { "existing": true, "type": "Microsoft.Compute/virtualMachines", @@ -2414,9 +2320,6 @@ "typeHandlerVersion": "[if(contains(parameters('extensionDependencyAgentConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionDependencyAgentConfig').typeHandlerVersion), createObject('value', '9.5'))]", "autoUpgradeMinorVersion": "[if(contains(parameters('extensionDependencyAgentConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionDependencyAgentConfig').autoUpgradeMinorVersion), createObject('value', true()))]", "enableAutomaticUpgrade": "[if(contains(parameters('extensionDependencyAgentConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionDependencyAgentConfig').enableAutomaticUpgrade), createObject('value', true()))]", - "enableDefaultTelemetry": { - "value": "[variables('enableReferencedModulesTelemetry')]" - }, "tags": { "value": "[coalesce(tryGet(parameters('extensionDependencyAgentConfig'), 'tags'), parameters('tags'))]" } @@ -2429,7 +2332,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "5421737065579119324" + "templateHash": "9445653680126696241" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -2513,13 +2416,6 @@ "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." } }, - "enableDefaultTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." - } - }, "tags": { "type": "object", "nullable": true, @@ -2529,20 +2425,6 @@ } }, "resources": { - "defaultTelemetry": { - "condition": "[parameters('enableDefaultTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2021-04-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [] - } - } - }, "virtualMachine": { "existing": true, "type": "Microsoft.Compute/virtualMachines", @@ -2634,9 +2516,6 @@ "typeHandlerVersion": "[if(contains(parameters('extensionNetworkWatcherAgentConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionNetworkWatcherAgentConfig').typeHandlerVersion), createObject('value', '1.4'))]", "autoUpgradeMinorVersion": "[if(contains(parameters('extensionNetworkWatcherAgentConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionNetworkWatcherAgentConfig').autoUpgradeMinorVersion), createObject('value', true()))]", "enableAutomaticUpgrade": "[if(contains(parameters('extensionNetworkWatcherAgentConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionNetworkWatcherAgentConfig').enableAutomaticUpgrade), createObject('value', false()))]", - "enableDefaultTelemetry": { - "value": "[variables('enableReferencedModulesTelemetry')]" - }, "tags": { "value": "[coalesce(tryGet(parameters('extensionNetworkWatcherAgentConfig'), 'tags'), parameters('tags'))]" } @@ -2649,7 +2528,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "5421737065579119324" + "templateHash": "9445653680126696241" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -2733,13 +2612,6 @@ "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." } }, - "enableDefaultTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." - } - }, "tags": { "type": "object", "nullable": true, @@ -2749,20 +2621,6 @@ } }, "resources": { - "defaultTelemetry": { - "condition": "[parameters('enableDefaultTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2021-04-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [] - } - } - }, "virtualMachine": { "existing": true, "type": "Microsoft.Compute/virtualMachines", @@ -2860,10 +2718,7 @@ "tags": { "value": "[coalesce(tryGet(parameters('extensionDSCConfig'), 'tags'), parameters('tags'))]" }, - "protectedSettings": "[if(contains(parameters('extensionDSCConfig'), 'protectedSettings'), createObject('value', parameters('extensionDSCConfig').protectedSettings), createObject('value', createObject()))]", - "enableDefaultTelemetry": { - "value": "[variables('enableReferencedModulesTelemetry')]" - } + "protectedSettings": "[if(contains(parameters('extensionDSCConfig'), 'protectedSettings'), createObject('value', parameters('extensionDSCConfig').protectedSettings), createObject('value', createObject()))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", @@ -2873,7 +2728,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "5421737065579119324" + "templateHash": "9445653680126696241" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -2957,13 +2812,6 @@ "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." } }, - "enableDefaultTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." - } - }, "tags": { "type": "object", "nullable": true, @@ -2973,20 +2821,6 @@ } }, "resources": { - "defaultTelemetry": { - "condition": "[parameters('enableDefaultTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2021-04-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [] - } - } - }, "virtualMachine": { "existing": true, "type": "Microsoft.Compute/virtualMachines", @@ -3092,9 +2926,6 @@ }, "protectedSettings": { "value": "[parameters('extensionCustomScriptProtectedSetting')]" - }, - "enableDefaultTelemetry": { - "value": "[variables('enableReferencedModulesTelemetry')]" } }, "template": { @@ -3105,7 +2936,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "5421737065579119324" + "templateHash": "9445653680126696241" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3189,13 +3020,6 @@ "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." } }, - "enableDefaultTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." - } - }, "tags": { "type": "object", "nullable": true, @@ -3205,20 +3029,6 @@ } }, "resources": { - "defaultTelemetry": { - "condition": "[parameters('enableDefaultTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2021-04-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [] - } - } - }, "virtualMachine": { "existing": true, "type": "Microsoft.Compute/virtualMachines", @@ -3317,9 +3127,6 @@ }, "tags": { "value": "[coalesce(tryGet(parameters('extensionAzureDiskEncryptionConfig'), 'tags'), parameters('tags'))]" - }, - "enableDefaultTelemetry": { - "value": "[variables('enableReferencedModulesTelemetry')]" } }, "template": { @@ -3330,7 +3137,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "5421737065579119324" + "templateHash": "9445653680126696241" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3414,13 +3221,6 @@ "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." } }, - "enableDefaultTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." - } - }, "tags": { "type": "object", "nullable": true, @@ -3430,20 +3230,6 @@ } }, "resources": { - "defaultTelemetry": { - "condition": "[parameters('enableDefaultTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2021-04-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [] - } - } - }, "virtualMachine": { "existing": true, "type": "Microsoft.Compute/virtualMachines", @@ -3542,9 +3328,6 @@ }, "sourceResourceId": { "value": "[resourceId('Microsoft.Compute/virtualMachines', parameters('name'))]" - }, - "enableDefaultTelemetry": { - "value": "[variables('enableReferencedModulesTelemetry')]" } }, "template": { @@ -3554,7 +3337,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "9921011786088905122" + "templateHash": "17653239179026707614" }, "name": "Recovery Service Vaults Protection Container Protected Item", "description": "This module deploys a Recovery Services Vault Protection Container Protected Item.", @@ -3615,30 +3398,9 @@ "metadata": { "description": "Required. Resource ID of the resource to back up." } - }, - "enableDefaultTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." - } } }, "resources": [ - { - "condition": "[parameters('enableDefaultTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2021-04-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [] - } - } - }, { "type": "Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems", "apiVersion": "2023-01-01", From fc7c2c64a882473d8c5c84ae39a38dda5934f25c Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 7 Dec 2023 15:20:03 +0100 Subject: [PATCH 23/96] update telemetry --- avm/res/compute/virtual-machine/main.bicep | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/avm/res/compute/virtual-machine/main.bicep b/avm/res/compute/virtual-machine/main.bicep index 47e3495ee3..a27fb170cd 100644 --- a/avm/res/compute/virtual-machine/main.bicep +++ b/avm/res/compute/virtual-machine/main.bicep @@ -323,14 +323,20 @@ var builtInRoleNames = { 'VM Scanner Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'd24ecba3-c1f4-40fa-a7bb-4588a071e8fd') } -resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (enableTelemetry) { - name: 'pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-${uniqueString(deployment().name, location)}' +resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { + name: '46d3xbcp.res.compute-virtualmachine.${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' + } + } } } } From 632de6237f2a4225ff65160b965eba92971f99a7 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 7 Dec 2023 17:06:24 +0100 Subject: [PATCH 24/96] add metadta to tests --- .../virtual-machine/tests/e2e/linux.atmg/main.test.bicep | 3 +++ .../virtual-machine/tests/e2e/windows.atmg/main.test.bicep | 3 +++ .../virtual-machine/tests/e2e/windows.ssecmk/main.test.bicep | 3 +++ 3 files changed, 9 insertions(+) diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux.atmg/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.atmg/main.test.bicep index 38b372c561..b506288b88 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/linux.atmg/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/linux.atmg/main.test.bicep @@ -1,5 +1,8 @@ targetScope = 'subscription' +metadata name = 'Using automanage for the VM.' +metadata description = 'This instance deploys the module with registering to an automation account.' + // ========== // // Parameters // // ========== // diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows.atmg/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.atmg/main.test.bicep index d246dc04ba..6cc1b15e50 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/windows.atmg/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/windows.atmg/main.test.bicep @@ -1,5 +1,8 @@ targetScope = 'subscription' +metadata name = 'Using automanage for the VM.' +metadata description = 'This instance deploys the module with registering to an automation account.' + // ========== // // Parameters // // ========== // diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows.ssecmk/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.ssecmk/main.test.bicep index 41cced4df4..1119647ab3 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/windows.ssecmk/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/windows.ssecmk/main.test.bicep @@ -1,5 +1,8 @@ targetScope = 'subscription' +metadata name = 'Using disk encryption set for the VM.' +metadata description = 'This instance deploys the module with disk enryption set.' + // ========== // // Parameters // // ========== // From 6128a6350ecb86cbcf3b3c27a3530ef64f73547e Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 7 Dec 2023 17:08:27 +0100 Subject: [PATCH 25/96] update readme --- avm/res/compute/virtual-machine/README.md | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/avm/res/compute/virtual-machine/README.md b/avm/res/compute/virtual-machine/README.md index be80e21bf8..9a79d570f8 100644 --- a/avm/res/compute/virtual-machine/README.md +++ b/avm/res/compute/virtual-machine/README.md @@ -31,16 +31,19 @@ The following section provides usage examples for the module, which were used to >**Note**: To reference the module, please use the following syntax `br/public:avm/res/compute/virtual-machine:`. -- [Linux.Atmg](#example-1-linuxatmg) +- [Using automanage for the VM.](#example-1-using-automanage-for-the-vm) - [Using only defaults](#example-2-using-only-defaults) - [Using large parameter set](#example-3-using-large-parameter-set) - [WAF-aligned](#example-4-waf-aligned) -- [Windows.Atmg](#example-5-windowsatmg) +- [Using automanage for the VM.](#example-5-using-automanage-for-the-vm) - [Using only defaults](#example-6-using-only-defaults) - [Using large parameter set](#example-7-using-large-parameter-set) -- [Windows.Ssecmk](#example-8-windowsssecmk) +- [Using disk encryption set for the VM.](#example-8-using-disk-encryption-set-for-the-vm) + +### Example 1: _Using automanage for the VM._ + +This instance deploys the module with registering to an automation account. -### Example 1: _Linux.Atmg_
@@ -1541,7 +1544,10 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = {

-### Example 5: _Windows.Atmg_ +### Example 5: _Using automanage for the VM._ + +This instance deploys the module with registering to an automation account. +

@@ -2398,7 +2404,10 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = {

-### Example 8: _Windows.Ssecmk_ +### Example 8: _Using disk encryption set for the VM._ + +This instance deploys the module with disk enryption set. +

From 466cb59dc87cf9ae987ff9b086b4968effa98327 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 7 Dec 2023 17:09:17 +0100 Subject: [PATCH 26/96] update json --- avm/res/compute/virtual-machine/main.json | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/avm/res/compute/virtual-machine/main.json b/avm/res/compute/virtual-machine/main.json index 06e1030f6b..ebbcd74022 100644 --- a/avm/res/compute/virtual-machine/main.json +++ b/avm/res/compute/virtual-machine/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "14776084147478527075" + "templateHash": "3578264423457994509" }, "name": "Virtual Machines", "description": "This module deploys a Virtual Machine with one or multiple NICs and optionally one or multiple public IPs.", @@ -781,17 +781,23 @@ } }, "resources": { - "defaultTelemetry": { + "avmTelemetry": { "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", - "apiVersion": "2021-04-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.compute-virtualmachine.{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": [] + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } } } }, From 199a15dfe4e44cd1e5aa358f2c18594dd178c025 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 7 Dec 2023 17:14:02 +0100 Subject: [PATCH 27/96] update extension --- .../virtual-machine/extension/README.md | 9 -------- .../virtual-machine/extension/main.json | 23 +------------------ 2 files changed, 1 insertion(+), 31 deletions(-) diff --git a/avm/res/compute/virtual-machine/extension/README.md b/avm/res/compute/virtual-machine/extension/README.md index 324ebc8179..dccac4e45c 100644 --- a/avm/res/compute/virtual-machine/extension/README.md +++ b/avm/res/compute/virtual-machine/extension/README.md @@ -38,7 +38,6 @@ This module deploys a Virtual Machine Extension. | Parameter | Type | Description | | :-- | :-- | :-- | -| [`enableDefaultTelemetry`](#parameter-enabledefaulttelemetry) | bool | Enable telemetry via a Globally Unique Identifier (GUID). | | [`forceUpdateTag`](#parameter-forceupdatetag) | string | How the extension handler should be forced to update even if the extension configuration has not changed. | | [`location`](#parameter-location) | string | The location the extension is deployed to. | | [`protectedSettings`](#parameter-protectedsettings) | secureObject | Any object that contains the extension specific protected settings. | @@ -95,14 +94,6 @@ The name of the parent virtual machine that extension is provisioned for. Requir - Required: Yes - Type: string -### Parameter: `enableDefaultTelemetry` - -Enable telemetry via a Globally Unique Identifier (GUID). - -- Required: No -- Type: bool -- Default: `True` - ### Parameter: `forceUpdateTag` How the extension handler should be forced to update even if the extension configuration has not changed. diff --git a/avm/res/compute/virtual-machine/extension/main.json b/avm/res/compute/virtual-machine/extension/main.json index 5ddd571641..a078645aa8 100644 --- a/avm/res/compute/virtual-machine/extension/main.json +++ b/avm/res/compute/virtual-machine/extension/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "5421737065579119324" + "templateHash": "9445653680126696241" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -90,13 +90,6 @@ "description": "Required. Indicates whether the extension should be automatically upgraded by the platform if there is a newer version of the extension available." } }, - "enableDefaultTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." - } - }, "tags": { "type": "object", "nullable": true, @@ -106,20 +99,6 @@ } }, "resources": { - "defaultTelemetry": { - "condition": "[parameters('enableDefaultTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2021-04-01", - "name": "[format('pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-{0}', uniqueString(deployment().name, parameters('location')))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [] - } - } - }, "virtualMachine": { "existing": true, "type": "Microsoft.Compute/virtualMachines", From b2b982191a9b740254700efc38cc4a0c1cd42217 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Fri, 8 Dec 2023 15:12:03 +0100 Subject: [PATCH 28/96] test --- avm/res/compute/virtual-machine/main.bicep | 1 + .../pipelines/staticValidation/compliance/module.tests.ps1 | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/avm/res/compute/virtual-machine/main.bicep b/avm/res/compute/virtual-machine/main.bicep index a27fb170cd..18ae9d33e5 100644 --- a/avm/res/compute/virtual-machine/main.bicep +++ b/avm/res/compute/virtual-machine/main.bicep @@ -426,6 +426,7 @@ resource vm 'Microsoft.Compute/virtualMachines@2022-11-01' = { deleteOption: contains(nicConfiguration, 'deleteOption') ? nicConfiguration.deleteOption : 'Delete' primary: index == 0 ? true : false } + #disable-next-line use-resource-id-functions id: az.resourceId('Microsoft.Network/networkInterfaces', '${name}${nicConfiguration.nicSuffix}') }] } diff --git a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 index 0421139a23..46af000aef 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 @@ -43,10 +43,8 @@ foreach ($moduleFolderPath in $moduleFolderPaths) { # building paths $builtTestFileMap = [System.Collections.Concurrent.ConcurrentDictionary[string, object]]::new() -# $pathsToBuild | ForEach-Object -Parallel { -$pathsToBuild | ForEach-Object { - # $dict = $using:builtTestFileMap - $dict = $builtTestFileMap +$pathsToBuild | ForEach-Object -Parallel { + $dict = $using:builtTestFileMap $builtTemplate = bicep build $_ --stdout | ConvertFrom-Json -AsHashtable $null = $dict.TryAdd($_, $builtTemplate) } From d3aabacd32cc12291b8617cba6a9598f84336699 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Sun, 10 Dec 2023 09:34:30 +0100 Subject: [PATCH 29/96] test different sku size --- .../compute/virtual-machine/tests/e2e/linux.max/main.test.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep index 1ab524b9f3..e228109804 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep @@ -164,7 +164,7 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' } } osType: 'Linux' - vmSize: 'Standard_DS2_v2' + vmSize: 'Standard_DS2_v4' availabilityZone: 1 backupPolicyName: nestedDependencies.outputs.recoveryServicesVaultBackupPolicyName backupVaultName: nestedDependencies.outputs.recoveryServicesVaultName From 2d80eb905c9b20f1e88b2a3bc9972fc00fc08c7d Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Sun, 10 Dec 2023 10:08:40 +0100 Subject: [PATCH 30/96] update sku size --- avm/res/compute/virtual-machine/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/avm/res/compute/virtual-machine/README.md b/avm/res/compute/virtual-machine/README.md index 9a79d570f8..f5dc65b859 100644 --- a/avm/res/compute/virtual-machine/README.md +++ b/avm/res/compute/virtual-machine/README.md @@ -461,7 +461,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { } } osType: 'Linux' - vmSize: 'Standard_DS2_v2' + vmSize: 'Standard_DS2_v4' // Non-required parameters availabilityZone: 1 backupPolicyName: '' @@ -725,7 +725,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { "value": "Linux" }, "vmSize": { - "value": "Standard_DS2_v2" + "value": "Standard_DS2_v4" }, // Non-required parameters "availabilityZone": { From e3b2932e441f4270c92eea38f1f6154f37d52cc1 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Sun, 10 Dec 2023 10:29:26 +0100 Subject: [PATCH 31/96] update SKU --- avm/res/compute/virtual-machine/README.md | 4 ++-- .../virtual-machine/tests/e2e/linux.max/main.test.bicep | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/avm/res/compute/virtual-machine/README.md b/avm/res/compute/virtual-machine/README.md index f5dc65b859..954018d69a 100644 --- a/avm/res/compute/virtual-machine/README.md +++ b/avm/res/compute/virtual-machine/README.md @@ -461,7 +461,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { } } osType: 'Linux' - vmSize: 'Standard_DS2_v4' + vmSize: 'Standard_D2_v4' // Non-required parameters availabilityZone: 1 backupPolicyName: '' @@ -725,7 +725,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { "value": "Linux" }, "vmSize": { - "value": "Standard_DS2_v4" + "value": "Standard_D2_v4" }, // Non-required parameters "availabilityZone": { diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep index e228109804..fa528ba484 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep @@ -164,7 +164,7 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' } } osType: 'Linux' - vmSize: 'Standard_DS2_v4' + vmSize: 'Standard_D2_v4' availabilityZone: 1 backupPolicyName: nestedDependencies.outputs.recoveryServicesVaultBackupPolicyName backupVaultName: nestedDependencies.outputs.recoveryServicesVaultName From 95f584f4cae8852f1b30b258937bb78e4fe2027d Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Sun, 10 Dec 2023 13:41:58 +0100 Subject: [PATCH 32/96] back to old SKU --- avm/res/compute/virtual-machine/README.md | 4 ++-- .../virtual-machine/tests/e2e/linux.max/main.test.bicep | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/avm/res/compute/virtual-machine/README.md b/avm/res/compute/virtual-machine/README.md index 954018d69a..9a79d570f8 100644 --- a/avm/res/compute/virtual-machine/README.md +++ b/avm/res/compute/virtual-machine/README.md @@ -461,7 +461,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { } } osType: 'Linux' - vmSize: 'Standard_D2_v4' + vmSize: 'Standard_DS2_v2' // Non-required parameters availabilityZone: 1 backupPolicyName: '' @@ -725,7 +725,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { "value": "Linux" }, "vmSize": { - "value": "Standard_D2_v4" + "value": "Standard_DS2_v2" }, // Non-required parameters "availabilityZone": { diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep index fa528ba484..1ab524b9f3 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep @@ -164,7 +164,7 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' } } osType: 'Linux' - vmSize: 'Standard_D2_v4' + vmSize: 'Standard_DS2_v2' availabilityZone: 1 backupPolicyName: nestedDependencies.outputs.recoveryServicesVaultBackupPolicyName backupVaultName: nestedDependencies.outputs.recoveryServicesVaultName From f2b663561875e18765e8f7479a827b2c01765797 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Sun, 10 Dec 2023 13:46:57 +0100 Subject: [PATCH 33/96] test with different region --- .github/workflows/avm.template.module.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/avm.template.module.yml b/.github/workflows/avm.template.module.yml index 24d865078e..4f1e601108 100644 --- a/.github/workflows/avm.template.module.yml +++ b/.github/workflows/avm.template.module.yml @@ -103,7 +103,7 @@ jobs: uses: ./.github/actions/templates/avm-validateModuleDeployment with: templateFilePath: "${{ inputs.modulePath }}/${{ matrix.moduleTestFilePaths }}" - location: "WestEurope" + location: "NorthEurope" subscriptionId: "${{ secrets.ARM_SUBSCRIPTION_ID }}" managementGroupId: "${{ secrets.ARM_MGMTGROUP_ID }}" removeDeployment: "${{ fromJson(inputs.workflowInput).removeDeployment }}" From 218ec8b2d2cd61a8200f77acadece80409073636 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Sun, 10 Dec 2023 13:49:28 +0100 Subject: [PATCH 34/96] hardcode region --- .github/workflows/avm.template.module.yml | 2 +- .../virtual-machine/tests/e2e/linux.max/dependencies.bicep | 2 +- .../compute/virtual-machine/tests/e2e/linux.max/main.test.bicep | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/avm.template.module.yml b/.github/workflows/avm.template.module.yml index 4f1e601108..24d865078e 100644 --- a/.github/workflows/avm.template.module.yml +++ b/.github/workflows/avm.template.module.yml @@ -103,7 +103,7 @@ jobs: uses: ./.github/actions/templates/avm-validateModuleDeployment with: templateFilePath: "${{ inputs.modulePath }}/${{ matrix.moduleTestFilePaths }}" - location: "NorthEurope" + location: "WestEurope" subscriptionId: "${{ secrets.ARM_SUBSCRIPTION_ID }}" managementGroupId: "${{ secrets.ARM_MGMTGROUP_ID }}" removeDeployment: "${{ fromJson(inputs.workflowInput).removeDeployment }}" diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux.max/dependencies.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.max/dependencies.bicep index f748f995d5..81f09a140f 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/linux.max/dependencies.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/linux.max/dependencies.bicep @@ -29,7 +29,7 @@ param sshDeploymentScriptName string param sshKeyName string @description('Optional. The location to deploy to.') -param location string = resourceGroup().location +param location string = 'NorthEurope' //resourceGroup().location var storageAccountCSEFileName = 'scriptExtensionMasterInstaller.ps1' var addressPrefix = '10.0.0.0/16' diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep index 1ab524b9f3..86cfa359bc 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep @@ -12,7 +12,7 @@ metadata description = 'This instance deploys the module with most of its featur param resourceGroupName string = 'dep-${namePrefix}-compute.virtualMachines-${serviceShort}-rg' @description('Optional. The location to deploy resources to.') -param location string = deployment().location +param location string = 'NorthEurope' //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 = 'cvmlinmax' From 514beffed23d46dd6dae454bc81d115dc96128df Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Sun, 10 Dec 2023 15:05:09 +0100 Subject: [PATCH 35/96] try different OS --- .../virtual-machine/tests/e2e/linux.max/main.test.bicep | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep index 86cfa359bc..1694bb3826 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep @@ -78,8 +78,8 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' adminUsername: 'localAdministrator' imageReference: { publisher: 'Canonical' - offer: '0001-com-ubuntu-server-focal' - sku: '20_04-lts-gen2' // Note: 22.04 does not support OMS extension + offer: '0001-com-ubuntu-server-jammy' + sku: '22_04-lts-gen2' version: 'latest' } nicConfigurations: [ From 9d5e6b31c6f01eefbeee7a9f2e4124b8b9380c0a Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Sun, 10 Dec 2023 16:34:04 +0100 Subject: [PATCH 36/96] remove linux.max test --- .../tests/e2e/linux.max/dependencies.bicep | 337 ------------------ .../tests/e2e/linux.max/main.test.bicep | 314 ---------------- 2 files changed, 651 deletions(-) delete mode 100644 avm/res/compute/virtual-machine/tests/e2e/linux.max/dependencies.bicep delete mode 100644 avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux.max/dependencies.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.max/dependencies.bicep deleted file mode 100644 index 81f09a140f..0000000000 --- a/avm/res/compute/virtual-machine/tests/e2e/linux.max/dependencies.bicep +++ /dev/null @@ -1,337 +0,0 @@ -@description('Required. The name of the Virtual Network to create.') -param virtualNetworkName string - -@description('Required. The name of the Application Security Group to create.') -param applicationSecurityGroupName string - -@description('Required. The name of the Managed Identity to create.') -param managedIdentityName string - -@description('Required. The name of the Load Balancer to create.') -param loadBalancerName string - -@description('Required. The name of the Recovery Services Vault to create.') -param recoveryServicesVaultName string - -@description('Required. The name of the Key Vault to create.') -param keyVaultName string - -@description('Required. The name of the Storage Account to create.') -param storageAccountName string - -@description('Required. The name of the Deployment Script used to upload data to the Storage Account.') -param storageUploadDeploymentScriptName string - -@description('Required. The name of the Deployment Script to create for the SSH Key generation.') -param sshDeploymentScriptName string - -@description('Required. The name of the SSH Key to create.') -param sshKeyName string - -@description('Optional. The location to deploy to.') -param location string = 'NorthEurope' //resourceGroup().location - -var storageAccountCSEFileName = 'scriptExtensionMasterInstaller.ps1' -var addressPrefix = '10.0.0.0/16' - -resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { - name: virtualNetworkName - location: location - properties: { - addressSpace: { - addressPrefixes: [ - addressPrefix - ] - } - subnets: [ - { - name: 'defaultSubnet' - properties: { - addressPrefix: cidrSubnet(addressPrefix, 16, 0) - } - } - ] - } -} - -resource applicationSecurityGroup 'Microsoft.Network/applicationSecurityGroups@2023-04-01' = { - name: applicationSecurityGroupName - location: location -} - -resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location -} - -resource msiRGContrRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid(resourceGroup().id, 'Contributor', managedIdentity.id) - scope: resourceGroup() - properties: { - principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor - principalType: 'ServicePrincipal' - } -} - -resource loadBalancer 'Microsoft.Network/loadBalancers@2023-04-01' = { - name: loadBalancerName - location: location - sku: { - name: 'Standard' - } - properties: { - frontendIPConfigurations: [ - { - name: 'privateIPConfig1' - properties: { - subnet: virtualNetwork.properties.subnets[0] - } - } - ] - backendAddressPools: [ - { - name: 'servers' - } - ] - } -} - -resource recoveryServicesVault 'Microsoft.RecoveryServices/vaults@2022-04-01' = { - name: recoveryServicesVaultName - location: location - sku: { - name: 'RS0' - tier: 'Standard' - } - properties: {} - - resource backupPolicy 'backupPolicies@2022-03-01' = { - name: 'backupPolicy' - properties: { - backupManagementType: 'AzureIaasVM' - instantRPDetails: {} - schedulePolicy: { - schedulePolicyType: 'SimpleSchedulePolicy' - scheduleRunFrequency: 'Daily' - scheduleRunTimes: [ - '2019-11-07T07:00:00Z' - ] - scheduleWeeklyFrequency: 0 - } - retentionPolicy: { - retentionPolicyType: 'LongTermRetentionPolicy' - dailySchedule: { - retentionTimes: [ - '2019-11-07T07:00:00Z' - ] - retentionDuration: { - count: 180 - durationType: 'Days' - } - } - weeklySchedule: { - daysOfTheWeek: [ - 'Sunday' - ] - retentionTimes: [ - '2019-11-07T07:00:00Z' - ] - retentionDuration: { - count: 12 - durationType: 'Weeks' - } - } - monthlySchedule: { - retentionScheduleFormatType: 'Weekly' - retentionScheduleWeekly: { - daysOfTheWeek: [ - 'Sunday' - ] - weeksOfTheMonth: [ - 'First' - ] - } - retentionTimes: [ - '2019-11-07T07:00:00Z' - ] - retentionDuration: { - count: 60 - durationType: 'Months' - } - } - yearlySchedule: { - retentionScheduleFormatType: 'Weekly' - monthsOfYear: [ - 'January' - ] - retentionScheduleWeekly: { - daysOfTheWeek: [ - 'Sunday' - ] - weeksOfTheMonth: [ - 'First' - ] - } - retentionTimes: [ - '2019-11-07T07:00:00Z' - ] - retentionDuration: { - count: 10 - durationType: 'Years' - } - } - } - instantRpRetentionRangeInDays: 2 - timeZone: 'UTC' - protectedItemsCount: 0 - } - } -} - -resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = { - name: keyVaultName - location: location - properties: { - sku: { - family: 'A' - name: 'standard' - } - tenantId: tenant().tenantId - enablePurgeProtection: null - enabledForTemplateDeployment: true - enabledForDiskEncryption: true - enabledForDeployment: true - enableRbacAuthorization: true - accessPolicies: [] - } - - resource key 'keys@2022-07-01' = { - name: 'encryptionKey' - properties: { - kty: 'RSA' - } - } -} - -resource msiKVCryptoUserRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid('msi-${keyVault::key.id}-${location}-${managedIdentity.id}-KeyVault-Key-Read-RoleAssignment') - scope: keyVault::key - properties: { - principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') // Key Vault Crypto User - principalType: 'ServicePrincipal' - } -} - -resource storageAccount 'Microsoft.Storage/storageAccounts@2021-09-01' = { - name: storageAccountName - location: location - sku: { - name: 'Standard_LRS' - } - kind: 'StorageV2' - - resource blobService 'blobServices@2021-09-01' = { - name: 'default' - - resource container 'containers@2021-09-01' = { - name: 'scripts' - } - } -} - -resource storageUpload 'Microsoft.Resources/deploymentScripts@2020-10-01' = { - name: storageUploadDeploymentScriptName - location: location - kind: 'AzurePowerShell' - identity: { - type: 'UserAssigned' - userAssignedIdentities: { - '${managedIdentity.id}': {} - } - } - properties: { - azPowerShellVersion: '9.0' - retentionInterval: 'P1D' - arguments: '-StorageAccountName "${storageAccount.name}" -ResourceGroupName "${resourceGroup().name}" -ContainerName "${storageAccount::blobService::container.name}" -FileName "${storageAccountCSEFileName}"' - scriptContent: loadTextContent('../../../../../../utilities/e2e-template-assets/scripts/Set-BlobContent.ps1') - } - dependsOn: [ - msiRGContrRoleAssignment - ] -} - -resource sshDeploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = { - name: sshDeploymentScriptName - location: location - kind: 'AzurePowerShell' - identity: { - type: 'UserAssigned' - userAssignedIdentities: { - '${managedIdentity.id}': {} - } - } - properties: { - azPowerShellVersion: '9.0' - retentionInterval: 'P1D' - arguments: '-SSHKeyName "${sshKeyName}" -ResourceGroupName "${resourceGroup().name}"' - scriptContent: loadTextContent('../../../../../../utilities/e2e-template-assets/scripts/New-SSHKey.ps1') - } - dependsOn: [ - msiRGContrRoleAssignment - ] -} - -resource sshKey 'Microsoft.Compute/sshPublicKeys@2022-03-01' = { - name: sshKeyName - location: location - properties: { - publicKey: sshDeploymentScript.properties.outputs.publicKey - } -} - -@description('The resource ID of the created Virtual Network Subnet.') -output subnetResourceId string = virtualNetwork.properties.subnets[0].id - -@description('The resource ID of the created Application Security Group.') -output applicationSecurityGroupResourceId string = applicationSecurityGroup.id - -@description('The principal ID of the created Managed Identity.') -output managedIdentityPrincipalId string = managedIdentity.properties.principalId - -@description('The resource ID of the created Managed Identity.') -output managedIdentityResourceId string = managedIdentity.id - -@description('The resource ID of the created Load Balancer Backend Pool.') -output loadBalancerBackendPoolResourceId string = loadBalancer.properties.backendAddressPools[0].id - -@description('The name of the created Recovery Services Vault.') -output recoveryServicesVaultName string = recoveryServicesVault.name - -@description('The name of the Resource Group, the Recovery Services Vault was created in.') -output recoveryServicesVaultResourceGroupName string = resourceGroup().name - -@description('The name of the Backup Policy created in the Backup Recovery Vault.') -output recoveryServicesVaultBackupPolicyName string = recoveryServicesVault::backupPolicy.name - -@description('The resource ID of the created Key Vault.') -output keyVaultResourceId string = keyVault.id - -@description('The URL of the created Key Vault.') -output keyVaultUrl string = keyVault.properties.vaultUri - -@description('The URL of the created Key Vault Encryption Key.') -output keyVaultEncryptionKeyUrl string = keyVault::key.properties.keyUriWithVersion - -@description('The resource ID of the created Storage Account.') -output storageAccountResourceId string = storageAccount.id - -@description('The URL of the Custom Script Extension in the created Storage Account.') -output storageAccountCSEFileUrl string = '${storageAccount.properties.primaryEndpoints.blob}${storageAccount::blobService::container.name}/${storageAccountCSEFileName}' - -@description('The name of the Custom Script Extension in the created Storage Account.') -output storageAccountCSEFileName string = storageAccountCSEFileName - -@description('The Public Key of the created SSH Key.') -output SSHKeyPublicKey string = sshKey.properties.publicKey diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep deleted file mode 100644 index 1694bb3826..0000000000 --- a/avm/res/compute/virtual-machine/tests/e2e/linux.max/main.test.bicep +++ /dev/null @@ -1,314 +0,0 @@ -targetScope = 'subscription' - -metadata name = 'Using large parameter set' -metadata description = 'This instance deploys the module with most of its features enabled.' - -// ========== // -// Parameters // -// ========== // - -@description('Optional. The name of the resource group to deploy for testing purposes.') -@maxLength(90) -param resourceGroupName string = 'dep-${namePrefix}-compute.virtualMachines-${serviceShort}-rg' - -@description('Optional. The location to deploy resources to.') -param location string = 'NorthEurope' //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 = 'cvmlinmax' - -@description('Optional. A token to inject into the name of each resource.') -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: { - location: location - virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' - applicationSecurityGroupName: 'dep-${namePrefix}-asg-${serviceShort}' - managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' - keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}' - loadBalancerName: 'dep-${namePrefix}-lb-${serviceShort}' - recoveryServicesVaultName: 'dep-${namePrefix}-rsv-${serviceShort}' - storageAccountName: 'dep${namePrefix}sa${serviceShort}01' - storageUploadDeploymentScriptName: 'dep-${namePrefix}-sads-${serviceShort}' - sshDeploymentScriptName: 'dep-${namePrefix}-ds-${serviceShort}' - sshKeyName: 'dep-${namePrefix}-ssh-${serviceShort}' - } -} - -// Diagnostics -// =========== -module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/templates/diagnostic.dependencies.bicep' = { - scope: resourceGroup - name: '${uniqueString(deployment().name, location)}-diagnosticDependencies' - params: { - storageAccountName: 'dep${namePrefix}diasa${serviceShort}01' - logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' - eventHubNamespaceEventHubName: 'dep-${namePrefix}-evh-${serviceShort}' - eventHubNamespaceName: 'dep-${namePrefix}-evhns-${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: '${namePrefix}${serviceShort}' - computerName: '${namePrefix}linvm1' - location: location - adminUsername: 'localAdministrator' - imageReference: { - publisher: 'Canonical' - offer: '0001-com-ubuntu-server-jammy' - sku: '22_04-lts-gen2' - version: 'latest' - } - nicConfigurations: [ - { - deleteOption: 'Delete' - ipConfigurations: [ - { - applicationSecurityGroups: [ - { - id: nestedDependencies.outputs.applicationSecurityGroupResourceId - } - ] - loadBalancerBackendAddressPools: [ - { - id: nestedDependencies.outputs.loadBalancerBackendPoolResourceId - } - ] - name: 'ipconfig01' - pipConfiguration: { - publicIpNameSuffix: '-pip-01' - roleAssignments: [ - { - roleDefinitionIdOrName: 'Reader' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - ] - } - zones: [ - '1' - '2' - '3' - ] - subnetResourceId: nestedDependencies.outputs.subnetResourceId - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - } - ] - nicSuffix: '-nic-01' - roleAssignments: [ - { - roleDefinitionIdOrName: 'Reader' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - ] - diagnosticSettings: [ - { - name: 'customSetting' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName - eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId - storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId - workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - } - ] - } - ] - osDisk: { - caching: 'ReadOnly' - createOption: 'fromImage' - deleteOption: 'Delete' - diskSizeGB: '128' - managedDisk: { - storageAccountType: 'Premium_LRS' - } - } - osType: 'Linux' - vmSize: 'Standard_DS2_v2' - availabilityZone: 1 - backupPolicyName: nestedDependencies.outputs.recoveryServicesVaultBackupPolicyName - backupVaultName: nestedDependencies.outputs.recoveryServicesVaultName - backupVaultResourceGroup: nestedDependencies.outputs.recoveryServicesVaultResourceGroupName - dataDisks: [ - { - caching: 'ReadWrite' - createOption: 'Empty' - deleteOption: 'Delete' - diskSizeGB: '128' - managedDisk: { - storageAccountType: 'Premium_LRS' - } - } - { - caching: 'ReadWrite' - createOption: 'Empty' - deleteOption: 'Delete' - diskSizeGB: '128' - managedDisk: { - storageAccountType: 'Premium_LRS' - } - } - ] - enableAutomaticUpdates: true - patchMode: 'AutomaticByPlatform' - disablePasswordAuthentication: true - encryptionAtHost: false - extensionCustomScriptConfig: { - enabled: true - fileData: [ - { - storageAccountId: nestedDependencies.outputs.storageAccountResourceId - uri: nestedDependencies.outputs.storageAccountCSEFileUrl - } - ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - } - extensionCustomScriptProtectedSetting: { - commandToExecute: 'value=$(./${nestedDependencies.outputs.storageAccountCSEFileName}); echo "$value"' - } - extensionDependencyAgentConfig: { - enabled: true - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - } - extensionAzureDiskEncryptionConfig: { - enabled: true - settings: { - EncryptionOperation: 'EnableEncryption' - KekVaultResourceId: nestedDependencies.outputs.keyVaultResourceId - KeyEncryptionAlgorithm: 'RSA-OAEP' - KeyEncryptionKeyURL: nestedDependencies.outputs.keyVaultEncryptionKeyUrl - KeyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId - KeyVaultURL: nestedDependencies.outputs.keyVaultUrl - ResizeOSDisk: 'false' - VolumeType: 'All' - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - } - extensionAadJoinConfig: { - enabled: true - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - } - extensionDSCConfig: { - enabled: false - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - } - extensionMonitoringAgentConfig: { - enabled: true - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - } - extensionNetworkWatcherAgentConfig: { - enabled: true - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - } - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - monitoringWorkspaceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId - publicKeys: [ - { - keyData: nestedDependencies.outputs.SSHKeyPublicKey - path: '/home/localAdministrator/.ssh/authorized_keys' - } - ] - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - ] - managedIdentities: { - systemAssigned: true - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] - } - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - } - dependsOn: [ - nestedDependencies // Required to leverage `existing` SSH key reference - ] -}] From aec3d20e9284c364c1747eaa392cd4fb88ac90eb Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Sun, 10 Dec 2023 16:48:34 +0100 Subject: [PATCH 37/96] update ReadMe --- avm/res/compute/virtual-machine/README.md | 595 +--------------------- 1 file changed, 10 insertions(+), 585 deletions(-) diff --git a/avm/res/compute/virtual-machine/README.md b/avm/res/compute/virtual-machine/README.md index 9a79d570f8..f86be60223 100644 --- a/avm/res/compute/virtual-machine/README.md +++ b/avm/res/compute/virtual-machine/README.md @@ -33,12 +33,11 @@ The following section provides usage examples for the module, which were used to - [Using automanage for the VM.](#example-1-using-automanage-for-the-vm) - [Using only defaults](#example-2-using-only-defaults) -- [Using large parameter set](#example-3-using-large-parameter-set) -- [WAF-aligned](#example-4-waf-aligned) -- [Using automanage for the VM.](#example-5-using-automanage-for-the-vm) -- [Using only defaults](#example-6-using-only-defaults) -- [Using large parameter set](#example-7-using-large-parameter-set) -- [Using disk encryption set for the VM.](#example-8-using-disk-encryption-set-for-the-vm) +- [WAF-aligned](#example-3-waf-aligned) +- [Using automanage for the VM.](#example-4-using-automanage-for-the-vm) +- [Using only defaults](#example-5-using-only-defaults) +- [Using large parameter set](#example-6-using-large-parameter-set) +- [Using disk encryption set for the VM.](#example-7-using-disk-encryption-set-for-the-vm) ### Example 1: _Using automanage for the VM._ @@ -358,581 +357,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = {

-### Example 3: _Using large parameter set_ - -This instance deploys the module with most of its features enabled. - - -

- -via Bicep module - -```bicep -module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { - name: '${uniqueString(deployment().name, location)}-test-cvmlinmax' - params: { - // Required parameters - adminUsername: 'localAdministrator' - imageReference: { - offer: '0001-com-ubuntu-server-focal' - publisher: 'Canonical' - sku: '' - version: 'latest' - } - nicConfigurations: [ - { - deleteOption: 'Delete' - diagnosticSettings: [ - { - eventHubAuthorizationRuleResourceId: '' - eventHubName: '' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - name: 'customSetting' - storageAccountResourceId: '' - workspaceResourceId: '' - } - ] - ipConfigurations: [ - { - applicationSecurityGroups: [ - { - id: '' - } - ] - diagnosticSettings: [ - { - eventHubAuthorizationRuleResourceId: '' - eventHubName: '' - metricCategories: [ - { - category: 'AllMetrics' - } - ] - name: 'customSetting' - storageAccountResourceId: '' - workspaceResourceId: '' - } - ] - loadBalancerBackendAddressPools: [ - { - id: '' - } - ] - name: 'ipconfig01' - pipConfiguration: { - publicIpNameSuffix: '-pip-01' - roleAssignments: [ - { - principalId: '' - principalType: 'ServicePrincipal' - roleDefinitionIdOrName: 'Reader' - } - ] - } - subnetResourceId: '' - zones: [ - '1' - '2' - '3' - ] - } - ] - nicSuffix: '-nic-01' - roleAssignments: [ - { - principalId: '' - principalType: 'ServicePrincipal' - roleDefinitionIdOrName: 'Reader' - } - ] - } - ] - osDisk: { - caching: 'ReadOnly' - createOption: 'fromImage' - deleteOption: 'Delete' - diskSizeGB: '128' - managedDisk: { - storageAccountType: 'Premium_LRS' - } - } - osType: 'Linux' - vmSize: 'Standard_DS2_v2' - // Non-required parameters - availabilityZone: 1 - backupPolicyName: '' - backupVaultName: '' - backupVaultResourceGroup: '' - computerName: 'linvm1' - dataDisks: [ - { - caching: 'ReadWrite' - createOption: 'Empty' - deleteOption: 'Delete' - diskSizeGB: '128' - managedDisk: { - storageAccountType: 'Premium_LRS' - } - } - { - caching: 'ReadWrite' - createOption: 'Empty' - deleteOption: 'Delete' - diskSizeGB: '128' - managedDisk: { - storageAccountType: 'Premium_LRS' - } - } - ] - disablePasswordAuthentication: true - enableAutomaticUpdates: true - encryptionAtHost: false - extensionAadJoinConfig: { - enabled: true - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } - extensionAzureDiskEncryptionConfig: { - enabled: true - settings: { - EncryptionOperation: 'EnableEncryption' - KekVaultResourceId: '' - KeyEncryptionAlgorithm: 'RSA-OAEP' - KeyEncryptionKeyURL: '' - KeyVaultResourceId: '' - KeyVaultURL: '' - ResizeOSDisk: 'false' - VolumeType: 'All' - } - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } - extensionCustomScriptConfig: { - enabled: true - fileData: [ - { - storageAccountId: '' - uri: '' - } - ] - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } - extensionCustomScriptProtectedSetting: { - commandToExecute: '' - } - extensionDependencyAgentConfig: { - enabled: true - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } - extensionDSCConfig: { - enabled: false - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } - extensionMonitoringAgentConfig: { - enabled: true - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } - extensionNetworkWatcherAgentConfig: { - enabled: true - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } - location: '' - lock: { - kind: 'CanNotDelete' - name: 'myCustomLockName' - } - managedIdentities: { - systemAssigned: true - userAssignedResourceIds: [ - '' - ] - } - monitoringWorkspaceId: '' - name: 'cvmlinmax' - patchMode: 'AutomaticByPlatform' - publicKeys: [ - { - keyData: '' - path: '/home/localAdministrator/.ssh/authorized_keys' - } - ] - roleAssignments: [ - { - principalId: '' - principalType: 'ServicePrincipal' - roleDefinitionIdOrName: 'Owner' - } - { - principalId: '' - principalType: 'ServicePrincipal' - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - } - { - principalId: '' - principalType: 'ServicePrincipal' - roleDefinitionIdOrName: '' - } - ] - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } -} -``` - -
-

- -

- -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 - "adminUsername": { - "value": "localAdministrator" - }, - "imageReference": { - "value": { - "offer": "0001-com-ubuntu-server-focal", - "publisher": "Canonical", - "sku": "", - "version": "latest" - } - }, - "nicConfigurations": { - "value": [ - { - "deleteOption": "Delete", - "diagnosticSettings": [ - { - "eventHubAuthorizationRuleResourceId": "", - "eventHubName": "", - "metricCategories": [ - { - "category": "AllMetrics" - } - ], - "name": "customSetting", - "storageAccountResourceId": "", - "workspaceResourceId": "" - } - ], - "ipConfigurations": [ - { - "applicationSecurityGroups": [ - { - "id": "" - } - ], - "diagnosticSettings": [ - { - "eventHubAuthorizationRuleResourceId": "", - "eventHubName": "", - "metricCategories": [ - { - "category": "AllMetrics" - } - ], - "name": "customSetting", - "storageAccountResourceId": "", - "workspaceResourceId": "" - } - ], - "loadBalancerBackendAddressPools": [ - { - "id": "" - } - ], - "name": "ipconfig01", - "pipConfiguration": { - "publicIpNameSuffix": "-pip-01", - "roleAssignments": [ - { - "principalId": "", - "principalType": "ServicePrincipal", - "roleDefinitionIdOrName": "Reader" - } - ] - }, - "subnetResourceId": "", - "zones": [ - "1", - "2", - "3" - ] - } - ], - "nicSuffix": "-nic-01", - "roleAssignments": [ - { - "principalId": "", - "principalType": "ServicePrincipal", - "roleDefinitionIdOrName": "Reader" - } - ] - } - ] - }, - "osDisk": { - "value": { - "caching": "ReadOnly", - "createOption": "fromImage", - "deleteOption": "Delete", - "diskSizeGB": "128", - "managedDisk": { - "storageAccountType": "Premium_LRS" - } - } - }, - "osType": { - "value": "Linux" - }, - "vmSize": { - "value": "Standard_DS2_v2" - }, - // Non-required parameters - "availabilityZone": { - "value": 1 - }, - "backupPolicyName": { - "value": "" - }, - "backupVaultName": { - "value": "" - }, - "backupVaultResourceGroup": { - "value": "" - }, - "computerName": { - "value": "linvm1" - }, - "dataDisks": { - "value": [ - { - "caching": "ReadWrite", - "createOption": "Empty", - "deleteOption": "Delete", - "diskSizeGB": "128", - "managedDisk": { - "storageAccountType": "Premium_LRS" - } - }, - { - "caching": "ReadWrite", - "createOption": "Empty", - "deleteOption": "Delete", - "diskSizeGB": "128", - "managedDisk": { - "storageAccountType": "Premium_LRS" - } - } - ] - }, - "disablePasswordAuthentication": { - "value": true - }, - "enableAutomaticUpdates": { - "value": true - }, - "encryptionAtHost": { - "value": false - }, - "extensionAadJoinConfig": { - "value": { - "enabled": true, - "tags": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - }, - "extensionAzureDiskEncryptionConfig": { - "value": { - "enabled": true, - "settings": { - "EncryptionOperation": "EnableEncryption", - "KekVaultResourceId": "", - "KeyEncryptionAlgorithm": "RSA-OAEP", - "KeyEncryptionKeyURL": "", - "KeyVaultResourceId": "", - "KeyVaultURL": "", - "ResizeOSDisk": "false", - "VolumeType": "All" - }, - "tags": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - }, - "extensionCustomScriptConfig": { - "value": { - "enabled": true, - "fileData": [ - { - "storageAccountId": "", - "uri": "" - } - ], - "tags": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - }, - "extensionCustomScriptProtectedSetting": { - "value": { - "commandToExecute": "" - } - }, - "extensionDependencyAgentConfig": { - "value": { - "enabled": true, - "tags": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - }, - "extensionDSCConfig": { - "value": { - "enabled": false, - "tags": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - }, - "extensionMonitoringAgentConfig": { - "value": { - "enabled": true, - "tags": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - }, - "extensionNetworkWatcherAgentConfig": { - "value": { - "enabled": true, - "tags": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - }, - "location": { - "value": "" - }, - "lock": { - "value": { - "kind": "CanNotDelete", - "name": "myCustomLockName" - } - }, - "managedIdentities": { - "value": { - "systemAssigned": true, - "userAssignedResourceIds": [ - "" - ] - } - }, - "monitoringWorkspaceId": { - "value": "" - }, - "name": { - "value": "cvmlinmax" - }, - "patchMode": { - "value": "AutomaticByPlatform" - }, - "publicKeys": { - "value": [ - { - "keyData": "", - "path": "/home/localAdministrator/.ssh/authorized_keys" - } - ] - }, - "roleAssignments": { - "value": [ - { - "principalId": "", - "principalType": "ServicePrincipal", - "roleDefinitionIdOrName": "Owner" - }, - { - "principalId": "", - "principalType": "ServicePrincipal", - "roleDefinitionIdOrName": "b24988ac-6180-42a0-ab88-20f7382dd24c" - }, - { - "principalId": "", - "principalType": "ServicePrincipal", - "roleDefinitionIdOrName": "" - } - ] - }, - "tags": { - "value": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - } -} -``` - -
-

- -### Example 4: _WAF-aligned_ +### Example 3: _WAF-aligned_ This instance deploys the module in alignment with the best-practices of the Well-Architected Framework. @@ -1544,7 +969,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = {

-### Example 5: _Using automanage for the VM._ +### Example 4: _Using automanage for the VM._ This instance deploys the module with registering to an automation account. @@ -1676,7 +1101,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = {

-### Example 6: _Using only defaults_ +### Example 5: _Using only defaults_ This instance deploys the module with the minimum set of required parameters. @@ -1792,7 +1217,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = {

-### Example 7: _Using large parameter set_ +### Example 6: _Using large parameter set_ This instance deploys the module with most of its features enabled. @@ -2404,7 +1829,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = {

-### Example 8: _Using disk encryption set for the VM._ +### Example 7: _Using disk encryption set for the VM._ This instance deploys the module with disk enryption set. From fbfbadf80eee9cf82657ffb6b95f3036ec4bfd98 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Tue, 12 Dec 2023 08:47:09 +0100 Subject: [PATCH 38/96] restore accidently deleted files --- .../availability-set/.bicep/nested_rbac.bicep | 44 + modules/compute/availability-set/README.md | 75 + modules/compute/availability-set/main.bicep | 80 + modules/compute/availability-set/main.json | 241 +++ .../availability-set/test/main.test.bicep | 65 + modules/compute/availability-set/version.json | 8 + .../.bicep/nested_privateEndpoint.bicep | 58 + .../.bicep/nested_rbac.bicep | 59 + modules/compute/container-registry/README.md | 147 ++ modules/compute/container-registry/main.bicep | 295 +++ modules/compute/container-registry/main.json | 896 ++++++++ .../container-registry/task/task.bicep | 49 + .../test/dependencies.test.bicep | 114 ++ .../container-registry/test/main.test.bicep | 179 ++ .../compute/container-registry/test/task.yaml | 5 + .../compute/container-registry/version.json | 8 + modules/compute/custom-image-vmss/README.md | 92 + modules/compute/custom-image-vmss/main.bicep | 165 ++ modules/compute/custom-image-vmss/main.json | 1102 ++++++++++ .../modules/virtualNetworks.bicep | 35 + .../custom-image-vmss/test/imageConfig.json | 11 + .../custom-image-vmss/test/main.test.bicep | 23 + .../compute/custom-image-vmss/version.json | 8 + modules/compute/event-hub/README.md | 269 +++ modules/compute/event-hub/bicepconfig.json | 5 + modules/compute/event-hub/main.bicep | 407 ++++ modules/compute/event-hub/main.json | 1802 +++++++++++++++++ .../event-hub/modules/authorizationRule.bicep | 15 + .../event-hub/modules/diagnosticSetting.bicep | 25 + .../modules/disasterRecoveryConfig.bicep | 16 + .../modules/eventHub/authorizationRule.bicep | 21 + .../modules/eventHub/consumerGroup.bicep | 20 + .../event-hub/modules/eventHub/eventHub.bicep | 71 + .../modules/eventHub/roleAssignment.bicep | 48 + .../event-hub/modules/privateEndpoint.bicep | 53 + .../event-hub/modules/roleAssignment.bicep | 42 + .../compute/event-hub/test/main.test.bicep | 237 +++ .../compute/event-hub/test/prereq.test.bicep | 126 ++ modules/compute/event-hub/version.json | 8 + modules/compute/function-app/README.md | 141 ++ modules/compute/function-app/bicepconfig.json | 5 + modules/compute/function-app/main.bicep | 339 ++++ modules/compute/function-app/main.json | 638 ++++++ .../functions_source_code/test_1_index.js | 8 + .../compute/function-app/test/main.test.bicep | 76 + .../function-app/test/prereq.test.bicep | 96 + .../function-app/test/upload-file.bicep | 35 + modules/compute/function-app/version.json | 8 + 48 files changed, 8270 insertions(+) create mode 100644 modules/compute/availability-set/.bicep/nested_rbac.bicep create mode 100644 modules/compute/availability-set/README.md create mode 100644 modules/compute/availability-set/main.bicep create mode 100644 modules/compute/availability-set/main.json create mode 100644 modules/compute/availability-set/test/main.test.bicep create mode 100644 modules/compute/availability-set/version.json create mode 100644 modules/compute/container-registry/.bicep/nested_privateEndpoint.bicep create mode 100644 modules/compute/container-registry/.bicep/nested_rbac.bicep create mode 100644 modules/compute/container-registry/README.md create mode 100644 modules/compute/container-registry/main.bicep create mode 100644 modules/compute/container-registry/main.json create mode 100644 modules/compute/container-registry/task/task.bicep create mode 100644 modules/compute/container-registry/test/dependencies.test.bicep create mode 100644 modules/compute/container-registry/test/main.test.bicep create mode 100644 modules/compute/container-registry/test/task.yaml create mode 100644 modules/compute/container-registry/version.json create mode 100644 modules/compute/custom-image-vmss/README.md create mode 100644 modules/compute/custom-image-vmss/main.bicep create mode 100644 modules/compute/custom-image-vmss/main.json create mode 100644 modules/compute/custom-image-vmss/modules/virtualNetworks.bicep create mode 100644 modules/compute/custom-image-vmss/test/imageConfig.json create mode 100644 modules/compute/custom-image-vmss/test/main.test.bicep create mode 100644 modules/compute/custom-image-vmss/version.json create mode 100644 modules/compute/event-hub/README.md create mode 100644 modules/compute/event-hub/bicepconfig.json create mode 100644 modules/compute/event-hub/main.bicep create mode 100644 modules/compute/event-hub/main.json create mode 100644 modules/compute/event-hub/modules/authorizationRule.bicep create mode 100644 modules/compute/event-hub/modules/diagnosticSetting.bicep create mode 100644 modules/compute/event-hub/modules/disasterRecoveryConfig.bicep create mode 100644 modules/compute/event-hub/modules/eventHub/authorizationRule.bicep create mode 100644 modules/compute/event-hub/modules/eventHub/consumerGroup.bicep create mode 100644 modules/compute/event-hub/modules/eventHub/eventHub.bicep create mode 100644 modules/compute/event-hub/modules/eventHub/roleAssignment.bicep create mode 100644 modules/compute/event-hub/modules/privateEndpoint.bicep create mode 100644 modules/compute/event-hub/modules/roleAssignment.bicep create mode 100644 modules/compute/event-hub/test/main.test.bicep create mode 100644 modules/compute/event-hub/test/prereq.test.bicep create mode 100644 modules/compute/event-hub/version.json create mode 100644 modules/compute/function-app/README.md create mode 100644 modules/compute/function-app/bicepconfig.json create mode 100644 modules/compute/function-app/main.bicep create mode 100644 modules/compute/function-app/main.json create mode 100644 modules/compute/function-app/test/functions_source_code/test_1_index.js create mode 100644 modules/compute/function-app/test/main.test.bicep create mode 100644 modules/compute/function-app/test/prereq.test.bicep create mode 100644 modules/compute/function-app/test/upload-file.bicep create mode 100644 modules/compute/function-app/version.json diff --git a/modules/compute/availability-set/.bicep/nested_rbac.bicep b/modules/compute/availability-set/.bicep/nested_rbac.bicep new file mode 100644 index 0000000000..1c6f4c3502 --- /dev/null +++ b/modules/compute/availability-set/.bicep/nested_rbac.bicep @@ -0,0 +1,44 @@ +param description string = '' +param principalType string = '' +param principalIds array +param roleDefinitionIdOrName string +param resourceId string + +var builtInRoleNames = { + 'Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') + 'Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') + 'Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + 'Avere Cluster Create': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a7b1b19a-0e83-4fe5-935c-faaefbfd18c3') + 'Avere Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a') + 'Azure Service Deploy Release Management Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '21d96096-b162-414a-8302-d8354f9d91b2') + 'CAL-Custom-Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b266cd7-0bba-4ae2-8423-90ede5e1e898') + 'DevTest Labs User': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64') + 'Log Analytics Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293') + 'Log Analytics Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893') + 'Managed Application Contributor Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e') + 'Managed Application Operator Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae') + 'Managed Applications Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44') + 'masterreader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a48d7796-14b4-4889-afef-fbb65a93e5a2') + 'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa') + 'Monitoring Metrics Publisher': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb') + 'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05') + 'Reservation Purchaser': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f7b75c60-3036-4b75-91c3-6b41c27c1689') + 'Resource Policy Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608') + 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') + 'Virtual Machine Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c') +} + +resource availabilitySet 'Microsoft.Compute/availabilitySets@2021-04-01' existing = { + name: last(split(resourceId, '/')) +} + +resource roleAssignment 'Microsoft.Authorization/roleAssignments@2021-04-01-preview' = [for principalId in principalIds: { + name: guid(availabilitySet.name, principalId, roleDefinitionIdOrName) + properties: { + description: description + roleDefinitionId: contains(builtInRoleNames, roleDefinitionIdOrName) ? builtInRoleNames[roleDefinitionIdOrName] : roleDefinitionIdOrName + principalId: principalId + principalType: !empty(principalType) ? principalType : null + } + scope: availabilitySet +}] diff --git a/modules/compute/availability-set/README.md b/modules/compute/availability-set/README.md new file mode 100644 index 0000000000..35a04e0baa --- /dev/null +++ b/modules/compute/availability-set/README.md @@ -0,0 +1,75 @@ +# Availability Set + +This module deploys Microsoft.Compute Availability Sets and optionally available children or extensions + +## Details + +{{ Add detailed information about the module. }} + +## Parameters + +| Name | Type | Required | Description | +| :---------------------------- | :------: | :------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `name` | `string` | Yes | Required. The name of the availability set that is being created. | +| `availabilitySetFaultDomain` | `int` | No | Optional. The number of fault domains to use. | +| `availabilitySetUpdateDomain` | `int` | No | Optional. The number of update domains to use. | +| `availabilitySetSku` | `string` | No | Optional. Sku of the availability set. Use 'Aligned' for virtual machines with managed disks and 'Classic' for virtual machines with unmanaged disks. | +| `proximityPlacementGroupId` | `string` | No | Optional. Resource ID of a proximity placement group. | +| `location` | `string` | No | Optional. Resource location. | +| `lock` | `string` | No | Optional. Specify the type of lock. | +| `roleAssignments` | `array` | No | Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11' | +| `tags` | `object` | No | Optional. Tags of the availability set resource. | + +## Outputs + +| Name | Type | Description | +| :------------------ | :------: | :-------------------------------------------------------- | +| `name` | `string` | The name of the availability set | +| `resourceId` | `string` | The resource ID of the availability set | +| `resourceGroupName` | `string` | The resource group the availability set was deployed into | + +## Examples + +### Example 1 + +Example invocation with the minimum required parameters. + +```bicep +module minavs 'br/public:compute/availability-set:1.0.2' = { + name: '${uniqueString(deployment().name, 'WestEurope')}-minavs' + params: { + name: 'carml-az-avs-min-01' + } +} +``` + +### Example 2 + +Example invocation with several properties including tags & role assignments. + +```bicep +module genavs 'br/public:compute/availability-set:1.0.2' = { + name: '${uniqueString(deployment().name, 'WestEurope')}-genavs' + params: { + name: 'carml-az-avs-gen-01' + proximityPlacementGroupId: '/subscriptions/111111-1111-1111-1111-111111111111/resourceGroups/validation-rg/providers/Microsoft.Compute/proximityPlacementGroups/adp-carml-az-ppg-x-001' + availabilitySetSku: 'aligned' + availabilitySetUpdateDomain: 2 + availabilitySetFaultDomain: 2 + tags: { + tag1: 'tag1Value' + tag2: 'tag2Value' + } + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalIds: [ + '222222-2222-2222-2222-2222222222' + ] + principalType: 'ServicePrincipal' + } + ] + location: 'WestEurope' + } +} +``` \ No newline at end of file diff --git a/modules/compute/availability-set/main.bicep b/modules/compute/availability-set/main.bicep new file mode 100644 index 0000000000..aa5ab99ba3 --- /dev/null +++ b/modules/compute/availability-set/main.bicep @@ -0,0 +1,80 @@ +metadata name = 'Availability Set' +metadata description = 'This module deploys Microsoft.Compute Availability Sets and optionally available children or extensions' +metadata owner = 'CARML' + +@description('Required. The name of the availability set that is being created.') +param name string + +@description('Optional. The number of fault domains to use.') +param availabilitySetFaultDomain int = 2 + +@description('Optional. The number of update domains to use.') +param availabilitySetUpdateDomain int = 5 + +@description('Optional. Sku of the availability set. Use \'Aligned\' for virtual machines with managed disks and \'Classic\' for virtual machines with unmanaged disks.') +param availabilitySetSku string = 'Aligned' + +@description('Optional. Resource ID of a proximity placement group.') +param proximityPlacementGroupId string = '' + +@description('Optional. Resource location.') +param location string = resourceGroup().location + +@allowed([ + 'CanNotDelete' + 'NotSpecified' + 'ReadOnly' +]) +@description('Optional. Specify the type of lock.') +param lock string = 'NotSpecified' + +@description('Optional. Array of role assignment objects that contain the \'roleDefinitionIdOrName\' and \'principalId\' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'') +param roleAssignments array = [] + +@description('Optional. Tags of the availability set resource.') +param tags object = {} + +resource availabilitySet 'Microsoft.Compute/availabilitySets@2021-07-01' = { + name: name + location: location + tags: tags + properties: { + platformFaultDomainCount: availabilitySetFaultDomain + platformUpdateDomainCount: availabilitySetUpdateDomain + proximityPlacementGroup: !empty(proximityPlacementGroupId) ? { + id: proximityPlacementGroupId + } : null + } + sku: { + name: availabilitySetSku + } +} + +resource availabilitySet_lock 'Microsoft.Authorization/locks@2017-04-01' = if (lock != 'NotSpecified') { + name: '${availabilitySet.name}-${lock}-lock' + properties: { + level: lock + notes: lock == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot modify the resource or child resources.' + } + scope: availabilitySet +} + +module availabilitySet_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: { + name: '${uniqueString(deployment().name, location)}-AvSet-Rbac-${index}' + params: { + description: contains(roleAssignment, 'description') ? roleAssignment.description : '' + principalIds: roleAssignment.principalIds + roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName + principalType: contains(roleAssignment, 'principalType') ? roleAssignment.principalType : '' + resourceId: availabilitySet.id + } +}] + +@description('The name of the availability set') +output name string = availabilitySet.name + +@description('The resource ID of the availability set') +output resourceId string = availabilitySet.id + +@description('The resource group the availability set was deployed into') +output resourceGroupName string = resourceGroup().name diff --git a/modules/compute/availability-set/main.json b/modules/compute/availability-set/main.json new file mode 100644 index 0000000000..34639b12a3 --- /dev/null +++ b/modules/compute/availability-set/main.json @@ -0,0 +1,241 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.19.5.34762", + "templateHash": "18288547414035236019" + }, + "name": "Availability Set", + "description": "This module deploys Microsoft.Compute Availability Sets and optionally available children or extensions", + "owner": "CARML" + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the availability set that is being created." + } + }, + "availabilitySetFaultDomain": { + "type": "int", + "defaultValue": 2, + "metadata": { + "description": "Optional. The number of fault domains to use." + } + }, + "availabilitySetUpdateDomain": { + "type": "int", + "defaultValue": 5, + "metadata": { + "description": "Optional. The number of update domains to use." + } + }, + "availabilitySetSku": { + "type": "string", + "defaultValue": "Aligned", + "metadata": { + "description": "Optional. Sku of the availability set. Use 'Aligned' for virtual machines with managed disks and 'Classic' for virtual machines with unmanaged disks." + } + }, + "proximityPlacementGroupId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of a proximity placement group." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Resource location." + } + }, + "lock": { + "type": "string", + "defaultValue": "NotSpecified", + "metadata": { + "description": "Optional. Specify the type of lock." + }, + "allowedValues": [ + "CanNotDelete", + "NotSpecified", + "ReadOnly" + ] + }, + "roleAssignments": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'" + } + }, + "tags": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Tags of the availability set resource." + } + } + }, + "resources": [ + { + "type": "Microsoft.Compute/availabilitySets", + "apiVersion": "2021-07-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "platformFaultDomainCount": "[parameters('availabilitySetFaultDomain')]", + "platformUpdateDomainCount": "[parameters('availabilitySetUpdateDomain')]", + "proximityPlacementGroup": "[if(not(empty(parameters('proximityPlacementGroupId'))), createObject('id', parameters('proximityPlacementGroupId')), null())]" + }, + "sku": { + "name": "[parameters('availabilitySetSku')]" + } + }, + { + "condition": "[not(equals(parameters('lock'), 'NotSpecified'))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2017-04-01", + "scope": "[format('Microsoft.Compute/availabilitySets/{0}', parameters('name'))]", + "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "properties": { + "level": "[parameters('lock')]", + "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + }, + "dependsOn": [ + "[resourceId('Microsoft.Compute/availabilitySets', parameters('name'))]" + ] + }, + { + "copy": { + "name": "availabilitySet_rbac", + "count": "[length(parameters('roleAssignments'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-AvSet-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", + "principalIds": { + "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" + }, + "roleDefinitionIdOrName": { + "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" + }, + "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", + "resourceId": { + "value": "[resourceId('Microsoft.Compute/availabilitySets', parameters('name'))]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.19.5.34762", + "templateHash": "13867729327786497095" + } + }, + "parameters": { + "description": { + "type": "string", + "defaultValue": "" + }, + "principalType": { + "type": "string", + "defaultValue": "" + }, + "principalIds": { + "type": "array" + }, + "roleDefinitionIdOrName": { + "type": "string" + }, + "resourceId": { + "type": "string" + } + }, + "variables": { + "builtInRoleNames": { + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Avere Cluster Create": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a7b1b19a-0e83-4fe5-935c-faaefbfd18c3')]", + "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", + "Azure Service Deploy Release Management Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '21d96096-b162-414a-8302-d8354f9d91b2')]", + "CAL-Custom-Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b266cd7-0bba-4ae2-8423-90ede5e1e898')]", + "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", + "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", + "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", + "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", + "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", + "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", + "masterreader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a48d7796-14b4-4889-afef-fbb65a93e5a2')]", + "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", + "Monitoring Metrics Publisher": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')]", + "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", + "Reservation Purchaser": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f7b75c60-3036-4b75-91c3-6b41c27c1689')]", + "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", + "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]" + } + }, + "resources": [ + { + "copy": { + "name": "roleAssignment", + "count": "[length(parameters('principalIds'))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2021-04-01-preview", + "scope": "[format('Microsoft.Compute/availabilitySets/{0}', last(split(parameters('resourceId'), '/')))]", + "name": "[guid(last(split(parameters('resourceId'), '/')), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", + "properties": { + "description": "[parameters('description')]", + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", + "principalId": "[parameters('principalIds')[copyIndex()]]", + "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]" + } + } + ] + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Compute/availabilitySets', parameters('name'))]" + ] + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the availability set" + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the availability set" + }, + "value": "[resourceId('Microsoft.Compute/availabilitySets', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the availability set was deployed into" + }, + "value": "[resourceGroup().name]" + } + } +} \ No newline at end of file diff --git a/modules/compute/availability-set/test/main.test.bicep b/modules/compute/availability-set/test/main.test.bicep new file mode 100644 index 0000000000..2bf46dd84f --- /dev/null +++ b/modules/compute/availability-set/test/main.test.bicep @@ -0,0 +1,65 @@ +// ========== // +// Parameters // +// ========== // + +// Shared +@description('Optional. The location to deploy resources to') +param location string = resourceGroup().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 = 'avs' + +// ========== // +// Test Setup // +// ========== // + +// General resources +// ================= +resource proximityPlacementGroup 'Microsoft.Compute/proximityPlacementGroups@2021-11-01' = { + name: 'adp-${serviceShort}-az-ppg-x-01' + location: location +} + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: 'adp-${serviceShort}-az-msi-x-01' + location: location +} + +// ============== // +// Test Execution // +// ============== // + +// TEST 1 - MIN +module minavs '../main.bicep' = { + name: '${uniqueString(deployment().name, location)}-minavs' + params: { + name: '${serviceShort}-az-avs-min-01' + location: location + } +} + +// TEST 2 - GENERAL +module genavs '../main.bicep' = { + name: '${uniqueString(deployment().name, location)}-genavs' + params: { + name: '${serviceShort}-az-avs-gen-01' + proximityPlacementGroupId: proximityPlacementGroup.id + availabilitySetSku: 'aligned' + availabilitySetUpdateDomain: 2 + availabilitySetFaultDomain: 2 + tags: { + tag1: 'tag1Value' + tag2: 'tag2Value' + } + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalIds: [ + managedIdentity.properties.principalId + ] + principalType: 'ServicePrincipal' + } + ] + location: location + } +} diff --git a/modules/compute/availability-set/version.json b/modules/compute/availability-set/version.json new file mode 100644 index 0000000000..e40897e287 --- /dev/null +++ b/modules/compute/availability-set/version.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "1.0", + "pathFilters": [ + "./main.json", + "./metadata.json" + ] +} \ No newline at end of file diff --git a/modules/compute/container-registry/.bicep/nested_privateEndpoint.bicep b/modules/compute/container-registry/.bicep/nested_privateEndpoint.bicep new file mode 100644 index 0000000000..eafeabc00e --- /dev/null +++ b/modules/compute/container-registry/.bicep/nested_privateEndpoint.bicep @@ -0,0 +1,58 @@ +param location string +param tags object +param manualApprovalEnabled bool +param privateEndpoints array + +var varPrivateEndpoints = [for (p, i) in privateEndpoints: { + name: p.name + privateLinkServiceId: p.privateLinkServiceId + groupIds: p.groupIds + subnetId: p.subnetId + privateDnsZones: contains(p, 'privateDnsZones') ? p.privateDnsZones : [] + customNetworkInterfaceName: contains(p, 'customNetworkInterfaceName') ? p.customNetworkInterfaceName : null +}] + +@batchSize(1) +resource privateEndpoint 'Microsoft.Network/privateEndpoints@2022-05-01' = [for endpoint in varPrivateEndpoints: { + name: '${endpoint.name}-${uniqueString(endpoint.name, endpoint.subnetId, endpoint.privateLinkServiceId)}' + location: location + tags: tags + properties: { + privateLinkServiceConnections: manualApprovalEnabled ? null : [ + { + name: endpoint.name + properties: { + privateLinkServiceId: endpoint.privateLinkServiceId + groupIds: !empty(endpoint.groupIds) ? endpoint.groupIds : null + } + } + ] + manualPrivateLinkServiceConnections: manualApprovalEnabled ? [ + { + name: endpoint.name + properties: { + privateLinkServiceId: endpoint.privateLinkServiceId + groupIds: !empty(endpoint.groupIds) ? endpoint.groupIds : null + } + } + ] : null + subnet: { + id: endpoint.subnetId + } + customNetworkInterfaceName: endpoint.customNetworkInterfaceName + } +}] + +@batchSize(1) +resource privateDnsZoneGroup 'Microsoft.Network/privateEndpoints/privateDnsZoneGroups@2022-05-01' = [for (endpoint, i) in varPrivateEndpoints: { + name: 'default' + parent: privateEndpoint[i] + properties: { + privateDnsZoneConfigs: [for privateDnsZone in endpoint.privateDnsZones: { + name: contains(privateDnsZone, 'name') ? privateDnsZone.name : 'default' + properties: { + privateDnsZoneId: privateDnsZone.zoneId + } + }] + } +}] diff --git a/modules/compute/container-registry/.bicep/nested_rbac.bicep b/modules/compute/container-registry/.bicep/nested_rbac.bicep new file mode 100644 index 0000000000..ccd434646e --- /dev/null +++ b/modules/compute/container-registry/.bicep/nested_rbac.bicep @@ -0,0 +1,59 @@ +param description string = '' +param principalIds array +param principalType string = '' +param roleDefinitionIdOrName string +param resourceId string + +var builtInRoleNames = { + Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') + Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') + Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + 'Avere Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a') + 'Avere Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9') + 'Backup Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b') + 'Backup Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324') + 'Cosmos DB Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa') + 'DevTest Labs User': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64') + 'DocumentDB Account Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450') + 'Log Analytics Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293') + 'Log Analytics Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893') + 'Managed Application Contributor Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e') + 'Managed Application Operator Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae') + 'Managed Applications Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44') + 'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa') + 'Monitoring Metrics Publisher': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb') + 'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05') + 'Network Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7') + 'Private DNS Zone Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f') + 'Resource Policy Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608') + 'Site Recovery Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567') + 'Site Recovery Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca') + 'SQL Managed Instance Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d') + 'SQL Security Manager': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3') + 'Storage Account Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab') + 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') + 'Virtual Machine Administrator Login': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4') + 'Virtual Machine Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c') + 'Virtual Machine User Login': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52') + AcrDelete: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c2f4ef07-c644-48eb-af81-4b1b4947fb11') + AcrImageSigner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c2f4ef07-c644-48eb-af81-4b1b4947fb11') + AcrPull: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d') + AcrPush: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8311e382-0749-4cb8-b61a-304f252e45ec') + AcrQuarantineReader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'cdda3590-29a3-44f6-95f2-9f980659eb04') + AcrQuarantineWriter: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c8d4ff99-41c3-41a8-9f60-21dfdad59608') +} + +resource containerRegistry 'Microsoft.ContainerRegistry/registries@2021-09-01' existing = { + name: last(split(resourceId, '/')) +} + +resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for principalId in principalIds: { + name: guid(containerRegistry.name, principalId, roleDefinitionIdOrName) + properties: { + description: description + roleDefinitionId: contains(builtInRoleNames, roleDefinitionIdOrName) ? builtInRoleNames[roleDefinitionIdOrName] : roleDefinitionIdOrName + principalId: principalId + principalType: !empty(principalType) ? principalType : null + } + scope: containerRegistry +}] diff --git a/modules/compute/container-registry/README.md b/modules/compute/container-registry/README.md new file mode 100644 index 0000000000..477259e0ff --- /dev/null +++ b/modules/compute/container-registry/README.md @@ -0,0 +1,147 @@ +# Container Registry + +This module deploys Container Registry (Microsoft.ContainerRegistry/registries) and optionally available integrations. + +## Details + +[Azure Container Registry (ACR)](http://aka.ms/acr) is a hosted registry for Docker and Open Container Initiative (OCI) artifacts. This module provides an Infrastructure as Code alternative for management of Container Registry using Bicep, and is intended to mirror the available functionality of provisioning with Azure Portal or CLI. + +## Parameters + +| Name | Type | Required | Description | +| :-------------------------------------- | :------: | :------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `name` | `string` | Yes | The name of the Azure Container Registry. | +| `location` | `string` | No | Location for all resources. | +| `tags` | `object` | No | Tags for all resource(s). | +| `skuName` | `string` | No | The SKU of the Azure Container Registry. | +| `adminUserEnabled` | `bool` | No | Toggle the Azure Container Registry admin user. | +| `publicNetworkAccessEnabled` | `bool` | No | Toggle public network access to Azure Container Registry. | +| `publicAzureAccessEnabled` | `bool` | No | When public network access is disabled, toggle this to allow Azure services to bypass the public network access rule. | +| `networkAllowedIpRanges` | `array` | No | A list of IP or IP ranges in CIDR format, that should be allowed access to Azure Container Registry. | +| `networkDefaultAction` | `string` | No | The default action to take when no network rule match is found for accessing Azure Container Registry. | +| `roleAssignments` | `array` | No | Array of role assignment objects that contain the 'roleDefinitionIdOrName'(string) and 'principalIds'(array of strings) to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11' | +| `lock` | `string` | No | Specify the type of lock. | +| `privateEndpoints` | `array` | No | Define Private Endpoints that should be created for Azure Container Registry. | +| `privateEndpointsApprovalEnabled` | `bool` | No | Toggle if Private Endpoints manual approval for Azure Container Registry should be enabled. | +| `zoneRedundancyEnabled` | `bool` | No | Toggle if Zone Redundancy should be enabled on Azure Container Registry. | +| `replicationLocations` | `array` | No | Array of Azure Location configurations that this Azure Container Registry should replicate too. | +| `dataEndpointEnabled` | `bool` | No | Toggle if a single data endpoint per region for serving data from Azure Container Registry should be enabled. | +| `encryptionEnabled` | `bool` | No | Toggle if encryption should be enabled on Azure Container Registry. | +| `exportPolicyEnabled` | `bool` | No | Toggle if export policy should be enabled on Azure Container Registry. | +| `quarantinePolicyEnabled` | `bool` | No | Toggle if quarantine policy should be enabled on Azure Container Registry. | +| `retentionPolicyEnabled` | `bool` | No | Toggle if retention policy should be enabled on Azure Container Registry. | +| `retentionPolicyInDays` | `int` | No | Configure the retention policy in days for Azure Container Registry. Only effective is 'retentionPolicyEnabled' is 'true'. | +| `trustPolicyEnabled` | `bool` | No | Toggle if trust policy should be enabled on Azure Container Registry. | +| `encryptionKeyVaultIdentity` | `string` | No | The client ID of the identity which will be used to access Key Vault. | +| `encryptionKeyVaultKeyIdentifier` | `string` | No | The Key Vault URI to access the encryption key. | +| `diagnosticLogsRetentionInDays` | `int` | No | Specifies the number of days that logs will be kept for; a value of 0 will retain data indefinitely. | +| `diagnosticStorageAccountId` | `string` | No | Resource ID of the diagnostic storage account. | +| `diagnosticWorkspaceId` | `string` | No | Resource ID of the diagnostic log analytics workspace. | +| `diagnosticEventHubAuthorizationRuleId` | `string` | No | 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. | +| `diagnosticEventHubName` | `string` | No | 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. | +| `logsToEnable` | `array` | No | The name of logs that will be streamed. | +| `metricsToEnable` | `array` | No | The name of metrics that will be streamed. | +| `tasks` | `array` | No | Optional. The list of ACR tasks to create. | + +## Outputs + +| Name | Type | Description | +| :------------------ | :------: | :----------------------------------------------------------------- | +| `resourceGroupName` | `string` | The resource group the Azure Container Registry was deployed into. | +| `resourceId` | `string` | The resource ID of the Azure Container Registry. | +| `name` | `string` | The name of the Azure Container Registry. | +| `loginServer` | `string` | The login server URL of the Azure Container Registry. | + +## Examples + +### Example 1 + +An example of how to deploy Azure Container Registry using the minimum required parameters. + +```bicep +module containerRegistry 'br/public:compute/container-registry:1.1.1' = { + name: '${uniqueString(deployment().name, 'eastus')}-container-registry' + params: { + name: 'acr${uniqueString(deployment().name, location)}' + location: 'eastus' + } +} +``` + +### Example 2 + +An example of how to deploy a 'Premium' SKU instance of Azure Container Registry with private networking. + +```bicep +param subnetId string +param privateDnsZoneId string + +module containerRegistry 'br/public:compute/container-registry:1.1.1' = { + name: '${uniqueString(deployment().name, 'eastus')}-container-registry' + params: { + name: 'acr${uniqueString(deployment().name, location)}' + location: 'eastus' + skuName: 'Premium' + privateEndpoints: [ + { + name: 'endpoint1' + subnetId: subnetId + privateDnsZoneId: privateDnsZoneId + } + ] + tasks: [ { + taskName: 'task1' + status: 'Enabled' + platform: { + os: 'Linux' + architecture: 'Amd64' + } + agentConfiguration: { + cpu: 2 + } + trigger: { + timerTriggers: [ + { + name: 'trigger1' + status: 'Enabled' + schedule: '*/1 * * * Mon-Fri' + } + ] + } + step: { + type: 'EncodedTask' + encodedTaskContent: loadFileAsBase64('task.yaml') + } + identity: { + type: 'SystemAssigned' + } + } + ] + } +} +``` + +### Example 3 + +An example of how to deploy a 'Premium' SKU instance of Azure Container Registry with replication to multiple Azure Locations. + +```bicep +module containerRegistry 'br/public:compute/container-registry:1.1.1' = { + name: '${uniqueString(deployment().name, 'eastus')}-container-registry' + params: { + name: 'acr${uniqueString(deployment().name, location)}' + location: 'eastus' + skuName: 'Premium' + replicationLocations: [ + { + location: 'eastus2' + } + { + location: 'northeurope' + regionEndpointEnabled: true + zoneRedundancy: true + } + ] + } +} +``` \ No newline at end of file diff --git a/modules/compute/container-registry/main.bicep b/modules/compute/container-registry/main.bicep new file mode 100644 index 0000000000..6a6d4e4e0e --- /dev/null +++ b/modules/compute/container-registry/main.bicep @@ -0,0 +1,295 @@ +metadata name = 'Container Registry' +metadata description = 'This module deploys Container Registry (Microsoft.ContainerRegistry/registries) and optionally available integrations.' +metadata owner = 'thomasriley' + +@minLength(5) +@maxLength(50) +@description('The name of the Azure Container Registry.') +param name string + +@description('Location for all resources.') +param location string = resourceGroup().location + +@description('Tags for all resource(s).') +param tags object = {} + +@description('The SKU of the Azure Container Registry.') +@allowed([ + 'Basic' + 'Standard' + 'Premium' +]) +param skuName string = 'Basic' + +@description('Toggle the Azure Container Registry admin user.') +param adminUserEnabled bool = false + +@description('Toggle public network access to Azure Container Registry.') +param publicNetworkAccessEnabled bool = true + +@description('When public network access is disabled, toggle this to allow Azure services to bypass the public network access rule.') +param publicAzureAccessEnabled bool = true + +@description('A list of IP or IP ranges in CIDR format, that should be allowed access to Azure Container Registry.') +param networkAllowedIpRanges array = [] + +@description('The default action to take when no network rule match is found for accessing Azure Container Registry.') +@allowed([ + 'Allow' + 'Deny' +]) +param networkDefaultAction string = 'Deny' + +@description('Array of role assignment objects that contain the \'roleDefinitionIdOrName\'(string) and \'principalIds\'(array of strings) to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'') +param roleAssignments array = [] + +@allowed([ + 'CanNotDelete' + 'NotSpecified' + 'ReadOnly' +]) +@description('Specify the type of lock.') +param lock string = 'NotSpecified' + +@description('Define Private Endpoints that should be created for Azure Container Registry.') +param privateEndpoints array = [] + +@description('Toggle if Private Endpoints manual approval for Azure Container Registry should be enabled.') +param privateEndpointsApprovalEnabled bool = false + +@description('Toggle if Zone Redundancy should be enabled on Azure Container Registry.') +param zoneRedundancyEnabled bool = false + +@description('Array of Azure Location configurations that this Azure Container Registry should replicate too.') +param replicationLocations array = [] + +@description('Toggle if a single data endpoint per region for serving data from Azure Container Registry should be enabled.') +param dataEndpointEnabled bool = false + +@description('Toggle if encryption should be enabled on Azure Container Registry.') +param encryptionEnabled bool = false + +@description('Toggle if export policy should be enabled on Azure Container Registry.') +param exportPolicyEnabled bool = false + +@description('Toggle if quarantine policy should be enabled on Azure Container Registry.') +param quarantinePolicyEnabled bool = false + +@description('Toggle if retention policy should be enabled on Azure Container Registry.') +param retentionPolicyEnabled bool = false + +@description('Configure the retention policy in days for Azure Container Registry. Only effective is \'retentionPolicyEnabled\' is \'true\'.') +param retentionPolicyInDays int = 10 + +@description('Toggle if trust policy should be enabled on Azure Container Registry.') +param trustPolicyEnabled bool = false + +@description('The client ID of the identity which will be used to access Key Vault.') +param encryptionKeyVaultIdentity string = '' + +@description('The Key Vault URI to access the encryption key.') +param encryptionKeyVaultKeyIdentifier string = '' + +@description('Specifies the number of days that logs will be kept for; a value of 0 will retain data indefinitely.') +@minValue(0) +@maxValue(365) +param diagnosticLogsRetentionInDays int = 365 + +@description('Resource ID of the diagnostic storage account.') +param diagnosticStorageAccountId string = '' + +@description('Resource ID of the diagnostic log analytics workspace.') +param diagnosticWorkspaceId string = '' + +@description('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.') +param diagnosticEventHubAuthorizationRuleId string = '' + +@description('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.') +param diagnosticEventHubName string = '' + +@description('The name of logs that will be streamed.') +@allowed([ + 'ContainerRegistryRepositoryEvents' + 'ContainerRegistryLoginEvents' +]) +param logsToEnable array = [ + 'ContainerRegistryRepositoryEvents' + 'ContainerRegistryLoginEvents' +] + +@description('The name of metrics that will be streamed.') +@allowed([ + 'AllMetrics' +]) +param metricsToEnable array = [ + 'AllMetrics' +] + +@description('Optional. The list of ACR tasks to create.') +param tasks array = [] + +var diagnosticsLogs = [for log in logsToEnable: { + category: log + enabled: true + retentionPolicy: { + enabled: true + days: diagnosticLogsRetentionInDays + } +}] + +var diagnosticsMetrics = [for metric in metricsToEnable: { + category: metric + timeGrain: null + enabled: true + retentionPolicy: { + enabled: true + days: diagnosticLogsRetentionInDays + } +}] + +var varNetworkAllowedIpRanges = [for item in networkAllowedIpRanges: { + value: item + action: 'Allow' +}] + +var IS_PREMIUM_SKU = skuName == 'Premium' + +var varPrivateEndpoints = [for privateEndpoint in privateEndpoints: { + name: '${privateEndpoint.name}-${containerRegistry.name}' + privateLinkServiceId: containerRegistry.id + groupIds: [ + 'registry' + ] + subnetId: privateEndpoint.subnetId + privateDnsZones: contains(privateEndpoint, 'privateDnsZoneId') ? [ + { + name: 'default' + zoneId: privateEndpoint.privateDnsZoneId + } + ] : [] +}] + +var varReplicationLocations = [for replicationLocation in replicationLocations: { + location: replicationLocation.location + regionEndpointEnabled: contains(replicationLocation, 'regionEndpointEnabled') ? replicationLocation.regionEndpointEnabled : false + zoneRedundancy: contains(replicationLocation, 'zoneRedundancy') ? replicationLocation.zoneRedundancy : false +}] + +resource containerRegistry 'Microsoft.ContainerRegistry/registries@2021-09-01' = { + name: name + location: location + tags: tags + sku: { + name: skuName + } + properties: { + adminUserEnabled: adminUserEnabled + publicNetworkAccess: IS_PREMIUM_SKU ? publicNetworkAccessEnabled ? 'Enabled' : 'Disabled' : null + networkRuleBypassOptions: IS_PREMIUM_SKU ? publicAzureAccessEnabled ? 'AzureServices' : 'None' : null + networkRuleSet: IS_PREMIUM_SKU ? { + defaultAction: networkDefaultAction + ipRules: varNetworkAllowedIpRanges + } : null + dataEndpointEnabled: dataEndpointEnabled + encryption: IS_PREMIUM_SKU ? encryptionEnabled ? { + keyVaultProperties: { + identity: encryptionKeyVaultIdentity + keyIdentifier: encryptionKeyVaultKeyIdentifier + } + status: 'enabled' + } : null : null + zoneRedundancy: IS_PREMIUM_SKU ? zoneRedundancyEnabled ? 'Enabled' : 'Disabled' : null + policies: { + exportPolicy: publicAzureAccessEnabled == 'false' ? { + status: exportPolicyEnabled ? 'enabled' : 'disabled' + } : null + quarantinePolicy: { + status: quarantinePolicyEnabled ? 'enabled' : 'disabled' + } + retentionPolicy: IS_PREMIUM_SKU ? retentionPolicyEnabled ? { + days: retentionPolicyInDays + status: 'enabled' + } : null : null + trustPolicy: IS_PREMIUM_SKU ? trustPolicyEnabled ? { + status: 'enabled' + type: 'Notary' + } : null : null + } + } +} + +resource replications 'Microsoft.ContainerRegistry/registries/replications@2021-09-01' = [for replicationLocation in varReplicationLocations: if (IS_PREMIUM_SKU) { + name: replicationLocation.location + parent: containerRegistry + location: replicationLocation.location + tags: tags + properties: { + regionEndpointEnabled: replicationLocation.regionEndpointEnabled + zoneRedundancy: replicationLocation.zoneRedundancy ? 'Enabled' : 'Disabled' + } +}] + +resource containerRegistry_lock 'Microsoft.Authorization/locks@2020-05-01' = if (lock != 'NotSpecified') { + name: '${containerRegistry.name}-${lock}-lock' + properties: { + level: lock + notes: lock == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot modify the resource or child resources.' + } + scope: containerRegistry +} + +resource containerRegistry_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if (!empty(diagnosticStorageAccountId) || !empty(diagnosticWorkspaceId) || !empty(diagnosticEventHubAuthorizationRuleId) || !empty(diagnosticEventHubName)) { + name: '${containerRegistry.name}-diagnosticSettings' + properties: { + storageAccountId: !empty(diagnosticStorageAccountId) ? diagnosticStorageAccountId : null + workspaceId: !empty(diagnosticWorkspaceId) ? diagnosticWorkspaceId : null + eventHubAuthorizationRuleId: !empty(diagnosticEventHubAuthorizationRuleId) ? diagnosticEventHubAuthorizationRuleId : null + eventHubName: !empty(diagnosticEventHubName) ? diagnosticEventHubName : null + metrics: diagnosticsMetrics + logs: diagnosticsLogs + } + scope: containerRegistry +} + +module containerRegistry_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: { + name: '${uniqueString(deployment().name, location)}-acr-rbac-${index}' + params: { + description: contains(roleAssignment, 'description') ? roleAssignment.description : '' + principalIds: roleAssignment.principalIds + roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName + principalType: contains(roleAssignment, 'principalType') ? roleAssignment.principalType : '' + resourceId: containerRegistry.id + } +}] + +module containerRegistry_privateEndpoint '.bicep/nested_privateEndpoint.bicep' = { + name: '${uniqueString(deployment().name, location)}-acr-private-endpoints' + params: { + location: location + privateEndpoints: varPrivateEndpoints + tags: tags + manualApprovalEnabled: privateEndpointsApprovalEnabled + } +} + +module task 'task/task.bicep' = { + name: '${uniqueString(deployment().name, location)}-acr-task' + params: { + acrName: containerRegistry.name + location: location + tasks: tasks + loginServer: containerRegistry.properties.loginServer + } +} + +@description('The resource group the Azure Container Registry was deployed into.') +output resourceGroupName string = resourceGroup().name + +@description('The resource ID of the Azure Container Registry.') +output resourceId string = containerRegistry.id + +@description('The name of the Azure Container Registry.') +output name string = containerRegistry.name + +@description('The login server URL of the Azure Container Registry.') +output loginServer string = containerRegistry.properties.loginServer diff --git a/modules/compute/container-registry/main.json b/modules/compute/container-registry/main.json new file mode 100644 index 0000000000..c002f0d291 --- /dev/null +++ b/modules/compute/container-registry/main.json @@ -0,0 +1,896 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.20.4.51522", + "templateHash": "15501758245983767624" + }, + "name": "Container Registry", + "description": "This module deploys Container Registry (Microsoft.ContainerRegistry/registries) and optionally available integrations.", + "owner": "thomasriley" + }, + "parameters": { + "name": { + "type": "string", + "minLength": 5, + "maxLength": 50, + "metadata": { + "description": "The name of the Azure Container Registry." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Location for all resources." + } + }, + "tags": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Tags for all resource(s)." + } + }, + "skuName": { + "type": "string", + "defaultValue": "Basic", + "allowedValues": [ + "Basic", + "Standard", + "Premium" + ], + "metadata": { + "description": "The SKU of the Azure Container Registry." + } + }, + "adminUserEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Toggle the Azure Container Registry admin user." + } + }, + "publicNetworkAccessEnabled": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Toggle public network access to Azure Container Registry." + } + }, + "publicAzureAccessEnabled": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "When public network access is disabled, toggle this to allow Azure services to bypass the public network access rule." + } + }, + "networkAllowedIpRanges": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "A list of IP or IP ranges in CIDR format, that should be allowed access to Azure Container Registry." + } + }, + "networkDefaultAction": { + "type": "string", + "defaultValue": "Deny", + "allowedValues": [ + "Allow", + "Deny" + ], + "metadata": { + "description": "The default action to take when no network rule match is found for accessing Azure Container Registry." + } + }, + "roleAssignments": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Array of role assignment objects that contain the 'roleDefinitionIdOrName'(string) and 'principalIds'(array of strings) to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'" + } + }, + "lock": { + "type": "string", + "defaultValue": "NotSpecified", + "allowedValues": [ + "CanNotDelete", + "NotSpecified", + "ReadOnly" + ], + "metadata": { + "description": "Specify the type of lock." + } + }, + "privateEndpoints": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Define Private Endpoints that should be created for Azure Container Registry." + } + }, + "privateEndpointsApprovalEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Toggle if Private Endpoints manual approval for Azure Container Registry should be enabled." + } + }, + "zoneRedundancyEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Toggle if Zone Redundancy should be enabled on Azure Container Registry." + } + }, + "replicationLocations": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Array of Azure Location configurations that this Azure Container Registry should replicate too." + } + }, + "dataEndpointEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Toggle if a single data endpoint per region for serving data from Azure Container Registry should be enabled." + } + }, + "encryptionEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Toggle if encryption should be enabled on Azure Container Registry." + } + }, + "exportPolicyEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Toggle if export policy should be enabled on Azure Container Registry." + } + }, + "quarantinePolicyEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Toggle if quarantine policy should be enabled on Azure Container Registry." + } + }, + "retentionPolicyEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Toggle if retention policy should be enabled on Azure Container Registry." + } + }, + "retentionPolicyInDays": { + "type": "int", + "defaultValue": 10, + "metadata": { + "description": "Configure the retention policy in days for Azure Container Registry. Only effective is 'retentionPolicyEnabled' is 'true'." + } + }, + "trustPolicyEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Toggle if trust policy should be enabled on Azure Container Registry." + } + }, + "encryptionKeyVaultIdentity": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The client ID of the identity which will be used to access Key Vault." + } + }, + "encryptionKeyVaultKeyIdentifier": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The Key Vault URI to access the encryption key." + } + }, + "diagnosticLogsRetentionInDays": { + "type": "int", + "defaultValue": 365, + "minValue": 0, + "maxValue": 365, + "metadata": { + "description": "Specifies the number of days that logs will be kept for; a value of 0 will retain data indefinitely." + } + }, + "diagnosticStorageAccountId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Resource ID of the diagnostic storage account." + } + }, + "diagnosticWorkspaceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Resource ID of the diagnostic log analytics workspace." + } + }, + "diagnosticEventHubAuthorizationRuleId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "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." + } + }, + "diagnosticEventHubName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "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." + } + }, + "logsToEnable": { + "type": "array", + "defaultValue": [ + "ContainerRegistryRepositoryEvents", + "ContainerRegistryLoginEvents" + ], + "allowedValues": [ + "ContainerRegistryRepositoryEvents", + "ContainerRegistryLoginEvents" + ], + "metadata": { + "description": "The name of logs that will be streamed." + } + }, + "metricsToEnable": { + "type": "array", + "defaultValue": [ + "AllMetrics" + ], + "allowedValues": [ + "AllMetrics" + ], + "metadata": { + "description": "The name of metrics that will be streamed." + } + }, + "tasks": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. The list of ACR tasks to create." + } + } + }, + "variables": { + "copy": [ + { + "name": "diagnosticsLogs", + "count": "[length(parameters('logsToEnable'))]", + "input": { + "category": "[parameters('logsToEnable')[copyIndex('diagnosticsLogs')]]", + "enabled": true, + "retentionPolicy": { + "enabled": true, + "days": "[parameters('diagnosticLogsRetentionInDays')]" + } + } + }, + { + "name": "diagnosticsMetrics", + "count": "[length(parameters('metricsToEnable'))]", + "input": { + "category": "[parameters('metricsToEnable')[copyIndex('diagnosticsMetrics')]]", + "timeGrain": null, + "enabled": true, + "retentionPolicy": { + "enabled": true, + "days": "[parameters('diagnosticLogsRetentionInDays')]" + } + } + }, + { + "name": "varNetworkAllowedIpRanges", + "count": "[length(parameters('networkAllowedIpRanges'))]", + "input": { + "value": "[parameters('networkAllowedIpRanges')[copyIndex('varNetworkAllowedIpRanges')]]", + "action": "Allow" + } + }, + { + "name": "varPrivateEndpoints", + "count": "[length(parameters('privateEndpoints'))]", + "input": { + "name": "[format('{0}-{1}', parameters('privateEndpoints')[copyIndex('varPrivateEndpoints')].name, parameters('name'))]", + "privateLinkServiceId": "[resourceId('Microsoft.ContainerRegistry/registries', parameters('name'))]", + "groupIds": [ + "registry" + ], + "subnetId": "[parameters('privateEndpoints')[copyIndex('varPrivateEndpoints')].subnetId]", + "privateDnsZones": "[if(contains(parameters('privateEndpoints')[copyIndex('varPrivateEndpoints')], 'privateDnsZoneId'), createArray(createObject('name', 'default', 'zoneId', parameters('privateEndpoints')[copyIndex('varPrivateEndpoints')].privateDnsZoneId)), createArray())]" + } + }, + { + "name": "varReplicationLocations", + "count": "[length(parameters('replicationLocations'))]", + "input": { + "location": "[parameters('replicationLocations')[copyIndex('varReplicationLocations')].location]", + "regionEndpointEnabled": "[if(contains(parameters('replicationLocations')[copyIndex('varReplicationLocations')], 'regionEndpointEnabled'), parameters('replicationLocations')[copyIndex('varReplicationLocations')].regionEndpointEnabled, false())]", + "zoneRedundancy": "[if(contains(parameters('replicationLocations')[copyIndex('varReplicationLocations')], 'zoneRedundancy'), parameters('replicationLocations')[copyIndex('varReplicationLocations')].zoneRedundancy, false())]" + } + } + ], + "IS_PREMIUM_SKU": "[equals(parameters('skuName'), 'Premium')]" + }, + "resources": [ + { + "type": "Microsoft.ContainerRegistry/registries", + "apiVersion": "2021-09-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "sku": { + "name": "[parameters('skuName')]" + }, + "properties": { + "adminUserEnabled": "[parameters('adminUserEnabled')]", + "publicNetworkAccess": "[if(variables('IS_PREMIUM_SKU'), if(parameters('publicNetworkAccessEnabled'), 'Enabled', 'Disabled'), null())]", + "networkRuleBypassOptions": "[if(variables('IS_PREMIUM_SKU'), if(parameters('publicAzureAccessEnabled'), 'AzureServices', 'None'), null())]", + "networkRuleSet": "[if(variables('IS_PREMIUM_SKU'), createObject('defaultAction', parameters('networkDefaultAction'), 'ipRules', variables('varNetworkAllowedIpRanges')), null())]", + "dataEndpointEnabled": "[parameters('dataEndpointEnabled')]", + "encryption": "[if(variables('IS_PREMIUM_SKU'), if(parameters('encryptionEnabled'), createObject('keyVaultProperties', createObject('identity', parameters('encryptionKeyVaultIdentity'), 'keyIdentifier', parameters('encryptionKeyVaultKeyIdentifier')), 'status', 'enabled'), null()), null())]", + "zoneRedundancy": "[if(variables('IS_PREMIUM_SKU'), if(parameters('zoneRedundancyEnabled'), 'Enabled', 'Disabled'), null())]", + "policies": { + "exportPolicy": "[if(equals(parameters('publicAzureAccessEnabled'), 'false'), createObject('status', if(parameters('exportPolicyEnabled'), 'enabled', 'disabled')), null())]", + "quarantinePolicy": { + "status": "[if(parameters('quarantinePolicyEnabled'), 'enabled', 'disabled')]" + }, + "retentionPolicy": "[if(variables('IS_PREMIUM_SKU'), if(parameters('retentionPolicyEnabled'), createObject('days', parameters('retentionPolicyInDays'), 'status', 'enabled'), null()), null())]", + "trustPolicy": "[if(variables('IS_PREMIUM_SKU'), if(parameters('trustPolicyEnabled'), createObject('status', 'enabled', 'type', 'Notary'), null()), null())]" + } + } + }, + { + "copy": { + "name": "replications", + "count": "[length(variables('varReplicationLocations'))]" + }, + "condition": "[variables('IS_PREMIUM_SKU')]", + "type": "Microsoft.ContainerRegistry/registries/replications", + "apiVersion": "2021-09-01", + "name": "[format('{0}/{1}', parameters('name'), variables('varReplicationLocations')[copyIndex()].location)]", + "location": "[variables('varReplicationLocations')[copyIndex()].location]", + "tags": "[parameters('tags')]", + "properties": { + "regionEndpointEnabled": "[variables('varReplicationLocations')[copyIndex()].regionEndpointEnabled]", + "zoneRedundancy": "[if(variables('varReplicationLocations')[copyIndex()].zoneRedundancy, 'Enabled', 'Disabled')]" + }, + "dependsOn": [ + "[resourceId('Microsoft.ContainerRegistry/registries', parameters('name'))]" + ] + }, + { + "condition": "[not(equals(parameters('lock'), 'NotSpecified'))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.ContainerRegistry/registries/{0}', parameters('name'))]", + "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "properties": { + "level": "[parameters('lock')]", + "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + }, + "dependsOn": [ + "[resourceId('Microsoft.ContainerRegistry/registries', parameters('name'))]" + ] + }, + { + "condition": "[or(or(or(not(empty(parameters('diagnosticStorageAccountId'))), not(empty(parameters('diagnosticWorkspaceId')))), not(empty(parameters('diagnosticEventHubAuthorizationRuleId')))), not(empty(parameters('diagnosticEventHubName'))))]", + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.ContainerRegistry/registries/{0}', parameters('name'))]", + "name": "[format('{0}-diagnosticSettings', parameters('name'))]", + "properties": { + "storageAccountId": "[if(not(empty(parameters('diagnosticStorageAccountId'))), parameters('diagnosticStorageAccountId'), null())]", + "workspaceId": "[if(not(empty(parameters('diagnosticWorkspaceId'))), parameters('diagnosticWorkspaceId'), null())]", + "eventHubAuthorizationRuleId": "[if(not(empty(parameters('diagnosticEventHubAuthorizationRuleId'))), parameters('diagnosticEventHubAuthorizationRuleId'), null())]", + "eventHubName": "[if(not(empty(parameters('diagnosticEventHubName'))), parameters('diagnosticEventHubName'), null())]", + "metrics": "[variables('diagnosticsMetrics')]", + "logs": "[variables('diagnosticsLogs')]" + }, + "dependsOn": [ + "[resourceId('Microsoft.ContainerRegistry/registries', parameters('name'))]" + ] + }, + { + "copy": { + "name": "containerRegistry_rbac", + "count": "[length(parameters('roleAssignments'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-acr-rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", + "principalIds": { + "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" + }, + "roleDefinitionIdOrName": { + "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" + }, + "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", + "resourceId": { + "value": "[resourceId('Microsoft.ContainerRegistry/registries', parameters('name'))]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.20.4.51522", + "templateHash": "11276824333704269750" + } + }, + "parameters": { + "description": { + "type": "string", + "defaultValue": "" + }, + "principalIds": { + "type": "array" + }, + "principalType": { + "type": "string", + "defaultValue": "" + }, + "roleDefinitionIdOrName": { + "type": "string" + }, + "resourceId": { + "type": "string" + } + }, + "variables": { + "builtInRoleNames": { + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", + "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", + "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", + "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", + "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", + "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", + "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", + "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", + "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", + "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", + "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", + "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", + "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", + "Monitoring Metrics Publisher": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')]", + "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", + "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", + "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", + "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", + "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", + "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", + "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", + "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", + "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", + "AcrDelete": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c2f4ef07-c644-48eb-af81-4b1b4947fb11')]", + "AcrImageSigner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c2f4ef07-c644-48eb-af81-4b1b4947fb11')]", + "AcrPull": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d')]", + "AcrPush": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8311e382-0749-4cb8-b61a-304f252e45ec')]", + "AcrQuarantineReader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'cdda3590-29a3-44f6-95f2-9f980659eb04')]", + "AcrQuarantineWriter": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c8d4ff99-41c3-41a8-9f60-21dfdad59608')]" + } + }, + "resources": [ + { + "copy": { + "name": "roleAssignment", + "count": "[length(parameters('principalIds'))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.ContainerRegistry/registries/{0}', last(split(parameters('resourceId'), '/')))]", + "name": "[guid(last(split(parameters('resourceId'), '/')), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", + "properties": { + "description": "[parameters('description')]", + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", + "principalId": "[parameters('principalIds')[copyIndex()]]", + "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]" + } + } + ] + } + }, + "dependsOn": [ + "[resourceId('Microsoft.ContainerRegistry/registries', parameters('name'))]" + ] + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-acr-private-endpoints', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "location": { + "value": "[parameters('location')]" + }, + "privateEndpoints": { + "value": "[variables('varPrivateEndpoints')]" + }, + "tags": { + "value": "[parameters('tags')]" + }, + "manualApprovalEnabled": { + "value": "[parameters('privateEndpointsApprovalEnabled')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.20.4.51522", + "templateHash": "1569431369010361825" + } + }, + "parameters": { + "location": { + "type": "string" + }, + "tags": { + "type": "object" + }, + "manualApprovalEnabled": { + "type": "bool" + }, + "privateEndpoints": { + "type": "array" + } + }, + "variables": { + "copy": [ + { + "name": "varPrivateEndpoints", + "count": "[length(parameters('privateEndpoints'))]", + "input": { + "name": "[parameters('privateEndpoints')[copyIndex('varPrivateEndpoints')].name]", + "privateLinkServiceId": "[parameters('privateEndpoints')[copyIndex('varPrivateEndpoints')].privateLinkServiceId]", + "groupIds": "[parameters('privateEndpoints')[copyIndex('varPrivateEndpoints')].groupIds]", + "subnetId": "[parameters('privateEndpoints')[copyIndex('varPrivateEndpoints')].subnetId]", + "privateDnsZones": "[if(contains(parameters('privateEndpoints')[copyIndex('varPrivateEndpoints')], 'privateDnsZones'), parameters('privateEndpoints')[copyIndex('varPrivateEndpoints')].privateDnsZones, createArray())]", + "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex('varPrivateEndpoints')], 'customNetworkInterfaceName'), parameters('privateEndpoints')[copyIndex('varPrivateEndpoints')].customNetworkInterfaceName, null())]" + } + } + ] + }, + "resources": [ + { + "copy": { + "name": "privateEndpoint", + "count": "[length(variables('varPrivateEndpoints'))]", + "mode": "serial", + "batchSize": 1 + }, + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2022-05-01", + "name": "[format('{0}-{1}', variables('varPrivateEndpoints')[copyIndex()].name, uniqueString(variables('varPrivateEndpoints')[copyIndex()].name, variables('varPrivateEndpoints')[copyIndex()].subnetId, variables('varPrivateEndpoints')[copyIndex()].privateLinkServiceId))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "privateLinkServiceConnections": "[if(parameters('manualApprovalEnabled'), null(), createArray(createObject('name', variables('varPrivateEndpoints')[copyIndex()].name, 'properties', createObject('privateLinkServiceId', variables('varPrivateEndpoints')[copyIndex()].privateLinkServiceId, 'groupIds', if(not(empty(variables('varPrivateEndpoints')[copyIndex()].groupIds)), variables('varPrivateEndpoints')[copyIndex()].groupIds, null())))))]", + "manualPrivateLinkServiceConnections": "[if(parameters('manualApprovalEnabled'), createArray(createObject('name', variables('varPrivateEndpoints')[copyIndex()].name, 'properties', createObject('privateLinkServiceId', variables('varPrivateEndpoints')[copyIndex()].privateLinkServiceId, 'groupIds', if(not(empty(variables('varPrivateEndpoints')[copyIndex()].groupIds)), variables('varPrivateEndpoints')[copyIndex()].groupIds, null())))), null())]", + "subnet": { + "id": "[variables('varPrivateEndpoints')[copyIndex()].subnetId]" + }, + "customNetworkInterfaceName": "[variables('varPrivateEndpoints')[copyIndex()].customNetworkInterfaceName]" + } + }, + { + "copy": { + "name": "privateDnsZoneGroup", + "count": "[length(variables('varPrivateEndpoints'))]", + "mode": "serial", + "batchSize": 1 + }, + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2022-05-01", + "name": "[format('{0}/{1}', format('{0}-{1}', variables('varPrivateEndpoints')[copyIndex()].name, uniqueString(variables('varPrivateEndpoints')[copyIndex()].name, variables('varPrivateEndpoints')[copyIndex()].subnetId, variables('varPrivateEndpoints')[copyIndex()].privateLinkServiceId)), 'default')]", + "properties": { + "copy": [ + { + "name": "privateDnsZoneConfigs", + "count": "[length(variables('varPrivateEndpoints')[copyIndex()].privateDnsZones)]", + "input": { + "name": "[if(contains(variables('varPrivateEndpoints')[copyIndex()].privateDnsZones[copyIndex('privateDnsZoneConfigs')], 'name'), variables('varPrivateEndpoints')[copyIndex()].privateDnsZones[copyIndex('privateDnsZoneConfigs')].name, 'default')]", + "properties": { + "privateDnsZoneId": "[variables('varPrivateEndpoints')[copyIndex()].privateDnsZones[copyIndex('privateDnsZoneConfigs')].zoneId]" + } + } + } + ] + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/privateEndpoints', format('{0}-{1}', variables('varPrivateEndpoints')[copyIndex()].name, uniqueString(variables('varPrivateEndpoints')[copyIndex()].name, variables('varPrivateEndpoints')[copyIndex()].subnetId, variables('varPrivateEndpoints')[copyIndex()].privateLinkServiceId)))]" + ] + } + ] + } + }, + "dependsOn": [ + "[resourceId('Microsoft.ContainerRegistry/registries', parameters('name'))]" + ] + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-acr-task', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "acrName": { + "value": "[parameters('name')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "tasks": { + "value": "[parameters('tasks')]" + }, + "loginServer": { + "value": "[reference(resourceId('Microsoft.ContainerRegistry/registries', parameters('name')), '2021-09-01').loginServer]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.20.4.51522", + "templateHash": "15495887558517410579" + } + }, + "parameters": { + "acrName": { + "type": "string" + }, + "location": { + "type": "string" + }, + "loginServer": { + "type": "string" + }, + "tasks": { + "type": "array", + "defaultValue": [] + } + }, + "resources": [ + { + "copy": { + "name": "task", + "count": "[length(parameters('tasks'))]" + }, + "type": "Microsoft.ContainerRegistry/registries/tasks", + "apiVersion": "2019-06-01-preview", + "name": "[format('{0}/{1}', parameters('acrName'), parameters('tasks')[copyIndex()].taskName)]", + "location": "[parameters('location')]", + "identity": "[parameters('tasks')[copyIndex()].identity]", + "properties": { + "status": "[parameters('tasks')[copyIndex()].status]", + "platform": "[parameters('tasks')[copyIndex()].platform]", + "agentConfiguration": "[parameters('tasks')[copyIndex()].agentConfiguration]", + "trigger": "[parameters('tasks')[copyIndex()].trigger]", + "step": "[parameters('tasks')[copyIndex()].step]", + "credentials": { + "customRegistries": { + "[format('{0}', parameters('loginServer'))]": "[if(equals(parameters('tasks')[copyIndex()].identity.type, 'SystemAssigned'), createObject('identity', '[system]'), createObject())]" + } + } + } + }, + { + "copy": { + "name": "containerRegistry_rbac", + "count": "[length(parameters('tasks'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-acr-task-rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "description": { + "value": "[format('role assignment for task {0}', parameters('tasks')[copyIndex()].taskName)]" + }, + "roleDefinitionIdOrName": { + "value": "Contributor" + }, + "principalIds": { + "value": [ + "[reference(resourceId('Microsoft.ContainerRegistry/registries/tasks', parameters('acrName'), parameters('tasks')[copyIndex()].taskName), '2019-06-01-preview', 'full').identity.principalId]" + ] + }, + "principalType": { + "value": "ServicePrincipal" + }, + "resourceId": { + "value": "[resourceId('Microsoft.ContainerRegistry/registries', parameters('acrName'))]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.20.4.51522", + "templateHash": "11276824333704269750" + } + }, + "parameters": { + "description": { + "type": "string", + "defaultValue": "" + }, + "principalIds": { + "type": "array" + }, + "principalType": { + "type": "string", + "defaultValue": "" + }, + "roleDefinitionIdOrName": { + "type": "string" + }, + "resourceId": { + "type": "string" + } + }, + "variables": { + "builtInRoleNames": { + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", + "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", + "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", + "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", + "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", + "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", + "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", + "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", + "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", + "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", + "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", + "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", + "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", + "Monitoring Metrics Publisher": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')]", + "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", + "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", + "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", + "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", + "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", + "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", + "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", + "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", + "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", + "AcrDelete": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c2f4ef07-c644-48eb-af81-4b1b4947fb11')]", + "AcrImageSigner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c2f4ef07-c644-48eb-af81-4b1b4947fb11')]", + "AcrPull": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d')]", + "AcrPush": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8311e382-0749-4cb8-b61a-304f252e45ec')]", + "AcrQuarantineReader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'cdda3590-29a3-44f6-95f2-9f980659eb04')]", + "AcrQuarantineWriter": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c8d4ff99-41c3-41a8-9f60-21dfdad59608')]" + } + }, + "resources": [ + { + "copy": { + "name": "roleAssignment", + "count": "[length(parameters('principalIds'))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.ContainerRegistry/registries/{0}', last(split(parameters('resourceId'), '/')))]", + "name": "[guid(last(split(parameters('resourceId'), '/')), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", + "properties": { + "description": "[parameters('description')]", + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", + "principalId": "[parameters('principalIds')[copyIndex()]]", + "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]" + } + } + ] + } + }, + "dependsOn": [ + "[resourceId('Microsoft.ContainerRegistry/registries/tasks', parameters('acrName'), parameters('tasks')[copyIndex()].taskName)]" + ] + } + ], + "outputs": { + "tasksRoleAssignments": { + "type": "array", + "copy": { + "count": "[length(parameters('tasks'))]", + "input": { + "description": "[format('role assignment for task {0}', parameters('tasks')[copyIndex()].taskName)]", + "roleDefinitionIdOrName": "Contributor", + "principalType": "ServicePrincipal", + "principalIds": "[reference(resourceId('Microsoft.ContainerRegistry/registries/tasks', parameters('acrName'), parameters('tasks')[copyIndex()].taskName), '2019-06-01-preview', 'full').identity.principalId]" + } + } + } + } + } + }, + "dependsOn": [ + "[resourceId('Microsoft.ContainerRegistry/registries', parameters('name'))]" + ] + } + ], + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the Azure Container Registry was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the Azure Container Registry." + }, + "value": "[resourceId('Microsoft.ContainerRegistry/registries', parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the Azure Container Registry." + }, + "value": "[parameters('name')]" + }, + "loginServer": { + "type": "string", + "metadata": { + "description": "The login server URL of the Azure Container Registry." + }, + "value": "[reference(resourceId('Microsoft.ContainerRegistry/registries', parameters('name')), '2021-09-01').loginServer]" + } + } +} \ No newline at end of file diff --git a/modules/compute/container-registry/task/task.bicep b/modules/compute/container-registry/task/task.bicep new file mode 100644 index 0000000000..9619762292 --- /dev/null +++ b/modules/compute/container-registry/task/task.bicep @@ -0,0 +1,49 @@ +param acrName string +param location string +param loginServer string +param tasks array = [] + +resource containerRegistry 'Microsoft.ContainerRegistry/registries@2023-01-01-preview' existing = { + name: acrName +} + +resource task 'Microsoft.ContainerRegistry/registries/tasks@2019-06-01-preview' = [for task in tasks: { + name: task.taskName + location: location + parent: containerRegistry + identity: task.identity + properties: { + status: task.status + platform: task.platform + agentConfiguration: task.agentConfiguration + trigger: task.trigger + step: task.step + credentials: { + customRegistries: { + '${loginServer}': task.identity.type == 'SystemAssigned' ? { + identity: '[system]' + } : {} + } + } + } +}] + +module containerRegistry_rbac '../.bicep/nested_rbac.bicep' = [for (t, index) in tasks: { + name: '${uniqueString(deployment().name, location)}-acr-task-rbac-${index}' + params: { + description: 'role assignment for task ${t.taskName}' + roleDefinitionIdOrName: 'Contributor' + principalIds: [ + task[index].identity.principalId + ] + principalType: 'ServicePrincipal' + resourceId: containerRegistry.id + } +}] + +output tasksRoleAssignments array = [for (t, index) in tasks: { + description: 'role assignment for task ${t.taskName}' + roleDefinitionIdOrName: 'Contributor' + principalType: 'ServicePrincipal' + principalIds: task[index].identity.principalId +}] diff --git a/modules/compute/container-registry/test/dependencies.test.bicep b/modules/compute/container-registry/test/dependencies.test.bicep new file mode 100644 index 0000000000..ce03711a12 --- /dev/null +++ b/modules/compute/container-registry/test/dependencies.test.bicep @@ -0,0 +1,114 @@ +param location string +param name string +param prefix string + +resource storageAccount 'Microsoft.Storage/storageAccounts@2022-05-01' = { + name: '${prefix}${name}01' + kind: 'StorageV2' + sku: { + name: 'Standard_LRS' + } + location: location + properties: { + allowBlobPublicAccess: false + } +} + +resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' = { + name: '${prefix}-law-${name}-01' + location: location +} + +resource eventHubNamespace 'Microsoft.EventHub/namespaces@2021-11-01' = { + name: '${prefix}-evhns-${name}-01' + location: location +} + +resource eventHub 'Microsoft.EventHub/namespaces/eventhubs@2021-11-01' = { + name: '${prefix}-evh-${name}-01' + parent: eventHubNamespace +} + +resource authorizationRule 'Microsoft.EventHub/namespaces/authorizationRules@2022-01-01-preview' = { + name: 'RootManageSharedAccessKey' + properties: { + rights: [ + 'Listen' + 'Manage' + 'Send' + ] + } + parent: eventHubNamespace +} + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2022-05-01' = { + name: '${prefix}-${name}-vnet' + location: location + properties: { + addressSpace: { + addressPrefixes: [ + '10.0.0.0/16' + ] + } + subnets: [ + { + name: '${name}-subnet-0' + properties: { + addressPrefix: '10.0.0.0/24' + privateEndpointNetworkPolicies: 'Disabled' + } + } + { + name: '${name}-subnet-1' + properties: { + addressPrefix: '10.0.1.0/24' + privateEndpointNetworkPolicies: 'Disabled' + } + } + ] + } +} + +resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { + name: 'privatelink.azurecr.io' + location: 'global' + properties: {} +} + +resource virtualNetworkLinks 'Microsoft.Network/privateDnsZones/virtualNetworkLinks@2020-06-01' = { + parent: privateDNSZone + name: '${prefix}-${name}-vnet-link' + location: 'global' + properties: { + registrationEnabled: false + virtualNetwork: { + id: virtualNetwork.id + } + } +} + +resource managedIdentity_01 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: '${prefix}-${name}-01' + location: location +} + +resource managedIdentity_02 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: '${prefix}-${name}-02' + location: location +} + +output storageAccountId string = storageAccount.id +output workspaceId string = logAnalyticsWorkspace.id +output vnetId string = virtualNetwork.id +output subnetIds array = [ + virtualNetwork.properties.subnets[0].id + virtualNetwork.properties.subnets[1].id +] +output privateDNSZoneId string = privateDNSZone.id +output eventHubNamespaceId string = eventHubNamespace.id +output eventHubName string = eventHub.name +output authorizationRuleId string = authorizationRule.id +output identityPrincipalIds array = [ + managedIdentity_01.properties.principalId + managedIdentity_02.properties.principalId +] diff --git a/modules/compute/container-registry/test/main.test.bicep b/modules/compute/container-registry/test/main.test.bicep new file mode 100644 index 0000000000..636822edca --- /dev/null +++ b/modules/compute/container-registry/test/main.test.bicep @@ -0,0 +1,179 @@ +targetScope = 'resourceGroup' + +// ========== // +// Parameters // +// ========== // + +param location string = 'westus2' +param serviceShort string = 'acr' +var uniqueName = uniqueString(resourceGroup().id, deployment().name, location) + +// ============ // +// Dependencies // +// ============ // + +module dependencies 'dependencies.test.bicep' = { + name: 'test-dependencies' + params: { + name: serviceShort + location: location + prefix: uniqueName + } +} + +// ===== // +// Tests // +// ===== // + +// Test 01 - Basic SKU - Minimal Parameters +module test_01 '../main.bicep' = { + name: '${uniqueName}-test-01' + params: { + name: 'test01${uniqueName}' + location: location + } +} + +// Test 02 - Standard SKU - Parameters, RBAC and Diagnostic Settings +module test_02 '../main.bicep' = { + name: '${uniqueName}-test-02' + params: { + name: 'test02${uniqueName}' + location: location + skuName: 'Standard' + adminUserEnabled: true + tags: { + tag1: 'tag1value' + tag2: 'tag2value' + } + diagnosticStorageAccountId: dependencies.outputs.storageAccountId + diagnosticWorkspaceId: dependencies.outputs.workspaceId + roleAssignments: [ + { + roleDefinitionIdOrName: 'AcrPull' + principalIds: [ dependencies.outputs.identityPrincipalIds[0] ] + } + ] + tasks: [ { + taskName: 'task1' + status: 'Enabled' + platform: { + os: 'Linux' + architecture: 'Amd64' + } + agentConfiguration: { + cpu: 2 + } + trigger: { + timerTriggers: [ + { + name: 'trigger1' + status: 'Enabled' + schedule: '*/1 * * * Mon-Fri' + } + ] + } + step: { + type: 'EncodedTask' + encodedTaskContent: loadFileAsBase64('task.yaml') + } + identity: { + type: 'SystemAssigned' + } + } + ] + } +} + +// Test 03 - Standard SKU - Parameters, RBAC and Diagnostic Settings +module test_03 '../main.bicep' = { + name: '${uniqueName}-test-03' + params: { + name: 'test03${uniqueName}' + location: location + skuName: 'Standard' + adminUserEnabled: false + diagnosticEventHubAuthorizationRuleId: dependencies.outputs.authorizationRuleId + diagnosticEventHubName: dependencies.outputs.eventHubName + roleAssignments: [ + { + roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d') // AcrPull + principalIds: [ dependencies.outputs.identityPrincipalIds[1] ] + } + ] + } +} + +// Test 04 - Premium Test - Network Rules & Zone Redundancy +module test_04 '../main.bicep' = { + name: '${uniqueName}-test-04' + params: { + name: 'test04${uniqueName}' + location: location + skuName: 'Premium' + publicAzureAccessEnabled: false + networkAllowedIpRanges: [ + '20.112.52.29' + '20.53.204.50' + ] + zoneRedundancyEnabled: true + } +} + +// Test 05 - Premium Test - Private Endpoint +module test_05 '../main.bicep' = { + name: '${uniqueName}-test-05' + params: { + name: 'test05${uniqueName}' + location: location + skuName: 'Premium' + publicNetworkAccessEnabled: false + privateEndpoints: [ + { + name: 'endpoint1' + subnetId: dependencies.outputs.subnetIds[0] + } + { + name: 'endpoint2' + subnetId: dependencies.outputs.subnetIds[1] + privateDnsZoneId: dependencies.outputs.privateDNSZoneId + } + ] + } +} + +// Test 06 - Premium Test - Private Endpoint +module test_06 '../main.bicep' = { + name: '${uniqueName}-test-06' + params: { + name: 'test06${uniqueName}' + location: location + skuName: 'Premium' + publicNetworkAccessEnabled: false + exportPolicyEnabled: true + quarantinePolicyEnabled: true + retentionPolicyEnabled: true + retentionPolicyInDays: 5 + trustPolicyEnabled: true + } +} + +// Test 07 - Premium Test - Replication +module test_07 '../main.bicep' = { + name: '${uniqueName}-test-07' + params: { + name: 'test07${uniqueName}' + location: location + skuName: 'Premium' + replicationLocations: [ + { + location: 'eastus2' + } + { + location: 'northeurope' + regionEndpointEnabled: true + zoneRedundancy: true + } + ] + } +} diff --git a/modules/compute/container-registry/test/task.yaml b/modules/compute/container-registry/test/task.yaml new file mode 100644 index 0000000000..745b33f770 --- /dev/null +++ b/modules/compute/container-registry/test/task.yaml @@ -0,0 +1,5 @@ +version: v1.1.0 +steps: + - cmd: acr purge --filter 'hello:.*' --untagged --ago 1d + disableWorkingDirectoryOverride: true + timeout: 3600 \ No newline at end of file diff --git a/modules/compute/container-registry/version.json b/modules/compute/container-registry/version.json new file mode 100644 index 0000000000..455678cf6f --- /dev/null +++ b/modules/compute/container-registry/version.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "1.1", + "pathFilters": [ + "./main.json", + "./metadata.json" + ] +} \ No newline at end of file diff --git a/modules/compute/custom-image-vmss/README.md b/modules/compute/custom-image-vmss/README.md new file mode 100644 index 0000000000..9755513c6b --- /dev/null +++ b/modules/compute/custom-image-vmss/README.md @@ -0,0 +1,92 @@ +# Azure VMSS with Custom Image + +Create an Azure VMSS Cluster with a Custom Image to simplify creation of Marketplace Applications + +## Details + +The Azure Marketplace makes it easy to [create and publish](https://learn.microsoft.com/en-us/azure/marketplace/azure-vm-use-own-image) custom Virtual Machine images. +Customers can then use the custom image to create a Virtual Machine or [Scale Set](https://learn.microsoft.com/en-us/azure/virtual-machine-scale-sets/overview). But, if custom configurations are required, the user must provide the proper custom data input. Creating a [Marketplace Application](https://learn.microsoft.com/en-us/azure/marketplace/azure-app-offer-setup) enables publishers to customize the [creation experince](https://learn.microsoft.com/en-us/azure/azure-resource-manager/managed-applications/create-uidefinition-overview) in the portal. +This Bicep Module can be used to easily wrap a Marketplace or Community image for use on Azure VMSS. + +## Parameters + +| Name | Type | Required | Description | +| :--------------------------- | :------------: | :------: | :----------------------------------------------------------------------------------------------------------------------- | +| `location` | `string` | No | Deployment Location | +| `vmssName` | `string` | Yes | Name of VMSS Cluster | +| `vmssSku` | `string` | No | GameDev Sku | +| `vmssImgPublisher` | `string` | No | Image Publisher | +| `vmssImgProduct` | `string` | No | Image Product Id | +| `vmssImgSku` | `string` | No | Image Sku | +| `vmssImgVersion` | `string` | No | GameDev Image Product Id | +| `vmssOsDiskType` | `string` | No | GameDev Disk Type | +| `vmssInstanceCount` | `int` | No | VMSS Instance Count | +| `administratorLogin` | `string` | Yes | Administrator Login for access | +| `passwordAdministratorLogin` | `securestring` | Yes | Administrator Password for access | +| `vnetName` | `string` | No | Virtual Network Resource Name | +| `subnetName` | `string` | No | Virtual Network Subnet Name | +| `networkSecurityGroupName` | `string` | No | Virtual Network Security Group Name | +| `vnetAddressPrefix` | `string` | No | Virtual Network Address Prefix | +| `subnetAddressPrefix` | `string` | No | Virtual Network Subnet Address Prefix | +| `imageLocation` | `string` | No | Parameter used for debugging with trail offer | +| `communityGalleryImageId` | `string` | No | Pointer to community gallery image. Example: /CommunityGalleries//Images//Versions/ | +| `customData` | `string` | No | Base64 Encoded string to provide to VMSS for configuration | + +## Outputs + +| Name | Type | Description | +| :----- | :------: | :----------------------------------------- | +| `id` | `string` | Resource Id of Virtual Machine Scale Set | +| `name` | `string` | Resource Name of Virtual Machine Scale Set | + +## Examples + +### Example 1 + +The custom data can be loaded from a file. + +```bicep +var communityGalleryImageId = '/CommunityGalleries/${sharedGalleryID}/Images/${definitionId}/Versions/${imageVer}' + +var customData = loadFileAsBase64('imageConfig.json') + +module Example1 'br/public:compute/custom-image-vmss:1.0.2' = { + name: 'Example1' + params: { + location: location + administratorLogin: uniqueString(resourceGroup().name) + passwordAdministratorLogin: guid(resourceGroup().name) + vmssName: uniqueString(resourceGroup().name) + communityGalleryImageId: communityGalleryImageId + customData: customData + } +} + +``` + +### Example 2 + +The custom data may also be created directly in Bicep, so that the settings may be provided at deployment time. + +```bicep +param developer_mode bool = true + +var communityGalleryImageId = '/CommunityGalleries/${sharedGalleryId}/Images/${definitionId}/Versions/${imageVer}' + +var customData = { + developer_mode: developer_mode +} + +module Example2 'br/public:compute/custom-image-vmss:1.0.2' = { + name: 'Example2' + params: { + location: location + administratorLogin: uniqueString(resourceGroup().name) + passwordAdministratorLogin: guid(resourceGroup().name) + vmssName: uniqueString(resourceGroup().name) + communityGalleryImageId: communityGalleryImageId + customData: base64(string(customData)) + } +} + +``` \ No newline at end of file diff --git a/modules/compute/custom-image-vmss/main.bicep b/modules/compute/custom-image-vmss/main.bicep new file mode 100644 index 0000000000..e0502e4721 --- /dev/null +++ b/modules/compute/custom-image-vmss/main.bicep @@ -0,0 +1,165 @@ +metadata name = 'Azure VMSS with Custom Image' +metadata description = 'Create an Azure VMSS Cluster with a Custom Image to simplify creation of Marketplace Applications' +metadata owner = 'dciborow' + +@description('Deployment Location') +param location string = resourceGroup().location + +@description('Name of VMSS Cluster') +param vmssName string + +@description('GameDev Sku') +param vmssSku string = 'Standard_D4ds_v4' + +@description('Image Publisher') +param vmssImgPublisher string = '' + +@description('Image Product Id') +param vmssImgProduct string = '' + +@description('Image Sku') +param vmssImgSku string = '' + +@description('GameDev Image Product Id') +param vmssImgVersion string = 'latest' + +@description('GameDev Disk Type') +param vmssOsDiskType string = 'Premium_LRS' + +@description('VMSS Instance Count') +@maxValue(100) +@minValue(1) +param vmssInstanceCount int = 1 + +@description('Administrator Login for access') +param administratorLogin string + +@description('Administrator Password for access') +@secure() +param passwordAdministratorLogin string + +@description('Virtual Network Resource Name') +param vnetName string = 'vnet-${vmssName}' + +@description('Virtual Network Subnet Name') +param subnetName string = 'subnet${vmssName}' + +@description('Virtual Network Security Group Name') +param networkSecurityGroupName string = 'nsg-${vmssName}' + +@description('Virtual Network Address Prefix') +param vnetAddressPrefix string = '172.17.72.0/24' //Change as needed + +@description('Virtual Network Subnet Address Prefix') +param subnetAddressPrefix string = '172.17.72.0/25' // 172.17.72.[0-128] is part of this subnet + +@allowed([ + 'gallery' + 'marketplace' +]) +@description('Parameter used for debugging with trail offer') +param imageLocation string = 'marketplace' + +@description('Pointer to community gallery image. Example: /CommunityGalleries//Images//Versions/') +param communityGalleryImageId string = '' + +@description('Base64 Encoded string to provide to VMSS for configuration') +param customData string = '' + +var locations = { + gallery: { + plan: null + imageReference: { communityGalleryImageId: communityGalleryImageId } + } + marketplace: { + plan: { + name: vmssImgSku + publisher: vmssImgPublisher + product: vmssImgProduct + } + imageReference: { + publisher: vmssImgPublisher + offer: vmssImgProduct + sku: vmssImgSku + version: vmssImgVersion + } + } +} + +module vnet 'modules/virtualNetworks.bicep' = { + name: '${vnetName}-${uniqueString(resourceGroup().name, location)}' + params: { + location: location + vnetName: vnetName + subnetName: subnetName + networkSecurityGroupName: networkSecurityGroupName + vnetAddressPrefix: vnetAddressPrefix + subnetAddressPrefix: subnetAddressPrefix + } +} + +resource vmss 'Microsoft.Compute/virtualMachineScaleSets@2022-03-01' = { + name: '${vmssName}-${uniqueString(resourceGroup().name, location)}' + location: location + sku: { + name: vmssSku + tier: 'Standard' + capacity: vmssInstanceCount + } + plan: locations[imageLocation].plan + properties: { + singlePlacementGroup: false + upgradePolicy: { + mode: 'Manual' + } + virtualMachineProfile: { + storageProfile: { + osDisk: { + createOption: 'FromImage' + caching: 'ReadWrite' + managedDisk: { + storageAccountType: vmssOsDiskType + } + } + imageReference: locations[imageLocation].imageReference + } + networkProfile: { + networkInterfaceConfigurations: [ + { + name: '${vmssName}Nic' + properties: { + primary: true + ipConfigurations: [ + { + name: '${vmssName}IpConfig' + properties: { + subnet: { + id: resourceId('Microsoft.Network/virtualNetworks/subnets', vnetName, subnetName) + } + } + } + ] + networkSecurityGroup: { + id: vnet.outputs.nsgID + } + } + } + ] + } + osProfile: { + computerNamePrefix: vmssName + adminUsername: administratorLogin + adminPassword: passwordAdministratorLogin + customData: customData + } + priority: 'Regular' + } + overprovision: false + } +} + +@description('Resource Id of Virtual Machine Scale Set') +output id string = vmss.id + +@description('Resource Name of Virtual Machine Scale Set') +output name string = vmss.name diff --git a/modules/compute/custom-image-vmss/main.json b/modules/compute/custom-image-vmss/main.json new file mode 100644 index 0000000000..06fde7c959 --- /dev/null +++ b/modules/compute/custom-image-vmss/main.json @@ -0,0 +1,1102 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.19.5.34762", + "templateHash": "1275515054012573586" + }, + "name": "Azure VMSS with Custom Image", + "description": "Create an Azure VMSS Cluster with a Custom Image to simplify creation of Marketplace Applications", + "owner": "dciborow" + }, + "parameters": { + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Deployment Location" + } + }, + "vmssName": { + "type": "string", + "metadata": { + "description": "Name of VMSS Cluster" + } + }, + "vmssSku": { + "type": "string", + "defaultValue": "Standard_D4ds_v4", + "metadata": { + "description": "GameDev Sku" + } + }, + "vmssImgPublisher": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Image Publisher" + } + }, + "vmssImgProduct": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Image Product Id" + } + }, + "vmssImgSku": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Image Sku" + } + }, + "vmssImgVersion": { + "type": "string", + "defaultValue": "latest", + "metadata": { + "description": "GameDev Image Product Id" + } + }, + "vmssOsDiskType": { + "type": "string", + "defaultValue": "Premium_LRS", + "metadata": { + "description": "GameDev Disk Type" + } + }, + "vmssInstanceCount": { + "type": "int", + "defaultValue": 1, + "minValue": 1, + "maxValue": 100, + "metadata": { + "description": "VMSS Instance Count" + } + }, + "administratorLogin": { + "type": "string", + "metadata": { + "description": "Administrator Login for access" + } + }, + "passwordAdministratorLogin": { + "type": "securestring", + "metadata": { + "description": "Administrator Password for access" + } + }, + "vnetName": { + "type": "string", + "defaultValue": "[format('vnet-{0}', parameters('vmssName'))]", + "metadata": { + "description": "Virtual Network Resource Name" + } + }, + "subnetName": { + "type": "string", + "defaultValue": "[format('subnet{0}', parameters('vmssName'))]", + "metadata": { + "description": "Virtual Network Subnet Name" + } + }, + "networkSecurityGroupName": { + "type": "string", + "defaultValue": "[format('nsg-{0}', parameters('vmssName'))]", + "metadata": { + "description": "Virtual Network Security Group Name" + } + }, + "vnetAddressPrefix": { + "type": "string", + "defaultValue": "172.17.72.0/24", + "metadata": { + "description": "Virtual Network Address Prefix" + } + }, + "subnetAddressPrefix": { + "type": "string", + "defaultValue": "172.17.72.0/25", + "metadata": { + "description": "Virtual Network Subnet Address Prefix" + } + }, + "imageLocation": { + "type": "string", + "defaultValue": "marketplace", + "metadata": { + "description": "Parameter used for debugging with trail offer" + }, + "allowedValues": [ + "gallery", + "marketplace" + ] + }, + "communityGalleryImageId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Pointer to community gallery image. Example: /CommunityGalleries//Images//Versions/" + } + }, + "customData": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Base64 Encoded string to provide to VMSS for configuration" + } + } + }, + "variables": { + "locations": { + "gallery": { + "plan": null, + "imageReference": { + "communityGalleryImageId": "[parameters('communityGalleryImageId')]" + } + }, + "marketplace": { + "plan": { + "name": "[parameters('vmssImgSku')]", + "publisher": "[parameters('vmssImgPublisher')]", + "product": "[parameters('vmssImgProduct')]" + }, + "imageReference": { + "publisher": "[parameters('vmssImgPublisher')]", + "offer": "[parameters('vmssImgProduct')]", + "sku": "[parameters('vmssImgSku')]", + "version": "[parameters('vmssImgVersion')]" + } + } + } + }, + "resources": [ + { + "type": "Microsoft.Compute/virtualMachineScaleSets", + "apiVersion": "2022-03-01", + "name": "[format('{0}-{1}', parameters('vmssName'), uniqueString(resourceGroup().name, parameters('location')))]", + "location": "[parameters('location')]", + "sku": { + "name": "[parameters('vmssSku')]", + "tier": "Standard", + "capacity": "[parameters('vmssInstanceCount')]" + }, + "plan": "[variables('locations')[parameters('imageLocation')].plan]", + "properties": { + "singlePlacementGroup": false, + "upgradePolicy": { + "mode": "Manual" + }, + "virtualMachineProfile": { + "storageProfile": { + "osDisk": { + "createOption": "FromImage", + "caching": "ReadWrite", + "managedDisk": { + "storageAccountType": "[parameters('vmssOsDiskType')]" + } + }, + "imageReference": "[variables('locations')[parameters('imageLocation')].imageReference]" + }, + "networkProfile": { + "networkInterfaceConfigurations": [ + { + "name": "[format('{0}Nic', parameters('vmssName'))]", + "properties": { + "primary": true, + "ipConfigurations": [ + { + "name": "[format('{0}IpConfig', parameters('vmssName'))]", + "properties": { + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('subnetName'))]" + } + } + } + ], + "networkSecurityGroup": { + "id": "[reference(resourceId('Microsoft.Resources/deployments', format('{0}-{1}', parameters('vnetName'), uniqueString(resourceGroup().name, parameters('location')))), '2022-09-01').outputs.nsgID.value]" + } + } + } + ] + }, + "osProfile": { + "computerNamePrefix": "[parameters('vmssName')]", + "adminUsername": "[parameters('administratorLogin')]", + "adminPassword": "[parameters('passwordAdministratorLogin')]", + "customData": "[parameters('customData')]" + }, + "priority": "Regular" + }, + "overprovision": false + }, + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', format('{0}-{1}', parameters('vnetName'), uniqueString(resourceGroup().name, parameters('location'))))]" + ] + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-{1}', parameters('vnetName'), uniqueString(resourceGroup().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "location": { + "value": "[parameters('location')]" + }, + "vnetName": { + "value": "[parameters('vnetName')]" + }, + "subnetName": { + "value": "[parameters('subnetName')]" + }, + "networkSecurityGroupName": { + "value": "[parameters('networkSecurityGroupName')]" + }, + "vnetAddressPrefix": { + "value": "[parameters('vnetAddressPrefix')]" + }, + "subnetAddressPrefix": { + "value": "[parameters('subnetAddressPrefix')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.19.5.34762", + "templateHash": "10388055362477215042" + } + }, + "parameters": { + "location": { + "type": "string" + }, + "vnetAddressPrefix": { + "type": "string" + }, + "subnetAddressPrefix": { + "type": "string" + }, + "vnetName": { + "type": "string" + }, + "subnetName": { + "type": "string" + }, + "networkSecurityGroupName": { + "type": "string" + } + }, + "resources": [ + { + "type": "Microsoft.Network/networkSecurityGroups", + "apiVersion": "2021-08-01", + "name": "[parameters('networkSecurityGroupName')]", + "location": "[parameters('location')]" + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-minvnet', uniqueString(deployment().name, 'WestEurope'))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "location": { + "value": "[parameters('location')]" + }, + "name": { + "value": "[parameters('vnetName')]" + }, + "subnets": { + "value": [ + { + "name": "[parameters('subnetName')]", + "addressPrefix": "[parameters('subnetAddressPrefix')]", + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('networkSecurityGroupName'))]" + } + } + ] + }, + "addressPrefixes": { + "value": [ + "[parameters('vnetAddressPrefix')]" + ] + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.9.1.41621", + "templateHash": "10893164274897986397" + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The Virtual Network (vNet) Name." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "addressPrefixes": { + "type": "array", + "metadata": { + "description": "Required. An Array of 1 or more IP Address Prefixes for the Virtual Network." + } + }, + "subnets": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. An Array of subnets to deploy to the Virtual Network." + } + }, + "dnsServers": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. DNS Servers associated to the Virtual Network." + } + }, + "ddosProtectionPlanId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of the DDoS protection plan to assign the VNET to. If it's left blank, DDoS protection will not be configured. If it's provided, the VNET created by this template will be attached to the referenced DDoS protection plan. The DDoS protection plan can exist in the same or in a different subscription." + } + }, + "virtualNetworkPeerings": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Virtual Network Peerings configurations" + } + }, + "diagnosticLogsRetentionInDays": { + "type": "int", + "defaultValue": 365, + "maxValue": 365, + "minValue": 0, + "metadata": { + "description": "Optional. Specifies the number of days that logs will be kept for; a value of 0 will retain data indefinitely." + } + }, + "diagnosticStorageAccountId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of the diagnostic storage account." + } + }, + "diagnosticWorkspaceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of the diagnostic log analytics workspace." + } + }, + "diagnosticEventHubAuthorizationRuleId": { + "type": "string", + "defaultValue": "", + "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." + } + }, + "diagnosticEventHubName": { + "type": "string", + "defaultValue": "", + "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." + } + }, + "lock": { + "type": "string", + "defaultValue": "NotSpecified", + "metadata": { + "description": "Optional. Specify the type of lock." + }, + "allowedValues": [ + "CanNotDelete", + "NotSpecified", + "ReadOnly" + ] + }, + "roleAssignments": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'" + } + }, + "tags": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "logsToEnable": { + "type": "array", + "defaultValue": [ + "VMProtectionAlerts" + ], + "allowedValues": [ + "VMProtectionAlerts" + ], + "metadata": { + "description": "Optional. The name of logs that will be streamed." + } + }, + "metricsToEnable": { + "type": "array", + "defaultValue": [ + "AllMetrics" + ], + "allowedValues": [ + "AllMetrics" + ], + "metadata": { + "description": "Optional. The name of metrics that will be streamed." + } + } + }, + "variables": { + "copy": [ + { + "name": "diagnosticsLogs", + "count": "[length(parameters('logsToEnable'))]", + "input": { + "category": "[parameters('logsToEnable')[copyIndex('diagnosticsLogs')]]", + "enabled": true, + "retentionPolicy": { + "enabled": true, + "days": "[parameters('diagnosticLogsRetentionInDays')]" + } + } + }, + { + "name": "diagnosticsMetrics", + "count": "[length(parameters('metricsToEnable'))]", + "input": { + "category": "[parameters('metricsToEnable')[copyIndex('diagnosticsMetrics')]]", + "timeGrain": null, + "enabled": true, + "retentionPolicy": { + "enabled": true, + "days": "[parameters('diagnosticLogsRetentionInDays')]" + } + } + } + ], + "dnsServers_var": { + "dnsServers": "[array(parameters('dnsServers'))]" + }, + "ddosProtectionPlan": { + "id": "[parameters('ddosProtectionPlanId')]" + } + }, + "resources": [ + { + "type": "Microsoft.Network/virtualNetworks", + "apiVersion": "2021-05-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "copy": [ + { + "name": "subnets", + "count": "[length(parameters('subnets'))]", + "input": { + "name": "[parameters('subnets')[copyIndex('subnets')].name]", + "properties": { + "addressPrefix": "[parameters('subnets')[copyIndex('subnets')].addressPrefix]", + "addressPrefixes": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'addressPrefixes'), parameters('subnets')[copyIndex('subnets')].addressPrefixes, createArray())]", + "applicationGatewayIpConfigurations": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'applicationGatewayIpConfigurations'), parameters('subnets')[copyIndex('subnets')].applicationGatewayIpConfigurations, createArray())]", + "delegations": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'delegations'), parameters('subnets')[copyIndex('subnets')].delegations, createArray())]", + "ipAllocations": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'ipAllocations'), parameters('subnets')[copyIndex('subnets')].ipAllocations, createArray())]", + "natGateway": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'natGatewayId'), createObject('id', parameters('subnets')[copyIndex('subnets')].natGatewayId), json('null'))]", + "networkSecurityGroup": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'networkSecurityGroupId'), createObject('id', parameters('subnets')[copyIndex('subnets')].networkSecurityGroupId), json('null'))]", + "privateEndpointNetworkPolicies": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'privateEndpointNetworkPolicies'), parameters('subnets')[copyIndex('subnets')].privateEndpointNetworkPolicies, null())]", + "privateLinkServiceNetworkPolicies": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'privateLinkServiceNetworkPolicies'), parameters('subnets')[copyIndex('subnets')].privateLinkServiceNetworkPolicies, null())]", + "routeTable": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'routeTableId'), createObject('id', parameters('subnets')[copyIndex('subnets')].routeTableId), json('null'))]", + "serviceEndpoints": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'serviceEndpoints'), parameters('subnets')[copyIndex('subnets')].serviceEndpoints, createArray())]", + "serviceEndpointPolicies": "[if(contains(parameters('subnets')[copyIndex('subnets')], 'serviceEndpointPolicies'), parameters('subnets')[copyIndex('subnets')].serviceEndpointPolicies, createArray())]" + } + } + } + ], + "addressSpace": { + "addressPrefixes": "[parameters('addressPrefixes')]" + }, + "ddosProtectionPlan": "[if(not(empty(parameters('ddosProtectionPlanId'))), variables('ddosProtectionPlan'), null())]", + "dhcpOptions": "[if(not(empty(parameters('dnsServers'))), variables('dnsServers_var'), null())]", + "enableDdosProtection": "[not(empty(parameters('ddosProtectionPlanId')))]" + } + }, + { + "condition": "[not(equals(parameters('lock'), 'NotSpecified'))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2017-04-01", + "scope": "[format('Microsoft.Network/virtualNetworks/{0}', parameters('name'))]", + "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "properties": { + "level": "[parameters('lock')]", + "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/virtualNetworks', parameters('name'))]" + ] + }, + { + "condition": "[or(or(or(not(empty(parameters('diagnosticStorageAccountId'))), not(empty(parameters('diagnosticWorkspaceId')))), not(empty(parameters('diagnosticEventHubAuthorizationRuleId')))), not(empty(parameters('diagnosticEventHubName'))))]", + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.Network/virtualNetworks/{0}', parameters('name'))]", + "name": "[format('{0}-diagnosticSettings', parameters('name'))]", + "properties": { + "storageAccountId": "[if(not(empty(parameters('diagnosticStorageAccountId'))), parameters('diagnosticStorageAccountId'), null())]", + "workspaceId": "[if(not(empty(parameters('diagnosticWorkspaceId'))), parameters('diagnosticWorkspaceId'), null())]", + "eventHubAuthorizationRuleId": "[if(not(empty(parameters('diagnosticEventHubAuthorizationRuleId'))), parameters('diagnosticEventHubAuthorizationRuleId'), null())]", + "eventHubName": "[if(not(empty(parameters('diagnosticEventHubName'))), parameters('diagnosticEventHubName'), null())]", + "metrics": "[variables('diagnosticsMetrics')]", + "logs": "[variables('diagnosticsLogs')]" + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/virtualNetworks', parameters('name'))]" + ] + }, + { + "copy": { + "name": "virtualNetwork_peering_local", + "count": "[length(parameters('virtualNetworkPeerings'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2020-10-01", + "name": "[format('{0}-virtualNetworkPeering-local-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "localVnetName": { + "value": "[parameters('name')]" + }, + "remoteVirtualNetworkId": { + "value": "[parameters('virtualNetworkPeerings')[copyIndex()].remoteVirtualNetworkId]" + }, + "name": { + "value": "[if(contains(parameters('virtualNetworkPeerings')[copyIndex()], 'name'), parameters('virtualNetworkPeerings')[copyIndex()].name, format('{0}-{1}', parameters('name'), last(split(parameters('virtualNetworkPeerings')[copyIndex()].remoteVirtualNetworkId, '/'))))]" + }, + "allowForwardedTraffic": { + "value": "[if(contains(parameters('virtualNetworkPeerings')[copyIndex()], 'allowForwardedTraffic'), parameters('virtualNetworkPeerings')[copyIndex()].allowForwardedTraffic, true())]" + }, + "allowGatewayTransit": { + "value": "[if(contains(parameters('virtualNetworkPeerings')[copyIndex()], 'allowGatewayTransit'), parameters('virtualNetworkPeerings')[copyIndex()].allowGatewayTransit, false())]" + }, + "allowVirtualNetworkAccess": { + "value": "[if(contains(parameters('virtualNetworkPeerings')[copyIndex()], 'allowVirtualNetworkAccess'), parameters('virtualNetworkPeerings')[copyIndex()].allowVirtualNetworkAccess, true())]" + }, + "doNotVerifyRemoteGateways": { + "value": "[if(contains(parameters('virtualNetworkPeerings')[copyIndex()], 'doNotVerifyRemoteGateways'), parameters('virtualNetworkPeerings')[copyIndex()].doNotVerifyRemoteGateways, true())]" + }, + "useRemoteGateways": { + "value": "[if(contains(parameters('virtualNetworkPeerings')[copyIndex()], 'useRemoteGateways'), parameters('virtualNetworkPeerings')[copyIndex()].useRemoteGateways, false())]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.9.1.41621", + "templateHash": "7913383313645172292" + } + }, + "parameters": { + "name": { + "type": "string", + "defaultValue": "[format('{0}-{1}', parameters('localVnetName'), last(split(parameters('remoteVirtualNetworkId'), '/')))]", + "metadata": { + "description": "Optional. The Name of Vnet Peering resource. If not provided, default value will be localVnetName-remoteVnetName" + } + }, + "localVnetName": { + "type": "string", + "metadata": { + "description": "Required. The Name of the Virtual Network to add the peering to." + } + }, + "remoteVirtualNetworkId": { + "type": "string", + "metadata": { + "description": "Required. The Resource ID of the VNet that is this Local VNet is being peered to. Should be in the format of a Resource ID" + } + }, + "allowForwardedTraffic": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Whether the forwarded traffic from the VMs in the local virtual network will be allowed/disallowed in remote virtual network. Default is true" + } + }, + "allowGatewayTransit": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. If gateway links can be used in remote virtual networking to link to this virtual network. Default is false" + } + }, + "allowVirtualNetworkAccess": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Whether the VMs in the local virtual network space would be able to access the VMs in remote virtual network space. Default is true" + } + }, + "doNotVerifyRemoteGateways": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. If we need to verify the provisioning state of the remote gateway. Default is true" + } + }, + "useRemoteGateways": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. If remote gateways can be used on this virtual network. If the flag is set to true, and allowGatewayTransit on remote peering is also true, virtual network will use gateways of remote virtual network for transit. Only one peering can have this flag set to true. This flag cannot be set if virtual network already has a gateway. Default is false" + } + } + }, + "resources": [ + { + "type": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings", + "apiVersion": "2022-01-01", + "name": "[format('{0}/{1}', parameters('localVnetName'), parameters('name'))]", + "properties": { + "allowForwardedTraffic": "[parameters('allowForwardedTraffic')]", + "allowGatewayTransit": "[parameters('allowGatewayTransit')]", + "allowVirtualNetworkAccess": "[parameters('allowVirtualNetworkAccess')]", + "doNotVerifyRemoteGateways": "[parameters('doNotVerifyRemoteGateways')]", + "useRemoteGateways": "[parameters('useRemoteGateways')]", + "remoteVirtualNetwork": { + "id": "[parameters('remoteVirtualNetworkId')]" + } + } + } + ], + "outputs": { + "resourceGroupName": { + "type": "string", + "value": "[resourceGroup().name]", + "metadata": { + "description": "The resource group the virtual network peering was deployed into" + } + }, + "name": { + "type": "string", + "value": "[parameters('name')]", + "metadata": { + "description": "The name of the virtual network peering" + } + }, + "resourceId": { + "type": "string", + "value": "[resourceId('Microsoft.Network/virtualNetworks/virtualNetworkPeerings', parameters('localVnetName'), parameters('name'))]", + "metadata": { + "description": "The resource ID of the virtual network peering" + } + } + } + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/virtualNetworks', parameters('name'))]" + ] + }, + { + "condition": "[if(contains(parameters('virtualNetworkPeerings')[copyIndex()], 'remotePeeringEnabled'), equals(parameters('virtualNetworkPeerings')[copyIndex()].remotePeeringEnabled, true()), false())]", + "copy": { + "name": "virtualNetwork_peering_remote", + "count": "[length(parameters('virtualNetworkPeerings'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2020-10-01", + "name": "[format('{0}-virtualNetworkPeering-remote-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "subscriptionId": "[split(parameters('virtualNetworkPeerings')[copyIndex()].remoteVirtualNetworkId, '/')[2]]", + "resourceGroup": "[split(parameters('virtualNetworkPeerings')[copyIndex()].remoteVirtualNetworkId, '/')[4]]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "localVnetName": { + "value": "[last(split(parameters('virtualNetworkPeerings')[copyIndex()].remoteVirtualNetworkId, '/'))]" + }, + "remoteVirtualNetworkId": { + "value": "[resourceId('Microsoft.Network/virtualNetworks', parameters('name'))]" + }, + "name": { + "value": "[if(contains(parameters('virtualNetworkPeerings')[copyIndex()], 'remotePeeringName'), parameters('virtualNetworkPeerings')[copyIndex()].remotePeeringName, format('{0}-{1}', last(split(parameters('virtualNetworkPeerings')[copyIndex()].remoteVirtualNetworkId, '/')), parameters('name')))]" + }, + "allowForwardedTraffic": { + "value": "[if(contains(parameters('virtualNetworkPeerings')[copyIndex()], 'remotePeeringAllowForwardedTraffic'), parameters('virtualNetworkPeerings')[copyIndex()].remotePeeringAllowForwardedTraffic, true())]" + }, + "allowGatewayTransit": { + "value": "[if(contains(parameters('virtualNetworkPeerings')[copyIndex()], 'remotePeeringAllowGatewayTransit'), parameters('virtualNetworkPeerings')[copyIndex()].remotePeeringAllowGatewayTransit, false())]" + }, + "allowVirtualNetworkAccess": { + "value": "[if(contains(parameters('virtualNetworkPeerings')[copyIndex()], 'remotePeeringAllowVirtualNetworkAccess'), parameters('virtualNetworkPeerings')[copyIndex()].remotePeeringAllowVirtualNetworkAccess, true())]" + }, + "doNotVerifyRemoteGateways": { + "value": "[if(contains(parameters('virtualNetworkPeerings')[copyIndex()], 'remotePeeringDoNotVerifyRemoteGateways'), parameters('virtualNetworkPeerings')[copyIndex()].remotePeeringDoNotVerifyRemoteGateways, true())]" + }, + "useRemoteGateways": { + "value": "[if(contains(parameters('virtualNetworkPeerings')[copyIndex()], 'remotePeeringUseRemoteGateways'), parameters('virtualNetworkPeerings')[copyIndex()].remotePeeringUseRemoteGateways, false())]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.9.1.41621", + "templateHash": "7913383313645172292" + } + }, + "parameters": { + "name": { + "type": "string", + "defaultValue": "[format('{0}-{1}', parameters('localVnetName'), last(split(parameters('remoteVirtualNetworkId'), '/')))]", + "metadata": { + "description": "Optional. The Name of Vnet Peering resource. If not provided, default value will be localVnetName-remoteVnetName" + } + }, + "localVnetName": { + "type": "string", + "metadata": { + "description": "Required. The Name of the Virtual Network to add the peering to." + } + }, + "remoteVirtualNetworkId": { + "type": "string", + "metadata": { + "description": "Required. The Resource ID of the VNet that is this Local VNet is being peered to. Should be in the format of a Resource ID" + } + }, + "allowForwardedTraffic": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Whether the forwarded traffic from the VMs in the local virtual network will be allowed/disallowed in remote virtual network. Default is true" + } + }, + "allowGatewayTransit": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. If gateway links can be used in remote virtual networking to link to this virtual network. Default is false" + } + }, + "allowVirtualNetworkAccess": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Whether the VMs in the local virtual network space would be able to access the VMs in remote virtual network space. Default is true" + } + }, + "doNotVerifyRemoteGateways": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. If we need to verify the provisioning state of the remote gateway. Default is true" + } + }, + "useRemoteGateways": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. If remote gateways can be used on this virtual network. If the flag is set to true, and allowGatewayTransit on remote peering is also true, virtual network will use gateways of remote virtual network for transit. Only one peering can have this flag set to true. This flag cannot be set if virtual network already has a gateway. Default is false" + } + } + }, + "resources": [ + { + "type": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings", + "apiVersion": "2022-01-01", + "name": "[format('{0}/{1}', parameters('localVnetName'), parameters('name'))]", + "properties": { + "allowForwardedTraffic": "[parameters('allowForwardedTraffic')]", + "allowGatewayTransit": "[parameters('allowGatewayTransit')]", + "allowVirtualNetworkAccess": "[parameters('allowVirtualNetworkAccess')]", + "doNotVerifyRemoteGateways": "[parameters('doNotVerifyRemoteGateways')]", + "useRemoteGateways": "[parameters('useRemoteGateways')]", + "remoteVirtualNetwork": { + "id": "[parameters('remoteVirtualNetworkId')]" + } + } + } + ], + "outputs": { + "resourceGroupName": { + "type": "string", + "value": "[resourceGroup().name]", + "metadata": { + "description": "The resource group the virtual network peering was deployed into" + } + }, + "name": { + "type": "string", + "value": "[parameters('name')]", + "metadata": { + "description": "The name of the virtual network peering" + } + }, + "resourceId": { + "type": "string", + "value": "[resourceId('Microsoft.Network/virtualNetworks/virtualNetworkPeerings', parameters('localVnetName'), parameters('name'))]", + "metadata": { + "description": "The resource ID of the virtual network peering" + } + } + } + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/virtualNetworks', parameters('name'))]" + ] + }, + { + "copy": { + "name": "virtualNetwork_rbac", + "count": "[length(parameters('roleAssignments'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2020-10-01", + "name": "[format('{0}-VNet-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "description": { + "value": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), parameters('roleAssignments')[copyIndex()].description, '')]" + }, + "principalIds": { + "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" + }, + "roleDefinitionIdOrName": { + "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" + }, + "principalType": { + "value": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), parameters('roleAssignments')[copyIndex()].principalType, '')]" + }, + "resourceId": { + "value": "[resourceId('Microsoft.Network/virtualNetworks', parameters('name'))]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.9.1.41621", + "templateHash": "6570518281545653594" + } + }, + "parameters": { + "description": { + "type": "string", + "defaultValue": "" + }, + "principalIds": { + "type": "array" + }, + "principalType": { + "type": "string", + "defaultValue": "" + }, + "roleDefinitionIdOrName": { + "type": "string" + }, + "resourceId": { + "type": "string" + } + }, + "variables": { + "builtInRoleNames": { + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", + "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", + "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", + "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", + "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", + "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", + "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", + "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", + "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", + "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", + "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", + "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", + "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", + "Monitoring Metrics Publisher": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')]", + "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", + "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", + "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", + "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", + "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", + "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", + "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", + "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", + "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]" + } + }, + "resources": [ + { + "copy": { + "name": "roleAssignment", + "count": "[length(parameters('principalIds'))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/virtualNetworks/{0}', last(split(parameters('resourceId'), '/')))]", + "name": "[guid(last(split(parameters('resourceId'), '/')), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", + "properties": { + "description": "[parameters('description')]", + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", + "principalId": "[parameters('principalIds')[copyIndex()]]", + "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]" + } + } + ] + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/virtualNetworks', parameters('name'))]" + ] + } + ], + "outputs": { + "resourceGroupName": { + "type": "string", + "value": "[resourceGroup().name]", + "metadata": { + "description": "The resource group the virtual network was deployed into" + } + }, + "resourceId": { + "type": "string", + "value": "[resourceId('Microsoft.Network/virtualNetworks', parameters('name'))]", + "metadata": { + "description": "The resource ID of the virtual network" + } + }, + "name": { + "type": "string", + "value": "[parameters('name')]", + "metadata": { + "description": "The name of the virtual network" + } + }, + "subnetNames": { + "type": "array", + "copy": { + "count": "[length(parameters('subnets'))]", + "input": "[parameters('subnets')[copyIndex()].name]" + }, + "metadata": { + "description": "The names of the deployed subnets" + } + }, + "subnetResourceIds": { + "type": "array", + "copy": { + "count": "[length(parameters('subnets'))]", + "input": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('name'), parameters('subnets')[copyIndex()].name)]" + }, + "metadata": { + "description": "The resource IDs of the deployed subnets" + } + } + } + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('networkSecurityGroupName'))]" + ] + } + ], + "outputs": { + "vnetId": { + "type": "string", + "value": "[reference(resourceId('Microsoft.Resources/deployments', format('{0}-minvnet', uniqueString(deployment().name, 'WestEurope'))), '2022-09-01').outputs.resourceId.value]" + }, + "vnet": { + "type": "string", + "value": "[reference(resourceId('Microsoft.Resources/deployments', format('{0}-minvnet', uniqueString(deployment().name, 'WestEurope'))), '2022-09-01').outputs.name.value]" + }, + "nsgID": { + "type": "string", + "value": "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('networkSecurityGroupName'))]" + }, + "subnetName": { + "type": "string", + "value": "[parameters('subnetName')]" + } + } + } + } + } + ], + "outputs": { + "id": { + "type": "string", + "metadata": { + "description": "Resource Id of Virtual Machine Scale Set" + }, + "value": "[resourceId('Microsoft.Compute/virtualMachineScaleSets', format('{0}-{1}', parameters('vmssName'), uniqueString(resourceGroup().name, parameters('location'))))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "Resource Name of Virtual Machine Scale Set" + }, + "value": "[format('{0}-{1}', parameters('vmssName'), uniqueString(resourceGroup().name, parameters('location')))]" + } + } +} \ No newline at end of file diff --git a/modules/compute/custom-image-vmss/modules/virtualNetworks.bicep b/modules/compute/custom-image-vmss/modules/virtualNetworks.bicep new file mode 100644 index 0000000000..b69153ad8c --- /dev/null +++ b/modules/compute/custom-image-vmss/modules/virtualNetworks.bicep @@ -0,0 +1,35 @@ +param location string +param vnetAddressPrefix string +param subnetAddressPrefix string +param vnetName string +param subnetName string +param networkSecurityGroupName string + +//By Default the nsg will allow the vnet access and deny all other access +resource networkSecurityGroup 'Microsoft.Network/networkSecurityGroups@2021-08-01' = { + name: networkSecurityGroupName + location: location +} + +module minvnet 'br/public:network/virtual-network:1.0.3' = { + name: '${uniqueString(deployment().name, 'WestEurope')}-minvnet' + params: { + location: location + name: vnetName + subnets: [ + { + name: subnetName + addressPrefix: subnetAddressPrefix + networkSecurityGroup: { + id: networkSecurityGroup.id + } + } + ] + addressPrefixes: [vnetAddressPrefix] + } +} + +output vnetId string = minvnet.outputs.resourceId +output vnet string = minvnet.outputs.name +output nsgID string = networkSecurityGroup.id +output subnetName string = subnetName diff --git a/modules/compute/custom-image-vmss/test/imageConfig.json b/modules/compute/custom-image-vmss/test/imageConfig.json new file mode 100644 index 0000000000..5a9db3ec9e --- /dev/null +++ b/modules/compute/custom-image-vmss/test/imageConfig.json @@ -0,0 +1,11 @@ +{ + "scylla_yaml": { + "cluster_name": "azure_test", + "experimental": "True", + "auto_bootstrap": "True", + "seed_provider": [{"class_name": "org.apache.cassandra.locator.SimpleSeedProvider", + "parameters": [{"seeds": "172.17.0.5"}]}], + "auto_snapshot": "False" + }, + "developer_mode": "True" +} \ No newline at end of file diff --git a/modules/compute/custom-image-vmss/test/main.test.bicep b/modules/compute/custom-image-vmss/test/main.test.bicep new file mode 100644 index 0000000000..f32d88aa22 --- /dev/null +++ b/modules/compute/custom-image-vmss/test/main.test.bicep @@ -0,0 +1,23 @@ +/* +Write deployment tests in this file. Any module that references the main +module file is a deployment test. Make sure at least one test is added. +*/ +@description('Deployment Location') +param location string = 'eastus' + +var communityGalleryImageId = '/CommunityGalleries/scylladb-7e8d8a04-23db-487d-87ec-0e175c0615bb/Images/scylla-enterprise-2023.1' + +var customData = loadFileAsBase64('imageConfig.json') + +module test1 '../main.bicep' = { + name: 'Test1' + params: { + location: location + administratorLogin: uniqueString(resourceGroup().name) + passwordAdministratorLogin: guid(resourceGroup().name) + vmssName: uniqueString(resourceGroup().name) + communityGalleryImageId: communityGalleryImageId + customData: customData + imageLocation: 'gallery' + } +} diff --git a/modules/compute/custom-image-vmss/version.json b/modules/compute/custom-image-vmss/version.json new file mode 100644 index 0000000000..e40897e287 --- /dev/null +++ b/modules/compute/custom-image-vmss/version.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "1.0", + "pathFilters": [ + "./main.json", + "./metadata.json" + ] +} \ No newline at end of file diff --git a/modules/compute/event-hub/README.md b/modules/compute/event-hub/README.md new file mode 100644 index 0000000000..860c44bb6f --- /dev/null +++ b/modules/compute/event-hub/README.md @@ -0,0 +1,269 @@ +# Azure Event-Hub + +This module deploys Microsoft.data event clusters, event namespaces, event hubs and associated configurations. + +## Details + +[Azure Event Hubs](https://azure.microsoft.com/en-us/products/event-hubs/) is a fully managed, real-time data ingestion service that’s simple, trusted, and scalable. This module provides an Infrastructure as Code alternative for management of Azure event hubs using Bicep, and is intended to mirror the available functionality of provisioning with Azure Portal or CLI. + +## Parameters + +| Name | Type | Required | Description | +| :--------------------------------- | :------: | :------: | :---------------------------------------------------------------------------------------------------------------------------- | +| `clusterName` | `string` | No | Optional. Name for the Event Hub cluster, Alphanumerics and hyphens characters, Start with letter, End with letter or number. | +| `clusterCapacity` | `int` | No | Optional. The quantity of Event Hubs Cluster Capacity Units contained in this cluster. | +| `location` | `string` | No | Required. Location for all resources. | +| `tags` | `object` | No | Optional. Tags of the resource. | +| `namespaces` | `array` | No | Required. The list of the event hub namespaces with its configurations to be created. | +| `namespaceAuthorizationRules` | `array` | No | Optional. Authorization Rules for the Event Hub Namespace. | +| `namespaceRoleAssignments` | `array` | No | Optional. Role assignments for the namespace. | +| `namespaceDisasterRecoveryConfigs` | `array` | No | Optional. The disaster recovery config for the namespace. | +| `namespaceDiagnosticSettings` | `array` | No | Optional. The Diagnostics Settings config for the namespace. | +| `eventHubs` | `array` | No | Optional. Name for the eventhub with its all configurations to be created. | +| `eventHubAuthorizationRules` | `array` | No | Optional. Authorization Rules for the Event Hub . | +| `eventHubConsumerGroups` | `array` | No | Optional. consumer groups for the Event Hub . | +| `namespacePrivateEndpoints` | `array` | No | Private Endpoints that should be created for Azure EventHub Namespaces. | + +## Outputs + +| Name | Type | Description | +| :----------------------------- | :-----: | :-------------------------------------- | +| `eventHubNamespaceNames` | `array` | Azure Event Hub namespace names. | +| `eventHubNamespaceResourceIds` | `array` | Azure Event Hub namespace resource Ids. | + +## Examples + +### Example 1 + +```bicep +module evh 'br/public:compute/event-hub:2.0.2' = { + name: 'evh-${uniqueString(deployment().name, 'eastus2')}' + params: { + location: 'eastus2' + clusterName: 'evhcluster1' + clusterCapacity: 2 + namespaces: [ + { + name: 'testns1' + capacity: 2 + isAutoInflateEnabled: true + maximumThroughputUnits: 6 + zoneRedundant: true + publicNetworkAccess: false + } + { + name: 'testns2' + sku: 'Basic' + } + ] + namespaceAuthorizationRules: [ + { + name: 'authrule01' + rights: [ 'Listen', 'Manage', 'Send' ] + namespaceName: 'testns1' + } + { + name: 'authrule02' + rights: [ 'Listen' ] + namespaceName: 'testns1' + } + ] + eventHubs: [ + { + name: 'evh1' + messageRetentionInDays: 4 + partitionCount: 4 + namespaceName: 'testns1' + } + { + name: 'evh2' + messageRetentionInDays: 7 + partitionCount: 2 + namespaceName: 'testns1' + } + ] + eventHubAuthorizationRules: [ + { + name: 'evh-rule01' + rights: [ 'Listen', 'Manage', 'Send' ] + namespaceName: 'testns1' + eventHubName: 'evh1' + } + ] + eventHubConsumerGroups: [ + { + name: 'cg01' + namespaceName: 'testns1' + eventHubName: 'evh1' + } + ] + tags: { + tag1: 'tag1value' + tag2: 'tag2value' + } + } +} +``` + +### Example 2 + +```bicep +module evhns 'br/public:compute/event-hub:2.0.2' = { + name: 'evhns-${uniqueString(deployment().name, 'eastus')}' + params: { + location: 'eastus' + namespaces: [ + { + name: 'testns' + sku: 'Premium' + capacity: 2 + zoneRedundant: true + } + ] + namespaceRoleAssignments: [ + { + name: 'rol01' + description: 'Reader Role Assignment' + principalIds: [ '30ec80f4-43d7-1280-99ba-2571db1cc45b' ] + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'f526a384-b230-433a-b45c-95f59c4a2dec' // Azure Event Hubs Data Owner + namespaceName: 'testns' + } + ] + eventHubs: [ + { + name: 'evh' + messageRetentionInDays: 1 + partitionCount: 1 + namespaceName: 'testns' + roleAssignments: [ + { + name: 'role01' + roleDefinitionIdOrName: 'Contributor' + description: 'Contributor Role Assignment' + principalIds: [ '10ec80f4-43d7-1280-99aa-2571db1cc45b' ] + principalType: 'ServicePrincipal' + } + ] + } + ] + } +} +``` + +### Example 3 + +```bicep +module evhns 'br/public:compute/event-hub:2.0.2' = { + name: 'evhns-${uniqueString(deployment().name, 'eastus')}' + params: { + location: 'eastus' + namespaces: [ + { + name: 'testns3' + sku: 'Standard' + capacity: 4 + publicNetworkAccess: 'Disabled' + } + ] + namespacePrivateEndpoints: [ + { + name: 'endpoint1' + subnetId: dependencies.outputs.subnetIds[0] + namespaceName: 'testns3' + manualApprovalEnabled: true + } + { + name: 'endpoint2' + subnetId: dependencies.outputs.subnetIds[1] + privateDnsZoneId: dependencies.outputs.privateDNSZoneId + namespaceName: 'testns3' + } + ] + namespaceDiagnosticSettings: [ + { + name: 'testds' + namespaceName: 'testns3' + eventHubAuthorizationRuleId: < external evenetHub authorizationRuleId > + eventHubName: < external eventHub name + metricsSettings: [ + { + category: 'AllMetrics' + timeGrain: 'PT1M' + enabled: true + retentionPolicy: { + days: 7 + enabled: true + } + } + ] + logsSettings: [ + { + category: 'OperationalLogs' + enabled: true + retentionPolicy: { + days: 36 + enabled: true + } + } + { + category: 'ArchiveLogs' + enabled: true + } + ] + } + ] + } +} +``` + +### Example 4 + +```bicep +module eventhubnamespace 'br/public:compute/event-hub:2.0.2' = { + name: 'evhns-${uniqueString(deployment().name, 'eastus')}' + params: { + location: 'eastus' + namespaces: [ + { + name: 'testns4' + sku: 'Standard' + capacity: 1 + zoneRedundant: false + } + ] + eventHubs: [ + { + name: 'testevh' + messageRetentionInDays: 1 + partitionCount: 2 + namespaceName: 'testns4' + captureDescriptionEnabled: true + captureDescriptionDestinationBlobContainer: << external storageAccount blob container name >> + captureDescriptionDestinationStorageAccountResourceId: << external storageAccount Id >> + } + ] + namespaceDiagnosticSettings: [ + { + name: 'ds' + namespaceName: 'testns4' + storageAccountId: << external storageAccount Id >> + workspaceId: << external long analytics workspace Id >> + metricsSettings: [ { category: 'AllMetrics', enabled: true, retentionPolicy: { days: 365, enabled: true } } ] + logsSettings: [ + { + category: 'ArchiveLogs' + enabled: true + retentionPolicy: { days: 7, enabled: true } + } + { + category: 'RuntimeAuditLogs' + enabled: true + retentionPolicy: { days: 3, enabled: true } + } + ] + } + ] + } +} +``` \ No newline at end of file diff --git a/modules/compute/event-hub/bicepconfig.json b/modules/compute/event-hub/bicepconfig.json new file mode 100644 index 0000000000..763ace4e09 --- /dev/null +++ b/modules/compute/event-hub/bicepconfig.json @@ -0,0 +1,5 @@ +{ + "experimentalFeaturesEnabled": { + "userDefinedTypes": true + } +} \ No newline at end of file diff --git a/modules/compute/event-hub/main.bicep b/modules/compute/event-hub/main.bicep new file mode 100644 index 0000000000..c7a7c11de6 --- /dev/null +++ b/modules/compute/event-hub/main.bicep @@ -0,0 +1,407 @@ +metadata name = 'Azure Event-Hub' +metadata description = 'This module deploys Microsoft.data event clusters, event namespaces, event hubs and associated configurations.' +metadata owner = 'sumit-salunke' + +@description('Optional. Name for the Event Hub cluster, Alphanumerics and hyphens characters, Start with letter, End with letter or number.') +// We can not pass default variable value ''. Because it was showing The template resource '' of type 'Microsoft.EventHub/clusters' at line '1' is not valid. The name property cannot be null or empty. +param clusterName string = 'null' + +@description('Optional. The quantity of Event Hubs Cluster Capacity Units contained in this cluster.') +param clusterCapacity int = 1 + +@description('Required. Location for all resources.') +param location string = resourceGroup().location + +@description('Optional. Tags of the resource.') +param tags object = {} + +@description('Required. The list of the event hub namespaces with its configurations to be created.') +param namespaces namespacesType[] = [ + { + name: 'evhns001' + sku: 'Standard' + capacity: 1 + disableLocalAuth: false + kafkaEnabled: true + isAutoInflateEnabled: false + maximumThroughputUnits: 0 + zoneRedundant: false + minimumTlsVersion: '1.2' + publicNetworkAccess: 'Enabled' + } +] + +@description('Optional. Authorization Rules for the Event Hub Namespace.') +param namespaceAuthorizationRules authorizationRulesType[] = [] + +@description('Optional. Role assignments for the namespace.') +param namespaceRoleAssignments namespaceRoleAssignmentsType[] = [] + +@description('Optional. The disaster recovery config for the namespace.') +param namespaceDisasterRecoveryConfigs namespaceDisasterRecoveryConfigsType[] = [] + +@description('Optional. The Diagnostics Settings config for the namespace.') +param namespaceDiagnosticSettings namespaceDiagnosticSettingsType[] = [] + +@description('Optional. Name for the eventhub with its all configurations to be created.') +param eventHubs eventHubsType[] = [] + +@description('Optional. Authorization Rules for the Event Hub .') +param eventHubAuthorizationRules authorizationRulesType[] = [] + +@description('Optional. consumer groups for the Event Hub .') +param eventHubConsumerGroups eventHubConsumerGroupsType[] = [] + +@description('Private Endpoints that should be created for Azure EventHub Namespaces.') +param namespacePrivateEndpoints privateEndpointType[] = [] + +resource cluster 'Microsoft.EventHub/clusters@2022-10-01-preview' = if (clusterName != 'null') { + name: clusterName + location: location + tags: tags + sku: { + name: 'Dedicated' + capacity: clusterCapacity + } +} + +resource evhns 'Microsoft.EventHub/namespaces@2022-10-01-preview' = [for ns in namespaces: { + name: ns.name + location: location + sku: { + name: ns.?sku ?? 'Standard' + capacity: ns.?capacity ?? 1 + } + properties: { + disableLocalAuth: ns.?disableLocalAuth ?? false + kafkaEnabled: ns.?kafkaEnabled ?? true + isAutoInflateEnabled: ns.?isAutoInflateEnabled ?? false + maximumThroughputUnits: ns.?maximumThroughputUnits ?? 0 + zoneRedundant: ns.?zoneRedundant ?? false + clusterArmId: (clusterName != 'null') ? cluster.id : null + minimumTlsVersion: ns.?minimumTlsVersion ?? '1.2' + publicNetworkAccess: ns.?publicNetworkAccess ?? 'Enabled' + } + tags: tags +}] + +module evhns_authorizationRules 'modules/authorizationRule.bicep' = [for (rule, index) in namespaceAuthorizationRules: { + name: '${uniqueString(deployment().name, location)}-evhns-authrule-${index}' + params: { + name: rule.name + rights: rule.rights + namespaceName: rule.namespaceName + } + dependsOn: [ + evhns + ] +}] + +module evhns_roleAssignments 'modules/roleAssignment.bicep' = [for (role, index) in namespaceRoleAssignments: { + name: '${deployment().name}-evhns-role-${index}' + params: { + roleName: role.?name ?? '' + description: role.?description ?? '' + principalIds: role.principalIds + principalType: role.?principalType ?? '' + roleDefinitionIdOrName: role.roleDefinitionIdOrName + namespaceName: role.namespaceName + } + dependsOn: [ + evhns + ] +}] + +module evhns_disasterRecoveryConfigs 'modules/disasterRecoveryConfig.bicep' = [for (drConfig, index) in namespaceDisasterRecoveryConfigs: { + name: '${uniqueString(deployment().name, location)}-evhns-drconfig-${index}' + params: { + name: drConfig.name + partnerNamespaceId: drConfig.partnerNamespaceId + namespaceName: drConfig.namespaceName + } + dependsOn: [ + evhns + ] +}] + +module evh 'modules/eventHub/eventHub.bicep' = [for (evh, index) in eventHubs: { + name: '${uniqueString(deployment().name, location)}-evh-${index}' + params: { + namespaceName: evh.namespaceName + name: evh.name + messageRetentionInDays: evh.?messageRetentionInDays ?? 1 + partitionCount: evh.?partitionCount ?? 2 + status: evh.?status ?? 'Active' + captureDescriptionEnabled: evh.?captureDescriptionEnabled ?? false + captureDescriptionEncoding: evh.?captureDescriptionEncoding ?? 'Avro' + captureDescriptionIntervalInSeconds: evh.?captureDescriptionIntervalInSeconds ?? 300 + captureDescriptionSizeLimitInBytes: evh.?captureDescriptionSizeLimitInBytes ?? 314572800 + captureDescriptionSkipEmptyArchives: evh.?captureDescriptionSkipEmptyArchives ?? false + captureDescriptionDestinationName: evh.?captureDescriptionDestinationName ?? 'EventHubArchive.AzureBlockBlob' + captureDescriptionDestinationArchiveNameFormat: evh.?captureDescriptionDestinationArchiveNameFormat ?? '{Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}' + captureDescriptionDestinationBlobContainer: evh.?captureDescriptionDestinationBlobContainer ?? '' + captureDescriptionDestinationStorageAccountResourceId: evh.?captureDescriptionDestinationStorageAccountResourceId ?? '' + captureDescriptionDestinationdataLakeAccountName: evh.?captureDescriptionDestinationdataLakeAccountName ?? '' + captureDescriptionDestinationdataLakeFolderPath: evh.?captureDescriptionDestinationdataLakeFolderPath ?? '' + captureDescriptionDestinationdataLakeSubscriptionId: evh.?captureDescriptionDestinationdataLakeSubscriptionId ?? '' + roleAssignments: evh.?roleAssignments ?? [] + } + dependsOn: [ + evhns + ] +}] + +module evh_authorizationRules 'modules/eventHub/authorizationRule.bicep' = [for (rule, index) in eventHubAuthorizationRules: { + name: '${uniqueString(deployment().name, location)}-evh-authrule-${index}' + params: { + namespaceName: rule.namespaceName + eventHubName: rule.eventHubName + name: rule.name + rights: rule.rights + } + dependsOn: [ + evh + ] +}] + +module evh_consumerGroups 'modules/eventHub/consumerGroup.bicep' = [for (cg, index) in eventHubConsumerGroups: { + name: '${deployment().name}-evh-cg-${index}' + params: { + namespaceName: cg.namespaceName + eventHubName: cg.eventHubName + name: cg.name + userMetadata: cg.?userMetadata ?? '' + } + dependsOn: [ + evh + ] +}] + +module evhns_diagnosticSettings 'modules/diagnosticSetting.bicep' = [for (ds, index) in namespaceDiagnosticSettings: { + name: '${deployment().name}-evhns-diagnosticSettings-${index}' + params: { + namespaceName: ds.namespaceName + name: ds.name + storageAccountId: ds.?storageAccountId ?? '' + workspaceId: ds.?workspaceId ?? '' + eventHubAuthorizationRuleId: ds.?eventHubAuthorizationRuleId ?? '' + eventHubName: ds.?eventHubName ?? '' + metricsSettings: ds.?metricsSettings ?? [] + logsSettings: ds.?logsSettings ?? [] + } + dependsOn: [ + evhns + ] +}] + +module evhns_privateEndpoints 'modules/privateEndpoint.bicep' = [for (pep, index) in namespacePrivateEndpoints: { + name: '${uniqueString(deployment().name)}-evhns-pep-${index}' + params: { + name: pep.name + namespaceName: pep.namespaceName + location: location + groupIds: pep.?groupIds ?? [ 'namespace' ] + subnetId: pep.subnetId + privateDnsZoneId: pep.?privateDnsZoneId ?? '' + tags: tags + manualApprovalEnabled: pep.?manualApprovalEnabled ?? false + } + dependsOn: [ + evhns + ] +}] + +// output +@description('Azure Event Hub namespace names.') +output eventHubNamespaceNames array = [for ns in namespaces: ns.name] + +@description('Azure Event Hub namespace resource Ids.') +output eventHubNamespaceResourceIds array = [for ns in namespaces: resourceId('Microsoft.EventHub/namespaces', ns.name)] + +// user defined type +type namespacesType = { + @description('Name of the Event Hub Namespace.') + name: string + @description('SKU of the Event Hub Namespace. Possible values are "Basic" or "Standard" or "Premium') + sku: ('Basic' | 'Standard' | 'Premium')?// Default 'Standard' + @description('Event Hubs throughput units for Basic or Standard tiers where value should be 0 to 20 units. For Premium tier, value should be 0 to 10 premium units.') + capacity: int?// Default 1 + @description('Enabling this property creates a Standard Event Hubs Namespace in regions supported availability zones.') + zoneRedundant: bool?// Default false + @description('Whether to enable AutoInflate or not.') + isAutoInflateEnabled: bool?// Default false + @description('Upper limit of throughput units when AutoInflate is enabled.') + maximumThroughputUnits: int?// Default 0 + @description('Whether to enable Kafka or not.') + kafkaEnabled: bool?// Default 'true' + @description('Whethere tp disable SAS authentication or not.') + disableLocalAuth: bool?// Default false + @description('Whether to enable public network access or not.') + publicNetworkAccess: ('Enabled' | 'Disabled' | 'SecuredByPerimeter')?// Default 'Enabled' + @description('Set the minimum TLS version for the Event Hub Namespace.') + minimumTlsVersion: ('1.0' | '1.1' | '1.2')?// Default '1.2' + +} + +type authorizationRulesType = { + @description('Name of the namespace authorization rule.') + name: string + @description('The rights associated with the rule.') + rights: string[] + @description('The eventhub namespace name.') + namespaceName: string + @description('The eventhub name. Optional if the authorization rule is for namespace and not for an eventhub.') + eventHubName: string? +} + +type namespaceRoleAssignmentsType = { + @description('Name of the namespace role assignment.') + name: string? + @description('The description of the role assignment.') + description: string? + @description('The principal ids associated with the role assignment.') + principalIds: string[] + @description('The principal type associated with the role assignment.') + principalType: ('Device' | 'ForeignGroup' | 'Group' | 'ServicePrincipal' | 'User')? + @description('The role definition id or name associated with the role assignment.') + roleDefinitionIdOrName: string + @description('The eventhub namespace name.') + namespaceName: string +} + +type eventHubRoleAssignmentsType = { + @description('Name of the namespace role assignment.') + name: string? + @description('The description of the role assignment.') + description: string? + @description('The principal ids associated with the role assignment.') + principalIds: string[] + @description('The principal type associated with the role assignment.') + principalType: ('Device' | 'ForeignGroup' | 'Group' | 'ServicePrincipal' | 'User')? + @description('The role definition id or name associated with the role assignment.') + roleDefinitionIdOrName: string +} + +type namespaceDisasterRecoveryConfigsType = { + @description('Name of the namespace disaster recovery config.') + name: string + @description('The resource id of the secondary partner namespace, which is part of GEO DR pairing.') + partnerNamespaceId: string + @description('The eventhub namespace name.') + namespaceName: string +} + +type eventHubsType = { + @description('Name of the Event Hub.') + name: string + @description('The eventhub namespace name.') + namespaceName: string + @description('Number of partitions created for the Event Hub, allowed values are from 1 to 32 partitions.') + partitionCount: int?// Default 2 + @description('Number of days to retain the events for this Event Hub, value should be 1 to 7 days.') + messageRetentionInDays: int?// Default 1 + @description('A value that indicates whether capture description is enabled.') + captureDescriptionEnabled: bool?// Default false + @description('TEnumerates the possible values for the encoding format of capture description.') + captureDescriptionEncoding: ('Avro' | 'Parquet')?// Default 'Avro' + @description('The time window allows you to set the frequency with which the capture to Azure Blobs will happen, value should between 60 to 900 seconds.') + captureDescriptionIntervalInSeconds: int? + @description('The size window defines the amount of data built up in your Event Hub before an capture operation, value should be between 10485760 to 524288000 bytes.') + captureDescriptionSizeLimitInBytes: int? + @description('A value that indicates whether to Skip Empty Archives') + captureDescriptionSkipEmptyArchives: bool? + @description('The eventhub capture destination name.') + captureDescriptionDestinationName: ('EventHubArchive.AzureBlockBlob' | 'EventHubArchive.AzureDataLake')?// Default 'EventHubArchive.AzureBlockBlob' + @description('Blob naming convention for archive, e.g. {Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}.') + captureDescriptionDestinationArchiveNameFormat: string? + @description('The eventhub capture description destination blob container name.') + captureDescriptionDestinationBlobContainer: string? + @description('TSubscription Id of Azure Data Lake Store') + captureDescriptionDestinationStorageAccountResourceId: string? + @description('The Azure Data Lake Store name for the captured events') + captureDescriptionDestinationdataLakeAccountName: string? + @description('The destination folder path for the captured events') + captureDescriptionDestinationdataLakeFolderPath: string? + @description('Subscription Id of Azure Data Lake Store') + captureDescriptionDestinationdataLakeSubscriptionId: string? + @description('The role assignements scoped to event hub.') + roleAssignments: eventHubRoleAssignmentsType[]? + @description('The possible values for the status of the Event Hub..') + status: ('Active' | 'Disabled' | 'SendDisabled')?// Default 'Active' +} + +type eventHubConsumerGroupsType = { + @description('Name of the Event Hub Consumer Group.') + name: string + @description('The eventhub namespace name.') + namespaceName: string + @description('The eventhub name.') + eventHubName: string + @description('The user metadata.') + userMetadata: string? +} + +type namespaceDiagnosticSettingsType = { + @description('Name of the namespace diagnostic setting.') + name: string + @description('The eventhub namespace name.') + namespaceName: string + @description('The log analytics workspace id.') + workspaceId: string? + @description('The storage account id.') + storageAccountId: string? + @description('The eventhub name.') + eventHubName: string? + @description('The eventhub authorization rule id.') + eventHubAuthorizationRuleId: string? + @description('The list of metic settings.') + metricsSettings: metricSettingsType[] + @description('The list of logs settings.') + logsSettings: logSettingsType[] +} + +type metricSettingsType = { + @description('A value indicating whether this category is enabled.') + enabled: bool + @description('The category of the metrics.') + category: ('AllMetrics') + @description('The time grain of the metric in ISO8601 format.') + timeGrain: string? + @description('The retention policy of the metric.') + retentionPolicy: retentionPolicyType? +} + +type retentionPolicyType = { + @description('The retention period of the metric.') + days: int + @description('The retention policy enabled flag.') + enabled: bool +} + +type logSettingsType = { + @description('A value indicating whether this log is enabled.') + enabled: bool + @description('The category of the logs.') + category: string? + @description('The category group of the logs.') + categoryGroup: ('allLogs' | 'audit')? + @description('The retention policy of the logs.') + retentionPolicy: retentionPolicyType? +} + +type privateEndpointType = { + @description('The name of the private endpoint.') + name: string + @description('The eventhub namespace name.') + namespaceName: string + @description('The subnet that the private endpoint should be created in.') + subnetId: string + @description('The subresource name of the target Azure resource that private endpoint will connect to.') + groupIds: array?// Default ['namespace'] + @description('The ID of the private DNS zone in which private endpoint will register its private IP address.') + privateDnsZoneId: string? + @description('When set to true, users will need to manually approve the private endpoint connection request.') + manualApprovalEnabled: bool?// Default false + @description('Tags for the resource.') + tags: { *: string }? +} diff --git a/modules/compute/event-hub/main.json b/modules/compute/event-hub/main.json new file mode 100644 index 0000000000..501f76b1cd --- /dev/null +++ b/modules/compute/event-hub/main.json @@ -0,0 +1,1802 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "1.10-experimental", + "contentVersion": "1.0.0.0", + "metadata": { + "_EXPERIMENTAL_WARNING": "Symbolic name support in ARM is experimental, and should be enabled for testing purposes only. Do not enable this setting for any production usage, or you may be unexpectedly broken at any time!", + "_generator": { + "name": "bicep", + "version": "0.19.5.34762", + "templateHash": "13506265071276900614" + }, + "name": "Azure Event-Hub", + "description": "This module deploys Microsoft.data event clusters, event namespaces, event hubs and associated configurations.", + "owner": "sumit-salunke" + }, + "definitions": { + "namespacesType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Name of the Event Hub Namespace." + } + }, + "sku": { + "type": "string", + "allowedValues": [ + "Basic", + "Premium", + "Standard" + ], + "nullable": true, + "metadata": { + "description": "SKU of the Event Hub Namespace. Possible values are \"Basic\" or \"Standard\" or \"Premium" + } + }, + "capacity": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Event Hubs throughput units for Basic or Standard tiers where value should be 0 to 20 units. For Premium tier, value should be 0 to 10 premium units." + } + }, + "zoneRedundant": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Enabling this property creates a Standard Event Hubs Namespace in regions supported availability zones." + } + }, + "isAutoInflateEnabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Whether to enable AutoInflate or not." + } + }, + "maximumThroughputUnits": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Upper limit of throughput units when AutoInflate is enabled." + } + }, + "kafkaEnabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Whether to enable Kafka or not." + } + }, + "disableLocalAuth": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Whethere tp disable SAS authentication or not." + } + }, + "publicNetworkAccess": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled", + "SecuredByPerimeter" + ], + "nullable": true, + "metadata": { + "description": "Whether to enable public network access or not." + } + }, + "minimumTlsVersion": { + "type": "string", + "allowedValues": [ + "1.0", + "1.1", + "1.2" + ], + "nullable": true, + "metadata": { + "description": "Set the minimum TLS version for the Event Hub Namespace." + } + } + } + }, + "authorizationRulesType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Name of the namespace authorization rule." + } + }, + "rights": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "The rights associated with the rule." + } + }, + "namespaceName": { + "type": "string", + "metadata": { + "description": "The eventhub namespace name." + } + }, + "eventHubName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "The eventhub name. Optional if the authorization rule is for namespace and not for an eventhub." + } + } + } + }, + "namespaceRoleAssignmentsType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Name of the namespace role assignment." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "The description of the role assignment." + } + }, + "principalIds": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "The principal ids associated with the role assignment." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "The principal type associated with the role assignment." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "The role definition id or name associated with the role assignment." + } + }, + "namespaceName": { + "type": "string", + "metadata": { + "description": "The eventhub namespace name." + } + } + } + }, + "eventHubRoleAssignmentsType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Name of the namespace role assignment." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "The description of the role assignment." + } + }, + "principalIds": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "The principal ids associated with the role assignment." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "The principal type associated with the role assignment." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "The role definition id or name associated with the role assignment." + } + } + } + }, + "namespaceDisasterRecoveryConfigsType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Name of the namespace disaster recovery config." + } + }, + "partnerNamespaceId": { + "type": "string", + "metadata": { + "description": "The resource id of the secondary partner namespace, which is part of GEO DR pairing." + } + }, + "namespaceName": { + "type": "string", + "metadata": { + "description": "The eventhub namespace name." + } + } + } + }, + "eventHubsType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Name of the Event Hub." + } + }, + "namespaceName": { + "type": "string", + "metadata": { + "description": "The eventhub namespace name." + } + }, + "partitionCount": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Number of partitions created for the Event Hub, allowed values are from 1 to 32 partitions." + } + }, + "messageRetentionInDays": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Number of days to retain the events for this Event Hub, value should be 1 to 7 days." + } + }, + "captureDescriptionEnabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "A value that indicates whether capture description is enabled." + } + }, + "captureDescriptionEncoding": { + "type": "string", + "allowedValues": [ + "Avro", + "Parquet" + ], + "nullable": true, + "metadata": { + "description": "TEnumerates the possible values for the encoding format of capture description." + } + }, + "captureDescriptionIntervalInSeconds": { + "type": "int", + "nullable": true, + "metadata": { + "description": "The time window allows you to set the frequency with which the capture to Azure Blobs will happen, value should between 60 to 900 seconds." + } + }, + "captureDescriptionSizeLimitInBytes": { + "type": "int", + "nullable": true, + "metadata": { + "description": "The size window defines the amount of data built up in your Event Hub before an capture operation, value should be between 10485760 to 524288000 bytes." + } + }, + "captureDescriptionSkipEmptyArchives": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "A value that indicates whether to Skip Empty Archives" + } + }, + "captureDescriptionDestinationName": { + "type": "string", + "allowedValues": [ + "EventHubArchive.AzureBlockBlob", + "EventHubArchive.AzureDataLake" + ], + "nullable": true, + "metadata": { + "description": "The eventhub capture destination name." + } + }, + "captureDescriptionDestinationArchiveNameFormat": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Blob naming convention for archive, e.g. {Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}." + } + }, + "captureDescriptionDestinationBlobContainer": { + "type": "string", + "nullable": true, + "metadata": { + "description": "The eventhub capture description destination blob container name." + } + }, + "captureDescriptionDestinationStorageAccountResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "TSubscription Id of Azure Data Lake Store" + } + }, + "captureDescriptionDestinationdataLakeAccountName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "The Azure Data Lake Store name for the captured events" + } + }, + "captureDescriptionDestinationdataLakeFolderPath": { + "type": "string", + "nullable": true, + "metadata": { + "description": "The destination folder path for the captured events" + } + }, + "captureDescriptionDestinationdataLakeSubscriptionId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Subscription Id of Azure Data Lake Store" + } + }, + "roleAssignments": { + "type": "array", + "items": { + "$ref": "#/definitions/eventHubRoleAssignmentsType" + }, + "nullable": true, + "metadata": { + "description": "The role assignements scoped to event hub." + } + }, + "status": { + "type": "string", + "allowedValues": [ + "Active", + "Disabled", + "SendDisabled" + ], + "nullable": true, + "metadata": { + "description": "The possible values for the status of the Event Hub.." + } + } + } + }, + "eventHubConsumerGroupsType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Name of the Event Hub Consumer Group." + } + }, + "namespaceName": { + "type": "string", + "metadata": { + "description": "The eventhub namespace name." + } + }, + "eventHubName": { + "type": "string", + "metadata": { + "description": "The eventhub name." + } + }, + "userMetadata": { + "type": "string", + "nullable": true, + "metadata": { + "description": "The user metadata." + } + } + } + }, + "namespaceDiagnosticSettingsType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Name of the namespace diagnostic setting." + } + }, + "namespaceName": { + "type": "string", + "metadata": { + "description": "The eventhub namespace name." + } + }, + "workspaceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "The log analytics workspace id." + } + }, + "storageAccountId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "The storage account id." + } + }, + "eventHubName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "The eventhub name." + } + }, + "eventHubAuthorizationRuleId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "The eventhub authorization rule id." + } + }, + "metricsSettings": { + "type": "array", + "items": { + "$ref": "#/definitions/metricSettingsType" + }, + "metadata": { + "description": "The list of metic settings." + } + }, + "logsSettings": { + "type": "array", + "items": { + "$ref": "#/definitions/logSettingsType" + }, + "metadata": { + "description": "The list of logs settings." + } + } + } + }, + "metricSettingsType": { + "type": "object", + "properties": { + "enabled": { + "type": "bool", + "metadata": { + "description": "A value indicating whether this category is enabled." + } + }, + "category": { + "type": "string", + "allowedValues": [ + "AllMetrics" + ], + "metadata": { + "description": "The category of the metrics." + } + }, + "timeGrain": { + "type": "string", + "nullable": true, + "metadata": { + "description": "The time grain of the metric in ISO8601 format." + } + }, + "retentionPolicy": { + "$ref": "#/definitions/retentionPolicyType", + "nullable": true, + "metadata": { + "description": "The retention policy of the metric." + } + } + } + }, + "retentionPolicyType": { + "type": "object", + "properties": { + "days": { + "type": "int", + "metadata": { + "description": "The retention period of the metric." + } + }, + "enabled": { + "type": "bool", + "metadata": { + "description": "The retention policy enabled flag." + } + } + } + }, + "logSettingsType": { + "type": "object", + "properties": { + "enabled": { + "type": "bool", + "metadata": { + "description": "A value indicating whether this log is enabled." + } + }, + "category": { + "type": "string", + "nullable": true, + "metadata": { + "description": "The category of the logs." + } + }, + "categoryGroup": { + "type": "string", + "allowedValues": [ + "allLogs", + "audit" + ], + "nullable": true, + "metadata": { + "description": "The category group of the logs." + } + }, + "retentionPolicy": { + "$ref": "#/definitions/retentionPolicyType", + "nullable": true, + "metadata": { + "description": "The retention policy of the logs." + } + } + } + }, + "privateEndpointType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint." + } + }, + "namespaceName": { + "type": "string", + "metadata": { + "description": "The eventhub namespace name." + } + }, + "subnetId": { + "type": "string", + "metadata": { + "description": "The subnet that the private endpoint should be created in." + } + }, + "groupIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "The subresource name of the target Azure resource that private endpoint will connect to." + } + }, + "privateDnsZoneId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "The ID of the private DNS zone in which private endpoint will register its private IP address." + } + }, + "manualApprovalEnabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "When set to true, users will need to manually approve the private endpoint connection request." + } + }, + "tags": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Tags for the resource." + } + } + } + } + }, + "parameters": { + "clusterName": { + "type": "string", + "defaultValue": "null", + "metadata": { + "description": "Optional. Name for the Event Hub cluster, Alphanumerics and hyphens characters, Start with letter, End with letter or number." + } + }, + "clusterCapacity": { + "type": "int", + "defaultValue": 1, + "metadata": { + "description": "Optional. The quantity of Event Hubs Cluster Capacity Units contained in this cluster." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Required. Location for all resources." + } + }, + "tags": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "namespaces": { + "type": "array", + "items": { + "$ref": "#/definitions/namespacesType" + }, + "defaultValue": [ + { + "name": "evhns001", + "sku": "Standard", + "capacity": 1, + "disableLocalAuth": false, + "kafkaEnabled": true, + "isAutoInflateEnabled": false, + "maximumThroughputUnits": 0, + "zoneRedundant": false, + "minimumTlsVersion": "1.2", + "publicNetworkAccess": "Enabled" + } + ], + "metadata": { + "description": "Required. The list of the event hub namespaces with its configurations to be created." + } + }, + "namespaceAuthorizationRules": { + "type": "array", + "items": { + "$ref": "#/definitions/authorizationRulesType" + }, + "defaultValue": [], + "metadata": { + "description": "Optional. Authorization Rules for the Event Hub Namespace." + } + }, + "namespaceRoleAssignments": { + "type": "array", + "items": { + "$ref": "#/definitions/namespaceRoleAssignmentsType" + }, + "defaultValue": [], + "metadata": { + "description": "Optional. Role assignments for the namespace." + } + }, + "namespaceDisasterRecoveryConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/namespaceDisasterRecoveryConfigsType" + }, + "defaultValue": [], + "metadata": { + "description": "Optional. The disaster recovery config for the namespace." + } + }, + "namespaceDiagnosticSettings": { + "type": "array", + "items": { + "$ref": "#/definitions/namespaceDiagnosticSettingsType" + }, + "defaultValue": [], + "metadata": { + "description": "Optional. The Diagnostics Settings config for the namespace." + } + }, + "eventHubs": { + "type": "array", + "items": { + "$ref": "#/definitions/eventHubsType" + }, + "defaultValue": [], + "metadata": { + "description": "Optional. Name for the eventhub with its all configurations to be created." + } + }, + "eventHubAuthorizationRules": { + "type": "array", + "items": { + "$ref": "#/definitions/authorizationRulesType" + }, + "defaultValue": [], + "metadata": { + "description": "Optional. Authorization Rules for the Event Hub ." + } + }, + "eventHubConsumerGroups": { + "type": "array", + "items": { + "$ref": "#/definitions/eventHubConsumerGroupsType" + }, + "defaultValue": [], + "metadata": { + "description": "Optional. consumer groups for the Event Hub ." + } + }, + "namespacePrivateEndpoints": { + "type": "array", + "items": { + "$ref": "#/definitions/privateEndpointType" + }, + "defaultValue": [], + "metadata": { + "description": "Private Endpoints that should be created for Azure EventHub Namespaces." + } + } + }, + "resources": { + "cluster": { + "condition": "[not(equals(parameters('clusterName'), 'null'))]", + "type": "Microsoft.EventHub/clusters", + "apiVersion": "2022-10-01-preview", + "name": "[parameters('clusterName')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "sku": { + "name": "Dedicated", + "capacity": "[parameters('clusterCapacity')]" + } + }, + "evhns": { + "copy": { + "name": "evhns", + "count": "[length(parameters('namespaces'))]" + }, + "type": "Microsoft.EventHub/namespaces", + "apiVersion": "2022-10-01-preview", + "name": "[parameters('namespaces')[copyIndex()].name]", + "location": "[parameters('location')]", + "sku": { + "name": "[coalesce(tryGet(parameters('namespaces')[copyIndex()], 'sku'), 'Standard')]", + "capacity": "[coalesce(tryGet(parameters('namespaces')[copyIndex()], 'capacity'), 1)]" + }, + "properties": { + "disableLocalAuth": "[coalesce(tryGet(parameters('namespaces')[copyIndex()], 'disableLocalAuth'), false())]", + "kafkaEnabled": "[coalesce(tryGet(parameters('namespaces')[copyIndex()], 'kafkaEnabled'), true())]", + "isAutoInflateEnabled": "[coalesce(tryGet(parameters('namespaces')[copyIndex()], 'isAutoInflateEnabled'), false())]", + "maximumThroughputUnits": "[coalesce(tryGet(parameters('namespaces')[copyIndex()], 'maximumThroughputUnits'), 0)]", + "zoneRedundant": "[coalesce(tryGet(parameters('namespaces')[copyIndex()], 'zoneRedundant'), false())]", + "clusterArmId": "[if(not(equals(parameters('clusterName'), 'null')), resourceId('Microsoft.EventHub/clusters', parameters('clusterName')), null())]", + "minimumTlsVersion": "[coalesce(tryGet(parameters('namespaces')[copyIndex()], 'minimumTlsVersion'), '1.2')]", + "publicNetworkAccess": "[coalesce(tryGet(parameters('namespaces')[copyIndex()], 'publicNetworkAccess'), 'Enabled')]" + }, + "tags": "[parameters('tags')]", + "dependsOn": [ + "cluster" + ] + }, + "evhns_authorizationRules": { + "copy": { + "name": "evhns_authorizationRules", + "count": "[length(parameters('namespaceAuthorizationRules'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-evhns-authrule-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[parameters('namespaceAuthorizationRules')[copyIndex()].name]" + }, + "rights": { + "value": "[parameters('namespaceAuthorizationRules')[copyIndex()].rights]" + }, + "namespaceName": { + "value": "[parameters('namespaceAuthorizationRules')[copyIndex()].namespaceName]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "1.10-experimental", + "contentVersion": "1.0.0.0", + "metadata": { + "_EXPERIMENTAL_WARNING": "Symbolic name support in ARM is experimental, and should be enabled for testing purposes only. Do not enable this setting for any production usage, or you may be unexpectedly broken at any time!", + "_generator": { + "name": "bicep", + "version": "0.19.5.34762", + "templateHash": "16560230268819578887" + } + }, + "parameters": { + "namespaceName": { + "type": "string" + }, + "name": { + "type": "string" + }, + "rights": { + "type": "array" + } + }, + "resources": { + "namespace": { + "existing": true, + "type": "Microsoft.EventHub/namespaces", + "apiVersion": "2022-10-01-preview", + "name": "[parameters('namespaceName')]" + }, + "namespaceAuthorizationRule": { + "type": "Microsoft.EventHub/namespaces/authorizationRules", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}', parameters('namespaceName'), parameters('name'))]", + "properties": { + "rights": "[parameters('rights')]" + } + } + } + } + }, + "dependsOn": [ + "evhns" + ] + }, + "evhns_roleAssignments": { + "copy": { + "name": "evhns_roleAssignments", + "count": "[length(parameters('namespaceRoleAssignments'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-evhns-role-{1}', deployment().name, copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "roleName": { + "value": "[coalesce(tryGet(parameters('namespaceRoleAssignments')[copyIndex()], 'name'), '')]" + }, + "description": { + "value": "[coalesce(tryGet(parameters('namespaceRoleAssignments')[copyIndex()], 'description'), '')]" + }, + "principalIds": { + "value": "[parameters('namespaceRoleAssignments')[copyIndex()].principalIds]" + }, + "principalType": { + "value": "[coalesce(tryGet(parameters('namespaceRoleAssignments')[copyIndex()], 'principalType'), '')]" + }, + "roleDefinitionIdOrName": { + "value": "[parameters('namespaceRoleAssignments')[copyIndex()].roleDefinitionIdOrName]" + }, + "namespaceName": { + "value": "[parameters('namespaceRoleAssignments')[copyIndex()].namespaceName]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "1.10-experimental", + "contentVersion": "1.0.0.0", + "metadata": { + "_EXPERIMENTAL_WARNING": "Symbolic name support in ARM is experimental, and should be enabled for testing purposes only. Do not enable this setting for any production usage, or you may be unexpectedly broken at any time!", + "_generator": { + "name": "bicep", + "version": "0.19.5.34762", + "templateHash": "10570742932814464407" + } + }, + "parameters": { + "roleName": { + "type": "string" + }, + "description": { + "type": "string" + }, + "principalIds": { + "type": "array" + }, + "roleDefinitionIdOrName": { + "type": "string" + }, + "principalType": { + "type": "string" + }, + "namespaceName": { + "type": "string" + } + }, + "variables": { + "builtInRoleNames": { + "Azure Event Hubs Data Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f526a384-b230-433a-b45c-95f59c4a2dec')]", + "Azure Event Hubs Data Receiver": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a638d3c7-ab3a-418d-83e6-5f17a39d4fde')]", + "Azure Event Hubs Data Sender": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2b629674-e913-4c01-ae53-ef4638d8f975')]", + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", + "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", + "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", + "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", + "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", + "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", + "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "Schema Registry Contributor (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5dffeca3-4936-4216-b2bc-10343a5abb25')]", + "Schema Registry Reader (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2c56ea50-c6b3-40a6-83c0-9d98858bc7d2')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "namespace": { + "existing": true, + "type": "Microsoft.EventHub/namespaces", + "apiVersion": "2022-10-01-preview", + "name": "[parameters('namespaceName')]" + }, + "roleAssignment": { + "copy": { + "name": "roleAssignment", + "count": "[length(parameters('principalIds'))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.EventHub/namespaces/{0}', parameters('namespaceName'))]", + "name": "[guid(parameters('roleName'), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", + "properties": { + "description": "[parameters('description')]", + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], subscriptionResourceId('Microsoft.Authorization/roleDefinitions', parameters('roleDefinitionIdOrName')))]", + "principalId": "[parameters('principalIds')[copyIndex()]]", + "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]" + } + } + } + } + }, + "dependsOn": [ + "evhns" + ] + }, + "evhns_disasterRecoveryConfigs": { + "copy": { + "name": "evhns_disasterRecoveryConfigs", + "count": "[length(parameters('namespaceDisasterRecoveryConfigs'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-evhns-drconfig-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[parameters('namespaceDisasterRecoveryConfigs')[copyIndex()].name]" + }, + "partnerNamespaceId": { + "value": "[parameters('namespaceDisasterRecoveryConfigs')[copyIndex()].partnerNamespaceId]" + }, + "namespaceName": { + "value": "[parameters('namespaceDisasterRecoveryConfigs')[copyIndex()].namespaceName]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "1.10-experimental", + "contentVersion": "1.0.0.0", + "metadata": { + "_EXPERIMENTAL_WARNING": "Symbolic name support in ARM is experimental, and should be enabled for testing purposes only. Do not enable this setting for any production usage, or you may be unexpectedly broken at any time!", + "_generator": { + "name": "bicep", + "version": "0.19.5.34762", + "templateHash": "14264603254199121226" + } + }, + "parameters": { + "namespaceName": { + "type": "string" + }, + "name": { + "type": "string" + }, + "partnerNamespaceId": { + "type": "string", + "defaultValue": "" + } + }, + "resources": { + "namespace": { + "existing": true, + "type": "Microsoft.EventHub/namespaces", + "apiVersion": "2022-10-01-preview", + "name": "[parameters('namespaceName')]" + }, + "disasterRecoveryConfig": { + "type": "Microsoft.EventHub/namespaces/disasterRecoveryConfigs", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}', parameters('namespaceName'), parameters('name'))]", + "properties": { + "partnerNamespace": "[parameters('partnerNamespaceId')]", + "alternateName": "alternateName" + } + } + } + } + }, + "dependsOn": [ + "evhns" + ] + }, + "evh": { + "copy": { + "name": "evh", + "count": "[length(parameters('eventHubs'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-evh-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "namespaceName": { + "value": "[parameters('eventHubs')[copyIndex()].namespaceName]" + }, + "name": { + "value": "[parameters('eventHubs')[copyIndex()].name]" + }, + "messageRetentionInDays": { + "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'messageRetentionInDays'), 1)]" + }, + "partitionCount": { + "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'partitionCount'), 2)]" + }, + "status": { + "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'status'), 'Active')]" + }, + "captureDescriptionEnabled": { + "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'captureDescriptionEnabled'), false())]" + }, + "captureDescriptionEncoding": { + "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'captureDescriptionEncoding'), 'Avro')]" + }, + "captureDescriptionIntervalInSeconds": { + "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'captureDescriptionIntervalInSeconds'), 300)]" + }, + "captureDescriptionSizeLimitInBytes": { + "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'captureDescriptionSizeLimitInBytes'), 314572800)]" + }, + "captureDescriptionSkipEmptyArchives": { + "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'captureDescriptionSkipEmptyArchives'), false())]" + }, + "captureDescriptionDestinationName": { + "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'captureDescriptionDestinationName'), 'EventHubArchive.AzureBlockBlob')]" + }, + "captureDescriptionDestinationArchiveNameFormat": { + "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'captureDescriptionDestinationArchiveNameFormat'), '{Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}')]" + }, + "captureDescriptionDestinationBlobContainer": { + "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'captureDescriptionDestinationBlobContainer'), '')]" + }, + "captureDescriptionDestinationStorageAccountResourceId": { + "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'captureDescriptionDestinationStorageAccountResourceId'), '')]" + }, + "captureDescriptionDestinationdataLakeAccountName": { + "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'captureDescriptionDestinationdataLakeAccountName'), '')]" + }, + "captureDescriptionDestinationdataLakeFolderPath": { + "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'captureDescriptionDestinationdataLakeFolderPath'), '')]" + }, + "captureDescriptionDestinationdataLakeSubscriptionId": { + "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'captureDescriptionDestinationdataLakeSubscriptionId'), '')]" + }, + "roleAssignments": { + "value": "[coalesce(tryGet(parameters('eventHubs')[copyIndex()], 'roleAssignments'), createArray())]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "1.10-experimental", + "contentVersion": "1.0.0.0", + "metadata": { + "_EXPERIMENTAL_WARNING": "Symbolic name support in ARM is experimental, and should be enabled for testing purposes only. Do not enable this setting for any production usage, or you may be unexpectedly broken at any time!", + "_generator": { + "name": "bicep", + "version": "0.19.5.34762", + "templateHash": "168464517665905008" + } + }, + "parameters": { + "namespaceName": { + "type": "string" + }, + "name": { + "type": "string" + }, + "messageRetentionInDays": { + "type": "int" + }, + "partitionCount": { + "type": "int" + }, + "captureDescriptionEnabled": { + "type": "bool" + }, + "captureDescriptionDestinationName": { + "type": "string" + }, + "captureDescriptionDestinationArchiveNameFormat": { + "type": "string" + }, + "captureDescriptionDestinationBlobContainer": { + "type": "string" + }, + "captureDescriptionDestinationStorageAccountResourceId": { + "type": "string" + }, + "captureDescriptionDestinationdataLakeAccountName": { + "type": "string" + }, + "captureDescriptionDestinationdataLakeFolderPath": { + "type": "string" + }, + "captureDescriptionDestinationdataLakeSubscriptionId": { + "type": "string" + }, + "captureDescriptionEncoding": { + "type": "string" + }, + "captureDescriptionIntervalInSeconds": { + "type": "int" + }, + "captureDescriptionSizeLimitInBytes": { + "type": "int" + }, + "captureDescriptionSkipEmptyArchives": { + "type": "bool" + }, + "roleAssignments": { + "type": "array" + }, + "status": { + "type": "string" + } + }, + "variables": { + "eventHubPropertiesSimple": { + "messageRetentionInDays": "[parameters('messageRetentionInDays')]", + "partitionCount": "[parameters('partitionCount')]", + "status": "[parameters('status')]" + }, + "eventHubPropertiesWithCapture": { + "messageRetentionInDays": "[parameters('messageRetentionInDays')]", + "partitionCount": "[parameters('partitionCount')]", + "captureDescription": { + "destination": { + "name": "[parameters('captureDescriptionDestinationName')]", + "properties": { + "archiveNameFormat": "[parameters('captureDescriptionDestinationArchiveNameFormat')]", + "blobContainer": "[parameters('captureDescriptionDestinationBlobContainer')]", + "storageAccountResourceId": "[parameters('captureDescriptionDestinationStorageAccountResourceId')]", + "dataLakeAccountName": "[parameters('captureDescriptionDestinationdataLakeAccountName')]", + "dataLakeFolderPath": "[parameters('captureDescriptionDestinationdataLakeFolderPath')]", + "dataLakeSubscriptionId": "[parameters('captureDescriptionDestinationdataLakeSubscriptionId')]" + } + }, + "enabled": "[parameters('captureDescriptionEnabled')]", + "encoding": "[parameters('captureDescriptionEncoding')]", + "intervalInSeconds": "[parameters('captureDescriptionIntervalInSeconds')]", + "sizeLimitInBytes": "[parameters('captureDescriptionSizeLimitInBytes')]", + "skipEmptyArchives": "[parameters('captureDescriptionSkipEmptyArchives')]", + "status": "[parameters('status')]" + } + } + }, + "resources": { + "namespace": { + "existing": true, + "type": "Microsoft.EventHub/namespaces", + "apiVersion": "2022-10-01-preview", + "name": "[parameters('namespaceName')]" + }, + "eventHub": { + "type": "Microsoft.EventHub/namespaces/eventhubs", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}', parameters('namespaceName'), parameters('name'))]", + "properties": "[if(parameters('captureDescriptionEnabled'), variables('eventHubPropertiesWithCapture'), variables('eventHubPropertiesSimple'))]" + }, + "eventHub_roleAssignments": { + "copy": { + "name": "eventHub_roleAssignments", + "count": "[length(parameters('roleAssignments'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-evh-role-{1}', deployment().name, copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "description": { + "value": "[coalesce(tryGet(parameters('roleAssignments')[copyIndex()], 'description'), '')]" + }, + "principalIds": { + "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" + }, + "principalType": { + "value": "[coalesce(tryGet(parameters('roleAssignments')[copyIndex()], 'principalType'), '')]" + }, + "roleDefinitionIdOrName": { + "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" + }, + "roleName": { + "value": "[coalesce(tryGet(parameters('roleAssignments')[copyIndex()], 'name'), '')]" + }, + "namespaceName": { + "value": "[parameters('namespaceName')]" + }, + "eventHubName": { + "value": "[parameters('name')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "1.10-experimental", + "contentVersion": "1.0.0.0", + "metadata": { + "_EXPERIMENTAL_WARNING": "Symbolic name support in ARM is experimental, and should be enabled for testing purposes only. Do not enable this setting for any production usage, or you may be unexpectedly broken at any time!", + "_generator": { + "name": "bicep", + "version": "0.19.5.34762", + "templateHash": "14896444724696374233" + } + }, + "parameters": { + "roleName": { + "type": "string" + }, + "description": { + "type": "string" + }, + "principalIds": { + "type": "array" + }, + "roleDefinitionIdOrName": { + "type": "string" + }, + "principalType": { + "type": "string" + }, + "namespaceName": { + "type": "string" + }, + "eventHubName": { + "type": "string" + } + }, + "variables": { + "builtInRoleNames": { + "Azure Event Hubs Data Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f526a384-b230-433a-b45c-95f59c4a2dec')]", + "Azure Event Hubs Data Receiver": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a638d3c7-ab3a-418d-83e6-5f17a39d4fde')]", + "Azure Event Hubs Data Sender": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2b629674-e913-4c01-ae53-ef4638d8f975')]", + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", + "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", + "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", + "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", + "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", + "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", + "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "Schema Registry Contributor (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5dffeca3-4936-4216-b2bc-10343a5abb25')]", + "Schema Registry Reader (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2c56ea50-c6b3-40a6-83c0-9d98858bc7d2')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "namespace": { + "existing": true, + "type": "Microsoft.EventHub/namespaces", + "apiVersion": "2022-10-01-preview", + "name": "[parameters('namespaceName')]" + }, + "eventHub": { + "existing": true, + "type": "Microsoft.EventHub/namespaces/eventhubs", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}', parameters('namespaceName'), parameters('eventHubName'))]" + }, + "roleAssignment": { + "copy": { + "name": "roleAssignment", + "count": "[length(parameters('principalIds'))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.EventHub/namespaces/{0}/eventhubs/{1}', parameters('namespaceName'), parameters('eventHubName'))]", + "name": "[guid(parameters('roleName'), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", + "properties": { + "description": "[parameters('description')]", + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], subscriptionResourceId('Microsoft.Authorization/roleDefinitions', parameters('roleDefinitionIdOrName')))]", + "principalId": "[parameters('principalIds')[copyIndex()]]", + "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]" + } + } + } + } + } + } + } + } + }, + "dependsOn": [ + "evhns" + ] + }, + "evh_authorizationRules": { + "copy": { + "name": "evh_authorizationRules", + "count": "[length(parameters('eventHubAuthorizationRules'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-evh-authrule-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "namespaceName": { + "value": "[parameters('eventHubAuthorizationRules')[copyIndex()].namespaceName]" + }, + "eventHubName": { + "value": "[parameters('eventHubAuthorizationRules')[copyIndex()].eventHubName]" + }, + "name": { + "value": "[parameters('eventHubAuthorizationRules')[copyIndex()].name]" + }, + "rights": { + "value": "[parameters('eventHubAuthorizationRules')[copyIndex()].rights]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "1.10-experimental", + "contentVersion": "1.0.0.0", + "metadata": { + "_EXPERIMENTAL_WARNING": "Symbolic name support in ARM is experimental, and should be enabled for testing purposes only. Do not enable this setting for any production usage, or you may be unexpectedly broken at any time!", + "_generator": { + "name": "bicep", + "version": "0.19.5.34762", + "templateHash": "3736679263237493437" + } + }, + "parameters": { + "namespaceName": { + "type": "string" + }, + "eventHubName": { + "type": "string" + }, + "name": { + "type": "string" + }, + "rights": { + "type": "array" + } + }, + "resources": { + "namespace": { + "existing": true, + "type": "Microsoft.EventHub/namespaces", + "apiVersion": "2022-10-01-preview", + "name": "[parameters('namespaceName')]" + }, + "eventhub": { + "existing": true, + "type": "Microsoft.EventHub/namespaces/eventhubs", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}', parameters('namespaceName'), parameters('eventHubName'))]" + }, + "eventHubAuthorizationRule": { + "type": "Microsoft.EventHub/namespaces/eventhubs/authorizationRules", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}/{2}', parameters('namespaceName'), parameters('eventHubName'), parameters('name'))]", + "properties": { + "rights": "[parameters('rights')]" + } + } + } + } + }, + "dependsOn": [ + "evh" + ] + }, + "evh_consumerGroups": { + "copy": { + "name": "evh_consumerGroups", + "count": "[length(parameters('eventHubConsumerGroups'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-evh-cg-{1}', deployment().name, copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "namespaceName": { + "value": "[parameters('eventHubConsumerGroups')[copyIndex()].namespaceName]" + }, + "eventHubName": { + "value": "[parameters('eventHubConsumerGroups')[copyIndex()].eventHubName]" + }, + "name": { + "value": "[parameters('eventHubConsumerGroups')[copyIndex()].name]" + }, + "userMetadata": { + "value": "[coalesce(tryGet(parameters('eventHubConsumerGroups')[copyIndex()], 'userMetadata'), '')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "1.10-experimental", + "contentVersion": "1.0.0.0", + "metadata": { + "_EXPERIMENTAL_WARNING": "Symbolic name support in ARM is experimental, and should be enabled for testing purposes only. Do not enable this setting for any production usage, or you may be unexpectedly broken at any time!", + "_generator": { + "name": "bicep", + "version": "0.19.5.34762", + "templateHash": "250162708936612016" + } + }, + "parameters": { + "namespaceName": { + "type": "string" + }, + "eventHubName": { + "type": "string" + }, + "name": { + "type": "string" + }, + "userMetadata": { + "type": "string" + } + }, + "resources": { + "namespace::eventhub": { + "existing": true, + "type": "Microsoft.EventHub/namespaces/eventhubs", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}', parameters('namespaceName'), parameters('eventHubName'))]" + }, + "namespace": { + "existing": true, + "type": "Microsoft.EventHub/namespaces", + "apiVersion": "2022-10-01-preview", + "name": "[parameters('namespaceName')]" + }, + "consumerGroup": { + "type": "Microsoft.EventHub/namespaces/eventhubs/consumergroups", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}/{2}', parameters('namespaceName'), parameters('eventHubName'), parameters('name'))]", + "properties": { + "userMetadata": "[if(not(empty(parameters('userMetadata'))), parameters('userMetadata'), null())]" + } + } + } + } + }, + "dependsOn": [ + "evh" + ] + }, + "evhns_diagnosticSettings": { + "copy": { + "name": "evhns_diagnosticSettings", + "count": "[length(parameters('namespaceDiagnosticSettings'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-evhns-diagnosticSettings-{1}', deployment().name, copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "namespaceName": { + "value": "[parameters('namespaceDiagnosticSettings')[copyIndex()].namespaceName]" + }, + "name": { + "value": "[parameters('namespaceDiagnosticSettings')[copyIndex()].name]" + }, + "storageAccountId": { + "value": "[coalesce(tryGet(parameters('namespaceDiagnosticSettings')[copyIndex()], 'storageAccountId'), '')]" + }, + "workspaceId": { + "value": "[coalesce(tryGet(parameters('namespaceDiagnosticSettings')[copyIndex()], 'workspaceId'), '')]" + }, + "eventHubAuthorizationRuleId": { + "value": "[coalesce(tryGet(parameters('namespaceDiagnosticSettings')[copyIndex()], 'eventHubAuthorizationRuleId'), '')]" + }, + "eventHubName": { + "value": "[coalesce(tryGet(parameters('namespaceDiagnosticSettings')[copyIndex()], 'eventHubName'), '')]" + }, + "metricsSettings": { + "value": "[coalesce(tryGet(parameters('namespaceDiagnosticSettings')[copyIndex()], 'metricsSettings'), createArray())]" + }, + "logsSettings": { + "value": "[coalesce(tryGet(parameters('namespaceDiagnosticSettings')[copyIndex()], 'logsSettings'), createArray())]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "1.10-experimental", + "contentVersion": "1.0.0.0", + "metadata": { + "_EXPERIMENTAL_WARNING": "Symbolic name support in ARM is experimental, and should be enabled for testing purposes only. Do not enable this setting for any production usage, or you may be unexpectedly broken at any time!", + "_generator": { + "name": "bicep", + "version": "0.19.5.34762", + "templateHash": "1483698508983111743" + } + }, + "parameters": { + "namespaceName": { + "type": "string" + }, + "name": { + "type": "string" + }, + "storageAccountId": { + "type": "string" + }, + "workspaceId": { + "type": "string" + }, + "eventHubAuthorizationRuleId": { + "type": "string" + }, + "eventHubName": { + "type": "string" + }, + "metricsSettings": { + "type": "array" + }, + "logsSettings": { + "type": "array" + } + }, + "resources": { + "namespace": { + "existing": true, + "type": "Microsoft.EventHub/namespaces", + "apiVersion": "2022-10-01-preview", + "name": "[parameters('namespaceName')]" + }, + "namespace_diagnosticSettings": { + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.EventHub/namespaces/{0}', parameters('namespaceName'))]", + "name": "[parameters('name')]", + "properties": { + "storageAccountId": "[if(not(empty(parameters('storageAccountId'))), parameters('storageAccountId'), null())]", + "workspaceId": "[if(not(empty(parameters('workspaceId'))), parameters('workspaceId'), null())]", + "eventHubAuthorizationRuleId": "[if(not(empty(parameters('eventHubAuthorizationRuleId'))), parameters('eventHubAuthorizationRuleId'), null())]", + "eventHubName": "[if(not(empty(parameters('eventHubName'))), parameters('eventHubName'), null())]", + "metrics": "[parameters('metricsSettings')]", + "logs": "[parameters('logsSettings')]" + } + } + } + } + }, + "dependsOn": [ + "evhns" + ] + }, + "evhns_privateEndpoints": { + "copy": { + "name": "evhns_privateEndpoints", + "count": "[length(parameters('namespacePrivateEndpoints'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-evhns-pep-{1}', uniqueString(deployment().name), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[parameters('namespacePrivateEndpoints')[copyIndex()].name]" + }, + "namespaceName": { + "value": "[parameters('namespacePrivateEndpoints')[copyIndex()].namespaceName]" + }, + "location": { + "value": "[parameters('location')]" + }, + "groupIds": { + "value": "[coalesce(tryGet(parameters('namespacePrivateEndpoints')[copyIndex()], 'groupIds'), createArray('namespace'))]" + }, + "subnetId": { + "value": "[parameters('namespacePrivateEndpoints')[copyIndex()].subnetId]" + }, + "privateDnsZoneId": { + "value": "[coalesce(tryGet(parameters('namespacePrivateEndpoints')[copyIndex()], 'privateDnsZoneId'), '')]" + }, + "tags": { + "value": "[parameters('tags')]" + }, + "manualApprovalEnabled": { + "value": "[coalesce(tryGet(parameters('namespacePrivateEndpoints')[copyIndex()], 'manualApprovalEnabled'), false())]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "1.10-experimental", + "contentVersion": "1.0.0.0", + "metadata": { + "_EXPERIMENTAL_WARNING": "Symbolic name support in ARM is experimental, and should be enabled for testing purposes only. Do not enable this setting for any production usage, or you may be unexpectedly broken at any time!", + "_generator": { + "name": "bicep", + "version": "0.19.5.34762", + "templateHash": "11271554108121564487" + } + }, + "parameters": { + "location": { + "type": "string" + }, + "tags": { + "type": "object" + }, + "manualApprovalEnabled": { + "type": "bool" + }, + "namespaceName": { + "type": "string" + }, + "name": { + "type": "string" + }, + "groupIds": { + "type": "array" + }, + "subnetId": { + "type": "string" + }, + "privateDnsZoneId": { + "type": "string" + } + }, + "resources": { + "privateEndpoint::privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneId')))]", + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2022-05-01", + "name": "[format('{0}/{1}', parameters('name'), 'default')]", + "properties": { + "privateDnsZoneConfigs": [ + { + "name": "default", + "properties": { + "privateDnsZoneId": "[parameters('privateDnsZoneId')]" + } + } + ] + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "namespace": { + "existing": true, + "type": "Microsoft.EventHub/namespaces", + "apiVersion": "2022-10-01-preview", + "name": "[parameters('namespaceName')]" + }, + "privateEndpoint": { + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2022-05-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "privateLinkServiceConnections": "[if(parameters('manualApprovalEnabled'), null(), createArray(createObject('name', parameters('name'), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.EventHub/namespaces', parameters('namespaceName')), 'groupIds', if(not(empty(parameters('groupIds'))), parameters('groupIds'), null())))))]", + "manualPrivateLinkServiceConnections": "[if(parameters('manualApprovalEnabled'), createArray(createObject('name', parameters('name'), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.EventHub/namespaces', parameters('namespaceName')), 'groupIds', if(not(empty(parameters('groupIds'))), parameters('groupIds'), null())))), null())]", + "subnet": { + "id": "[parameters('subnetId')]" + } + } + } + } + } + }, + "dependsOn": [ + "evhns" + ] + } + }, + "outputs": { + "eventHubNamespaceNames": { + "type": "array", + "metadata": { + "description": "Azure Event Hub namespace names." + }, + "copy": { + "count": "[length(parameters('namespaces'))]", + "input": "[parameters('namespaces')[copyIndex()].name]" + } + }, + "eventHubNamespaceResourceIds": { + "type": "array", + "metadata": { + "description": "Azure Event Hub namespace resource Ids." + }, + "copy": { + "count": "[length(parameters('namespaces'))]", + "input": "[resourceId('Microsoft.EventHub/namespaces', parameters('namespaces')[copyIndex()].name)]" + } + } + } +} \ No newline at end of file diff --git a/modules/compute/event-hub/modules/authorizationRule.bicep b/modules/compute/event-hub/modules/authorizationRule.bicep new file mode 100644 index 0000000000..62e4dc4e07 --- /dev/null +++ b/modules/compute/event-hub/modules/authorizationRule.bicep @@ -0,0 +1,15 @@ +param namespaceName string +param name string +param rights array + +resource namespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' existing = { + name: namespaceName +} + +resource namespaceAuthorizationRule 'Microsoft.EventHub/namespaces/authorizationRules@2022-10-01-preview' = { + name: name + parent: namespace + properties: { + rights: rights + } +} diff --git a/modules/compute/event-hub/modules/diagnosticSetting.bicep b/modules/compute/event-hub/modules/diagnosticSetting.bicep new file mode 100644 index 0000000000..636eeb9654 --- /dev/null +++ b/modules/compute/event-hub/modules/diagnosticSetting.bicep @@ -0,0 +1,25 @@ +param namespaceName string +param name string +param storageAccountId string +param workspaceId string +param eventHubAuthorizationRuleId string +param eventHubName string +param metricsSettings array +param logsSettings array + +resource namespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' existing = { + name: namespaceName +} + +resource namespace_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = { + name: name + properties: { + storageAccountId: !empty(storageAccountId) ? storageAccountId : null + workspaceId: !empty(workspaceId) ? workspaceId : null + eventHubAuthorizationRuleId: !empty(eventHubAuthorizationRuleId) ? eventHubAuthorizationRuleId : null + eventHubName: !empty(eventHubName) ? eventHubName : null + metrics: metricsSettings + logs: logsSettings + } + scope: namespace +} diff --git a/modules/compute/event-hub/modules/disasterRecoveryConfig.bicep b/modules/compute/event-hub/modules/disasterRecoveryConfig.bicep new file mode 100644 index 0000000000..f330977228 --- /dev/null +++ b/modules/compute/event-hub/modules/disasterRecoveryConfig.bicep @@ -0,0 +1,16 @@ +param namespaceName string +param name string +param partnerNamespaceId string = '' + +resource namespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' existing = { + name: namespaceName +} + +resource disasterRecoveryConfig 'Microsoft.EventHub/namespaces/disasterRecoveryConfigs@2022-10-01-preview' = { + name: name + parent: namespace + properties: { + partnerNamespace: partnerNamespaceId + alternateName: 'alternateName' + } +} diff --git a/modules/compute/event-hub/modules/eventHub/authorizationRule.bicep b/modules/compute/event-hub/modules/eventHub/authorizationRule.bicep new file mode 100644 index 0000000000..36d3b11c6b --- /dev/null +++ b/modules/compute/event-hub/modules/eventHub/authorizationRule.bicep @@ -0,0 +1,21 @@ +param namespaceName string +param eventHubName string +param name string +param rights array + +resource namespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' existing = { + name: namespaceName +} + +resource eventhub 'Microsoft.EventHub/namespaces/eventHubs@2022-10-01-preview' existing = { + name: eventHubName + parent: namespace +} + +resource eventHubAuthorizationRule 'Microsoft.EventHub/namespaces/eventhubs/authorizationRules@2022-10-01-preview' = { + name: name + parent: eventhub + properties: { + rights: rights + } +} diff --git a/modules/compute/event-hub/modules/eventHub/consumerGroup.bicep b/modules/compute/event-hub/modules/eventHub/consumerGroup.bicep new file mode 100644 index 0000000000..6d55eeeae0 --- /dev/null +++ b/modules/compute/event-hub/modules/eventHub/consumerGroup.bicep @@ -0,0 +1,20 @@ +param namespaceName string +param eventHubName string +param name string +param userMetadata string + +resource namespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' existing = { + name: namespaceName + + resource eventhub 'eventHubs@2022-10-01-preview' existing = { + name: eventHubName + } +} + +resource consumerGroup 'Microsoft.EventHub/namespaces/eventhubs/consumergroups@2022-10-01-preview' = { + name: name + parent: namespace::eventhub + properties: { + userMetadata: !empty(userMetadata) ? userMetadata : null + } +} diff --git a/modules/compute/event-hub/modules/eventHub/eventHub.bicep b/modules/compute/event-hub/modules/eventHub/eventHub.bicep new file mode 100644 index 0000000000..dc4b4c04b9 --- /dev/null +++ b/modules/compute/event-hub/modules/eventHub/eventHub.bicep @@ -0,0 +1,71 @@ +param namespaceName string +param name string +param messageRetentionInDays int +param partitionCount int +param captureDescriptionEnabled bool +param captureDescriptionDestinationName string +param captureDescriptionDestinationArchiveNameFormat string +param captureDescriptionDestinationBlobContainer string +param captureDescriptionDestinationStorageAccountResourceId string +param captureDescriptionDestinationdataLakeAccountName string +param captureDescriptionDestinationdataLakeFolderPath string +param captureDescriptionDestinationdataLakeSubscriptionId string +param captureDescriptionEncoding string +param captureDescriptionIntervalInSeconds int +param captureDescriptionSizeLimitInBytes int +param captureDescriptionSkipEmptyArchives bool +param roleAssignments array +param status string + +var eventHubPropertiesSimple = { + messageRetentionInDays: messageRetentionInDays + partitionCount: partitionCount + status: status +} + +var eventHubPropertiesWithCapture = { + messageRetentionInDays: messageRetentionInDays + partitionCount: partitionCount + captureDescription: { + destination: { + name: captureDescriptionDestinationName + properties: { + archiveNameFormat: captureDescriptionDestinationArchiveNameFormat + blobContainer: captureDescriptionDestinationBlobContainer + storageAccountResourceId: captureDescriptionDestinationStorageAccountResourceId + dataLakeAccountName: captureDescriptionDestinationdataLakeAccountName + dataLakeFolderPath: captureDescriptionDestinationdataLakeFolderPath + dataLakeSubscriptionId: captureDescriptionDestinationdataLakeSubscriptionId + } + } + enabled: captureDescriptionEnabled + encoding: captureDescriptionEncoding + intervalInSeconds: captureDescriptionIntervalInSeconds + sizeLimitInBytes: captureDescriptionSizeLimitInBytes + skipEmptyArchives: captureDescriptionSkipEmptyArchives + status: status + } +} + +resource namespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' existing = { + name: namespaceName +} + +resource eventHub 'Microsoft.EventHub/namespaces/eventhubs@2022-10-01-preview' = { + name: name + parent: namespace + properties: captureDescriptionEnabled ? eventHubPropertiesWithCapture : eventHubPropertiesSimple +} + +module eventHub_roleAssignments './roleAssignment.bicep' = [for (role, index) in roleAssignments: { + name: '${deployment().name}-evh-role-${index}' + params: { + description: role.?description ?? '' + principalIds: role.principalIds + principalType: role.?principalType ?? '' + roleDefinitionIdOrName: role.roleDefinitionIdOrName + roleName: role.?name ?? '' + namespaceName: namespaceName + eventHubName: name + } +}] diff --git a/modules/compute/event-hub/modules/eventHub/roleAssignment.bicep b/modules/compute/event-hub/modules/eventHub/roleAssignment.bicep new file mode 100644 index 0000000000..a4c605afd2 --- /dev/null +++ b/modules/compute/event-hub/modules/eventHub/roleAssignment.bicep @@ -0,0 +1,48 @@ +param roleName string +param description string +param principalIds array +param roleDefinitionIdOrName string +param principalType string +param namespaceName string +param eventHubName string + +var builtInRoleNames = { + 'Azure Event Hubs Data Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f526a384-b230-433a-b45c-95f59c4a2dec') + 'Azure Event Hubs Data Receiver': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a638d3c7-ab3a-418d-83e6-5f17a39d4fde') + 'Azure Event Hubs Data Sender': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2b629674-e913-4c01-ae53-ef4638d8f975') + Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') + 'Log Analytics Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293') + 'Log Analytics Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893') + 'Managed Application Contributor Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e') + 'Managed Application Operator Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae') + 'Managed Applications Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44') + 'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa') + 'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05') + Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') + Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + 'Resource Policy Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608') + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168') + 'Schema Registry Contributor (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5dffeca3-4936-4216-b2bc-10343a5abb25') + 'Schema Registry Reader (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2c56ea50-c6b3-40a6-83c0-9d98858bc7d2') + 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') +} + +resource namespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' existing = { + name: namespaceName +} + +resource eventHub 'Microsoft.EventHub/namespaces/eventhubs@2022-10-01-preview' existing = { + name: eventHubName + parent: namespace +} + +resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for principalId in principalIds: { + name: guid(roleName, principalId, roleDefinitionIdOrName) + properties: { + description: description + roleDefinitionId: contains(builtInRoleNames, roleDefinitionIdOrName) ? builtInRoleNames[roleDefinitionIdOrName] : subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionIdOrName) + principalId: principalId + principalType: !empty(principalType) ? any(principalType) : null + } + scope: eventHub +}] diff --git a/modules/compute/event-hub/modules/privateEndpoint.bicep b/modules/compute/event-hub/modules/privateEndpoint.bicep new file mode 100644 index 0000000000..ad0d2a7103 --- /dev/null +++ b/modules/compute/event-hub/modules/privateEndpoint.bicep @@ -0,0 +1,53 @@ +param location string +param tags object +param manualApprovalEnabled bool +param namespaceName string +param name string +param groupIds array +param subnetId string +param privateDnsZoneId string + +resource namespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' existing = { + name: namespaceName +} + +resource privateEndpoint 'Microsoft.Network/privateEndpoints@2022-05-01' = { + name: name + location: location + tags: tags + properties: { + privateLinkServiceConnections: manualApprovalEnabled ? null : [ + { + name: name + properties: { + privateLinkServiceId: namespace.id + groupIds: !empty(groupIds) ? groupIds : null + } + } + ] + manualPrivateLinkServiceConnections: manualApprovalEnabled ? [ + { + name: name + properties: { + privateLinkServiceId: namespace.id + groupIds: !empty(groupIds) ? groupIds : null + } + } + ] : null + subnet: { + id: subnetId + } + } + resource privateDnsZoneGroup 'privateDnsZoneGroups@2022-05-01' = if (!empty(privateDnsZoneId)) { + name: 'default' + properties: { + privateDnsZoneConfigs: [ { + name: 'default' + properties: { + privateDnsZoneId: privateDnsZoneId + } + } ] + } + } + +} diff --git a/modules/compute/event-hub/modules/roleAssignment.bicep b/modules/compute/event-hub/modules/roleAssignment.bicep new file mode 100644 index 0000000000..251520a79b --- /dev/null +++ b/modules/compute/event-hub/modules/roleAssignment.bicep @@ -0,0 +1,42 @@ +param roleName string +param description string +param principalIds array +param roleDefinitionIdOrName string +param principalType string +param namespaceName string + +var builtInRoleNames = { + 'Azure Event Hubs Data Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f526a384-b230-433a-b45c-95f59c4a2dec') + 'Azure Event Hubs Data Receiver': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a638d3c7-ab3a-418d-83e6-5f17a39d4fde') + 'Azure Event Hubs Data Sender': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2b629674-e913-4c01-ae53-ef4638d8f975') + Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') + 'Log Analytics Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293') + 'Log Analytics Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893') + 'Managed Application Contributor Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e') + 'Managed Application Operator Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae') + 'Managed Applications Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44') + 'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa') + 'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05') + Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') + Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + 'Resource Policy Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608') + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168') + 'Schema Registry Contributor (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5dffeca3-4936-4216-b2bc-10343a5abb25') + 'Schema Registry Reader (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2c56ea50-c6b3-40a6-83c0-9d98858bc7d2') + 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') +} + +resource namespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' existing = { + name: namespaceName +} + +resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for principalId in principalIds: { + name: guid(roleName, principalId, roleDefinitionIdOrName) + properties: { + description: description + roleDefinitionId: contains(builtInRoleNames, roleDefinitionIdOrName) ? builtInRoleNames[roleDefinitionIdOrName] : subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionIdOrName) + principalId: principalId + principalType: !empty(principalType) ? any(principalType) : null + } + scope: namespace +}] diff --git a/modules/compute/event-hub/test/main.test.bicep b/modules/compute/event-hub/test/main.test.bicep new file mode 100644 index 0000000000..9942af1400 --- /dev/null +++ b/modules/compute/event-hub/test/main.test.bicep @@ -0,0 +1,237 @@ +targetScope = 'resourceGroup' +param location string = 'eastus2' +var uniqueName = uniqueString(resourceGroup().id, deployment().name, location) +param serviceShort string = 'eventhub' + +// ============= // +// Prerequisites // +// ============= // + +module dependencies 'prereq.test.bicep' = { + name: 'test-prereq' + params: { + name: serviceShort + location: location + prefix: uniqueName + } +} + +// Test 01 - Standard SKU with cluster and Parameters, AuthorizationRules(namespace,eventHub), EventHuba, ConsumerGroups +module test_01 '../main.bicep' = { + name: 'test01-${uniqueName}' + params: { + location: location + namespaces: [ + { + name: 'test01-${uniqueName}-ns1' + capacity: 2 + isAutoInflateEnabled: true + maximumThroughputUnits: 6 + zoneRedundant: true + } + { + name: 'test01-${uniqueName}-ns2' + sku: 'Basic' + } + ] + namespaceAuthorizationRules: [ + { + name: 'test01-${uniqueName}-ns-authrule01' + rights: [ 'Listen', 'Manage', 'Send' ] + namespaceName: 'test01-${uniqueName}-ns1' + } + { + name: 'test01-${uniqueName}-ns-authrule02' + rights: [ 'Listen' ] + namespaceName: 'test01-${uniqueName}-ns1' + } + ] + eventHubs: [ + { + name: 'test01-${uniqueName}-evh1' + messageRetentionInDays: 4 + partitionCount: 4 + namespaceName: 'test01-${uniqueName}-ns1' + } + { + name: 'test01-${uniqueName}-evh2' + messageRetentionInDays: 7 + partitionCount: 2 + namespaceName: 'test01-${uniqueName}-ns1' + } + ] + eventHubAuthorizationRules: [ + { + name: 'test01-${uniqueName}-evh-rule01' + rights: [ 'Listen', 'Manage', 'Send' ] + namespaceName: 'test01-${uniqueName}-ns1' + eventHubName: 'test01-${uniqueName}-evh1' + } + ] + eventHubConsumerGroups: [ + { + name: 'test01-${uniqueName}-cg01' + namespaceName: 'test01-${uniqueName}-ns1' + eventHubName: 'test01-${uniqueName}-evh1' + } + ] + tags: { + tag1: 'tag1value' + tag2: 'tag2value' + } + } +} + +// Test 02 - Premium SKU - Role Assignments at namespace and eventHub scope +module test_02 '../main.bicep' = { + name: 'test02-${uniqueName}' + params: { + location: location + namespaces: [ + { + name: 'test02-${uniqueName}-ns' + sku: 'Premium' + capacity: 2 + zoneRedundant: true + } + ] + namespaceRoleAssignments: [ + { + name: 'test02-${uniqueName}-rol01' + description: 'Reader Role Assignment' + principalIds: [ dependencies.outputs.identityPrincipalIds[1] ] + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'f526a384-b230-433a-b45c-95f59c4a2dec' // Azure Event Hubs Data Owner + namespaceName: 'test02-${uniqueName}-ns' + } + ] + eventHubs: [ + { + name: 'test02-${uniqueName}-evh' + messageRetentionInDays: 1 + partitionCount: 1 + namespaceName: 'test02-${uniqueName}-ns' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Contributor' + description: 'Contributor Role Assignment' + principalIds: [ dependencies.outputs.identityPrincipalIds[0] ] + principalType: 'ServicePrincipal' + + } + ] + } + ] + } +} + +// Test 03 - Standard SKU - PrivateEndpoints, DiagnosticSettings with EventHub +module test_03 '../main.bicep' = { + name: 'test03-${uniqueName}' + params: { + location: location + namespaces: [ + { + name: 'test03-${uniqueName}-ns' + sku: 'Standard' + capacity: 4 + publicNetworkAccess: 'Disabled' + } + ] + namespacePrivateEndpoints: [ + { + name: 'endpoint1' + subnetId: dependencies.outputs.subnetIds[0] + namespaceName: 'test03-${uniqueName}-ns' + manualApprovalEnabled: true + } + { + name: 'endpoint2' + subnetId: dependencies.outputs.subnetIds[1] + privateDnsZoneId: dependencies.outputs.privateDNSZoneId + namespaceName: 'test03-${uniqueName}-ns' + } + ] + namespaceDiagnosticSettings: [ + { + name: 'test03-${uniqueName}-ds' + namespaceName: 'test03-${uniqueName}-ns' + eventHubAuthorizationRuleId: dependencies.outputs.authorizationRuleId + eventHubName: dependencies.outputs.eventHubName + metricsSettings: [ + { + category: 'AllMetrics' + timeGrain: 'PT1M' + enabled: true + retentionPolicy: { + days: 7 + enabled: true + } + } + ] + logsSettings: [ + { + category: 'OperationalLogs' + enabled: true + retentionPolicy: { + days: 36 + enabled: true + } + } + { + category: 'ArchiveLogs' + enabled: true + } + ] + } + ] + } +} + +// Test 04 - Standard SKU - Event Hub Capture to StorageAccount, DiagnosticSettings with StorageAccount and LogAnalyticsWorkspace +module test_04 '../main.bicep' = { + name: 'test04-${uniqueName}' + params: { + location: location + namespaces: [ + { + name: 'test04-${uniqueName}-ns' + sku: 'Standard' + capacity: 1 + zoneRedundant: false + } + ] + eventHubs: [ + { + name: 'test04-${uniqueName}-evh' + messageRetentionInDays: 1 + partitionCount: 2 + namespaceName: 'test04-${uniqueName}-ns' + captureDescriptionEnabled: true + captureDescriptionDestinationBlobContainer: dependencies.outputs.containerName + captureDescriptionDestinationStorageAccountResourceId: dependencies.outputs.storageAccountId + } + ] + namespaceDiagnosticSettings: [ + { + name: 'test04-${uniqueName}-ds' + namespaceName: 'test04-${uniqueName}-ns' + storageAccountId: dependencies.outputs.storageAccountId + workspaceId: dependencies.outputs.workspaceId + metricsSettings: [ { category: 'AllMetrics', enabled: true, retentionPolicy: { days: 365, enabled: true } } ] + logsSettings: [ + { + category: 'ArchiveLogs' + enabled: true + retentionPolicy: { days: 7, enabled: true } + } + { + category: 'RuntimeAuditLogs' + enabled: true + retentionPolicy: { days: 3, enabled: true } + } + ] + } + ] + } +} diff --git a/modules/compute/event-hub/test/prereq.test.bicep b/modules/compute/event-hub/test/prereq.test.bicep new file mode 100644 index 0000000000..5e8f51a329 --- /dev/null +++ b/modules/compute/event-hub/test/prereq.test.bicep @@ -0,0 +1,126 @@ +param location string +param name string +param prefix string +param blobServiceName string = 'default' + +resource storageAccount 'Microsoft.Storage/storageAccounts@2022-05-01' = { + name: '${name}${prefix}01' + kind: 'StorageV2' + sku: { + name: 'Standard_LRS' + } + location: location + properties: { + allowBlobPublicAccess: false + } +} + +resource blobService 'Microsoft.Storage/storageAccounts/blobServices@2021-06-01' = { + name: blobServiceName + parent: storageAccount +} + +resource container 'Microsoft.Storage/storageAccounts/blobServices/containers@2021-06-01' = { + name: '${name}${prefix}01' + parent: blobService + properties: {} +} + +resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' = { + name: 'law-${name}${prefix}-01' + location: location +} + +resource eventHubNamespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' = { + name: 'evhns-${name}${prefix}-01' + location: location +} + +resource eventHub 'Microsoft.EventHub/namespaces/eventhubs@2022-10-01-preview' = { + name: 'eventHub-${name}${prefix}-01' + parent: eventHubNamespace +} + +resource authorizationRule 'Microsoft.EventHub/namespaces/authorizationRules@2022-01-01-preview' = { + name: 'RootManageSharedAccessKey' + properties: { + rights: [ + 'Listen' + 'Manage' + 'Send' + ] + } + parent: eventHubNamespace +} + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2022-05-01' = { + name: 'vnet-${name}${prefix}-01' + location: location + properties: { + addressSpace: { + addressPrefixes: [ + '10.0.0.0/16' + ] + } + subnets: [ + { + name: '${name}-subnet-0' + properties: { + addressPrefix: '10.0.0.0/24' + privateEndpointNetworkPolicies: 'Disabled' + } + } + { + name: '${name}-subnet-1' + properties: { + addressPrefix: '10.0.1.0/24' + privateEndpointNetworkPolicies: 'Disabled' + } + } + ] + } +} + +resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { + name: 'privatelink.servicebus.windows.net' + location: 'global' + properties: {} +} + +resource virtualNetworkLinks 'Microsoft.Network/privateDnsZones/virtualNetworkLinks@2020-06-01' = { + parent: privateDNSZone + name: '${name}-${prefix}-vnet-link' + location: 'global' + properties: { + registrationEnabled: false + virtualNetwork: { + id: virtualNetwork.id + } + } +} + +resource managedIdentity_01 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: '${name}-${prefix}-01' + location: location +} + +resource managedIdentity_02 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: '${name}-${prefix}-02' + location: location +} + +output storageAccountId string = storageAccount.id +output containerName string = container.name +output workspaceId string = logAnalyticsWorkspace.id +output eventHubNamespaceId string = eventHubNamespace.id +output eventHubName string = eventHub.name +output authorizationRuleId string = authorizationRule.id +output subnetIds array = [ + virtualNetwork.properties.subnets[0].id + virtualNetwork.properties.subnets[1].id +] +output privateDNSZoneId string = privateDNSZone.id +output identityPrincipalIds array = [ + managedIdentity_01.properties.principalId + managedIdentity_02.properties.principalId +] diff --git a/modules/compute/event-hub/version.json b/modules/compute/event-hub/version.json new file mode 100644 index 0000000000..4727c64800 --- /dev/null +++ b/modules/compute/event-hub/version.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "2.0", + "pathFilters": [ + "./main.json", + "./metadata.json" + ] +} \ No newline at end of file diff --git a/modules/compute/function-app/README.md b/modules/compute/function-app/README.md new file mode 100644 index 0000000000..e774998081 --- /dev/null +++ b/modules/compute/function-app/README.md @@ -0,0 +1,141 @@ +# Function app module + +Module to create function app for your application + +## Details + +This is a low-level Bicep module for managing Azure Functions, it supports an array of function, also the user has the option to either choose use user assigned identity or system assigned identity and also support the storage account to be in different resource group. + +## Parameters + +| Name | Type | Required | Description | +| :-------------------------------- | :------: | :------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `name` | `string` | Yes | Required. Name for the Azure Function App. | +| `location` | `string` | Yes | Required. Location for all resources. | +| `tags` | `object` | No | Optional. Tags for all resources within Azure Function App module. | +| `sku` | `object` | No | Required. Defines the name, tier, size, family and capacity of the app service plan. | +| `serverOS` | `string` | No | Optional. Kind of server OS. | +| `perSiteScaling` | `bool` | No | Optional. If true, apps assigned to this app service plan can be scaled independently. If false, apps assigned to this app service plan will scale to all instances of the plan. | +| `maximumElasticWorkerCount` | `int` | No | Optional. Maximum number of total workers allowed for this ElasticScaleEnabled app service plan. | +| `targetWorkerCount` | `int` | No | Optional. Scaling worker count. | +| `targetWorkerSizeId` | `int` | No | Optional. The instance size of the hosting plan (small, medium, or large). | +| `identityType` | `string` | No | Optional. The type of identity used for the virtual machine. The type 'SystemAssigned, UserAssigned' includes both an implicitly created identity and a set of user assigned identities. The type 'None' will remove any identities from the sites ( app or functionapp). | +| `userAssignedIdentityId` | `string` | No | Optional. Specify the resource ID of the user assigned Managed Identity, if 'identity' is set as 'UserAssigned'. | +| `httpsOnly` | `bool` | No | Optional. Configures a site to accept only HTTPS requests. Issues redirect for HTTP requests. | +| `appServiceEnvironmentId` | `string` | No | Optional. The resource ID of the app service environment to use for this resource. | +| `clientAffinityEnabled` | `bool` | No | Optional. If client affinity is enabled. | +| `kind` | `string` | No | Required. Type of site to deploy. | +| `functionsExtensionVersion` | `string` | No | Optional. Version of the function extension. | +| `functionAppEditMode` | `string` | No | Dictates whether editing in the Azure portal is enabled. | +| `functionsWorkerRuntime` | `string` | No | Optional. Runtime of the function worker. WARNING: NOT ALL OSes SUPPORT ALL RUNTIMES! | +| `functionsDefaultNodeversion` | `string` | No | Optional. NodeJS version. | +| `publicNetworkAccessForIngestion` | `string` | No | Optional. The network access type for accessing Application Insights ingestion. - Enabled or Disabled. | +| `publicNetworkAccessForQuery` | `string` | No | Optional. The network access type for accessing Application Insights query. - Enabled or Disabled. | +| `appInsightsType` | `string` | No | Optional. Application type. | +| `appInsightsKind` | `string` | No | Optional. The kind of application that this component refers to, used to customize UI. | +| `enableInsights` | `bool` | No | Optional. Enabled or Disable Insights for Azure functions. | +| `workspaceResourceId` | `string` | No | Optional. Resource ID of the log analytics workspace which the data will be ingested to, if enableaInsights is false. | +| `functions` | `array` | No | Optional. List of Azure function (Actual object where our code resides). | +| `enableVnetIntegration` | `bool` | No | Optional. Enable Vnet Integration or not. | +| `subnetId` | `string` | No | Optional. The subnet that will be integrated to enable vnet Integration. | +| `enableSourceControl` | `bool` | No | Optional. Enable Source control for the function. | +| `repoUrl` | `string` | No | Optional. Repository or source control URL. | +| `branch` | `string` | No | Optional. Name of branch to use for deployment. | +| `storageAccountName` | `string` | Yes | Required. Name of the storage account used by function app. | +| `isManualIntegration` | `bool` | No | Optional. to limit to manual integration; to enable continuous integration (which configures webhooks into online repos like GitHub). | +| `isMercurial` | `bool` | No | Optional. true for a Mercurial repository; false for a Git repository. | +| `storageAccountResourceGroup` | `string` | Yes | Required. Resource Group of storage account used by function app. | +| `enablePackageDeploy` | `bool` | No | Optional. True to deploy functions from zip package. "functionPackageUri" must be specified if enabled. The package option and sourcecontrol option should not be enabled at the same time. | +| `functionPackageUri` | `string` | No | Optional. URI to the function source code zip package, must be accessible by the deployer. E.g. A zip file on Azure storage in the same resource group. | +| `enableDockerContainer` | `bool` | No | Optional. Enable docker image deployment. | +| `dockerImage` | `string` | No | Optional. This will be required when enableDockerContainer passed as true. | +| `extraAppSettings` | `object` | No | Optional. Extra app settings that should be provisioned while creating the function app. Note! Settings below should not be included unless absolutely necessary, because settings in this param will override the ones added by the module:
AzureWebJobsStorage
AzureWebJobsDashboard
WEBSITE_CONTENTSHARE
WEBSITE_CONTENTAZUREFILECONNECTIONSTRING
FUNCTIONS_EXTENSION_VERSION
FUNCTIONS_WORKER_RUNTIME
WEBSITE_NODE_DEFAULT_VERSION
APPINSIGHTS_INSTRUMENTATIONKEY
APPLICATIONINSIGHTS_CONNECTION_STRING | +| `ftpsState` | `string` | No | The state of FTP / FTPS service. | +| `minTlsVersion` | `string` | No | Configures the minimum version of TLS required for SSL requests. | +| `linuxFxVersion` | `string` | No | Linux App Framework and version. e.g. PYTHON|3.9 | +| `connectionStringProperties` | `object` | No | The connection strings properties | + +## Outputs + +| Name | Type | Description | +| :---------------- | :------: | :------------------------------------------------------------------------ | +| `siteId` | `string` | Get resource id for app or functionapp. | +| `siteName` | `string` | Get resource name for app or functionapp. | +| `serverfarmsId` | `string` | Get resource ID of the app service plan. | +| `serverfarmsName` | `string` | Get name of the app service plan. | +| `functions` | `array` | Array of functions having name , language,isDisabled and id of functions. | +| `sitePrincipalId` | `string` | Principal Id of the identity assigned to the function app. | + +## Examples + +### Example 1 + +```bicep +@description(''' +In example, function app is using pre-built docker image, +deploy your code to Azure Functions as a custom Docker container using a image provided. +''') +module funcApp 'br/public:bicep/compute/function-app:2.0.1' = { + name: 'func1${uniqueString(name)}' + dependsOn: [ + dependencies + ] + params: { + name: take(replace('fun1-${name}', '.', ''), 55) + location: location + sku: { + name: 'Y1' + tier: 'Dynamic' + size: 'Y1' + family: 'Y' + capacity: 0 + } + tags: tags + storageAccountName: dependencies.outputs.saAccountName + storageAccountResourceGroup: resourceGroup().name + enableSourceControl: false + enableDockerContainer: true + dockerImage: 'mcr.microsoft.com/azure-functions/dotnet:4-appservice-quickstart' + serverOS: 'Linux' + } + scope: resourceGroup() +} + +### Example 2 +@description(''' +In example, function app uses source control option for +Continuous deployment for Azure Functions ie. repoUrl param value. +''') +module funcApp 'br/public:bicep/compute/function-app:2.0.1' = { + name: 'func2-${uniqueString(name)}' + scope: resourceGroup() + dependsOn: [ + dependencies + ] + params: { + name: take(replace('fun2-${name}', '.', ''), 55) + location: location + sku: { + name: 'EP1' + tier: 'ElasticPremium' + size: 'EP1' + family: 'EP' + capacity: 1 + } + tags: tags + maximumElasticWorkerCount: 20 + enableVnetIntegration: true + enableInsights: true + workspaceResourceId: dependencies.outputs.workspacesId + subnetId: dependencies.outputs.subnetResourceIds + functionsExtensionVersion: '~4' + functionsWorkerRuntime: 'powershell' + storageAccountName: dependencies.outputs.saAccountName + storageAccountResourceGroup: resourceGroup().name + enableSourceControl: true + repoUrl: 'https://github.com/Azure/KeyVault-Secrets-Rotation-Redis-PowerShell.git' + enableDockerContainer: false + } +} + +``` \ No newline at end of file diff --git a/modules/compute/function-app/bicepconfig.json b/modules/compute/function-app/bicepconfig.json new file mode 100644 index 0000000000..072e1e7264 --- /dev/null +++ b/modules/compute/function-app/bicepconfig.json @@ -0,0 +1,5 @@ +{ + "experimentalFeaturesEnabled": { + "userDefinedTypes": true + } +} diff --git a/modules/compute/function-app/main.bicep b/modules/compute/function-app/main.bicep new file mode 100644 index 0000000000..f7635586e9 --- /dev/null +++ b/modules/compute/function-app/main.bicep @@ -0,0 +1,339 @@ +metadata name = 'Function app module' +metadata description = 'Module to create function app for your application' +metadata owner = 'rhalloul' + +/*param section*/ +@description('Required. Name for the Azure Function App.') +@maxLength(64) +param name string + +@description('Required. Location for all resources.') +param location string + +@description('Optional. Tags for all resources within Azure Function App module.') +param tags object = {} + +@description('Required. Defines the name, tier, size, family and capacity of the app service plan.') +param sku object = { + name: 'Y1' + tier: 'Dynamic' + size: 'Y1' + family: 'Y' + capacity: 0 +} + +@description('Optional. Kind of server OS.') +@allowed([ 'Windows', 'Linux' ]) +param serverOS string = 'Windows' + +@description('Optional. If true, apps assigned to this app service plan can be scaled independently. If false, apps assigned to this app service plan will scale to all instances of the plan.') +param perSiteScaling bool = false + +@description('Optional. Maximum number of total workers allowed for this ElasticScaleEnabled app service plan.') +param maximumElasticWorkerCount int = 0 + +@description('Optional. Scaling worker count.') +param targetWorkerCount int = 0 + +@description('Optional. The instance size of the hosting plan (small, medium, or large).') +@allowed([ 0, 1, 2 ]) +param targetWorkerSizeId int = 0 + +@allowed(['None', 'SystemAssigned', 'UserAssigned', 'SystemAssigned, UserAssigned' +]) +@description('Optional. The type of identity used for the virtual machine. The type \'SystemAssigned, UserAssigned\' includes both an implicitly created identity and a set of user assigned identities. The type \'None\' will remove any identities from the sites ( app or functionapp).') +param identityType string = 'SystemAssigned' + +@description('Optional. Specify the resource ID of the user assigned Managed Identity, if \'identity\' is set as \'UserAssigned\'.') +param userAssignedIdentityId string = '' + +@description('Optional. Configures a site to accept only HTTPS requests. Issues redirect for HTTP requests.') +param httpsOnly bool = true + +@description('Optional. The resource ID of the app service environment to use for this resource.') +param appServiceEnvironmentId string = '' + +@description('Optional. If client affinity is enabled.') +param clientAffinityEnabled bool = true + +@description('Required. Type of site to deploy.') +@allowed([ 'functionapp', 'app' ]) +param kind string = 'functionapp' + +@description('Optional. Version of the function extension.') +param functionsExtensionVersion string = '~4' + +@description('Dictates whether editing in the Azure portal is enabled.') +@allowed(['readonly', 'readwrite']) +param functionAppEditMode string = 'readonly' + +@description('Optional. Runtime of the function worker. WARNING: NOT ALL OSes SUPPORT ALL RUNTIMES!') +@allowed(['dotnet', 'node', 'python', 'java', 'powershell', '']) +param functionsWorkerRuntime string = '' + +@description('Optional. NodeJS version.') +param functionsDefaultNodeversion string = '~14' + +@allowed([ 'Disabled', 'Enabled' ]) +@description('Optional. The network access type for accessing Application Insights ingestion. - Enabled or Disabled.') +param publicNetworkAccessForIngestion string = 'Enabled' + +@allowed([ 'Disabled', 'Enabled' ]) +@description('Optional. The network access type for accessing Application Insights query. - Enabled or Disabled.') +param publicNetworkAccessForQuery string = 'Enabled' + +@description('Optional. Application type.') +@allowed([ 'web', 'other' ]) +param appInsightsType string = 'web' + +@description('Optional. The kind of application that this component refers to, used to customize UI.') +param appInsightsKind string = 'azfunc' + +@description('Optional. Enabled or Disable Insights for Azure functions.') +param enableInsights bool = false + +@description('Optional. Resource ID of the log analytics workspace which the data will be ingested to, if enableaInsights is false.') +param workspaceResourceId string = '' + +@description('Optional. List of Azure function (Actual object where our code resides).') +param functions functionType[] = [] + +@description('Optional. Enable Vnet Integration or not.') +param enableVnetIntegration bool = false + +@description('Optional. The subnet that will be integrated to enable vnet Integration.') +param subnetId string = '' + +@description('Optional. Enable Source control for the function.') +param enableSourceControl bool = false + +@description('Optional. Repository or source control URL.') +param repoUrl string = '' + +@description('Optional. Name of branch to use for deployment.') +param branch string = 'main' + +@description('Required. Name of the storage account used by function app.') +param storageAccountName string + +@description('Optional. to limit to manual integration; to enable continuous integration (which configures webhooks into online repos like GitHub).') +param isManualIntegration bool = true + +@description('Optional. true for a Mercurial repository; false for a Git repository.') +param isMercurial bool = false + +@description('Required. Resource Group of storage account used by function app.') +param storageAccountResourceGroup string + +@description('Optional. True to deploy functions from zip package. "functionPackageUri" must be specified if enabled. The package option and sourcecontrol option should not be enabled at the same time.') +param enablePackageDeploy bool = false + +@description('Optional. URI to the function source code zip package, must be accessible by the deployer. E.g. A zip file on Azure storage in the same resource group.') +param functionPackageUri string = '' + +@description('Optional. Enable docker image deployment.') +param enableDockerContainer bool = false + +@description('Optional. This will be required when enableDockerContainer passed as true.') +param dockerImage string = '' + +@description('''Optional. Extra app settings that should be provisioned while creating the function app. Note! Settings below should not be included unless absolutely necessary, because settings in this param will override the ones added by the module: +AzureWebJobsStorage +AzureWebJobsDashboard +WEBSITE_CONTENTSHARE +WEBSITE_CONTENTAZUREFILECONNECTIONSTRING +FUNCTIONS_EXTENSION_VERSION +FUNCTIONS_WORKER_RUNTIME +WEBSITE_NODE_DEFAULT_VERSION +APPINSIGHTS_INSTRUMENTATIONKEY +APPLICATIONINSIGHTS_CONNECTION_STRING''') +param extraAppSettings object = {} + +@description('The kind of resource. Empty string means windows.') +var servicePlanKind = serverOS == 'Linux' ? toLower(serverOS) : '' + +@description('The state of FTP / FTPS service.') +@allowed(['Disabled', 'AllAllowed', 'FtpsOnly']) +param ftpsState string = 'Disabled' + +@description('Configures the minimum version of TLS required for SSL requests.') +@allowed(['1.0', '1.1', '1.2']) +param minTlsVersion string = '1.2' + +@description('Linux App Framework and version. e.g. PYTHON|3.9') +param linuxFxVersion string = '' + +@description('The connection strings properties') +param connectionStringProperties object = {} + +@description('Defines storageAccounts for Azure Function App.') +resource storageAccount 'Microsoft.Storage/storageAccounts@2021-06-01' existing = { + name: storageAccountName + scope: resourceGroup(storageAccountResourceGroup) +} + +@description('Defines Application service plan.') +resource serverfarms 'Microsoft.Web/serverfarms@2021-02-01' = { + name: name + location: location + tags: tags + sku: sku + kind: servicePlanKind + properties: { + perSiteScaling: perSiteScaling + maximumElasticWorkerCount: maximumElasticWorkerCount + reserved: serverOS == 'Linux' + targetWorkerCount: targetWorkerCount + targetWorkerSizeId: targetWorkerSizeId + } +} + +@description('If enabled, this will help monitor the application using the log analytics workspace.') +resource appInsights 'Microsoft.Insights/components@2020-02-02' = if (enableInsights) { + name: 'ai-${name}' + location: location + kind: appInsightsKind + properties: { + Application_Type: appInsightsType + WorkspaceResourceId: workspaceResourceId + publicNetworkAccessForIngestion: publicNetworkAccessForIngestion + publicNetworkAccessForQuery: publicNetworkAccessForQuery + } + tags: tags +} + +@description('''The app or function app resource. +Note: This is not actual Azure Function App this will be container for storing multiple functions.''') +resource sites 'Microsoft.Web/sites@2022-03-01' = { + name: name + location: location + tags: tags + kind: kind + identity: { + type: identityType + userAssignedIdentities: (identityType == 'UserAssigned' || identityType == 'SystemAssigned, UserAssigned') ? { + '${userAssignedIdentityId}': {} + } : null + } + properties: { + siteConfig: { + linuxFxVersion: enableDockerContainer ? 'DOCKER|${dockerImage}' : linuxFxVersion ?? null + ftpsState: ftpsState + minTlsVersion: minTlsVersion + } + serverFarmId: serverfarms.id + httpsOnly: httpsOnly + hostingEnvironmentProfile: !empty(appServiceEnvironmentId) ? { + id: appServiceEnvironmentId + } : null + clientAffinityEnabled: clientAffinityEnabled + } +} + +@description('Appsettings/config for the sites (app or functionapp).') +resource config 'Microsoft.Web/sites/config@2021-02-01' = { + parent: sites + name: 'appsettings' + properties: union({ + AzureWebJobsStorage: !empty(storageAccount.id) ? 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};AccountKey=${storageAccount.listKeys().keys[0].value};' : any(null) + AzureWebJobsDashboard: !empty(storageAccount.id) ? 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};AccountKey=${storageAccount.listKeys().keys[0].value};' : any(null) + WEBSITE_CONTENTSHARE: name + WEBSITE_CONTENTAZUREFILECONNECTIONSTRING: !empty(storageAccount.id) ? 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};AccountKey=${storageAccount.listKeys().keys[0].value};' : any(null) + FUNCTIONS_EXTENSION_VERSION: functionsExtensionVersion + FUNCTION_APP_EDIT_MODE: functionAppEditMode + FUNCTIONS_WORKER_RUNTIME: sites.kind == 'functionapp' && !empty(functionsWorkerRuntime) ? functionsWorkerRuntime : any(null) + WEBSITE_NODE_DEFAULT_VERSION: sites.kind == 'functionapp' && functionsWorkerRuntime == 'node' && !empty(functionsDefaultNodeversion) ? functionsDefaultNodeversion : any(null) + APPINSIGHTS_INSTRUMENTATIONKEY: !empty(appInsights.id) && enableInsights ? appInsights.properties.InstrumentationKey : any(null) + APPLICATIONINSIGHTS_CONNECTION_STRING: !empty(appInsights.id) && enableInsights ? appInsights.properties.ConnectionString : any(null) + }, extraAppSettings) + dependsOn: enableVnetIntegration ? [ networkConfig ] : [] +} + +resource connectionString 'Microsoft.Web/sites/config@2022-03-01' = if (!empty(connectionStringProperties)) { + name: 'connectionstrings' + kind: 'string' + parent: sites + properties: connectionStringProperties +} + +resource networkConfig 'Microsoft.Web/sites/networkConfig@2022-03-01' = if (enableVnetIntegration == true) { + parent: sites + name: 'virtualNetwork' + properties: { + subnetResourceId: subnetId + } +} + +@description('The resources actual is function where code exits.') +@batchSize(1) +resource azureFunction 'Microsoft.Web/sites/functions@2021-02-01' = [for function in functions: { + dependsOn: [ + serverfarms + config + ] + parent: sites + name: function.name + properties: { + language: function.properties.language + config: function.properties.config + isDisabled: function.properties.isDisabled + files: function.properties.files + } +}] + +resource sourcecontrol 'Microsoft.Web/sites/sourcecontrols@2022-03-01' = if (enableSourceControl) { + parent: sites + name: 'web' + properties: { + repoUrl: repoUrl + branch: branch + isManualIntegration: isManualIntegration + isMercurial: isMercurial + } +} + +@description('Deploy function app from zip file.') +resource extensions 'Microsoft.Web/sites/extensions@2022-03-01' = if (enablePackageDeploy) { + parent: sites + name: 'MSDeploy' + properties: { + packageUri: functionPackageUri + } +} + +/*output section*/ +@description('Get resource id for app or functionapp.') +output siteId string = sites.id + +@description('Get resource name for app or functionapp.') +output siteName string = sites.name + +@description('Get resource ID of the app service plan.') +output serverfarmsId string = serverfarms.id + +@description('Get name of the app service plan.') +output serverfarmsName string = serverfarms.name + +@description('Array of functions having name , language,isDisabled and id of functions.') +output functions array = [for function in functions: { + name: function.name + language: function.properties.language + isDisabled: function.properties.isDisabled + id: '${sites.id}/functions/${function.name}' + files: function.properties.files +}] + +@description('Principal Id of the identity assigned to the function app.') +output sitePrincipalId string = (sites.identity.type == 'SystemAssigned') ? sites.identity.principalId : '' + + +// user defined types +type functionType = { + name: string + properties: { + language: string + config: object + isDisabled: bool + files: object + } +} diff --git a/modules/compute/function-app/main.json b/modules/compute/function-app/main.json new file mode 100644 index 0000000000..c84ed7edbe --- /dev/null +++ b/modules/compute/function-app/main.json @@ -0,0 +1,638 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "1.10-experimental", + "contentVersion": "1.0.0.0", + "metadata": { + "_EXPERIMENTAL_WARNING": "Symbolic name support in ARM is experimental, and should be enabled for testing purposes only. Do not enable this setting for any production usage, or you may be unexpectedly broken at any time!", + "_generator": { + "name": "bicep", + "version": "0.19.5.34762", + "templateHash": "4252297606944310030" + }, + "name": "Function app module", + "description": "Module to create function app for your application", + "owner": "rhalloul" + }, + "definitions": { + "functionType": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "properties": { + "type": "object", + "properties": { + "language": { + "type": "string" + }, + "config": { + "type": "object" + }, + "isDisabled": { + "type": "bool" + }, + "files": { + "type": "object" + } + } + } + } + } + }, + "parameters": { + "name": { + "type": "string", + "maxLength": 64, + "metadata": { + "description": "Required. Name for the Azure Function App." + } + }, + "location": { + "type": "string", + "metadata": { + "description": "Required. Location for all resources." + } + }, + "tags": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Tags for all resources within Azure Function App module." + } + }, + "sku": { + "type": "object", + "defaultValue": { + "name": "Y1", + "tier": "Dynamic", + "size": "Y1", + "family": "Y", + "capacity": 0 + }, + "metadata": { + "description": "Required. Defines the name, tier, size, family and capacity of the app service plan." + } + }, + "serverOS": { + "type": "string", + "defaultValue": "Windows", + "allowedValues": [ + "Windows", + "Linux" + ], + "metadata": { + "description": "Optional. Kind of server OS." + } + }, + "perSiteScaling": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. If true, apps assigned to this app service plan can be scaled independently. If false, apps assigned to this app service plan will scale to all instances of the plan." + } + }, + "maximumElasticWorkerCount": { + "type": "int", + "defaultValue": 0, + "metadata": { + "description": "Optional. Maximum number of total workers allowed for this ElasticScaleEnabled app service plan." + } + }, + "targetWorkerCount": { + "type": "int", + "defaultValue": 0, + "metadata": { + "description": "Optional. Scaling worker count." + } + }, + "targetWorkerSizeId": { + "type": "int", + "defaultValue": 0, + "allowedValues": [ + 0, + 1, + 2 + ], + "metadata": { + "description": "Optional. The instance size of the hosting plan (small, medium, or large)." + } + }, + "identityType": { + "type": "string", + "defaultValue": "SystemAssigned", + "metadata": { + "description": "Optional. The type of identity used for the virtual machine. The type 'SystemAssigned, UserAssigned' includes both an implicitly created identity and a set of user assigned identities. The type 'None' will remove any identities from the sites ( app or functionapp)." + }, + "allowedValues": [ + "None", + "SystemAssigned", + "UserAssigned", + "SystemAssigned, UserAssigned" + ] + }, + "userAssignedIdentityId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Specify the resource ID of the user assigned Managed Identity, if 'identity' is set as 'UserAssigned'." + } + }, + "httpsOnly": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Configures a site to accept only HTTPS requests. Issues redirect for HTTP requests." + } + }, + "appServiceEnvironmentId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The resource ID of the app service environment to use for this resource." + } + }, + "clientAffinityEnabled": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. If client affinity is enabled." + } + }, + "kind": { + "type": "string", + "defaultValue": "functionapp", + "allowedValues": [ + "functionapp", + "app" + ], + "metadata": { + "description": "Required. Type of site to deploy." + } + }, + "functionsExtensionVersion": { + "type": "string", + "defaultValue": "~4", + "metadata": { + "description": "Optional. Version of the function extension." + } + }, + "functionAppEditMode": { + "type": "string", + "defaultValue": "readonly", + "allowedValues": [ + "readonly", + "readwrite" + ], + "metadata": { + "description": "Dictates whether editing in the Azure portal is enabled." + } + }, + "functionsWorkerRuntime": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "dotnet", + "node", + "python", + "java", + "powershell", + "" + ], + "metadata": { + "description": "Optional. Runtime of the function worker. WARNING: NOT ALL OSes SUPPORT ALL RUNTIMES!" + } + }, + "functionsDefaultNodeversion": { + "type": "string", + "defaultValue": "~14", + "metadata": { + "description": "Optional. NodeJS version." + } + }, + "publicNetworkAccessForIngestion": { + "type": "string", + "defaultValue": "Enabled", + "metadata": { + "description": "Optional. The network access type for accessing Application Insights ingestion. - Enabled or Disabled." + }, + "allowedValues": [ + "Disabled", + "Enabled" + ] + }, + "publicNetworkAccessForQuery": { + "type": "string", + "defaultValue": "Enabled", + "metadata": { + "description": "Optional. The network access type for accessing Application Insights query. - Enabled or Disabled." + }, + "allowedValues": [ + "Disabled", + "Enabled" + ] + }, + "appInsightsType": { + "type": "string", + "defaultValue": "web", + "allowedValues": [ + "web", + "other" + ], + "metadata": { + "description": "Optional. Application type." + } + }, + "appInsightsKind": { + "type": "string", + "defaultValue": "azfunc", + "metadata": { + "description": "Optional. The kind of application that this component refers to, used to customize UI." + } + }, + "enableInsights": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enabled or Disable Insights for Azure functions." + } + }, + "workspaceResourceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of the log analytics workspace which the data will be ingested to, if enableaInsights is false." + } + }, + "functions": { + "type": "array", + "items": { + "$ref": "#/definitions/functionType" + }, + "defaultValue": [], + "metadata": { + "description": "Optional. List of Azure function (Actual object where our code resides)." + } + }, + "enableVnetIntegration": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enable Vnet Integration or not." + } + }, + "subnetId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The subnet that will be integrated to enable vnet Integration." + } + }, + "enableSourceControl": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enable Source control for the function." + } + }, + "repoUrl": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Repository or source control URL." + } + }, + "branch": { + "type": "string", + "defaultValue": "main", + "metadata": { + "description": "Optional. Name of branch to use for deployment." + } + }, + "storageAccountName": { + "type": "string", + "metadata": { + "description": "Required. Name of the storage account used by function app." + } + }, + "isManualIntegration": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. to limit to manual integration; to enable continuous integration (which configures webhooks into online repos like GitHub)." + } + }, + "isMercurial": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. true for a Mercurial repository; false for a Git repository." + } + }, + "storageAccountResourceGroup": { + "type": "string", + "metadata": { + "description": "Required. Resource Group of storage account used by function app." + } + }, + "enablePackageDeploy": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. True to deploy functions from zip package. \"functionPackageUri\" must be specified if enabled. The package option and sourcecontrol option should not be enabled at the same time." + } + }, + "functionPackageUri": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. URI to the function source code zip package, must be accessible by the deployer. E.g. A zip file on Azure storage in the same resource group." + } + }, + "enableDockerContainer": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enable docker image deployment." + } + }, + "dockerImage": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. This will be required when enableDockerContainer passed as true." + } + }, + "extraAppSettings": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Extra app settings that should be provisioned while creating the function app. Note! Settings below should not be included unless absolutely necessary, because settings in this param will override the ones added by the module:\nAzureWebJobsStorage\nAzureWebJobsDashboard\nWEBSITE_CONTENTSHARE\nWEBSITE_CONTENTAZUREFILECONNECTIONSTRING\nFUNCTIONS_EXTENSION_VERSION\nFUNCTIONS_WORKER_RUNTIME\nWEBSITE_NODE_DEFAULT_VERSION\nAPPINSIGHTS_INSTRUMENTATIONKEY\nAPPLICATIONINSIGHTS_CONNECTION_STRING" + } + }, + "ftpsState": { + "type": "string", + "defaultValue": "Disabled", + "allowedValues": [ + "Disabled", + "AllAllowed", + "FtpsOnly" + ], + "metadata": { + "description": "The state of FTP / FTPS service." + } + }, + "minTlsVersion": { + "type": "string", + "defaultValue": "1.2", + "allowedValues": [ + "1.0", + "1.1", + "1.2" + ], + "metadata": { + "description": "Configures the minimum version of TLS required for SSL requests." + } + }, + "linuxFxVersion": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Linux App Framework and version. e.g. PYTHON|3.9" + } + }, + "connectionStringProperties": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "The connection strings properties" + } + } + }, + "variables": { + "servicePlanKind": "[if(equals(parameters('serverOS'), 'Linux'), toLower(parameters('serverOS')), '')]" + }, + "resources": { + "storageAccount": { + "existing": true, + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2021-06-01", + "resourceGroup": "[parameters('storageAccountResourceGroup')]", + "name": "[parameters('storageAccountName')]", + "metadata": { + "description": "Defines storageAccounts for Azure Function App." + } + }, + "serverfarms": { + "type": "Microsoft.Web/serverfarms", + "apiVersion": "2021-02-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "sku": "[parameters('sku')]", + "kind": "[variables('servicePlanKind')]", + "properties": { + "perSiteScaling": "[parameters('perSiteScaling')]", + "maximumElasticWorkerCount": "[parameters('maximumElasticWorkerCount')]", + "reserved": "[equals(parameters('serverOS'), 'Linux')]", + "targetWorkerCount": "[parameters('targetWorkerCount')]", + "targetWorkerSizeId": "[parameters('targetWorkerSizeId')]" + }, + "metadata": { + "description": "Defines Application service plan." + } + }, + "appInsights": { + "condition": "[parameters('enableInsights')]", + "type": "Microsoft.Insights/components", + "apiVersion": "2020-02-02", + "name": "[format('ai-{0}', parameters('name'))]", + "location": "[parameters('location')]", + "kind": "[parameters('appInsightsKind')]", + "properties": { + "Application_Type": "[parameters('appInsightsType')]", + "WorkspaceResourceId": "[parameters('workspaceResourceId')]", + "publicNetworkAccessForIngestion": "[parameters('publicNetworkAccessForIngestion')]", + "publicNetworkAccessForQuery": "[parameters('publicNetworkAccessForQuery')]" + }, + "tags": "[parameters('tags')]", + "metadata": { + "description": "If enabled, this will help monitor the application using the log analytics workspace." + } + }, + "sites": { + "type": "Microsoft.Web/sites", + "apiVersion": "2022-03-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "kind": "[parameters('kind')]", + "identity": { + "type": "[parameters('identityType')]", + "userAssignedIdentities": "[if(or(equals(parameters('identityType'), 'UserAssigned'), equals(parameters('identityType'), 'SystemAssigned, UserAssigned')), createObject(format('{0}', parameters('userAssignedIdentityId')), createObject()), null())]" + }, + "properties": { + "siteConfig": { + "linuxFxVersion": "[if(parameters('enableDockerContainer'), format('DOCKER|{0}', parameters('dockerImage')), coalesce(parameters('linuxFxVersion'), null()))]", + "ftpsState": "[parameters('ftpsState')]", + "minTlsVersion": "[parameters('minTlsVersion')]" + }, + "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('name'))]", + "httpsOnly": "[parameters('httpsOnly')]", + "hostingEnvironmentProfile": "[if(not(empty(parameters('appServiceEnvironmentId'))), createObject('id', parameters('appServiceEnvironmentId')), null())]", + "clientAffinityEnabled": "[parameters('clientAffinityEnabled')]" + }, + "dependsOn": [ + "serverfarms" + ], + "metadata": { + "description": "The app or function app resource.\nNote: This is not actual Azure Function App this will be container for storing multiple functions." + } + }, + "config": { + "type": "Microsoft.Web/sites/config", + "apiVersion": "2021-02-01", + "name": "[format('{0}/{1}', parameters('name'), 'appsettings')]", + "properties": "[union(createObject('AzureWebJobsStorage', if(not(empty(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('storageAccountResourceGroup')), 'Microsoft.Storage/storageAccounts', parameters('storageAccountName')))), format('DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};', parameters('storageAccountName'), listKeys(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('storageAccountResourceGroup')), 'Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2021-06-01').keys[0].value), null()), 'AzureWebJobsDashboard', if(not(empty(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('storageAccountResourceGroup')), 'Microsoft.Storage/storageAccounts', parameters('storageAccountName')))), format('DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};', parameters('storageAccountName'), listKeys(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('storageAccountResourceGroup')), 'Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2021-06-01').keys[0].value), null()), 'WEBSITE_CONTENTSHARE', parameters('name'), 'WEBSITE_CONTENTAZUREFILECONNECTIONSTRING', if(not(empty(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('storageAccountResourceGroup')), 'Microsoft.Storage/storageAccounts', parameters('storageAccountName')))), format('DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};', parameters('storageAccountName'), listKeys(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('storageAccountResourceGroup')), 'Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2021-06-01').keys[0].value), null()), 'FUNCTIONS_EXTENSION_VERSION', parameters('functionsExtensionVersion'), 'FUNCTION_APP_EDIT_MODE', parameters('functionAppEditMode'), 'FUNCTIONS_WORKER_RUNTIME', if(and(equals(reference('sites', '2022-03-01', 'full').kind, 'functionapp'), not(empty(parameters('functionsWorkerRuntime')))), parameters('functionsWorkerRuntime'), null()), 'WEBSITE_NODE_DEFAULT_VERSION', if(and(and(equals(reference('sites', '2022-03-01', 'full').kind, 'functionapp'), equals(parameters('functionsWorkerRuntime'), 'node')), not(empty(parameters('functionsDefaultNodeversion')))), parameters('functionsDefaultNodeversion'), null()), 'APPINSIGHTS_INSTRUMENTATIONKEY', if(and(not(empty(resourceId('Microsoft.Insights/components', format('ai-{0}', parameters('name'))))), parameters('enableInsights')), reference('appInsights').InstrumentationKey, null()), 'APPLICATIONINSIGHTS_CONNECTION_STRING', if(and(not(empty(resourceId('Microsoft.Insights/components', format('ai-{0}', parameters('name'))))), parameters('enableInsights')), reference('appInsights').ConnectionString, null())), parameters('extraAppSettings'))]", + "dependsOn": [ + "appInsights", + "networkConfig", + "sites" + ], + "metadata": { + "description": "Appsettings/config for the sites (app or functionapp)." + } + }, + "connectionString": { + "condition": "[not(empty(parameters('connectionStringProperties')))]", + "type": "Microsoft.Web/sites/config", + "apiVersion": "2022-03-01", + "name": "[format('{0}/{1}', parameters('name'), 'connectionstrings')]", + "kind": "string", + "properties": "[parameters('connectionStringProperties')]", + "dependsOn": [ + "sites" + ] + }, + "networkConfig": { + "condition": "[equals(parameters('enableVnetIntegration'), true())]", + "type": "Microsoft.Web/sites/networkConfig", + "apiVersion": "2022-03-01", + "name": "[format('{0}/{1}', parameters('name'), 'virtualNetwork')]", + "properties": { + "subnetResourceId": "[parameters('subnetId')]" + }, + "dependsOn": [ + "sites" + ] + }, + "azureFunction": { + "copy": { + "name": "azureFunction", + "count": "[length(parameters('functions'))]", + "mode": "serial", + "batchSize": 1 + }, + "type": "Microsoft.Web/sites/functions", + "apiVersion": "2021-02-01", + "name": "[format('{0}/{1}', parameters('name'), parameters('functions')[copyIndex()].name)]", + "properties": { + "language": "[parameters('functions')[copyIndex()].properties.language]", + "config": "[parameters('functions')[copyIndex()].properties.config]", + "isDisabled": "[parameters('functions')[copyIndex()].properties.isDisabled]", + "files": "[parameters('functions')[copyIndex()].properties.files]" + }, + "dependsOn": [ + "config", + "serverfarms", + "sites" + ], + "metadata": { + "description": "The resources actual is function where code exits." + } + }, + "sourcecontrol": { + "condition": "[parameters('enableSourceControl')]", + "type": "Microsoft.Web/sites/sourcecontrols", + "apiVersion": "2022-03-01", + "name": "[format('{0}/{1}', parameters('name'), 'web')]", + "properties": { + "repoUrl": "[parameters('repoUrl')]", + "branch": "[parameters('branch')]", + "isManualIntegration": "[parameters('isManualIntegration')]", + "isMercurial": "[parameters('isMercurial')]" + }, + "dependsOn": [ + "sites" + ] + }, + "extensions": { + "condition": "[parameters('enablePackageDeploy')]", + "type": "Microsoft.Web/sites/extensions", + "apiVersion": "2022-03-01", + "name": "[format('{0}/{1}', parameters('name'), 'MSDeploy')]", + "properties": { + "packageUri": "[parameters('functionPackageUri')]" + }, + "dependsOn": [ + "sites" + ], + "metadata": { + "description": "Deploy function app from zip file." + } + } + }, + "outputs": { + "siteId": { + "type": "string", + "metadata": { + "description": "Get resource id for app or functionapp." + }, + "value": "[resourceId('Microsoft.Web/sites', parameters('name'))]" + }, + "siteName": { + "type": "string", + "metadata": { + "description": "Get resource name for app or functionapp." + }, + "value": "[parameters('name')]" + }, + "serverfarmsId": { + "type": "string", + "metadata": { + "description": "Get resource ID of the app service plan." + }, + "value": "[resourceId('Microsoft.Web/serverfarms', parameters('name'))]" + }, + "serverfarmsName": { + "type": "string", + "metadata": { + "description": "Get name of the app service plan." + }, + "value": "[parameters('name')]" + }, + "functions": { + "type": "array", + "metadata": { + "description": "Array of functions having name , language,isDisabled and id of functions." + }, + "copy": { + "count": "[length(parameters('functions'))]", + "input": { + "name": "[parameters('functions')[copyIndex()].name]", + "language": "[parameters('functions')[copyIndex()].properties.language]", + "isDisabled": "[parameters('functions')[copyIndex()].properties.isDisabled]", + "id": "[format('{0}/functions/{1}', resourceId('Microsoft.Web/sites', parameters('name')), parameters('functions')[copyIndex()].name)]", + "files": "[parameters('functions')[copyIndex()].properties.files]" + } + } + }, + "sitePrincipalId": { + "type": "string", + "metadata": { + "description": "Principal Id of the identity assigned to the function app." + }, + "value": "[if(equals(reference('sites', '2022-03-01', 'full').identity.type, 'SystemAssigned'), reference('sites', '2022-03-01', 'full').identity.principalId, '')]" + } + } +} \ No newline at end of file diff --git a/modules/compute/function-app/test/functions_source_code/test_1_index.js b/modules/compute/function-app/test/functions_source_code/test_1_index.js new file mode 100644 index 0000000000..ab0f3ebe67 --- /dev/null +++ b/modules/compute/function-app/test/functions_source_code/test_1_index.js @@ -0,0 +1,8 @@ +module.exports = async function (context, myTimer) { + var timeStamp = new Date().toISOString(); + if (myTimer.IsPastDue) { + context.log('JavaScript is running late!'); + } + context.bindings.outputBlob2 = 'hello func2'; + context.log('written hello to blob func2', timeStamp); context.log('JavaScript timer trigger function ran!', timeStamp); +}; diff --git a/modules/compute/function-app/test/main.test.bicep b/modules/compute/function-app/test/main.test.bicep new file mode 100644 index 0000000000..6e14fe01a8 --- /dev/null +++ b/modules/compute/function-app/test/main.test.bicep @@ -0,0 +1,76 @@ +param name string = deployment().name +param location string = resourceGroup().location + +param tags object = { + costcenter: '000' + environment: 'dev' + location: resourceGroup().location +} + +module dependencies 'prereq.test.bicep' = { + scope: resourceGroup() + name: 'dependencies-${uniqueString(resourceGroup().id)}' + params: { + name: name + location: location + tags: tags + } +} + +module test1 '../main.bicep' = { + name: 'func01-${uniqueString(name)}' + dependsOn: [ + dependencies + ] + params: { + name: take(replace('func01-${name}', '.', ''), 55) + location: location + sku: { + name: 'Y1' + tier: 'Dynamic' + size: 'Y1' + family: 'Y' + capacity: 0 + } + tags: tags + storageAccountName: dependencies.outputs.saAccountName + storageAccountResourceGroup: resourceGroup().name + enableSourceControl: false + enableDockerContainer: true + dockerImage: 'mcr.microsoft.com/azure-functions/dotnet:4-appservice-quickstart' + serverOS: 'Linux' + } + scope: resourceGroup() +} + +// module test2 '../main.bicep' = { +// name: 'func02-${uniqueString(name)}' +// scope: resourceGroup() +// dependsOn: [ +// dependencies +// ] +// params: { +// name: take(replace('func02-${name}', '.', ''), 55) +// location: location +// sku: { +// name: 'EP1' +// tier: 'ElasticPremium' +// size: 'EP1' +// family: 'EP' +// capacity: 1 +// } +// tags: tags +// maximumElasticWorkerCount: 20 +// enableVnetIntegration: true +// enableInsights: true +// workspaceResourceId: dependencies.outputs.workspacesId +// subnetId: dependencies.outputs.subnetResourceIds +// functionsExtensionVersion: '~4' +// functionsWorkerRuntime: 'powershell' +// storageAccountName: dependencies.outputs.saAccountName +// storageAccountResourceGroup: resourceGroup().name +// enableSourceControl: true +// repoUrl: 'https://github.com/Azure/KeyVault-Secrets-Rotation-Redis-PowerShell.git' +// enableDockerContainer: false +// } +// } diff --git a/modules/compute/function-app/test/prereq.test.bicep b/modules/compute/function-app/test/prereq.test.bicep new file mode 100644 index 0000000000..480d9f4d17 --- /dev/null +++ b/modules/compute/function-app/test/prereq.test.bicep @@ -0,0 +1,96 @@ +param location string +param name string +param tags object + +var maxNameLength = 24 +var uniqueStoragename = length(uniqueString(name)) > maxNameLength ? substring(replace(guid(name, resourceGroup().name, subscription().id), '-', ''), 0, maxNameLength) : substring(replace(guid(name, resourceGroup().name, subscription().id), '-', ''), 0, maxNameLength) + +module vnet 'br/public:network/virtual-network:1.1.2' = { + name: 'vnet-network-${uniqueString(resourceGroup().id)}' + params: { + name: 'vnet-${uniqueString(resourceGroup().id)}' + addressPrefixes: [ + '10.0.0.0/16' + ] + subnets: [ + { + name: 'function-app' + addressPrefix: '10.0.3.0/24' + delegations: [ + { + name: 'Delegation' + properties: { + serviceName: 'Microsoft.Web/serverfarms' + } + } + ] + serviceEndpoints: [ + { + service: 'Microsoft.Storage' + } + ] + } + { + name: 'storage' + addressPrefix: '10.0.4.0/24' + serviceEndpoints: [ + { + service: 'Microsoft.Storage' + } + ] + } + ] + } +} + +resource storageAccount 'Microsoft.Storage/storageAccounts@2021-06-01' = { + name: uniqueStoragename + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' + properties: { + accessTier: 'Cool' + minimumTlsVersion: 'TLS1_2' + supportsHttpsTrafficOnly: true + allowBlobPublicAccess: true + allowSharedKeyAccess: true + networkAcls: { + bypass: 'AzureServices' + defaultAction: 'Allow' + } + publicNetworkAccess: 'Enabled' + } +} + +resource userAssignedIdentities 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: 'test2-${uniqueString(resourceGroup().id)}' + location: location +} + +resource workspaces 'Microsoft.OperationalInsights/workspaces@2022-10-01' = { + name: 'functionapp-workspace' + location: location + tags: tags + properties: { + sku: { + name: 'PerGB2018' + } + } +} + +@description('get Identity id.') +output userAssignedIdentitiesId string = userAssignedIdentities.id + +@description('get Identity name.') +output userAssignedIdentitiesName string = userAssignedIdentities.name + +@description('get OperationalInsights workspaces id.') +output workspacesId string = workspaces.id + +@description('get the subnets associated with the virtual network.') +output subnetResourceIds string = vnet.outputs.subnetResourceIds[0] + +@description('Name of the storage account used by function app.') +output saAccountName string = storageAccount.name diff --git a/modules/compute/function-app/test/upload-file.bicep b/modules/compute/function-app/test/upload-file.bicep new file mode 100644 index 0000000000..65930aa614 --- /dev/null +++ b/modules/compute/function-app/test/upload-file.bicep @@ -0,0 +1,35 @@ +param location string +param storageAccountName string +param containerName string + +var filename = 'functionapp.zip' +var zipfile = loadFileAsBase64('./data/functionapp.zip') + +resource storageAccount 'Microsoft.Storage/storageAccounts@2022-05-01' existing = { + name: storageAccountName +} + +resource uploadFunctionZip 'Microsoft.Resources/deploymentScripts@2020-10-01' = { + name: 'upload-zipfile' + location: location + kind: 'AzureCLI' + properties: { + azCliVersion: '2.26.1' + timeout: 'PT5M' + retentionInterval: 'PT1H' + environmentVariables: [ + { + name: 'AZURE_STORAGE_ACCOUNT' + value: storageAccountName + } + { + name: 'AZURE_STORAGE_KEY' + secureValue: storageAccount.listKeys().keys[0].value + } + ] + scriptContent: 'echo "${zipfile}" | base64 -d > ${filename} && az storage blob upload -f ${filename} -c ${containerName} -n ${filename}' + } +} + +@description('URI of the function app source code zip file.') +output zipFileUri string = '${storageAccount.properties.primaryEndpoints.blob}${containerName}/${filename}' diff --git a/modules/compute/function-app/version.json b/modules/compute/function-app/version.json new file mode 100644 index 0000000000..4727c64800 --- /dev/null +++ b/modules/compute/function-app/version.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "2.0", + "pathFilters": [ + "./main.json", + "./metadata.json" + ] +} \ No newline at end of file From 188a361012e01879a15b000fdd7fd646a678913b Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Tue, 12 Dec 2023 08:49:04 +0100 Subject: [PATCH 39/96] reset file to main --- .../compliance/module.tests.ps1 | 95 +++++++------------ 1 file changed, 32 insertions(+), 63 deletions(-) diff --git a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 index d199a0def7..097acbce2a 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 @@ -45,7 +45,7 @@ foreach ($moduleFolderPath in $moduleFolderPaths) { $builtTestFileMap = [System.Collections.Concurrent.ConcurrentDictionary[string, object]]::new() $pathsToBuild | ForEach-Object -Parallel { $dict = $using:builtTestFileMap - $builtTemplate = (bicep build $_ --stdout 2>$null) | ConvertFrom-Json -AsHashtable + $builtTemplate = bicep build $_ --stdout | ConvertFrom-Json -AsHashtable $null = $dict.TryAdd($_, $builtTemplate) } @@ -108,8 +108,7 @@ Describe 'File/folder tests' -Tag 'Modules' { # ========= try { $rawData = Invoke-WebRequest -Uri $telemetryCsvLink - } - catch { + } catch { $errorMessage = "Failed to download telemetry CSV file from [$telemetryCsvLink] due to [{0}]." -f $_.Exception.Message Write-Error $errorMessage Set-ItResult -Skipped -Because $errorMessage @@ -132,8 +131,7 @@ Describe 'File/folder tests' -Tag 'Modules' { if ($isOrphaned) { $pathExisting = Test-Path $orphanedFilePath $pathExisting | Should -Be $true -Because 'The module is orphaned.' - } - else { + } else { $pathExisting = Test-Path $orphanedFilePath $pathExisting | Should -Be $false -Because ('The module is not orphaned but owned by [{0}].' -f $relevantCSVRow.PrimaryModuleOwnerGHHandle) } @@ -425,17 +423,13 @@ Describe 'Module tests' -Tag 'Module' { $SchemaArray = @() if ($Schemaverion -eq $RgDeploymentSchema) { $SchemaOutput = $true - } - elseIf ($Schemaverion -eq $SubscriptionDeploymentSchema) { + } elseIf ($Schemaverion -eq $SubscriptionDeploymentSchema) { $SchemaOutput = $true - } - elseIf ($Schemaverion -eq $MgDeploymentSchema) { + } elseIf ($Schemaverion -eq $MgDeploymentSchema) { $SchemaOutput = $true - } - elseIf ($Schemaverion -eq $TenantDeploymentSchema) { + } elseIf ($Schemaverion -eq $TenantDeploymentSchema) { $SchemaOutput = $true - } - else { + } else { $SchemaOutput = $false } $SchemaArray += $SchemaOutput @@ -498,8 +492,7 @@ Describe 'Module tests' -Tag 'Module' { foreach ($Param in $Parameter) { if ($Param.substring(0, 1) -cnotmatch '[a-z]' -or $Param -match '-' -or $Param -match '_') { $CamelCasingFlag += $false - } - else { + } else { $CamelCasingFlag += $true } } @@ -524,8 +517,7 @@ Describe 'Module tests' -Tag 'Module' { foreach ($Variab in $Variable) { if ($Variab.substring(0, 1) -cnotmatch '[a-z]' -or $Variab -match '-') { $CamelCasingFlag += $false - } - else { + } else { $CamelCasingFlag += $true } } @@ -544,8 +536,7 @@ Describe 'Module tests' -Tag 'Module' { foreach ($Output in $Outputs) { if ($Output.substring(0, 1) -cnotmatch '[a-z]' -or $Output -match '-' -or $Output -match '_') { $CamelCasingFlag += $false - } - else { + } else { $CamelCasingFlag += $true } } @@ -562,8 +553,7 @@ Describe 'Module tests' -Tag 'Module' { # With the introduction of user defined types, the way resources are configured in the schema slightly changed. We have to account for that. if ($templateContent.resources.GetType().Name -eq 'Object[]') { $templateResources = $templateContent.resources - } - else { + } else { $templateResources = $templateContent.resources.Keys | ForEach-Object { $templateContent.resources[$_] } } @@ -581,8 +571,7 @@ Describe 'Module tests' -Tag 'Module' { # With the introduction of user defined types, the way resources are configured in the schema slightly changed. We have to account for that. if ($templateContent.resources.GetType().Name -eq 'Object[]') { $templateResources = $templateContent.resources - } - else { + } else { $templateResources = $templateContent.resources.Keys | ForEach-Object { $templateContent.resources[$_] } } @@ -606,8 +595,7 @@ Describe 'Module tests' -Tag 'Module' { # With the introduction of user defined types, the way resources are configured in the schema slightly changed. We have to account for that. if ($templateContent.resources.GetType().Name -eq 'Object[]') { $templateResources = $templateContent.resources - } - else { + } else { $templateResources = $templateContent.resources.Keys | ForEach-Object { $templateContent.resources[$_] } } @@ -636,8 +624,7 @@ Describe 'Module tests' -Tag 'Module' { # ========= try { $rawData = Invoke-WebRequest -Uri $telemetryCsvLink - } - catch { + } catch { $errorMessage = "Failed to download telemetry CSV file from [$telemetryCsvLink] due to [{0}]." -f $_.Exception.Message Write-Error $errorMessage Set-ItResult -Skipped -Because $errorMessage @@ -663,8 +650,7 @@ Describe 'Module tests' -Tag 'Module' { # With the introduction of user defined types, the way resources are configured in the schema slightly changed. We have to account for that. if ($templateContent.resources.GetType().Name -eq 'Object[]') { $templateResources = $templateContent.resources - } - else { + } else { $templateResources = $templateContent.resources.Keys | ForEach-Object { $templateContent.resources[$_] } } $telemetryDeploymentName = ($templateResources | Where-Object { $_.condition -like "*telemetry*" }).name # The AVM telemetry prefix @@ -685,8 +671,7 @@ Describe 'Module tests' -Tag 'Module' { if ($Locationparamoutput -contains 'Location') { if ($Locationparamoutputvalue -eq '[resourceGroup().Location]' -or $Locationparamoutputvalue -eq 'global') { $LocationFlag = $true - } - else { + } else { $LocationFlag = $false } @@ -747,8 +732,7 @@ Describe 'Module tests' -Tag 'Module' { $readMeFileContentHeader = (Get-Content -Path $readMeFilePath)[0] if ($readMeFileContentHeader -match '^.*`\[(.+)\]`.*') { $primaryResourceType = $matches[1] - } - else { + } else { Write-Error "Cannot identity primary resource type in readme header [$readMeFileContentHeader] and cannot execute the test." return } @@ -756,8 +740,7 @@ Describe 'Module tests' -Tag 'Module' { # With the introduction of user defined types, the way resources are configured in the schema slightly changed. We have to account for that. if ($templateContent.resources.GetType().Name -eq 'Object[]') { $templateResources = $templateContent.resources - } - else { + } else { $templateResources = $templateContent.resources.Keys | ForEach-Object { $templateContent.resources[$_] } } @@ -783,8 +766,7 @@ Describe 'Module tests' -Tag 'Module' { $readMeFileContentHeader = (Get-Content -Path $readMeFilePath)[0] if ($readMeFileContentHeader -match '^.*`\[(.+)\]`.*') { $primaryResourceType = $matches[1] - } - else { + } else { Write-Error "Cannot identity primary resource type in readme header [$readMeFileContentHeader] and cannot execute the test." return } @@ -792,8 +774,7 @@ Describe 'Module tests' -Tag 'Module' { # With the introduction of user defined types, the way resources are configured in the schema slightly changed. We have to account for that. if ($templateContent.resources.GetType().Name -eq 'Object[]') { $templateResources = $templateContent.resources - } - else { + } else { $templateResources = $templateContent.resources.Keys | ForEach-Object { $templateContent.resources[$_] } } @@ -1074,12 +1055,10 @@ Describe 'Module tests' -Tag 'Module' { $rawReponse = Invoke-WebRequest -Uri $expectedUdtUrl if (($rawReponse.Headers['Content-Type'] | Out-String) -like "*text/plain*") { $expectedSchemaFull = $rawReponse.Content -split '\n' - } - else { + } else { throw "Failed to fetch schema from [$expectedUdtUrl]. Skipping schema check" } - } - catch { + } catch { Write-Warning "Failed to fetch schema from [$expectedUdtUrl]. Skipping schema check" return } @@ -1098,8 +1077,7 @@ Describe 'Module tests' -Tag 'Module' { foreach ($finding in (Compare-Object $implementedSchema $expectedSchema)) { if ($finding.SideIndicator -eq '=>') { $formattedDiff += ('+ {0}' -f $finding.InputObject) - } - elseif ($finding.SideIndicator -eq '<=') { + } elseif ($finding.SideIndicator -eq '<=') { $formattedDiff += ('- {0}' -f $finding.InputObject) } } @@ -1116,8 +1094,7 @@ Describe 'Module tests' -Tag 'Module' { } } } - } - else { + } else { Set-ItResult -Skipped -Because "the module template has no [$parameterName] parameter." } } @@ -1130,8 +1107,7 @@ Describe 'Module tests' -Tag 'Module' { if ($templateFileContent.definitions.Keys -contains 'managedIdentitiesType' -and $templateFileContent.definitions.managedIdentitiesType.properties.keys -contains 'systemAssigned') { $templateFileContent.outputs.Keys | Should -Contain 'systemAssignedMIPrincipalId' -Because 'The AVM specs require a this output. For information please review the [AVM Specs](https://aka.ms/avm/interfaces/managed-identities).' - } - else { + } else { Set-ItResult -Skipped -Because 'the module template has no [managedIdentitiesType] UDT definition or does not support system-assigned-identities.' } } @@ -1144,8 +1120,7 @@ Describe 'Module tests' -Tag 'Module' { if ($templateFileContent.parameters.Keys -contains 'tags') { $templateFileContent.parameters.tags.nullable | Should -Be $true -Because 'The AVM specs require a specific format. For information please review the [AVM Specs](https://aka.ms/avm/interfaces/tags).' - } - else { + } else { Set-ItResult -Skipped -Because 'the module template has no [tags] parameter.' } } @@ -1191,8 +1166,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { if (($testFileContent | Out-String) -match "param serviceShort string = '(.*)'") { $Matches[1] | Should -BeLike '*min' - } - else { + } else { Set-ItResult -Skipped -Because 'the module test deployment file should contain a parameter [serviceShort] using the syntax [param serviceShort string = ''*min''] but it doesn''t.' } } @@ -1205,8 +1179,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { if (($testFileContent | Out-String) -match "param serviceShort string = '(.*)'") { $Matches[1] | Should -BeLike '*max' - } - else { + } else { Set-ItResult -Skipped -Because 'the module test deployment file should contain a parameter [serviceShort] using the syntax [param serviceShort string = ''*max''] but it doesn''t.' } } @@ -1219,8 +1192,7 @@ Describe 'Test file tests' -Tag 'TestTemplate' { if (($testFileContent | Out-String) -match "param serviceShort string = '(.*)'") { $Matches[1] | Should -BeLike '*waf' - } - else { + } else { Set-ItResult -Skipped -Because 'the module test deployment file should contain a parameter [serviceShort] using the syntax [param serviceShort string = ''*waf''] but it doesn''t.' } } @@ -1293,8 +1265,7 @@ Describe 'API version tests' -Tag 'ApiCheck' { try { $apiSpecs = Invoke-WebRequest -Uri $ApiSpecsFileUri $ApiVersions = ConvertFrom-Json $apiSpecs.Content -AsHashtable - } - catch { + } catch { Write-Warning "Failed to download API specs file from [$ApiSpecsFileUri]. Skipping API tests" Set-ItResult -Skipped -Because "Failed to download API specs file from [$ApiSpecsFileUri]. Skipping API tests." return @@ -1407,8 +1378,7 @@ Describe 'API version tests' -Tag 'ApiCheck' { # We allow the latest 5 including previews (in case somebody wants to use preview), or the latest 3 non-preview $approvedApiVersions += $resourceTypeApiVersions | Select-Object -Last 5 $approvedApiVersions += $resourceTypeApiVersions | Where-Object { $_ -notlike '*-preview' } | Select-Object -Last 5 - } - else { + } else { # We allow the latest 5 non-preview preview $approvedApiVersions += $resourceTypeApiVersions | Where-Object { $_ -notlike '*-preview' } | Select-Object -Last 5 } @@ -1421,8 +1391,7 @@ Describe 'API version tests' -Tag 'ApiCheck' { # The original failed test was # $approvedApiVersions | Should -Contain $TargetApi - } - else { + } else { # Provide a warning if an API version is second to next to expire. $indexOfVersion = $approvedApiVersions.IndexOf($TargetApi) From 63c8c9c04292355a5c73530e086233dd4cb144b4 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Tue, 12 Dec 2023 08:52:21 +0100 Subject: [PATCH 40/96] fix --- .../pipelines/staticValidation/compliance/module.tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 index 097acbce2a..5a007c118a 100644 --- a/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 +++ b/avm/utilities/pipelines/staticValidation/compliance/module.tests.ps1 @@ -45,7 +45,7 @@ foreach ($moduleFolderPath in $moduleFolderPaths) { $builtTestFileMap = [System.Collections.Concurrent.ConcurrentDictionary[string, object]]::new() $pathsToBuild | ForEach-Object -Parallel { $dict = $using:builtTestFileMap - $builtTemplate = bicep build $_ --stdout | ConvertFrom-Json -AsHashtable + $builtTemplate = (bicep build $_ --stdout 2>$null) | ConvertFrom-Json -AsHashtable $null = $dict.TryAdd($_, $builtTemplate) } From 6b25801b90abaae94e666d703d85a8b34f4dc2f3 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Wed, 20 Dec 2023 13:21:38 +0100 Subject: [PATCH 41/96] change agent --- avm/res/compute/virtual-machine/main.bicep | 32 +++++++++------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/avm/res/compute/virtual-machine/main.bicep b/avm/res/compute/virtual-machine/main.bicep index 18ae9d33e5..96594dd5ea 100644 --- a/avm/res/compute/virtual-machine/main.bicep +++ b/avm/res/compute/virtual-machine/main.bicep @@ -516,29 +516,23 @@ module vm_microsoftAntiMalwareExtension 'extension/main.bicep' = if (extensionAn } } -resource vm_logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2021-06-01' existing = if (!empty(monitoringWorkspaceId)) { - name: last(split((!empty(monitoringWorkspaceId) ? monitoringWorkspaceId : 'law'), '/'))! - scope: az.resourceGroup(split((!empty(monitoringWorkspaceId) ? monitoringWorkspaceId : '//'), '/')[2], split((!empty(monitoringWorkspaceId) ? monitoringWorkspaceId : '////'), '/')[4]) -} +// resource vm_logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2021-06-01' existing = if (!empty(monitoringWorkspaceId)) { +// name: last(split((!empty(monitoringWorkspaceId) ? monitoringWorkspaceId : 'law'), '/'))! +// scope: az.resourceGroup(split((!empty(monitoringWorkspaceId) ? monitoringWorkspaceId : '//'), '/')[2], split((!empty(monitoringWorkspaceId) ? monitoringWorkspaceId : '////'), '/')[4]) +// } -module vm_microsoftMonitoringAgentExtension 'extension/main.bicep' = if (extensionMonitoringAgentConfig.enabled) { - name: '${uniqueString(deployment().name, location)}-VM-MicrosoftMonitoringAgent' +module vm_azureMonitoringAgentExtension 'extension/main.bicep' = if (extensionMonitoringAgentConfig.enabled) { + name: '${uniqueString(deployment().name, location)}-VM-AzureMonitoringAgent' params: { virtualMachineName: vm.name - name: 'MicrosoftMonitoringAgent' + name: 'AzureMonitoringAgent' location: location - publisher: 'Microsoft.EnterpriseCloud.Monitoring' - type: osType == 'Windows' ? 'MicrosoftMonitoringAgent' : 'OmsAgentForLinux' - typeHandlerVersion: contains(extensionMonitoringAgentConfig, 'typeHandlerVersion') ? extensionMonitoringAgentConfig.typeHandlerVersion : (osType == 'Windows' ? '1.0' : '1.7') + publisher: 'Microsoft.Azure.Monitor' + type: osType == 'Windows' ? 'AzureMonitorWindowsAgent' : 'AzureMonitorLinuxAgent' + typeHandlerVersion: contains(extensionMonitoringAgentConfig, 'typeHandlerVersion') ? extensionMonitoringAgentConfig.typeHandlerVersion : (osType == 'Windows' ? '1.0' : '1.21') autoUpgradeMinorVersion: contains(extensionMonitoringAgentConfig, 'autoUpgradeMinorVersion') ? extensionMonitoringAgentConfig.autoUpgradeMinorVersion : true - enableAutomaticUpgrade: contains(extensionMonitoringAgentConfig, 'enableAutomaticUpgrade') ? extensionMonitoringAgentConfig.enableAutomaticUpgrade : false - settings: { - workspaceId: !empty(monitoringWorkspaceId) ? vm_logAnalyticsWorkspace.properties.customerId : '' - } + enableAutomaticUpgrade: contains(extensionMonitoringAgentConfig, 'enableAutomaticUpgrade') ? extensionMonitoringAgentConfig.enableAutomaticUpgrade : true tags: extensionMonitoringAgentConfig.?tags ?? tags - protectedSettings: { - workspaceKey: !empty(monitoringWorkspaceId) ? vm_logAnalyticsWorkspace.listKeys().primarySharedKey : '' - } } } @@ -628,7 +622,7 @@ module vm_azureDiskEncryptionExtension 'extension/main.bicep' = if (extensionAzu } dependsOn: [ vm_customScriptExtension - vm_microsoftMonitoringAgentExtension + vm_azureMonitoringAgentExtension ] } @@ -647,7 +641,7 @@ module vm_backup 'modules/protected-item.bicep' = if (!empty(backupVaultName)) { dependsOn: [ vm_aadJoinExtension vm_domainJoinExtension - vm_microsoftMonitoringAgentExtension + vm_azureMonitoringAgentExtension vm_microsoftAntiMalwareExtension vm_networkWatcherAgentExtension vm_dependencyAgentExtension From e29f14ef6a686e6845ae312f87d23949aaab0416 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Wed, 20 Dec 2023 13:48:12 +0100 Subject: [PATCH 42/96] update --- avm/res/compute/virtual-machine/main.json | 86 +++++++++-------------- 1 file changed, 33 insertions(+), 53 deletions(-) diff --git a/avm/res/compute/virtual-machine/main.json b/avm/res/compute/virtual-machine/main.json index ebbcd74022..fe50386aac 100644 --- a/avm/res/compute/virtual-machine/main.json +++ b/avm/res/compute/virtual-machine/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "3578264423457994509" + "version": "0.24.24.22086", + "templateHash": "5920374298787956143" }, "name": "Virtual Machines", "description": "This module deploys a Virtual Machine with one or multiple NICs and optionally one or multiple public IPs.", @@ -910,15 +910,6 @@ "vm" ] }, - "vm_logAnalyticsWorkspace": { - "condition": "[not(empty(parameters('monitoringWorkspaceId')))]", - "existing": true, - "type": "Microsoft.OperationalInsights/workspaces", - "apiVersion": "2021-06-01", - "subscriptionId": "[split(if(not(empty(parameters('monitoringWorkspaceId'))), parameters('monitoringWorkspaceId'), '//'), '/')[2]]", - "resourceGroup": "[split(if(not(empty(parameters('monitoringWorkspaceId'))), parameters('monitoringWorkspaceId'), '////'), '/')[4]]", - "name": "[last(split(if(not(empty(parameters('monitoringWorkspaceId'))), parameters('monitoringWorkspaceId'), 'law'), '/'))]" - }, "vm_lock": { "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", @@ -1527,8 +1518,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "9445653680126696241" + "version": "0.24.24.22086", + "templateHash": "10332103716678024514" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -1733,8 +1724,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "9445653680126696241" + "version": "0.24.24.22086", + "templateHash": "10332103716678024514" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -1934,8 +1925,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "9445653680126696241" + "version": "0.24.24.22086", + "templateHash": "10332103716678024514" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -2092,11 +2083,11 @@ "vm" ] }, - "vm_microsoftMonitoringAgentExtension": { + "vm_azureMonitoringAgentExtension": { "condition": "[parameters('extensionMonitoringAgentConfig').enabled]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-VM-MicrosoftMonitoringAgent', uniqueString(deployment().name, parameters('location')))]", + "name": "[format('{0}-VM-AzureMonitoringAgent', uniqueString(deployment().name, parameters('location')))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -2107,30 +2098,20 @@ "value": "[parameters('name')]" }, "name": { - "value": "MicrosoftMonitoringAgent" + "value": "AzureMonitoringAgent" }, "location": { "value": "[parameters('location')]" }, "publisher": { - "value": "Microsoft.EnterpriseCloud.Monitoring" + "value": "Microsoft.Azure.Monitor" }, - "type": "[if(equals(parameters('osType'), 'Windows'), createObject('value', 'MicrosoftMonitoringAgent'), createObject('value', 'OmsAgentForLinux'))]", - "typeHandlerVersion": "[if(contains(parameters('extensionMonitoringAgentConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionMonitoringAgentConfig').typeHandlerVersion), if(equals(parameters('osType'), 'Windows'), createObject('value', '1.0'), createObject('value', '1.7')))]", + "type": "[if(equals(parameters('osType'), 'Windows'), createObject('value', 'AzureMonitorWindowsAgent'), createObject('value', 'AzureMonitorLinuxAgent'))]", + "typeHandlerVersion": "[if(contains(parameters('extensionMonitoringAgentConfig'), 'typeHandlerVersion'), createObject('value', parameters('extensionMonitoringAgentConfig').typeHandlerVersion), if(equals(parameters('osType'), 'Windows'), createObject('value', '1.0'), createObject('value', '1.21')))]", "autoUpgradeMinorVersion": "[if(contains(parameters('extensionMonitoringAgentConfig'), 'autoUpgradeMinorVersion'), createObject('value', parameters('extensionMonitoringAgentConfig').autoUpgradeMinorVersion), createObject('value', true()))]", - "enableAutomaticUpgrade": "[if(contains(parameters('extensionMonitoringAgentConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionMonitoringAgentConfig').enableAutomaticUpgrade), createObject('value', false()))]", - "settings": { - "value": { - "workspaceId": "[if(not(empty(parameters('monitoringWorkspaceId'))), reference('vm_logAnalyticsWorkspace').customerId, '')]" - } - }, + "enableAutomaticUpgrade": "[if(contains(parameters('extensionMonitoringAgentConfig'), 'enableAutomaticUpgrade'), createObject('value', parameters('extensionMonitoringAgentConfig').enableAutomaticUpgrade), createObject('value', true()))]", "tags": { "value": "[coalesce(tryGet(parameters('extensionMonitoringAgentConfig'), 'tags'), parameters('tags'))]" - }, - "protectedSettings": { - "value": { - "workspaceKey": "[if(not(empty(parameters('monitoringWorkspaceId'))), listKeys(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(if(not(empty(parameters('monitoringWorkspaceId'))), parameters('monitoringWorkspaceId'), '//'), '/')[2], split(if(not(empty(parameters('monitoringWorkspaceId'))), parameters('monitoringWorkspaceId'), '////'), '/')[4]), 'Microsoft.OperationalInsights/workspaces', last(split(if(not(empty(parameters('monitoringWorkspaceId'))), parameters('monitoringWorkspaceId'), 'law'), '/'))), '2021-06-01').primarySharedKey, '')]" - } } }, "template": { @@ -2140,8 +2121,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "9445653680126696241" + "version": "0.24.24.22086", + "templateHash": "10332103716678024514" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -2295,8 +2276,7 @@ } }, "dependsOn": [ - "vm", - "vm_logAnalyticsWorkspace" + "vm" ] }, "vm_dependencyAgentExtension": { @@ -2337,8 +2317,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "9445653680126696241" + "version": "0.24.24.22086", + "templateHash": "10332103716678024514" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -2533,8 +2513,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "9445653680126696241" + "version": "0.24.24.22086", + "templateHash": "10332103716678024514" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -2733,8 +2713,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "9445653680126696241" + "version": "0.24.24.22086", + "templateHash": "10332103716678024514" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -2941,8 +2921,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "9445653680126696241" + "version": "0.24.24.22086", + "templateHash": "10332103716678024514" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3142,8 +3122,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "9445653680126696241" + "version": "0.24.24.22086", + "templateHash": "10332103716678024514" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3298,8 +3278,8 @@ }, "dependsOn": [ "vm", - "vm_customScriptExtension", - "vm_microsoftMonitoringAgentExtension" + "vm_azureMonitoringAgentExtension", + "vm_customScriptExtension" ] }, "vm_backup": { @@ -3342,8 +3322,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "17653239179026707614" + "version": "0.24.24.22086", + "templateHash": "12595215410082531283" }, "name": "Recovery Service Vaults Protection Container Protected Item", "description": "This module deploys a Recovery Services Vault Protection Container Protected Item.", @@ -3447,12 +3427,12 @@ "dependsOn": [ "vm", "vm_aadJoinExtension", + "vm_azureMonitoringAgentExtension", "vm_customScriptExtension", "vm_dependencyAgentExtension", "vm_desiredStateConfigurationExtension", "vm_domainJoinExtension", "vm_microsoftAntiMalwareExtension", - "vm_microsoftMonitoringAgentExtension", "vm_networkWatcherAgentExtension" ] } From 50c9c4111ba580d53658afbe25c835df61838937 Mon Sep 17 00:00:00 2001 From: Rainer Halanek <61878316+rahalan@users.noreply.github.com> Date: Wed, 20 Dec 2023 14:48:15 +0100 Subject: [PATCH 43/96] Update .github/workflows/avm.res.compute.virtual-machine.yml Co-authored-by: Erika Gressi <56914614+eriqua@users.noreply.github.com> --- .github/workflows/avm.res.compute.virtual-machine.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/avm.res.compute.virtual-machine.yml b/.github/workflows/avm.res.compute.virtual-machine.yml index fb238043a1..5c4a56625e 100644 --- a/.github/workflows/avm.res.compute.virtual-machine.yml +++ b/.github/workflows/avm.res.compute.virtual-machine.yml @@ -71,7 +71,7 @@ jobs: # Call reusable workflow # ############################## call-workflow-passing-data: - name: "Module" + name: "Run" needs: - job_initialize_pipeline uses: ./.github/workflows/avm.template.module.yml From f843952e686424c6014e5c0b10ac10ff48009327 Mon Sep 17 00:00:00 2001 From: Rainer Halanek <61878316+rahalan@users.noreply.github.com> Date: Wed, 20 Dec 2023 14:55:12 +0100 Subject: [PATCH 44/96] Update avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep Co-authored-by: Erika Gressi <56914614+eriqua@users.noreply.github.com> --- .../virtual-machine/tests/e2e/linux.defaults/main.test.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep index 9009f7baaa..0c46974e4b 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep @@ -15,7 +15,7 @@ param resourceGroupName string = 'dep-${namePrefix}-compute.virtualMachines-${se 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 = 'cvmlindef' +param serviceShort string = 'cvmlinmin' @description('Optional. A token to inject into the name of each resource.') param namePrefix string = '#_namePrefix_#' From 000141e2cf5120f97f4c2a55db566a1f85fa4bbc Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Wed, 20 Dec 2023 14:58:38 +0100 Subject: [PATCH 45/96] update readme --- avm/res/compute/virtual-machine/README.md | 23 +++---------------- avm/res/compute/virtual-machine/main.bicep | 3 --- .../tests/e2e/waf-aligned/main.test.bicep | 1 - .../tests/e2e/windows.max/main.test.bicep | 1 - 4 files changed, 3 insertions(+), 25 deletions(-) diff --git a/avm/res/compute/virtual-machine/README.md b/avm/res/compute/virtual-machine/README.md index f86be60223..e4580b9a65 100644 --- a/avm/res/compute/virtual-machine/README.md +++ b/avm/res/compute/virtual-machine/README.md @@ -232,7 +232,7 @@ This instance deploys the module with the minimum set of required parameters. ```bicep module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { - name: '${uniqueString(deployment().name, location)}-test-cvmlindef' + name: '${uniqueString(deployment().name, location)}-test-cvmlinmin' params: { // Required parameters adminUsername: 'localAdminUser' @@ -267,7 +267,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { // Non-required parameters disablePasswordAuthentication: true location: '' - name: 'cvmlindef' + name: 'cvmlinmin' publicKeys: [ { keyData: '' @@ -340,7 +340,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { "value": "" }, "name": { - "value": "cvmlindef" + "value": "cvmlinmin" }, "publicKeys": { "value": [ @@ -599,7 +599,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { '' ] } - monitoringWorkspaceId: '' name: 'cvmwinwaf' patchMode: 'AutomaticByPlatform' proximityPlacementGroupResourceId: '' @@ -924,9 +923,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { ] } }, - "monitoringWorkspaceId": { - "value": "" - }, "name": { "value": "cvmwinwaf" }, @@ -1459,7 +1455,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { '' ] } - monitoringWorkspaceId: '' name: 'cvmwinmax' patchMode: 'AutomaticByPlatform' proximityPlacementGroupResourceId: '' @@ -1784,9 +1779,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { ] } }, - "monitoringWorkspaceId": { - "value": "" - }, "name": { "value": "cvmwinmax" }, @@ -2043,7 +2035,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { | [`lock`](#parameter-lock) | object | The lock settings of the service. | | [`managedIdentities`](#parameter-managedidentities) | object | The managed identity definition for this resource. The system-assigned managed identity will automatically be enabled if extensionAadJoinConfig.enabled = "True". | | [`maxPriceForLowPriorityVm`](#parameter-maxpriceforlowpriorityvm) | string | Specifies the maximum price you are willing to pay for a low priority VM/VMSS. This price is in US Dollars. | -| [`monitoringWorkspaceId`](#parameter-monitoringworkspaceid) | string | Resource ID of the monitoring log analytics workspace. Must be set when extensionMonitoringAgentConfig is set to true. | | [`name`](#parameter-name) | string | The name of the virtual machine to be created. You should use a unique prefix to reduce name collisions in Active Directory. If no value is provided, a 10 character long unique string will be generated based on the Resource Group's name. | | [`patchAssessmentMode`](#parameter-patchassessmentmode) | string | VM guest patching assessment mode. Set it to 'AutomaticByPlatform' to enable automatically check for updates every 24 hours. | | [`patchMode`](#parameter-patchmode) | string | VM guest patching orchestration mode. 'AutomaticByOS' & 'Manual' are for Windows only, 'ImageDefault' for Linux only. Refer to 'https://learn.microsoft.com/en-us/azure/virtual-machines/automatic-vm-guest-patching'. | @@ -2540,14 +2531,6 @@ Specifies the maximum price you are willing to pay for a low priority VM/VMSS. T - Type: string - Default: `''` -### Parameter: `monitoringWorkspaceId` - -Resource ID of the monitoring log analytics workspace. Must be set when extensionMonitoringAgentConfig is set to true. - -- Required: No -- Type: string -- Default: `''` - ### Parameter: `name` The name of the virtual machine to be created. You should use a unique prefix to reduce name collisions in Active Directory. If no value is provided, a 10 character long unique string will be generated based on the Resource Group's name. diff --git a/avm/res/compute/virtual-machine/main.bicep b/avm/res/compute/virtual-machine/main.bicep index 96594dd5ea..9108b33765 100644 --- a/avm/res/compute/virtual-machine/main.bicep +++ b/avm/res/compute/virtual-machine/main.bicep @@ -149,9 +149,6 @@ param extensionMonitoringAgentConfig object = { enabled: false } -@description('Optional. Resource ID of the monitoring log analytics workspace. Must be set when extensionMonitoringAgentConfig is set to true.') -param monitoringWorkspaceId string = '' - @description('Optional. The configuration for the [Dependency Agent] extension. Must at least contain the ["enabled": true] property to be executed.') param extensionDependencyAgentConfig object = { enabled: false diff --git a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep index 80cff1e036..b31999c21b 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep @@ -298,7 +298,6 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' kind: 'CanNotDelete' name: 'myCustomLockName' } - monitoringWorkspaceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId proximityPlacementGroupResourceId: nestedDependencies.outputs.proximityPlacementGroupResourceId roleAssignments: [ { diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep index 1b012ebcab..0aae1aa3ce 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep @@ -298,7 +298,6 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' kind: 'CanNotDelete' name: 'myCustomLockName' } - monitoringWorkspaceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId proximityPlacementGroupResourceId: nestedDependencies.outputs.proximityPlacementGroupResourceId roleAssignments: [ { From b51506986d1a30dcabfb26856675f7d4ce6fc31c Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Wed, 20 Dec 2023 15:11:41 +0100 Subject: [PATCH 46/96] change WInRm object to array --- avm/res/compute/virtual-machine/README.md | 6 +++--- avm/res/compute/virtual-machine/main.bicep | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/avm/res/compute/virtual-machine/README.md b/avm/res/compute/virtual-machine/README.md index e4580b9a65..1723315640 100644 --- a/avm/res/compute/virtual-machine/README.md +++ b/avm/res/compute/virtual-machine/README.md @@ -2051,7 +2051,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { | [`timeZone`](#parameter-timezone) | string | Specifies the time zone of the virtual machine. e.g. 'Pacific Standard Time'. Possible values can be `TimeZoneInfo.id` value from time zones returned by `TimeZoneInfo.GetSystemTimeZones`. | | [`ultraSSDEnabled`](#parameter-ultrassdenabled) | bool | The flag that enables or disables a capability to have one or more managed data disks with UltraSSD_LRS storage account type on the VM or VMSS. Managed disks with storage account type UltraSSD_LRS can be added to a virtual machine or virtual machine scale set only if this property is enabled. | | [`vTpmEnabled`](#parameter-vtpmenabled) | bool | Specifies whether vTPM should be enabled on the virtual machine. This parameter is part of the UefiSettings. SecurityType should be set to TrustedLaunch to enable UefiSettings. | -| [`winRM`](#parameter-winrm) | object | Specifies the Windows Remote Management listeners. This enables remote Windows PowerShell. - WinRMConfiguration object. | +| [`winRM`](#parameter-winrm) | array | Specifies the Windows Remote Management listeners. This enables remote Windows PowerShell. - WinRMConfiguration object. | **Generated parameters** @@ -2769,8 +2769,8 @@ Specifies whether vTPM should be enabled on the virtual machine. This parameter Specifies the Windows Remote Management listeners. This enables remote Windows PowerShell. - WinRMConfiguration object. - Required: No -- Type: object -- Default: `{}` +- Type: array +- Default: `[]` ### Parameter: `baseTime` diff --git a/avm/res/compute/virtual-machine/main.bicep b/avm/res/compute/virtual-machine/main.bicep index 9108b33765..d77d77cc52 100644 --- a/avm/res/compute/virtual-machine/main.bicep +++ b/avm/res/compute/virtual-machine/main.bicep @@ -242,7 +242,7 @@ param timeZone string = '' param additionalUnattendContent array = [] @description('Optional. Specifies the Windows Remote Management listeners. This enables remote Windows PowerShell. - WinRMConfiguration object.') -param winRM object = {} +param winRM array = [] @description('Required. The configuration profile of automanage.') @allowed([ From ee4b7cb95c08544c8eb558dccda04b9b87e2169d Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 21 Dec 2023 11:12:09 +0100 Subject: [PATCH 47/96] add PSRule exceptions --- avm/res/compute/virtual-machine/README.md | 6 +++--- .../tests/e2e/windows.defaults/main.test.bicep | 2 +- .../staticValidation/psrule/.ps-rule/min-suppress.Rule.yaml | 3 +++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/avm/res/compute/virtual-machine/README.md b/avm/res/compute/virtual-machine/README.md index 1723315640..3ba2bf038b 100644 --- a/avm/res/compute/virtual-machine/README.md +++ b/avm/res/compute/virtual-machine/README.md @@ -1108,7 +1108,7 @@ This instance deploys the module with the minimum set of required parameters. ```bicep module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { - name: '${uniqueString(deployment().name, location)}-test-cvmwindef' + name: '${uniqueString(deployment().name, location)}-test-cvmwinmin' params: { // Required parameters adminUsername: 'localAdminUser' @@ -1140,7 +1140,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { // Non-required parameters adminPassword: '' location: '' - name: 'cvmwindef' + name: 'cvmwinmin' } } ``` @@ -1204,7 +1204,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { "value": "" }, "name": { - "value": "cvmwindef" + "value": "cvmwinmin" } } } diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows.defaults/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.defaults/main.test.bicep index 59a9c66b6a..b20a5225f7 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/windows.defaults/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/windows.defaults/main.test.bicep @@ -15,7 +15,7 @@ param resourceGroupName string = 'dep-${namePrefix}-compute.virtualMachines-${se 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 = 'cvmwindef' +param serviceShort string = 'cvmwinmin' @description('Optional. The password to leverage for the login.') @secure() diff --git a/avm/utilities/pipelines/staticValidation/psrule/.ps-rule/min-suppress.Rule.yaml b/avm/utilities/pipelines/staticValidation/psrule/.ps-rule/min-suppress.Rule.yaml index 1e3de7fe85..318f8cdd60 100644 --- a/avm/utilities/pipelines/staticValidation/psrule/.ps-rule/min-suppress.Rule.yaml +++ b/avm/utilities/pipelines/staticValidation/psrule/.ps-rule/min-suppress.Rule.yaml @@ -23,6 +23,9 @@ spec: - Azure.TrafficManager.Protocol # Azure Load Balancer specific - Azure.LB.Probe + # Azure Virtual Machine + - Azure.VM.AMA + - Azure.VM.Standalone if: name: "." contains: From c3d50bda44c7c0f6ffefb5c6f6da644367cadadd Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 21 Dec 2023 11:22:24 +0100 Subject: [PATCH 48/96] update json --- avm/res/compute/virtual-machine/main.json | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/avm/res/compute/virtual-machine/main.json b/avm/res/compute/virtual-machine/main.json index fe50386aac..75cf77242f 100644 --- a/avm/res/compute/virtual-machine/main.json +++ b/avm/res/compute/virtual-machine/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "5920374298787956143" + "templateHash": "17379109609699248366" }, "name": "Virtual Machines", "description": "This module deploys a Virtual Machine with one or multiple NICs and optionally one or multiple public IPs.", @@ -526,13 +526,6 @@ "description": "Optional. The configuration for the [Monitoring Agent] extension. Must at least contain the [\"enabled\": true] property to be executed." } }, - "monitoringWorkspaceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Resource ID of the monitoring log analytics workspace. Must be set when extensionMonitoringAgentConfig is set to true." - } - }, "extensionDependencyAgentConfig": { "type": "object", "defaultValue": { @@ -704,8 +697,8 @@ } }, "winRM": { - "type": "object", - "defaultValue": {}, + "type": "array", + "defaultValue": [], "metadata": { "description": "Optional. Specifies the Windows Remote Management listeners. This enables remote Windows PowerShell. - WinRMConfiguration object." } From 30cc1cb2a3fc0109c6465a4d2ec360c30ee8aaa9 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Fri, 22 Dec 2023 10:25:50 +0100 Subject: [PATCH 49/96] add psrule supression --- .../psrule/.ps-rule/min-suppress.Rule.yaml | 3 +++ .../staticValidation/psrule/ps-rule.yaml | 19 ++++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/avm/utilities/pipelines/staticValidation/psrule/.ps-rule/min-suppress.Rule.yaml b/avm/utilities/pipelines/staticValidation/psrule/.ps-rule/min-suppress.Rule.yaml index d9678a83a5..f8bd41fc01 100644 --- a/avm/utilities/pipelines/staticValidation/psrule/.ps-rule/min-suppress.Rule.yaml +++ b/avm/utilities/pipelines/staticValidation/psrule/.ps-rule/min-suppress.Rule.yaml @@ -25,6 +25,9 @@ spec: - Azure.LB.Probe # App Managed Environment specific - Azure.ContainerApp.PublicAccess + # Azure Virtual Machine + - Azure.VM.AMA + - Azure.VM.Standalone if: name: "." contains: diff --git a/avm/utilities/pipelines/staticValidation/psrule/ps-rule.yaml b/avm/utilities/pipelines/staticValidation/psrule/ps-rule.yaml index 8ffa42cf71..79f48d21af 100644 --- a/avm/utilities/pipelines/staticValidation/psrule/ps-rule.yaml +++ b/avm/utilities/pipelines/staticValidation/psrule/ps-rule.yaml @@ -49,7 +49,23 @@ configuration: AZURE_BICEP_FILE_EXPANSION_TIMEOUT: 10 # Custom non-sensitive parameters' names - AZURE_DEPLOYMENT_NONSENSITIVE_PARAMETER_NAMES: ["sasTokenValidityLength", "passwordlength","secretname","secreturl","secreturi","secretrotation","secretinterval","secretprovider","secretsprovider","secretref","secretid","disablepassword","sync*passwords","tokenname"] + AZURE_DEPLOYMENT_NONSENSITIVE_PARAMETER_NAMES: + [ + "sasTokenValidityLength", + "passwordlength", + "secretname", + "secreturl", + "secreturi", + "secretrotation", + "secretinterval", + "secretprovider", + "secretsprovider", + "secretref", + "secretid", + "disablepassword", + "sync*passwords", + "tokenname", + ] rule: # Enable custom rules that don't exist in the baseline @@ -57,3 +73,4 @@ rule: exclude: # Ignore the following rules for all resources - Azure.KeyVault.PurgeProtect + - Azure.VM.UseHybridUseBenefit From 04a68e244e5762e115c472fdfb595f9223f974fb Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Fri, 22 Dec 2023 10:43:46 +0100 Subject: [PATCH 50/96] update caching --- avm/res/compute/virtual-machine/README.md | 12 ++++++++---- .../tests/e2e/linux.defaults/main.test.bicep | 1 + .../tests/e2e/waf-aligned/main.test.bicep | 2 +- .../tests/e2e/windows.defaults/main.test.bicep | 1 + .../tests/e2e/windows.max/main.test.bicep | 2 +- 5 files changed, 12 insertions(+), 6 deletions(-) diff --git a/avm/res/compute/virtual-machine/README.md b/avm/res/compute/virtual-machine/README.md index 3ba2bf038b..5a8935bb5b 100644 --- a/avm/res/compute/virtual-machine/README.md +++ b/avm/res/compute/virtual-machine/README.md @@ -257,6 +257,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { } ] osDisk: { + caching: 'ReadWrite' diskSizeGB: '128' managedDisk: { storageAccountType: 'Premium_LRS' @@ -320,6 +321,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { }, "osDisk": { "value": { + "caching": "ReadWrite", "diskSizeGB": "128", "managedDisk": { "storageAccountType": "Premium_LRS" @@ -451,7 +453,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { } ] osDisk: { - caching: 'None' + caching: 'ReadWrite' createOption: 'fromImage' deleteOption: 'Delete' diskSizeGB: '128' @@ -728,7 +730,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { }, "osDisk": { "value": { - "caching": "None", + "caching": "ReadWrite", "createOption": "fromImage", "deleteOption": "Delete", "diskSizeGB": "128", @@ -1130,6 +1132,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { } ] osDisk: { + caching: 'ReadWrite' diskSizeGB: '128' managedDisk: { storageAccountType: 'Premium_LRS' @@ -1184,6 +1187,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { }, "osDisk": { "value": { + "caching": "ReadWrite", "diskSizeGB": "128", "managedDisk": { "storageAccountType": "Premium_LRS" @@ -1307,7 +1311,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { } ] osDisk: { - caching: 'None' + caching: 'ReadWrite' createOption: 'fromImage' deleteOption: 'Delete' diskSizeGB: '128' @@ -1584,7 +1588,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { }, "osDisk": { "value": { - "caching": "None", + "caching": "ReadWrite", "createOption": "fromImage", "deleteOption": "Delete", "diskSizeGB": "128", diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep index 0c46974e4b..ff60259195 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep @@ -82,6 +82,7 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ] osDisk: { diskSizeGB: '128' + caching: 'ReadWrite' managedDisk: { storageAccountType: 'Premium_LRS' } diff --git a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep index b31999c21b..1a8ba4d277 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep @@ -158,7 +158,7 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' } ] osDisk: { - caching: 'None' + caching: 'ReadWrite' createOption: 'fromImage' deleteOption: 'Delete' diskSizeGB: '128' diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows.defaults/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.defaults/main.test.bicep index b20a5225f7..4c9c55e6b3 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/windows.defaults/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/windows.defaults/main.test.bicep @@ -74,6 +74,7 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ] osDisk: { diskSizeGB: '128' + caching: 'ReadWrite' managedDisk: { storageAccountType: 'Premium_LRS' } diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep index 0aae1aa3ce..51e19418b8 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep @@ -158,7 +158,7 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' } ] osDisk: { - caching: 'None' + caching: 'ReadWrite' createOption: 'fromImage' deleteOption: 'Delete' diskSizeGB: '128' From 032f923fd26f39f70fb46f497b954171de7010e7 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Fri, 22 Dec 2023 10:58:58 +0100 Subject: [PATCH 51/96] update caching --- avm/res/compute/virtual-machine/README.md | 8 ++++---- .../virtual-machine/tests/e2e/waf-aligned/main.test.bicep | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/avm/res/compute/virtual-machine/README.md b/avm/res/compute/virtual-machine/README.md index 5a8935bb5b..4f8f9c2737 100644 --- a/avm/res/compute/virtual-machine/README.md +++ b/avm/res/compute/virtual-machine/README.md @@ -472,7 +472,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { computerName: 'winvm1' dataDisks: [ { - caching: 'None' + caching: 'ReadOnly' createOption: 'Empty' deleteOption: 'Delete' diskSizeGB: '128' @@ -481,7 +481,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { } } { - caching: 'None' + caching: 'ReadOnly' createOption: 'Empty' deleteOption: 'Delete' diskSizeGB: '128' @@ -767,7 +767,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { "dataDisks": { "value": [ { - "caching": "None", + "caching": "ReadOnly", "createOption": "Empty", "deleteOption": "Delete", "diskSizeGB": "128", @@ -776,7 +776,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { } }, { - "caching": "None", + "caching": "ReadOnly", "createOption": "Empty", "deleteOption": "Delete", "diskSizeGB": "128", diff --git a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep index 1a8ba4d277..ee093a7c96 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep @@ -175,7 +175,7 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' backupVaultResourceGroup: nestedDependencies.outputs.recoveryServicesVaultResourceGroupName dataDisks: [ { - caching: 'None' + caching: 'ReadOnly' createOption: 'Empty' deleteOption: 'Delete' diskSizeGB: '128' @@ -184,7 +184,7 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' } } { - caching: 'None' + caching: 'ReadOnly' createOption: 'Empty' deleteOption: 'Delete' diskSizeGB: '128' From 2b5c734cf04c185f45cb715e59498a616e87601b Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Fri, 22 Dec 2023 11:11:20 +0100 Subject: [PATCH 52/96] change description of parameter --- avm/res/compute/virtual-machine/README.md | 4 ++-- avm/res/compute/virtual-machine/main.bicep | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/avm/res/compute/virtual-machine/README.md b/avm/res/compute/virtual-machine/README.md index 4f8f9c2737..3f610a0ce5 100644 --- a/avm/res/compute/virtual-machine/README.md +++ b/avm/res/compute/virtual-machine/README.md @@ -2002,7 +2002,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { | Parameter | Type | Description | | :-- | :-- | :-- | -| [`additionalUnattendContent`](#parameter-additionalunattendcontent) | array | Specifies additional base-64 encoded XML formatted information that can be included in the Unattend.xml file, which is used by Windows Setup. - AdditionalUnattendContent object. | +| [`additionalUnattendContent`](#parameter-additionalunattendcontent) | array | Specifies additional XML formatted information that can be included in the Unattend.xml file, which is used by Windows Setup. Contents are defined by setting name, component name, and the pass in which the content is applied. | | [`adminPassword`](#parameter-adminpassword) | securestring | When specifying a Windows Virtual Machine, this value should be passed. | | [`allowExtensionOperations`](#parameter-allowextensionoperations) | bool | Specifies whether extension operations should be allowed on the virtual machine. This may only be set to False when no extensions are present on the virtual machine. | | [`availabilitySetResourceId`](#parameter-availabilitysetresourceid) | string | Resource ID of an availability set. Cannot be used in combination with availability zone nor scale set. | @@ -2130,7 +2130,7 @@ Specifies the size for the VMs. ### Parameter: `additionalUnattendContent` -Specifies additional base-64 encoded XML formatted information that can be included in the Unattend.xml file, which is used by Windows Setup. - AdditionalUnattendContent object. +Specifies additional XML formatted information that can be included in the Unattend.xml file, which is used by Windows Setup. Contents are defined by setting name, component name, and the pass in which the content is applied. - Required: No - Type: array diff --git a/avm/res/compute/virtual-machine/main.bicep b/avm/res/compute/virtual-machine/main.bicep index d77d77cc52..4abfc78eaf 100644 --- a/avm/res/compute/virtual-machine/main.bicep +++ b/avm/res/compute/virtual-machine/main.bicep @@ -238,7 +238,7 @@ param patchAssessmentMode string = 'ImageDefault' @description('Optional. Specifies the time zone of the virtual machine. e.g. \'Pacific Standard Time\'. Possible values can be `TimeZoneInfo.id` value from time zones returned by `TimeZoneInfo.GetSystemTimeZones`.') param timeZone string = '' -@description('Optional. Specifies additional base-64 encoded XML formatted information that can be included in the Unattend.xml file, which is used by Windows Setup. - AdditionalUnattendContent object.') +@description('Optional. Specifies additional XML formatted information that can be included in the Unattend.xml file, which is used by Windows Setup. Contents are defined by setting name, component name, and the pass in which the content is applied.') param additionalUnattendContent array = [] @description('Optional. Specifies the Windows Remote Management listeners. This enables remote Windows PowerShell. - WinRMConfiguration object.') From f4d868b00a42ddf32b7104613fdad945c828a13d Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 4 Jan 2024 11:17:27 +0100 Subject: [PATCH 53/96] adding PIP functionality from CARML --- avm/res/compute/virtual-machine/main.bicep | 5 +- .../modules/nic-configuration.bicep | 147 ++++++++++++++++++ 2 files changed, 150 insertions(+), 2 deletions(-) create mode 100644 avm/res/compute/virtual-machine/modules/nic-configuration.bicep diff --git a/avm/res/compute/virtual-machine/main.bicep b/avm/res/compute/virtual-machine/main.bicep index 4abfc78eaf..202c312e8f 100644 --- a/avm/res/compute/virtual-machine/main.bicep +++ b/avm/res/compute/virtual-machine/main.bicep @@ -338,10 +338,11 @@ resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableT } } -module vm_nic 'br/public:avm/res/network/network-interface:0.2.2' = [for (nicConfiguration, index) in nicConfigurations: { +module vm_nic 'modules/nic-configuration.bicep' = [for (nicConfiguration, index) in nicConfigurations: { name: '${uniqueString(deployment().name, location)}-VM-Nic-${index}' params: { - name: '${name}${nicConfiguration.nicSuffix}' + networkInterfaceName: '${name}${nicConfiguration.nicSuffix}' + virtualMachineName: name location: location enableIPForwarding: contains(nicConfiguration, 'enableIPForwarding') ? (!empty(nicConfiguration.enableIPForwarding) ? nicConfiguration.enableIPForwarding : false) : false enableAcceleratedNetworking: contains(nicConfiguration, 'enableAcceleratedNetworking') ? nicConfiguration.enableAcceleratedNetworking : true diff --git a/avm/res/compute/virtual-machine/modules/nic-configuration.bicep b/avm/res/compute/virtual-machine/modules/nic-configuration.bicep new file mode 100644 index 0000000000..d4a35c8093 --- /dev/null +++ b/avm/res/compute/virtual-machine/modules/nic-configuration.bicep @@ -0,0 +1,147 @@ +param networkInterfaceName string +param virtualMachineName string +param location string +param tags object? +param enableIPForwarding bool = false +param enableAcceleratedNetworking bool = false +param dnsServers array = [] + +@description('Optional. The network security group (NSG) to attach to the network interface.') +param networkSecurityGroupResourceId string = '' + +param ipConfigurations array +param lock lockType + +@description('Optional. The diagnostic settings of the Network Interface.') +param diagnosticSettings diagnosticSettingType + +@description('Optional. Array of role assignments to create.') +param roleAssignments roleAssignmentType + +var enableReferencedModulesTelemetry = false + +module networkInterface_publicIPAddresses 'br/public:avm/res/network/public-ip-address:0.2.0' = [for (ipConfiguration, index) in ipConfigurations: if (contains(ipConfiguration, 'pipconfiguration')) { + name: '${deployment().name}-publicIP-${index}' + params: { + name: '${virtualMachineName}${ipConfiguration.pipconfiguration.publicIpNameSuffix}' + diagnosticSettings: ipConfiguration.?diagnosticSettings + location: location + lock: lock + publicIPAddressVersion: contains(ipConfiguration, 'publicIPAddressVersion') ? ipConfiguration.publicIPAddressVersion : 'IPv4' + publicIPAllocationMethod: contains(ipConfiguration, 'publicIPAllocationMethod') ? ipConfiguration.publicIPAllocationMethod : 'Static' + publicIpPrefixResourceId: contains(ipConfiguration, 'publicIPPrefixResourceId') ? ipConfiguration.publicIPPrefixResourceId : '' + roleAssignments: contains(ipConfiguration, 'roleAssignments') ? ipConfiguration.roleAssignments : [] + skuName: contains(ipConfiguration, 'skuName') ? ipConfiguration.skuName : 'Standard' + skuTier: contains(ipConfiguration, 'skuTier') ? ipConfiguration.skuTier : 'Regional' + tags: ipConfiguration.?tags ?? tags + zones: contains(ipConfiguration, 'zones') ? ipConfiguration.zones : [] + } +}] + +module networkInterface 'br/public:avm/res/network/network-interface:0.2.2' = { + name: '${deployment().name}-NetworkInterface' + params: { + name: networkInterfaceName + ipConfigurations: [for (ipConfiguration, index) in ipConfigurations: { + name: !empty(ipConfiguration.name) ? ipConfiguration.name : null + primary: index == 0 + privateIPAllocationMethod: contains(ipConfiguration, 'privateIPAllocationMethod') ? (!empty(ipConfiguration.privateIPAllocationMethod) ? ipConfiguration.privateIPAllocationMethod : null) : null + privateIPAddress: contains(ipConfiguration, 'privateIPAddress') ? (!empty(ipConfiguration.privateIPAddress) ? ipConfiguration.privateIPAddress : null) : null + publicIPAddressResourceId: contains(ipConfiguration, 'pipconfiguration') ? resourceId('Microsoft.Network/publicIPAddresses', '${virtualMachineName}${ipConfiguration.pipconfiguration.publicIpNameSuffix}') : null + subnetResourceId: ipConfiguration.subnetResourceId + loadBalancerBackendAddressPools: contains(ipConfiguration, 'loadBalancerBackendAddressPools') ? ipConfiguration.loadBalancerBackendAddressPools : null + applicationSecurityGroups: contains(ipConfiguration, 'applicationSecurityGroups') ? ipConfiguration.applicationSecurityGroups : null + applicationGatewayBackendAddressPools: contains(ipConfiguration, 'applicationGatewayBackendAddressPools') ? ipConfiguration.applicationGatewayBackendAddressPools : null + gatewayLoadBalancer: contains(ipConfiguration, 'gatewayLoadBalancer') ? ipConfiguration.gatewayLoadBalancer : null + loadBalancerInboundNatRules: contains(ipConfiguration, 'loadBalancerInboundNatRules') ? ipConfiguration.loadBalancerInboundNatRules : null + privateIPAddressVersion: contains(ipConfiguration, 'privateIPAddressVersion') ? ipConfiguration.privateIPAddressVersion : null + virtualNetworkTaps: contains(ipConfiguration, 'virtualNetworkTaps') ? ipConfiguration.virtualNetworkTaps : null + }] + location: location + tags: tags + diagnosticSettings: diagnosticSettings + dnsServers: !empty(dnsServers) ? dnsServers : [] + enableAcceleratedNetworking: enableAcceleratedNetworking + enableTelemetry: enableReferencedModulesTelemetry + enableIPForwarding: enableIPForwarding + lock: lock + networkSecurityGroupResourceId: !empty(networkSecurityGroupResourceId) ? networkSecurityGroupResourceId : '' + roleAssignments: !empty(roleAssignments) ? roleAssignments : [] + } + dependsOn: [ + networkInterface_publicIPAddresses + ] +} + +// =============== // +// Definitions // +// =============== // + +type lockType = { + @description('Optional. Specify the name of lock.') + name: string? + + @description('Optional. Specify the type of lock.') + kind: ('CanNotDelete' | 'ReadOnly' | 'None')? +}? + +type diagnosticSettingType = { + @description('Optional. The name of diagnostic setting.') + name: string? + + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + logCategoriesAndGroups: { + @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') + category: string? + + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to llLogs to collect all logs.') + categoryGroup: string? + }[]? + + @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: { + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to AllMetrics to collect all metrics.') + category: string + }[]? + + @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.') + logAnalyticsDestinationType: ('Dedicated' | 'AzureDiagnostics')? + + @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.') + workspaceResourceId: string? + + @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.') + storageAccountResourceId: string? + + @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.') + eventHubAuthorizationRuleResourceId: string? + + @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.') + eventHubName: string? + + @description('Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs.') + marketplacePartnerResourceId: string? +}[]? + +type roleAssignmentType = { + @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? +}[]? From ada22562bc0038ba82cf062b825c3ffbcfe03dcf Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 4 Jan 2024 11:23:05 +0100 Subject: [PATCH 54/96] update readme --- avm/res/compute/virtual-machine/README.md | 7 +- avm/res/compute/virtual-machine/main.json | 1419 ++++++++++++++--- .../modules/nic-configuration.bicep | 2 +- 3 files changed, 1172 insertions(+), 256 deletions(-) diff --git a/avm/res/compute/virtual-machine/README.md b/avm/res/compute/virtual-machine/README.md index 3f610a0ce5..8b8705aa50 100644 --- a/avm/res/compute/virtual-machine/README.md +++ b/avm/res/compute/virtual-machine/README.md @@ -21,6 +21,7 @@ This module deploys a Virtual Machine with one or multiple NICs and optionally o | `Microsoft.Compute/virtualMachines/extensions` | [2022-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Compute/2022-11-01/virtualMachines/extensions) | | `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | | `Microsoft.Network/networkInterfaces` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/networkInterfaces) | +| `Microsoft.Network/publicIPAddresses` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/publicIPAddresses) | | `Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems` | [2023-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.RecoveryServices/2023-01-01/vaults/backupFabrics/protectionContainers/protectedItems) | ## Usage examples @@ -2797,8 +2798,4 @@ Do not provide a value! This date value is used to generate a registration token ## Cross-referenced modules -This section gives you an overview of all local-referenced module files (i.e., other CARML 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/res/network/network-interface:0.2.2` | Remote reference | +_None_ diff --git a/avm/res/compute/virtual-machine/main.json b/avm/res/compute/virtual-machine/main.json index 75cf77242f..ac5e1cf834 100644 --- a/avm/res/compute/virtual-machine/main.json +++ b/avm/res/compute/virtual-machine/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "17379109609699248366" + "templateHash": "8273803838011690115" }, "name": "Virtual Machines", "description": "This module deploys a Virtual Machine with one or multiple NICs and optionally one or multiple public IPs.", @@ -693,7 +693,7 @@ "type": "array", "defaultValue": [], "metadata": { - "description": "Optional. Specifies additional base-64 encoded XML formatted information that can be included in the Unattend.xml file, which is used by Windows Setup. - AdditionalUnattendContent object." + "description": "Optional. Specifies additional XML formatted information that can be included in the Unattend.xml file, which is used by Windows Setup. Contents are defined by setting name, component name, and the pass in which the content is applied." } }, "winRM": { @@ -953,9 +953,12 @@ }, "mode": "Incremental", "parameters": { - "name": { + "networkInterfaceName": { "value": "[format('{0}{1}', parameters('name'), parameters('nicConfigurations')[copyIndex()].nicSuffix)]" }, + "virtualMachineName": { + "value": "[parameters('name')]" + }, "location": { "value": "[parameters('location')]" }, @@ -986,14 +989,36 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "14617314094453038306" - }, - "name": "Network Interface", - "description": "This module deploys a Network Interface.", - "owner": "Azure/module-maintainers" + "version": "0.24.24.22086", + "templateHash": "3350950112193420821" + } }, "definitions": { + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, "diagnosticSettingType": { "type": "array", "items": { @@ -1022,7 +1047,7 @@ "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." + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to \u0007llLogs to collect all logs." } } } @@ -1040,7 +1065,7 @@ "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." + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to AllMetrics to collect all metrics." } } } @@ -1165,81 +1190,33 @@ } }, "nullable": true - }, - "lockType": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Specify the name of lock." - } - }, - "kind": { - "type": "string", - "allowedValues": [ - "CanNotDelete", - "None", - "ReadOnly" - ], - "nullable": true, - "metadata": { - "description": "Optional. Specify the type of lock." - } - } - }, - "nullable": true } }, "parameters": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the network interface." - } + "networkInterfaceName": { + "type": "string" + }, + "virtualMachineName": { + "type": "string" }, "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. Location for all resources." - } + "type": "string" }, "tags": { "type": "object", - "nullable": true, - "metadata": { - "description": "Optional. Resource tags." - } - }, - "enableTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable/Disable usage telemetry for module." - } + "nullable": true }, "enableIPForwarding": { "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Indicates whether IP forwarding is enabled on this network interface." - } + "defaultValue": false }, "enableAcceleratedNetworking": { "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. If the network interface is accelerated networking enabled." - } + "defaultValue": false }, "dnsServers": { "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. List of DNS servers IP addresses. Use 'AzureProvidedDNS' to switch to azure provided DNS resolution. 'AzureProvidedDNS' value cannot be combined with other IPs, it must be the only value in dnsServers collection." - } + "defaultValue": [] }, "networkSecurityGroupResourceId": { "type": "string", @@ -1248,49 +1225,16 @@ "description": "Optional. The network security group (NSG) to attach to the network interface." } }, - "auxiliaryMode": { - "type": "string", - "defaultValue": "None", - "allowedValues": [ - "Floating", - "MaxConnections", - "None" - ], - "metadata": { - "description": "Optional. Auxiliary mode of Network Interface resource. Not all regions are enabled for Auxiliary Mode Nic." - } - }, - "auxiliarySku": { - "type": "string", - "defaultValue": "None", - "allowedValues": [ - "A1", - "A2", - "A4", - "A8", - "None" - ], - "metadata": { - "description": "Optional. Auxiliary sku of Network Interface resource. Not all regions are enabled for Auxiliary Mode Nic." - } - }, - "disableTcpStateTracking": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Indicates whether to disable tcp state tracking. Subscription must be registered for the Microsoft.Network/AllowDisableTcpStateTracking feature before this property can be set to true." - } - }, "ipConfigurations": { - "type": "array", - "metadata": { - "description": "Required. A list of IPConfigurations of the network interface." - } + "type": "array" }, "lock": { - "$ref": "#/definitions/lockType", + "$ref": "#/definitions/lockType" + }, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", "metadata": { - "description": "Optional. The lock settings of the service." + "description": "Optional. The diagnostic settings of the Network Interface." } }, "roleAssignments": { @@ -1298,176 +1242,1151 @@ "metadata": { "description": "Optional. Array of role assignments to create." } - }, - "diagnosticSettings": { - "$ref": "#/definitions/diagnosticSettingType", - "metadata": { - "description": "Optional. The diagnostic settings of the service." - } } }, "variables": { - "builtInRoleNames": { - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" - } + "enableReferencedModulesTelemetry": false }, "resources": { - "avmTelemetry": { - "condition": "[parameters('enableTelemetry')]", + "networkInterface_publicIPAddresses": { + "copy": { + "name": "networkInterface_publicIPAddresses", + "count": "[length(parameters('ipConfigurations'))]" + }, + "condition": "[contains(parameters('ipConfigurations')[copyIndex()], 'pipconfiguration')]", "type": "Microsoft.Resources/deployments", - "apiVersion": "2023-07-01", - "name": "[format('46d3xbcp.res.network-networkinterface.{0}.{1}', replace('0.2.2', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "apiVersion": "2022-09-01", + "name": "[format('{0}-publicIP-{1}', deployment().name, copyIndex())]", "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, "mode": "Incremental", + "parameters": { + "name": { + "value": "[format('{0}{1}', parameters('virtualMachineName'), parameters('ipConfigurations')[copyIndex()].pipconfiguration.publicIpNameSuffix)]" + }, + "diagnosticSettings": { + "value": "[tryGet(parameters('ipConfigurations')[copyIndex()], 'diagnosticSettings')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "lock": { + "value": "[parameters('lock')]" + }, + "publicIPAddressVersion": "[if(contains(parameters('ipConfigurations')[copyIndex()], 'publicIPAddressVersion'), createObject('value', parameters('ipConfigurations')[copyIndex()].publicIPAddressVersion), createObject('value', 'IPv4'))]", + "publicIPAllocationMethod": "[if(contains(parameters('ipConfigurations')[copyIndex()], 'publicIPAllocationMethod'), createObject('value', parameters('ipConfigurations')[copyIndex()].publicIPAllocationMethod), createObject('value', 'Static'))]", + "publicIpPrefixResourceId": "[if(contains(parameters('ipConfigurations')[copyIndex()], 'publicIPPrefixResourceId'), createObject('value', parameters('ipConfigurations')[copyIndex()].publicIPPrefixResourceId), createObject('value', ''))]", + "roleAssignments": "[if(contains(parameters('ipConfigurations')[copyIndex()], 'roleAssignments'), createObject('value', parameters('ipConfigurations')[copyIndex()].roleAssignments), createObject('value', createArray()))]", + "skuName": "[if(contains(parameters('ipConfigurations')[copyIndex()], 'skuName'), createObject('value', parameters('ipConfigurations')[copyIndex()].skuName), createObject('value', 'Standard'))]", + "skuTier": "[if(contains(parameters('ipConfigurations')[copyIndex()], 'skuTier'), createObject('value', parameters('ipConfigurations')[copyIndex()].skuTier), createObject('value', 'Regional'))]", + "tags": { + "value": "[coalesce(tryGet(parameters('ipConfigurations')[copyIndex()], 'tags'), parameters('tags'))]" + }, + "zones": "[if(contains(parameters('ipConfigurations')[copyIndex()], 'zones'), createObject('value', parameters('ipConfigurations')[copyIndex()].zones), createObject('value', createArray()))]" + }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", - "resources": [], + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.23.1.45101", + "templateHash": "11486686724612026983" + }, + "name": "Public IP Addresses", + "description": "This module deploys a Public IP Address.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "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 + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "dnsSettingsType": { + "type": "object", + "properties": { + "domainNameLabel": { + "type": "string", + "metadata": { + "description": "Required. The domain name label. The concatenation of the domain name label and the regionalized DNS zone make up the fully qualified domain name associated with the public IP address. If a domain name label is specified, an A DNS record is created for the public IP in the Microsoft Azure DNS system." + } + }, + "domainNameLabelScope": { + "type": "string", + "allowedValues": [ + "", + "NoReuse", + "ResourceGroupReuse", + "SubscriptionReuse", + "TenantReuse" + ], + "metadata": { + "description": "Required. The domain name label scope. If a domain name label and a domain name label scope are specified, an A DNS record is created for the public IP in the Microsoft Azure DNS system with a hashed value includes in FQDN." + } + }, + "fqdn": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Fully Qualified Domain Name of the A DNS record associated with the public IP. This is the concatenation of the domainNameLabel and the regionalized DNS zone." + } + }, + "reverseFqdn": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The reverse FQDN. A user-visible, fully qualified domain name that resolves to this public IP address. If the reverseFqdn is specified, then a PTR DNS record is created pointing from the IP address in the in-addr.arpa domain to the reverse FQDN." + } + } + } + }, + "ddosSettingsType": { + "type": "object", + "properties": { + "ddosProtectionPlan": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "metadata": { + "description": "Required. The DDoS protection plan ID associated with the public IP address." + } + }, + "protectionMode": { + "type": "string", + "allowedValues": [ + "Enabled" + ], + "metadata": { + "description": "Required. The DDoS protection policy customizations." + } + } + } + }, + "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." + } + } + } + }, + "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." + } + } + } + }, + "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." + } + }, + "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." + } + }, + "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." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the Public IP Address." + } + }, + "publicIpPrefixResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the Public IP Prefix object. This is only needed if you want your Public IPs created in a PIP Prefix." + } + }, + "publicIPAllocationMethod": { + "type": "string", + "defaultValue": "Static", + "allowedValues": [ + "Dynamic", + "Static" + ], + "metadata": { + "description": "Optional. The public IP address allocation method." + } + }, + "zones": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. A list of availability zones denoting the IP allocated for the resource needs to come from." + } + }, + "publicIPAddressVersion": { + "type": "string", + "defaultValue": "IPv4", + "allowedValues": [ + "IPv4", + "IPv6" + ], + "metadata": { + "description": "Optional. IP address version." + } + }, + "dnsSettings": { + "$ref": "#/definitions/dnsSettingsType", + "nullable": true, + "metadata": { + "description": "Optional. The DNS settings of the public IP address." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "skuName": { + "type": "string", + "defaultValue": "Standard", + "allowedValues": [ + "Basic", + "Standard" + ], + "metadata": { + "description": "Optional. Name of a public IP address SKU." + } + }, + "skuTier": { + "type": "string", + "defaultValue": "Regional", + "allowedValues": [ + "Global", + "Regional" + ], + "metadata": { + "description": "Optional. Tier of a public IP address SKU." + } + }, + "ddosSettings": { + "$ref": "#/definitions/ddosSettingsType", + "nullable": true, + "metadata": { + "description": "Optional. The DDoS protection plan configuration associated with the public IP address." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "idleTimeoutInMinutes": { + "type": "int", + "defaultValue": 4, + "metadata": { + "description": "Optional. The idle timeout of the public IP address." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.network-publicipaddress.{0}.{1}', replace('0.2.0', '.', '-'), 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" + } + } + } + } + }, + "publicIpAddress": { + "type": "Microsoft.Network/publicIPAddresses", + "apiVersion": "2023-04-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "sku": { + "name": "[parameters('skuName')]", + "tier": "[parameters('skuTier')]" + }, + "zones": "[parameters('zones')]", + "properties": { + "ddosSettings": "[parameters('ddosSettings')]", + "dnsSettings": "[parameters('dnsSettings')]", + "publicIPAddressVersion": "[parameters('publicIPAddressVersion')]", + "publicIPAllocationMethod": "[parameters('publicIPAllocationMethod')]", + "publicIPPrefix": "[if(not(empty(parameters('publicIpPrefixResourceId'))), createObject('id', parameters('publicIpPrefixResourceId')), null())]", + "idleTimeoutInMinutes": "[parameters('idleTimeoutInMinutes')]", + "ipTags": [] + } + }, + "publicIpAddress_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Network/publicIPAddresses/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "publicIpAddress" + ] + }, + "publicIpAddress_roleAssignments": { + "copy": { + "name": "publicIpAddress_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/publicIPAddresses/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/publicIPAddresses', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "publicIpAddress" + ] + }, + "publicIpAddress_diagnosticSettings": { + "copy": { + "name": "publicIpAddress_diagnosticSettings", + "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + }, + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.Network/publicIPAddresses/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", + "properties": { + "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", + "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", + "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", + "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", + "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", + "logs": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs', 'enabled', true())))]", + "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", + "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + }, + "dependsOn": [ + "publicIpAddress" + ] + } + }, "outputs": { - "telemetry": { - "type": "String", - "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the public IP address was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the public IP address." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the public IP address." + }, + "value": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('name'))]" + }, + "ipAddress": { + "type": "string", + "metadata": { + "description": "The public IP address of the public IP address resource." + }, + "value": "[if(contains(reference('publicIpAddress'), 'ipAddress'), reference('publicIpAddress').ipAddress, '')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('publicIpAddress', '2023-04-01', 'full').location]" } } } } }, "networkInterface": { - "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "2023-04-01", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-NetworkInterface', deployment().name)]", "properties": { - "copy": [ - { - "name": "ipConfigurations", - "count": "[length(parameters('ipConfigurations'))]", - "input": { - "name": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'name'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].name, format('ipconfig0{0}', add(copyIndex('ipConfigurations'), 1)))]", + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[parameters('networkInterfaceName')]" + }, + "ipConfigurations": { + "copy": [ + { + "name": "value", + "count": "[length(parameters('ipConfigurations'))]", + "input": "[createObject('name', if(not(empty(parameters('ipConfigurations')[copyIndex('value')].name)), parameters('ipConfigurations')[copyIndex('value')].name, null()), 'primary', equals(copyIndex('value'), 0), 'privateIPAllocationMethod', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'privateIPAllocationMethod'), if(not(empty(parameters('ipConfigurations')[copyIndex('value')].privateIPAllocationMethod)), parameters('ipConfigurations')[copyIndex('value')].privateIPAllocationMethod, null()), null()), 'privateIPAddress', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'privateIPAddress'), if(not(empty(parameters('ipConfigurations')[copyIndex('value')].privateIPAddress)), parameters('ipConfigurations')[copyIndex('value')].privateIPAddress, null()), null()), 'publicIPAddressResourceId', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'pipconfiguration'), resourceId('Microsoft.Network/publicIPAddresses', format('{0}{1}', parameters('virtualMachineName'), parameters('ipConfigurations')[copyIndex('value')].pipconfiguration.publicIpNameSuffix)), null()), 'subnetResourceId', parameters('ipConfigurations')[copyIndex('value')].subnetResourceId, 'loadBalancerBackendAddressPools', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'loadBalancerBackendAddressPools'), parameters('ipConfigurations')[copyIndex('value')].loadBalancerBackendAddressPools, null()), 'applicationSecurityGroups', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'applicationSecurityGroups'), parameters('ipConfigurations')[copyIndex('value')].applicationSecurityGroups, null()), 'applicationGatewayBackendAddressPools', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'applicationGatewayBackendAddressPools'), parameters('ipConfigurations')[copyIndex('value')].applicationGatewayBackendAddressPools, null()), 'gatewayLoadBalancer', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'gatewayLoadBalancer'), parameters('ipConfigurations')[copyIndex('value')].gatewayLoadBalancer, null()), 'loadBalancerInboundNatRules', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'loadBalancerInboundNatRules'), parameters('ipConfigurations')[copyIndex('value')].loadBalancerInboundNatRules, null()), 'privateIPAddressVersion', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'privateIPAddressVersion'), parameters('ipConfigurations')[copyIndex('value')].privateIPAddressVersion, null()), 'virtualNetworkTaps', if(contains(parameters('ipConfigurations')[copyIndex('value')], 'virtualNetworkTaps'), parameters('ipConfigurations')[copyIndex('value')].virtualNetworkTaps, null()))]" + } + ] + }, + "location": { + "value": "[parameters('location')]" + }, + "tags": { + "value": "[parameters('tags')]" + }, + "diagnosticSettings": { + "value": "[parameters('diagnosticSettings')]" + }, + "dnsServers": "[if(not(empty(parameters('dnsServers'))), createObject('value', parameters('dnsServers')), createObject('value', createArray()))]", + "enableAcceleratedNetworking": { + "value": "[parameters('enableAcceleratedNetworking')]" + }, + "enableTelemetry": { + "value": "[variables('enableReferencedModulesTelemetry')]" + }, + "enableIPForwarding": { + "value": "[parameters('enableIPForwarding')]" + }, + "lock": { + "value": "[parameters('lock')]" + }, + "networkSecurityGroupResourceId": "[if(not(empty(parameters('networkSecurityGroupResourceId'))), createObject('value', parameters('networkSecurityGroupResourceId')), createObject('value', ''))]", + "roleAssignments": "[if(not(empty(parameters('roleAssignments'))), createObject('value', parameters('roleAssignments')), createObject('value', createArray()))]" + }, + "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": "14617314094453038306" + }, + "name": "Network Interface", + "description": "This module deploys a Network Interface.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "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." + } + } + } + }, + "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." + } + } + } + }, + "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." + } + }, + "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." + } + }, + "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." + } + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "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 + }, + "lockType": { + "type": "object", "properties": { - "primary": "[if(equals(copyIndex('ipConfigurations'), 0), true(), false())]", - "privateIPAllocationMethod": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'privateIPAllocationMethod'), if(not(empty(parameters('ipConfigurations')[copyIndex('ipConfigurations')].privateIPAllocationMethod)), parameters('ipConfigurations')[copyIndex('ipConfigurations')].privateIPAllocationMethod, null()), null())]", - "privateIPAddress": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'privateIPAddress'), if(not(empty(parameters('ipConfigurations')[copyIndex('ipConfigurations')].privateIPAddress)), parameters('ipConfigurations')[copyIndex('ipConfigurations')].privateIPAddress, null()), null())]", - "publicIPAddress": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'publicIPAddressResourceId'), if(not(equals(parameters('ipConfigurations')[copyIndex('ipConfigurations')].publicIPAddressResourceId, null())), createObject('id', parameters('ipConfigurations')[copyIndex('ipConfigurations')].publicIPAddressResourceId), null()), null())]", - "subnet": { - "id": "[parameters('ipConfigurations')[copyIndex('ipConfigurations')].subnetResourceId]" + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } }, - "loadBalancerBackendAddressPools": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'loadBalancerBackendAddressPools'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].loadBalancerBackendAddressPools, null())]", - "applicationSecurityGroups": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'applicationSecurityGroups'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].applicationSecurityGroups, null())]", - "applicationGatewayBackendAddressPools": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'applicationGatewayBackendAddressPools'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].applicationGatewayBackendAddressPools, null())]", - "gatewayLoadBalancer": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'gatewayLoadBalancer'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].gatewayLoadBalancer, null())]", - "loadBalancerInboundNatRules": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'loadBalancerInboundNatRules'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].loadBalancerInboundNatRules, null())]", - "privateIPAddressVersion": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'privateIPAddressVersion'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].privateIPAddressVersion, null())]", - "virtualNetworkTaps": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'virtualNetworkTaps'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].virtualNetworkTaps, null())]" + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the network interface." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Resource tags." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "enableIPForwarding": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether IP forwarding is enabled on this network interface." + } + }, + "enableAcceleratedNetworking": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. If the network interface is accelerated networking enabled." + } + }, + "dnsServers": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. List of DNS servers IP addresses. Use 'AzureProvidedDNS' to switch to azure provided DNS resolution. 'AzureProvidedDNS' value cannot be combined with other IPs, it must be the only value in dnsServers collection." + } + }, + "networkSecurityGroupResourceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The network security group (NSG) to attach to the network interface." + } + }, + "auxiliaryMode": { + "type": "string", + "defaultValue": "None", + "allowedValues": [ + "Floating", + "MaxConnections", + "None" + ], + "metadata": { + "description": "Optional. Auxiliary mode of Network Interface resource. Not all regions are enabled for Auxiliary Mode Nic." + } + }, + "auxiliarySku": { + "type": "string", + "defaultValue": "None", + "allowedValues": [ + "A1", + "A2", + "A4", + "A8", + "None" + ], + "metadata": { + "description": "Optional. Auxiliary sku of Network Interface resource. Not all regions are enabled for Auxiliary Mode Nic." + } + }, + "disableTcpStateTracking": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether to disable tcp state tracking. Subscription must be registered for the Microsoft.Network/AllowDisableTcpStateTracking feature before this property can be set to true." + } + }, + "ipConfigurations": { + "type": "array", + "metadata": { + "description": "Required. A list of IPConfigurations of the network interface." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.network-networkinterface.{0}.{1}', replace('0.2.2', '.', '-'), 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" + } + } + } + } + }, + "networkInterface": { + "type": "Microsoft.Network/networkInterfaces", + "apiVersion": "2023-04-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "copy": [ + { + "name": "ipConfigurations", + "count": "[length(parameters('ipConfigurations'))]", + "input": { + "name": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'name'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].name, format('ipconfig0{0}', add(copyIndex('ipConfigurations'), 1)))]", + "properties": { + "primary": "[if(equals(copyIndex('ipConfigurations'), 0), true(), false())]", + "privateIPAllocationMethod": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'privateIPAllocationMethod'), if(not(empty(parameters('ipConfigurations')[copyIndex('ipConfigurations')].privateIPAllocationMethod)), parameters('ipConfigurations')[copyIndex('ipConfigurations')].privateIPAllocationMethod, null()), null())]", + "privateIPAddress": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'privateIPAddress'), if(not(empty(parameters('ipConfigurations')[copyIndex('ipConfigurations')].privateIPAddress)), parameters('ipConfigurations')[copyIndex('ipConfigurations')].privateIPAddress, null()), null())]", + "publicIPAddress": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'publicIPAddressResourceId'), if(not(equals(parameters('ipConfigurations')[copyIndex('ipConfigurations')].publicIPAddressResourceId, null())), createObject('id', parameters('ipConfigurations')[copyIndex('ipConfigurations')].publicIPAddressResourceId), null()), null())]", + "subnet": { + "id": "[parameters('ipConfigurations')[copyIndex('ipConfigurations')].subnetResourceId]" + }, + "loadBalancerBackendAddressPools": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'loadBalancerBackendAddressPools'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].loadBalancerBackendAddressPools, null())]", + "applicationSecurityGroups": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'applicationSecurityGroups'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].applicationSecurityGroups, null())]", + "applicationGatewayBackendAddressPools": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'applicationGatewayBackendAddressPools'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].applicationGatewayBackendAddressPools, null())]", + "gatewayLoadBalancer": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'gatewayLoadBalancer'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].gatewayLoadBalancer, null())]", + "loadBalancerInboundNatRules": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'loadBalancerInboundNatRules'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].loadBalancerInboundNatRules, null())]", + "privateIPAddressVersion": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'privateIPAddressVersion'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].privateIPAddressVersion, null())]", + "virtualNetworkTaps": "[if(contains(parameters('ipConfigurations')[copyIndex('ipConfigurations')], 'virtualNetworkTaps'), parameters('ipConfigurations')[copyIndex('ipConfigurations')].virtualNetworkTaps, null())]" + } + } + } + ], + "auxiliaryMode": "[parameters('auxiliaryMode')]", + "auxiliarySku": "[parameters('auxiliarySku')]", + "disableTcpStateTracking": "[parameters('disableTcpStateTracking')]", + "dnsSettings": "[if(not(empty(parameters('dnsServers'))), createObject('dnsServers', parameters('dnsServers')), null())]", + "enableAcceleratedNetworking": "[parameters('enableAcceleratedNetworking')]", + "enableIPForwarding": "[parameters('enableIPForwarding')]", + "networkSecurityGroup": "[if(not(empty(parameters('networkSecurityGroupResourceId'))), createObject('id', parameters('networkSecurityGroupResourceId')), null())]" + } + }, + "networkInterface_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Network/networkInterfaces/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "networkInterface" + ] + }, + "networkInterface_diagnosticSettings": { + "copy": { + "name": "networkInterface_diagnosticSettings", + "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + }, + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.Network/networkInterfaces/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", + "properties": { + "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", + "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", + "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", + "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", + "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", + "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", + "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + }, + "dependsOn": [ + "networkInterface" + ] + }, + "networkInterface_roleAssignments": { + "copy": { + "name": "networkInterface_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/networkInterfaces/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/networkInterfaces', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "networkInterface" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed resource." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed resource." + }, + "value": "[resourceId('Microsoft.Network/networkInterfaces', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed resource." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('networkInterface', '2023-04-01', 'full').location]" } } - ], - "auxiliaryMode": "[parameters('auxiliaryMode')]", - "auxiliarySku": "[parameters('auxiliarySku')]", - "disableTcpStateTracking": "[parameters('disableTcpStateTracking')]", - "dnsSettings": "[if(not(empty(parameters('dnsServers'))), createObject('dnsServers', parameters('dnsServers')), null())]", - "enableAcceleratedNetworking": "[parameters('enableAcceleratedNetworking')]", - "enableIPForwarding": "[parameters('enableIPForwarding')]", - "networkSecurityGroup": "[if(not(empty(parameters('networkSecurityGroupResourceId'))), createObject('id', parameters('networkSecurityGroupResourceId')), null())]" - } - }, - "networkInterface_lock": { - "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", - "type": "Microsoft.Authorization/locks", - "apiVersion": "2020-05-01", - "scope": "[format('Microsoft.Network/networkInterfaces/{0}', parameters('name'))]", - "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", - "properties": { - "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", - "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" - }, - "dependsOn": [ - "networkInterface" - ] - }, - "networkInterface_diagnosticSettings": { - "copy": { - "name": "networkInterface_diagnosticSettings", - "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" - }, - "type": "Microsoft.Insights/diagnosticSettings", - "apiVersion": "2021-05-01-preview", - "scope": "[format('Microsoft.Network/networkInterfaces/{0}', parameters('name'))]", - "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", - "properties": { - "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", - "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", - "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", - "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "metrics": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics', 'timeGrain', null(), 'enabled', true())))]", - "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", - "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" - }, - "dependsOn": [ - "networkInterface" - ] - }, - "networkInterface_roleAssignments": { - "copy": { - "name": "networkInterface_roleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/networkInterfaces/{0}', parameters('name'))]", - "name": "[guid(resourceId('Microsoft.Network/networkInterfaces', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", - "properties": { - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", - "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", - "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", - "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", - "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", - "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", - "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + } }, "dependsOn": [ - "networkInterface" + "networkInterface_publicIPAddresses" ] } - }, - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the deployed resource." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the deployed resource." - }, - "value": "[resourceId('Microsoft.Network/networkInterfaces', parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The resource group of the deployed resource." - }, - "value": "[resourceGroup().name]" - }, - "location": { - "type": "string", - "metadata": { - "description": "The location the resource was deployed into." - }, - "value": "[reference('networkInterface', '2023-04-01', 'full').location]" - } } } } diff --git a/avm/res/compute/virtual-machine/modules/nic-configuration.bicep b/avm/res/compute/virtual-machine/modules/nic-configuration.bicep index d4a35c8093..4010b94909 100644 --- a/avm/res/compute/virtual-machine/modules/nic-configuration.bicep +++ b/avm/res/compute/virtual-machine/modules/nic-configuration.bicep @@ -20,7 +20,7 @@ param roleAssignments roleAssignmentType var enableReferencedModulesTelemetry = false -module networkInterface_publicIPAddresses 'br/public:avm/res/network/public-ip-address:0.2.0' = [for (ipConfiguration, index) in ipConfigurations: if (contains(ipConfiguration, 'pipconfiguration')) { +module networkInterface_publicIPAddresses 'br/public:avm/res/network/public-ip-address:0.2.1' = [for (ipConfiguration, index) in ipConfigurations: if (contains(ipConfiguration, 'pipconfiguration')) { name: '${deployment().name}-publicIP-${index}' params: { name: '${virtualMachineName}${ipConfiguration.pipconfiguration.publicIpNameSuffix}' From 80c6a9bc6b490d677dae5c753a11bae3141af182 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 4 Jan 2024 11:33:18 +0100 Subject: [PATCH 55/96] make PIP zonal --- avm/res/compute/virtual-machine/main.json | 16 ++++++++-------- .../modules/nic-configuration.bicep | 6 +++++- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/avm/res/compute/virtual-machine/main.json b/avm/res/compute/virtual-machine/main.json index ac5e1cf834..de794626c9 100644 --- a/avm/res/compute/virtual-machine/main.json +++ b/avm/res/compute/virtual-machine/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "8273803838011690115" + "templateHash": "16217992416035116012" }, "name": "Virtual Machines", "description": "This module deploys a Virtual Machine with one or multiple NICs and optionally one or multiple public IPs.", @@ -990,7 +990,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "3350950112193420821" + "templateHash": "11564357055812588681" } }, "definitions": { @@ -1284,7 +1284,7 @@ "tags": { "value": "[coalesce(tryGet(parameters('ipConfigurations')[copyIndex()], 'tags'), parameters('tags'))]" }, - "zones": "[if(contains(parameters('ipConfigurations')[copyIndex()], 'zones'), createObject('value', parameters('ipConfigurations')[copyIndex()].zones), createObject('value', createArray()))]" + "zones": "[if(contains(parameters('ipConfigurations')[copyIndex()], 'zones'), createObject('value', parameters('ipConfigurations')[copyIndex()].zones), createObject('value', createArray('1', '2', '3')))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", @@ -1294,7 +1294,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "11486686724612026983" + "templateHash": "3488076626994379707" }, "name": "Public IP Addresses", "description": "This module deploys a Public IP Address.", @@ -1309,7 +1309,7 @@ "roleDefinitionIdOrName": { "type": "string", "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + "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": { @@ -1657,7 +1657,7 @@ "roleAssignments": { "$ref": "#/definitions/roleAssignmentType", "metadata": { - "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + "description": "Optional. Array of role assignments to create." } }, "enableTelemetry": { @@ -1707,7 +1707,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2023-07-01", - "name": "[format('46d3xbcp.res.network-publicipaddress.{0}.{1}', replace('0.2.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.network-publicipaddress.{0}.{1}', replace('0.2.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -1768,7 +1768,7 @@ "scope": "[format('Microsoft.Network/publicIPAddresses/{0}', parameters('name'))]", "name": "[guid(resourceId('Microsoft.Network/publicIPAddresses', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", "properties": { - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", diff --git a/avm/res/compute/virtual-machine/modules/nic-configuration.bicep b/avm/res/compute/virtual-machine/modules/nic-configuration.bicep index 4010b94909..13912cf7c7 100644 --- a/avm/res/compute/virtual-machine/modules/nic-configuration.bicep +++ b/avm/res/compute/virtual-machine/modules/nic-configuration.bicep @@ -34,7 +34,11 @@ module networkInterface_publicIPAddresses 'br/public:avm/res/network/public-ip-a skuName: contains(ipConfiguration, 'skuName') ? ipConfiguration.skuName : 'Standard' skuTier: contains(ipConfiguration, 'skuTier') ? ipConfiguration.skuTier : 'Regional' tags: ipConfiguration.?tags ?? tags - zones: contains(ipConfiguration, 'zones') ? ipConfiguration.zones : [] + zones: contains(ipConfiguration, 'zones') ? ipConfiguration.zones : [ + '1' + '2' + '3' + ] } }] From 4d6f1d839397b1e1481385695221174e35849b64 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 4 Jan 2024 11:57:21 +0100 Subject: [PATCH 56/96] fix test warning --- avm/res/compute/virtual-machine/modules/nic-configuration.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/res/compute/virtual-machine/modules/nic-configuration.bicep b/avm/res/compute/virtual-machine/modules/nic-configuration.bicep index 13912cf7c7..934c41a274 100644 --- a/avm/res/compute/virtual-machine/modules/nic-configuration.bicep +++ b/avm/res/compute/virtual-machine/modules/nic-configuration.bicep @@ -140,7 +140,7 @@ type roleAssignmentType = { @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"') + @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.') From 2123b04e39ca81e91ee8b296f300f7192177d402 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 4 Jan 2024 12:39:52 +0100 Subject: [PATCH 57/96] update json --- avm/res/compute/virtual-machine/main.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/avm/res/compute/virtual-machine/main.json b/avm/res/compute/virtual-machine/main.json index de794626c9..3d7ce7c5a6 100644 --- a/avm/res/compute/virtual-machine/main.json +++ b/avm/res/compute/virtual-machine/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "16217992416035116012" + "templateHash": "11281025329923300259" }, "name": "Virtual Machines", "description": "This module deploys a Virtual Machine with one or multiple NICs and optionally one or multiple public IPs.", @@ -990,7 +990,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "11564357055812588681" + "templateHash": "5939357302672592916" } }, "definitions": { @@ -1167,7 +1167,7 @@ "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\"" + "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": { From b7c331ffa5898ca47ba41a5c84be5594714f5ef4 Mon Sep 17 00:00:00 2001 From: Rainer Halanek <61878316+rahalan@users.noreply.github.com> Date: Thu, 4 Jan 2024 13:54:05 +0100 Subject: [PATCH 58/96] Update avm/res/compute/virtual-machine/extension/main.bicep Co-authored-by: Alexander Sehr --- avm/res/compute/virtual-machine/extension/main.bicep | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/avm/res/compute/virtual-machine/extension/main.bicep b/avm/res/compute/virtual-machine/extension/main.bicep index 51e12982c7..67f61b1d25 100644 --- a/avm/res/compute/virtual-machine/extension/main.bicep +++ b/avm/res/compute/virtual-machine/extension/main.bicep @@ -57,9 +57,9 @@ resource extension 'Microsoft.Compute/virtualMachines/extensions@2022-11-01' = { typeHandlerVersion: typeHandlerVersion autoUpgradeMinorVersion: autoUpgradeMinorVersion enableAutomaticUpgrade: enableAutomaticUpgrade - forceUpdateTag: !empty(forceUpdateTag) ? forceUpdateTag : null - settings: !empty(settings) ? settings : null - protectedSettings: !empty(protectedSettings) ? protectedSettings : null + forceUpdateTag:forceUpdateTag + settings: settings + protectedSettings: protectedSettings suppressFailures: supressFailures } } From 2f13891a6ed5856fd4417a666e99e418c260abc5 Mon Sep 17 00:00:00 2001 From: Rainer Halanek <61878316+rahalan@users.noreply.github.com> Date: Thu, 4 Jan 2024 13:54:12 +0100 Subject: [PATCH 59/96] Update avm/res/compute/virtual-machine/extension/main.bicep Co-authored-by: Alexander Sehr --- avm/res/compute/virtual-machine/extension/main.bicep | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/avm/res/compute/virtual-machine/extension/main.bicep b/avm/res/compute/virtual-machine/extension/main.bicep index 67f61b1d25..359f99cffd 100644 --- a/avm/res/compute/virtual-machine/extension/main.bicep +++ b/avm/res/compute/virtual-machine/extension/main.bicep @@ -24,14 +24,14 @@ param typeHandlerVersion string param autoUpgradeMinorVersion bool @description('Optional. How the extension handler should be forced to update even if the extension configuration has not changed.') -param forceUpdateTag string = '' +param forceUpdateTag string? @description('Optional. Any object that contains the extension specific settings.') -param settings object = {} +param settings object? @description('Optional. Any object that contains the extension specific protected settings.') @secure() -param protectedSettings object = {} +param protectedSettings object? @description('Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false.') param supressFailures bool = false From 189dde9cf773376f8a2984d8496fbdd924a56917 Mon Sep 17 00:00:00 2001 From: Rainer Halanek <61878316+rahalan@users.noreply.github.com> Date: Thu, 4 Jan 2024 13:54:31 +0100 Subject: [PATCH 60/96] Update avm/res/compute/virtual-machine/main.bicep Co-authored-by: Alexander Sehr --- avm/res/compute/virtual-machine/main.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/res/compute/virtual-machine/main.bicep b/avm/res/compute/virtual-machine/main.bicep index 202c312e8f..08ea79e2f5 100644 --- a/avm/res/compute/virtual-machine/main.bicep +++ b/avm/res/compute/virtual-machine/main.bicep @@ -424,7 +424,7 @@ resource vm 'Microsoft.Compute/virtualMachines@2022-11-01' = { deleteOption: contains(nicConfiguration, 'deleteOption') ? nicConfiguration.deleteOption : 'Delete' primary: index == 0 ? true : false } - #disable-next-line use-resource-id-functions + #disable-next-line use-resource-id-functions - Reason: It's a reference from inside a loop which makes resolving it using a resource reference particulary difficult. id: az.resourceId('Microsoft.Network/networkInterfaces', '${name}${nicConfiguration.nicSuffix}') }] } From b8a7011c632f48dad9df57e4523d76fef72c5136 Mon Sep 17 00:00:00 2001 From: Rainer Halanek <61878316+rahalan@users.noreply.github.com> Date: Thu, 4 Jan 2024 13:54:45 +0100 Subject: [PATCH 61/96] Update avm/res/compute/virtual-machine/tests/e2e/windows.ssecmk/main.test.bicep Co-authored-by: Alexander Sehr --- .../virtual-machine/tests/e2e/windows.ssecmk/main.test.bicep | 5 ----- 1 file changed, 5 deletions(-) diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows.ssecmk/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.ssecmk/main.test.bicep index 1119647ab3..66b285f155 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/windows.ssecmk/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/windows.ssecmk/main.test.bicep @@ -101,10 +101,5 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' } } ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } } }] From 682004ea21d9484b535fbbc2fcb65b2905a3cf1d Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 4 Jan 2024 13:58:49 +0100 Subject: [PATCH 62/96] remove name in default test --- .../virtual-machine/tests/e2e/linux.defaults/main.test.bicep | 1 - 1 file changed, 1 deletion(-) diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep index ff60259195..b87fa6cb2d 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep @@ -55,7 +55,6 @@ module nestedDependencies 'dependencies.bicep' = { @batchSize(1) module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { scope: resourceGroup - name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' params: { location: location name: '${namePrefix}${serviceShort}' From 6c8e8432366722ba0320875036c88bba9604532d Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 4 Jan 2024 14:01:10 +0100 Subject: [PATCH 63/96] fix comment --- avm/res/compute/virtual-machine/main.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/res/compute/virtual-machine/main.bicep b/avm/res/compute/virtual-machine/main.bicep index 08ea79e2f5..75e8a464ea 100644 --- a/avm/res/compute/virtual-machine/main.bicep +++ b/avm/res/compute/virtual-machine/main.bicep @@ -424,7 +424,7 @@ resource vm 'Microsoft.Compute/virtualMachines@2022-11-01' = { deleteOption: contains(nicConfiguration, 'deleteOption') ? nicConfiguration.deleteOption : 'Delete' primary: index == 0 ? true : false } - #disable-next-line use-resource-id-functions - Reason: It's a reference from inside a loop which makes resolving it using a resource reference particulary difficult. + #disable-next-line use-resource-id-functions // It's a reference from inside a loop which makes resolving it using a resource reference particulary difficult. id: az.resourceId('Microsoft.Network/networkInterfaces', '${name}${nicConfiguration.nicSuffix}') }] } From 7899c996be355a5c419d9a4ad0bcc7baf7a7bee4 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 4 Jan 2024 14:02:22 +0100 Subject: [PATCH 64/96] add name --- .../virtual-machine/tests/e2e/linux.defaults/main.test.bicep | 1 + 1 file changed, 1 insertion(+) diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep index b87fa6cb2d..ff60259195 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/linux.defaults/main.test.bicep @@ -55,6 +55,7 @@ module nestedDependencies 'dependencies.bicep' = { @batchSize(1) module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' params: { location: location name: '${namePrefix}${serviceShort}' From 0f75b0cce8283d04a0e31fa4449372454d5ddf8f Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 4 Jan 2024 14:25:45 +0100 Subject: [PATCH 65/96] enable telemetry for sub module --- avm/res/compute/virtual-machine/main.bicep | 1 + .../virtual-machine/modules/nic-configuration.bicep | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/avm/res/compute/virtual-machine/main.bicep b/avm/res/compute/virtual-machine/main.bicep index 75e8a464ea..8bb68bc4a1 100644 --- a/avm/res/compute/virtual-machine/main.bicep +++ b/avm/res/compute/virtual-machine/main.bicep @@ -353,6 +353,7 @@ module vm_nic 'modules/nic-configuration.bicep' = [for (nicConfiguration, index) tags: nicConfiguration.?tags ?? tags diagnosticSettings: nicConfiguration.?diagnosticSettings roleAssignments: nicConfiguration.?roleAssignments + enableTelemetry: nicConfiguration.?enableTelemetry ?? enableTelemetry } }] diff --git a/avm/res/compute/virtual-machine/modules/nic-configuration.bicep b/avm/res/compute/virtual-machine/modules/nic-configuration.bicep index 934c41a274..b0119f00fe 100644 --- a/avm/res/compute/virtual-machine/modules/nic-configuration.bicep +++ b/avm/res/compute/virtual-machine/modules/nic-configuration.bicep @@ -5,6 +5,8 @@ param tags object? param enableIPForwarding bool = false param enableAcceleratedNetworking bool = false param dnsServers array = [] +@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') +param enableTelemetry bool = true @description('Optional. The network security group (NSG) to attach to the network interface.') param networkSecurityGroupResourceId string = '' @@ -18,8 +20,6 @@ param diagnosticSettings diagnosticSettingType @description('Optional. Array of role assignments to create.') param roleAssignments roleAssignmentType -var enableReferencedModulesTelemetry = false - module networkInterface_publicIPAddresses 'br/public:avm/res/network/public-ip-address:0.2.1' = [for (ipConfiguration, index) in ipConfigurations: if (contains(ipConfiguration, 'pipconfiguration')) { name: '${deployment().name}-publicIP-${index}' params: { @@ -39,6 +39,7 @@ module networkInterface_publicIPAddresses 'br/public:avm/res/network/public-ip-a '2' '3' ] + enableTelemetry: enableTelemetry } }] @@ -66,7 +67,7 @@ module networkInterface 'br/public:avm/res/network/network-interface:0.2.2' = { diagnosticSettings: diagnosticSettings dnsServers: !empty(dnsServers) ? dnsServers : [] enableAcceleratedNetworking: enableAcceleratedNetworking - enableTelemetry: enableReferencedModulesTelemetry + enableTelemetry: enableTelemetry enableIPForwarding: enableIPForwarding lock: lock networkSecurityGroupResourceId: !empty(networkSecurityGroupResourceId) ? networkSecurityGroupResourceId : '' From 26ff54c500c0c2c24cc6a0ae74ac3fab2ee40cd7 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 4 Jan 2024 14:52:26 +0100 Subject: [PATCH 66/96] remove RBAC & MI from WAF test --- .../tests/e2e/waf-aligned/dependencies.bicep | 43 ------------------- .../tests/e2e/waf-aligned/main.test.bicep | 38 ---------------- 2 files changed, 81 deletions(-) diff --git a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/dependencies.bicep index e198bcd227..4d6d69ed7a 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/dependencies.bicep @@ -4,9 +4,6 @@ param virtualNetworkName string @description('Required. The name of the Application Security Group to create.') param applicationSecurityGroupName string -@description('Required. The name of the Managed Identity to create.') -param managedIdentityName string - @description('Required. The name of the Load Balancer to create.') param loadBalancerName string @@ -56,21 +53,6 @@ resource applicationSecurityGroup 'Microsoft.Network/applicationSecurityGroups@2 location: location } -resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location -} - -resource msiRGContrRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid(resourceGroup().id, 'Contributor', managedIdentity.id) - scope: resourceGroup() - properties: { - principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor - principalType: 'ServicePrincipal' - } -} - resource loadBalancer 'Microsoft.Network/loadBalancers@2023-04-01' = { name: loadBalancerName location: location @@ -211,16 +193,6 @@ resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = { } } -resource msiKVReadRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid('msi-${keyVault::key.id}-${location}-${managedIdentity.id}-KeyVault-Key-Read-RoleAssignment') - scope: keyVault::key - properties: { - principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') // Key Vault Crypto User - principalType: 'ServicePrincipal' - } -} - resource storageAccount 'Microsoft.Storage/storageAccounts@2021-09-01' = { name: storageAccountName location: location @@ -242,21 +214,12 @@ resource storageUpload 'Microsoft.Resources/deploymentScripts@2020-10-01' = { name: storageUploadDeploymentScriptName location: location kind: 'AzurePowerShell' - identity: { - type: 'UserAssigned' - userAssignedIdentities: { - '${managedIdentity.id}': {} - } - } properties: { azPowerShellVersion: '9.0' retentionInterval: 'P1D' arguments: '-StorageAccountName "${storageAccount.name}" -ResourceGroupName "${resourceGroup().name}" -ContainerName "${storageAccount::blobService::container.name}" -FileName "${storageAccountCSEFileName}"' scriptContent: loadTextContent('../../../../../../utilities/e2e-template-assets/scripts/Set-BlobContent.ps1') } - dependsOn: [ - msiRGContrRoleAssignment - ] } resource proximityPlacementGroup 'Microsoft.Compute/proximityPlacementGroups@2022-03-01' = { @@ -270,12 +233,6 @@ output subnetResourceId string = virtualNetwork.properties.subnets[0].id @description('The resource ID of the created Application Security Group.') output applicationSecurityGroupResourceId string = applicationSecurityGroup.id -@description('The principal ID of the created Managed Identity.') -output managedIdentityPrincipalId string = managedIdentity.properties.principalId - -@description('The resource ID of the created Managed Identity.') -output managedIdentityResourceId string = managedIdentity.id - @description('The resource ID of the created Load Balancer Backend Pool.') output loadBalancerBackendPoolResourceId string = loadBalancer.properties.backendAddressPools[0].id diff --git a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep index ee093a7c96..21c55ad87c 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep @@ -42,7 +42,6 @@ module nestedDependencies 'dependencies.bicep' = { location: location virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' applicationSecurityGroupName: 'dep-${namePrefix}-asg-${serviceShort}' - managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}' loadBalancerName: 'dep-${namePrefix}-lb-${serviceShort}' recoveryServicesVaultName: 'dep-${namePrefix}-rsv-${serviceShort}' @@ -103,13 +102,6 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: 'ipconfig01' pipConfiguration: { publicIpNameSuffix: '-pip-01' - roleAssignments: [ - { - roleDefinitionIdOrName: 'Reader' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - ] } zones: [ '1' @@ -134,13 +126,6 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' } ] nicSuffix: '-nic-01' - roleAssignments: [ - { - roleDefinitionIdOrName: 'Reader' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - ] diagnosticSettings: [ { name: 'customSetting' @@ -299,29 +284,6 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: 'myCustomLockName' } proximityPlacementGroupResourceId: nestedDependencies.outputs.proximityPlacementGroupResourceId - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - ] - managedIdentities: { - systemAssigned: true - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] - } tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' From cb1c0853fd03c197d33e8d1b5692117868ae3ce7 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 4 Jan 2024 14:54:41 +0100 Subject: [PATCH 67/96] remove test case --- .../tests/e2e/windows.atmg/dependencies.bicep | 30 ------ .../tests/e2e/windows.atmg/main.test.bicep | 92 ------------------- 2 files changed, 122 deletions(-) delete mode 100644 avm/res/compute/virtual-machine/tests/e2e/windows.atmg/dependencies.bicep delete mode 100644 avm/res/compute/virtual-machine/tests/e2e/windows.atmg/main.test.bicep diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows.atmg/dependencies.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.atmg/dependencies.bicep deleted file mode 100644 index a546ea7dba..0000000000 --- a/avm/res/compute/virtual-machine/tests/e2e/windows.atmg/dependencies.bicep +++ /dev/null @@ -1,30 +0,0 @@ -@description('Required. The name of the Virtual Network to create.') -param virtualNetworkName string - -@description('Optional. The location to deploy resources to.') -param location string = resourceGroup().location - -var addressPrefix = '10.0.0.0/16' - -resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { - name: virtualNetworkName - location: location - properties: { - addressSpace: { - addressPrefixes: [ - addressPrefix - ] - } - subnets: [ - { - name: 'defaultSubnet' - properties: { - addressPrefix: cidrSubnet(addressPrefix, 16, 0) - } - } - ] - } -} - -@description('The resource ID of the created Virtual Network Subnet.') -output subnetResourceId string = virtualNetwork.properties.subnets[0].id diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows.atmg/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.atmg/main.test.bicep deleted file mode 100644 index 6cc1b15e50..0000000000 --- a/avm/res/compute/virtual-machine/tests/e2e/windows.atmg/main.test.bicep +++ /dev/null @@ -1,92 +0,0 @@ -targetScope = 'subscription' - -metadata name = 'Using automanage for the VM.' -metadata description = 'This instance deploys the module with registering to an automation account.' - -// ========== // -// Parameters // -// ========== // - -@description('Optional. The name of the resource group to deploy for testing purposes.') -@maxLength(90) -param resourceGroupName string = 'dep-${namePrefix}-compute.virtualMachines-${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 = 'cvmwinatmg' - -@description('Optional. The password to leverage for the login.') -@secure() -param password string = newGuid() - -@description('Optional. A token to inject into the name of each resource.') -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: { - location: location - virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' - } -} - -// ============== // -// Test Execution // -// ============== // - -@batchSize(1) -module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { - scope: resourceGroup - name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' - params: { - location: location - name: '${namePrefix}${serviceShort}' - adminUsername: 'localAdministrator' - imageReference: { - publisher: 'MicrosoftWindowsServer' - offer: 'WindowsServer' - sku: '2022-datacenter-azure-edition' - version: 'latest' - } - nicConfigurations: [ - { - ipConfigurations: [ - { - name: 'ipconfig01' - subnetResourceId: nestedDependencies.outputs.subnetResourceId - } - ] - nicSuffix: '-nic-01' - } - ] - osDisk: { - diskSizeGB: '128' - managedDisk: { - storageAccountType: 'Premium_LRS' - } - } - osType: 'Windows' - vmSize: 'Standard_DS2_v2' - adminPassword: password - configurationProfile: '/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesProduction' - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - } -}] From 4a82cad5f44d9c06c90a72c825d70522df433cda Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 4 Jan 2024 16:19:17 +0100 Subject: [PATCH 68/96] make VM name mandatory --- avm/res/compute/virtual-machine/README.md | 304 +++------------------ avm/res/compute/virtual-machine/main.bicep | 4 +- avm/res/compute/virtual-machine/main.json | 153 ++++++----- 3 files changed, 123 insertions(+), 338 deletions(-) diff --git a/avm/res/compute/virtual-machine/README.md b/avm/res/compute/virtual-machine/README.md index 8b8705aa50..deeb7b539f 100644 --- a/avm/res/compute/virtual-machine/README.md +++ b/avm/res/compute/virtual-machine/README.md @@ -35,10 +35,9 @@ The following section provides usage examples for the module, which were used to - [Using automanage for the VM.](#example-1-using-automanage-for-the-vm) - [Using only defaults](#example-2-using-only-defaults) - [WAF-aligned](#example-3-waf-aligned) -- [Using automanage for the VM.](#example-4-using-automanage-for-the-vm) -- [Using only defaults](#example-5-using-only-defaults) -- [Using large parameter set](#example-6-using-large-parameter-set) -- [Using disk encryption set for the VM.](#example-7-using-disk-encryption-set-for-the-vm) +- [Using only defaults](#example-4-using-only-defaults) +- [Using large parameter set](#example-5-using-large-parameter-set) +- [Using disk encryption set for the VM.](#example-6-using-disk-encryption-set-for-the-vm) ### Example 1: _Using automanage for the VM._ @@ -61,6 +60,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { sku: '22_04-lts-gen2' version: 'latest' } + name: 'cvmlinatmg' nicConfigurations: [ { ipConfigurations: [ @@ -102,7 +102,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { configurationProfile: '/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesProduction' disablePasswordAuthentication: true location: '' - name: 'cvmlinatmg' publicKeys: [ { keyData: '' @@ -142,6 +141,9 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { "version": "latest" } }, + "name": { + "value": "cvmlinatmg" + }, "nicConfigurations": { "value": [ { @@ -197,9 +199,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { "location": { "value": "" }, - "name": { - "value": "cvmlinatmg" - }, "publicKeys": { "value": [ { @@ -243,6 +242,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { sku: '22_04-lts-gen2' version: 'latest' } + name: 'cvmlinmin' nicConfigurations: [ { ipConfigurations: [ @@ -269,7 +269,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { // Non-required parameters disablePasswordAuthentication: true location: '' - name: 'cvmlinmin' publicKeys: [ { keyData: '' @@ -304,6 +303,9 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { "version": "latest" } }, + "name": { + "value": "cvmlinmin" + }, "nicConfigurations": { "value": [ { @@ -342,9 +344,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { "location": { "value": "" }, - "name": { - "value": "cvmlinmin" - }, "publicKeys": { "value": [ { @@ -381,6 +380,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { sku: '2019-datacenter' version: 'latest' } + name: 'cvmwinwaf' nicConfigurations: [ { deleteOption: 'Delete' @@ -427,13 +427,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { name: 'ipconfig01' pipConfiguration: { publicIpNameSuffix: '-pip-01' - roleAssignments: [ - { - principalId: '' - principalType: 'ServicePrincipal' - roleDefinitionIdOrName: 'Reader' - } - ] } subnetResourceId: '' zones: [ @@ -444,13 +437,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { } ] nicSuffix: '-nic-01' - roleAssignments: [ - { - principalId: '' - principalType: 'ServicePrincipal' - roleDefinitionIdOrName: 'Reader' - } - ] } ] osDisk: { @@ -596,32 +582,8 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { kind: 'CanNotDelete' name: 'myCustomLockName' } - managedIdentities: { - systemAssigned: true - userAssignedResourceIds: [ - '' - ] - } - name: 'cvmwinwaf' patchMode: 'AutomaticByPlatform' proximityPlacementGroupResourceId: '' - roleAssignments: [ - { - principalId: '' - principalType: 'ServicePrincipal' - roleDefinitionIdOrName: 'Owner' - } - { - principalId: '' - principalType: 'ServicePrincipal' - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - } - { - principalId: '' - principalType: 'ServicePrincipal' - roleDefinitionIdOrName: '' - } - ] tags: { Environment: 'Non-Prod' 'hidden-title': 'This is visible in the resource name' @@ -655,6 +617,9 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { "version": "latest" } }, + "name": { + "value": "cvmwinwaf" + }, "nicConfigurations": { "value": [ { @@ -701,14 +666,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { ], "name": "ipconfig01", "pipConfiguration": { - "publicIpNameSuffix": "-pip-01", - "roleAssignments": [ - { - "principalId": "", - "principalType": "ServicePrincipal", - "roleDefinitionIdOrName": "Reader" - } - ] + "publicIpNameSuffix": "-pip-01" }, "subnetResourceId": "", "zones": [ @@ -718,14 +676,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { ] } ], - "nicSuffix": "-nic-01", - "roleAssignments": [ - { - "principalId": "", - "principalType": "ServicePrincipal", - "roleDefinitionIdOrName": "Reader" - } - ] + "nicSuffix": "-nic-01" } ] }, @@ -918,174 +869,12 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { "name": "myCustomLockName" } }, - "managedIdentities": { - "value": { - "systemAssigned": true, - "userAssignedResourceIds": [ - "" - ] - } - }, - "name": { - "value": "cvmwinwaf" - }, "patchMode": { "value": "AutomaticByPlatform" }, "proximityPlacementGroupResourceId": { "value": "" }, - "roleAssignments": { - "value": [ - { - "principalId": "", - "principalType": "ServicePrincipal", - "roleDefinitionIdOrName": "Owner" - }, - { - "principalId": "", - "principalType": "ServicePrincipal", - "roleDefinitionIdOrName": "b24988ac-6180-42a0-ab88-20f7382dd24c" - }, - { - "principalId": "", - "principalType": "ServicePrincipal", - "roleDefinitionIdOrName": "" - } - ] - }, - "tags": { - "value": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - } -} -``` - - -

- -### Example 4: _Using automanage for the VM._ - -This instance deploys the module with registering to an automation account. - - -

- -via Bicep module - -```bicep -module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { - name: '${uniqueString(deployment().name, location)}-test-cvmwinatmg' - params: { - // Required parameters - adminUsername: 'localAdministrator' - imageReference: { - offer: 'WindowsServer' - publisher: 'MicrosoftWindowsServer' - sku: '2022-datacenter-azure-edition' - version: 'latest' - } - nicConfigurations: [ - { - ipConfigurations: [ - { - name: 'ipconfig01' - subnetResourceId: '' - } - ] - nicSuffix: '-nic-01' - } - ] - osDisk: { - diskSizeGB: '128' - managedDisk: { - storageAccountType: 'Premium_LRS' - } - } - osType: 'Windows' - vmSize: 'Standard_DS2_v2' - // Non-required parameters - adminPassword: '' - configurationProfile: '/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesProduction' - location: '' - name: 'cvmwinatmg' - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } -} -``` - -
-

- -

- -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 - "adminUsername": { - "value": "localAdministrator" - }, - "imageReference": { - "value": { - "offer": "WindowsServer", - "publisher": "MicrosoftWindowsServer", - "sku": "2022-datacenter-azure-edition", - "version": "latest" - } - }, - "nicConfigurations": { - "value": [ - { - "ipConfigurations": [ - { - "name": "ipconfig01", - "subnetResourceId": "" - } - ], - "nicSuffix": "-nic-01" - } - ] - }, - "osDisk": { - "value": { - "diskSizeGB": "128", - "managedDisk": { - "storageAccountType": "Premium_LRS" - } - } - }, - "osType": { - "value": "Windows" - }, - "vmSize": { - "value": "Standard_DS2_v2" - }, - // Non-required parameters - "adminPassword": { - "value": "" - }, - "configurationProfile": { - "value": "/providers/Microsoft.Automanage/bestPractices/AzureBestPracticesProduction" - }, - "location": { - "value": "" - }, - "name": { - "value": "cvmwinatmg" - }, "tags": { "value": { "Environment": "Non-Prod", @@ -1100,7 +889,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = {

-### Example 5: _Using only defaults_ +### Example 4: _Using only defaults_ This instance deploys the module with the minimum set of required parameters. @@ -1121,6 +910,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { sku: '2022-datacenter-azure-edition' version: 'latest' } + name: 'cvmwinmin' nicConfigurations: [ { ipConfigurations: [ @@ -1144,7 +934,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { // Non-required parameters adminPassword: '' location: '' - name: 'cvmwinmin' } } ``` @@ -1173,6 +962,9 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { "version": "latest" } }, + "name": { + "value": "cvmwinmin" + }, "nicConfigurations": { "value": [ { @@ -1207,9 +999,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { }, "location": { "value": "" - }, - "name": { - "value": "cvmwinmin" } } } @@ -1218,7 +1007,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = {

-### Example 6: _Using large parameter set_ +### Example 5: _Using large parameter set_ This instance deploys the module with most of its features enabled. @@ -1239,6 +1028,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { sku: '2019-datacenter' version: 'latest' } + name: 'cvmwinmax' nicConfigurations: [ { deleteOption: 'Delete' @@ -1460,7 +1250,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { '' ] } - name: 'cvmwinmax' patchMode: 'AutomaticByPlatform' proximityPlacementGroupResourceId: '' roleAssignments: [ @@ -1513,6 +1302,9 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { "version": "latest" } }, + "name": { + "value": "cvmwinmax" + }, "nicConfigurations": { "value": [ { @@ -1784,9 +1576,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { ] } }, - "name": { - "value": "cvmwinmax" - }, "patchMode": { "value": "AutomaticByPlatform" }, @@ -1826,7 +1615,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = {

-### Example 7: _Using disk encryption set for the VM._ +### Example 6: _Using disk encryption set for the VM._ This instance deploys the module with disk enryption set. @@ -1847,6 +1636,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { sku: '2019-datacenter' version: 'latest' } + name: 'cvmwincmk' nicConfigurations: [ { ipConfigurations: [ @@ -1883,12 +1673,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { } ] location: '' - name: 'cvmwincmk' - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } } } ``` @@ -1917,6 +1701,9 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { "version": "latest" } }, + "name": { + "value": "cvmwincmk" + }, "nicConfigurations": { "value": [ { @@ -1966,16 +1753,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { }, "location": { "value": "" - }, - "name": { - "value": "cvmwincmk" - }, - "tags": { - "value": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } } } } @@ -1994,6 +1771,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { | [`adminUsername`](#parameter-adminusername) | securestring | Administrator username. | | [`configurationProfile`](#parameter-configurationprofile) | string | The configuration profile of automanage. | | [`imageReference`](#parameter-imagereference) | object | OS image reference. In case of marketplace images, it's the combination of the publisher, offer, sku, version attributes. In case of custom images it's the resource ID of the custom image. | +| [`name`](#parameter-name) | string | The name of the virtual machine to be created. You should use a unique prefix to reduce name collisions in Active Directory. | | [`nicConfigurations`](#parameter-nicconfigurations) | array | Configures NICs and PIPs. | | [`osDisk`](#parameter-osdisk) | object | Specifies the OS disk. For security reasons, it is recommended to specify DiskEncryptionSet into the osDisk object. Restrictions: DiskEncryptionSet cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. | | [`osType`](#parameter-ostype) | string | The chosen OS type. | @@ -2040,7 +1818,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { | [`lock`](#parameter-lock) | object | The lock settings of the service. | | [`managedIdentities`](#parameter-managedidentities) | object | The managed identity definition for this resource. The system-assigned managed identity will automatically be enabled if extensionAadJoinConfig.enabled = "True". | | [`maxPriceForLowPriorityVm`](#parameter-maxpriceforlowpriorityvm) | string | Specifies the maximum price you are willing to pay for a low priority VM/VMSS. This price is in US Dollars. | -| [`name`](#parameter-name) | string | The name of the virtual machine to be created. You should use a unique prefix to reduce name collisions in Active Directory. If no value is provided, a 10 character long unique string will be generated based on the Resource Group's name. | | [`patchAssessmentMode`](#parameter-patchassessmentmode) | string | VM guest patching assessment mode. Set it to 'AutomaticByPlatform' to enable automatically check for updates every 24 hours. | | [`patchMode`](#parameter-patchmode) | string | VM guest patching orchestration mode. 'AutomaticByOS' & 'Manual' are for Windows only, 'ImageDefault' for Linux only. Refer to 'https://learn.microsoft.com/en-us/azure/virtual-machines/automatic-vm-guest-patching'. | | [`plan`](#parameter-plan) | object | Specifies information about the marketplace image used to create the virtual machine. This element is only used for marketplace images. Before you can use a marketplace image from an API, you must enable the image for programmatic use. | @@ -2094,6 +1871,13 @@ OS image reference. In case of marketplace images, it's the combination of the p - Required: Yes - Type: object +### Parameter: `name` + +The name of the virtual machine to be created. You should use a unique prefix to reduce name collisions in Active Directory. + +- Required: Yes +- Type: string + ### Parameter: `nicConfigurations` Configures NICs and PIPs. @@ -2536,14 +2320,6 @@ Specifies the maximum price you are willing to pay for a low priority VM/VMSS. T - Type: string - Default: `''` -### Parameter: `name` - -The name of the virtual machine to be created. You should use a unique prefix to reduce name collisions in Active Directory. If no value is provided, a 10 character long unique string will be generated based on the Resource Group's name. - -- Required: No -- Type: string -- Default: `[take(toLower(uniqueString(resourceGroup().name)), 10)]` - ### Parameter: `patchAssessmentMode` VM guest patching assessment mode. Set it to 'AutomaticByPlatform' to enable automatically check for updates every 24 hours. diff --git a/avm/res/compute/virtual-machine/main.bicep b/avm/res/compute/virtual-machine/main.bicep index 8bb68bc4a1..5b72ddc2fa 100644 --- a/avm/res/compute/virtual-machine/main.bicep +++ b/avm/res/compute/virtual-machine/main.bicep @@ -3,8 +3,8 @@ metadata description = 'This module deploys a Virtual Machine with one or multip metadata owner = 'Azure/module-maintainers' // Main resource -@description('Optional. The name of the virtual machine to be created. You should use a unique prefix to reduce name collisions in Active Directory. If no value is provided, a 10 character long unique string will be generated based on the Resource Group\'s name.') -param name string = take(toLower(uniqueString(resourceGroup().name)), 10) +@description('Required. The name of the virtual machine to be created. You should use a unique prefix to reduce name collisions in Active Directory.') +param name string @description('Optional. Can be used if the computer name needs to be different from the Azure VM resource name. If not used, the resource name will be used as computer name.') param computerName string = name diff --git a/avm/res/compute/virtual-machine/main.json b/avm/res/compute/virtual-machine/main.json index 3d7ce7c5a6..9f8f0c17f3 100644 --- a/avm/res/compute/virtual-machine/main.json +++ b/avm/res/compute/virtual-machine/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "11281025329923300259" + "templateHash": "3906813880748579145" }, "name": "Virtual Machines", "description": "This module deploys a Virtual Machine with one or multiple NICs and optionally one or multiple public IPs.", @@ -237,9 +237,8 @@ "parameters": { "name": { "type": "string", - "defaultValue": "[take(toLower(uniqueString(resourceGroup().name)), 10)]", "metadata": { - "description": "Optional. The name of the virtual machine to be created. You should use a unique prefix to reduce name collisions in Active Directory. If no value is provided, a 10 character long unique string will be generated based on the Resource Group's name." + "description": "Required. The name of the virtual machine to be created. You should use a unique prefix to reduce name collisions in Active Directory." } }, "computerName": { @@ -980,6 +979,9 @@ }, "roleAssignments": { "value": "[tryGet(parameters('nicConfigurations')[copyIndex()], 'roleAssignments')]" + }, + "enableTelemetry": { + "value": "[coalesce(tryGet(parameters('nicConfigurations')[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]" } }, "template": { @@ -990,7 +992,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "5939357302672592916" + "templateHash": "18013796946460477676" } }, "definitions": { @@ -1218,6 +1220,13 @@ "type": "array", "defaultValue": [] }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + }, "networkSecurityGroupResourceId": { "type": "string", "defaultValue": "", @@ -1244,9 +1253,6 @@ } } }, - "variables": { - "enableReferencedModulesTelemetry": false - }, "resources": { "networkInterface_publicIPAddresses": { "copy": { @@ -1284,7 +1290,10 @@ "tags": { "value": "[coalesce(tryGet(parameters('ipConfigurations')[copyIndex()], 'tags'), parameters('tags'))]" }, - "zones": "[if(contains(parameters('ipConfigurations')[copyIndex()], 'zones'), createObject('value', parameters('ipConfigurations')[copyIndex()].zones), createObject('value', createArray('1', '2', '3')))]" + "zones": "[if(contains(parameters('ipConfigurations')[copyIndex()], 'zones'), createObject('value', parameters('ipConfigurations')[copyIndex()].zones), createObject('value', createArray('1', '2', '3')))]", + "enableTelemetry": { + "value": "[parameters('enableTelemetry')]" + } }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", @@ -1880,7 +1889,7 @@ "value": "[parameters('enableAcceleratedNetworking')]" }, "enableTelemetry": { - "value": "[variables('enableReferencedModulesTelemetry')]" + "value": "[parameters('enableTelemetry')]" }, "enableIPForwarding": { "value": "[parameters('enableIPForwarding')]" @@ -2431,7 +2440,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "10332103716678024514" + "templateHash": "13562327621635125722" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -2483,21 +2492,21 @@ }, "forceUpdateTag": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." } }, "settings": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } }, "protectedSettings": { "type": "secureObject", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific protected settings." } @@ -2542,9 +2551,9 @@ "typeHandlerVersion": "[parameters('typeHandlerVersion')]", "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", - "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", - "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", - "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", + "forceUpdateTag": "[parameters('forceUpdateTag')]", + "settings": "[parameters('settings')]", + "protectedSettings": "[parameters('protectedSettings')]", "suppressFailures": "[parameters('supressFailures')]" }, "dependsOn": [ @@ -2637,7 +2646,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "10332103716678024514" + "templateHash": "13562327621635125722" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -2689,21 +2698,21 @@ }, "forceUpdateTag": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." } }, "settings": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } }, "protectedSettings": { "type": "secureObject", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific protected settings." } @@ -2748,9 +2757,9 @@ "typeHandlerVersion": "[parameters('typeHandlerVersion')]", "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", - "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", - "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", - "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", + "forceUpdateTag": "[parameters('forceUpdateTag')]", + "settings": "[parameters('settings')]", + "protectedSettings": "[parameters('protectedSettings')]", "suppressFailures": "[parameters('supressFailures')]" }, "dependsOn": [ @@ -2838,7 +2847,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "10332103716678024514" + "templateHash": "13562327621635125722" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -2890,21 +2899,21 @@ }, "forceUpdateTag": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." } }, "settings": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } }, "protectedSettings": { "type": "secureObject", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific protected settings." } @@ -2949,9 +2958,9 @@ "typeHandlerVersion": "[parameters('typeHandlerVersion')]", "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", - "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", - "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", - "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", + "forceUpdateTag": "[parameters('forceUpdateTag')]", + "settings": "[parameters('settings')]", + "protectedSettings": "[parameters('protectedSettings')]", "suppressFailures": "[parameters('supressFailures')]" }, "dependsOn": [ @@ -3034,7 +3043,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "10332103716678024514" + "templateHash": "13562327621635125722" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3086,21 +3095,21 @@ }, "forceUpdateTag": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." } }, "settings": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } }, "protectedSettings": { "type": "secureObject", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific protected settings." } @@ -3145,9 +3154,9 @@ "typeHandlerVersion": "[parameters('typeHandlerVersion')]", "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", - "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", - "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", - "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", + "forceUpdateTag": "[parameters('forceUpdateTag')]", + "settings": "[parameters('settings')]", + "protectedSettings": "[parameters('protectedSettings')]", "suppressFailures": "[parameters('supressFailures')]" }, "dependsOn": [ @@ -3230,7 +3239,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "10332103716678024514" + "templateHash": "13562327621635125722" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3282,21 +3291,21 @@ }, "forceUpdateTag": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." } }, "settings": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } }, "protectedSettings": { "type": "secureObject", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific protected settings." } @@ -3341,9 +3350,9 @@ "typeHandlerVersion": "[parameters('typeHandlerVersion')]", "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", - "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", - "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", - "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", + "forceUpdateTag": "[parameters('forceUpdateTag')]", + "settings": "[parameters('settings')]", + "protectedSettings": "[parameters('protectedSettings')]", "suppressFailures": "[parameters('supressFailures')]" }, "dependsOn": [ @@ -3426,7 +3435,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "10332103716678024514" + "templateHash": "13562327621635125722" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3478,21 +3487,21 @@ }, "forceUpdateTag": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." } }, "settings": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } }, "protectedSettings": { "type": "secureObject", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific protected settings." } @@ -3537,9 +3546,9 @@ "typeHandlerVersion": "[parameters('typeHandlerVersion')]", "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", - "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", - "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", - "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", + "forceUpdateTag": "[parameters('forceUpdateTag')]", + "settings": "[parameters('settings')]", + "protectedSettings": "[parameters('protectedSettings')]", "suppressFailures": "[parameters('supressFailures')]" }, "dependsOn": [ @@ -3626,7 +3635,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "10332103716678024514" + "templateHash": "13562327621635125722" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3678,21 +3687,21 @@ }, "forceUpdateTag": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." } }, "settings": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } }, "protectedSettings": { "type": "secureObject", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific protected settings." } @@ -3737,9 +3746,9 @@ "typeHandlerVersion": "[parameters('typeHandlerVersion')]", "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", - "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", - "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", - "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", + "forceUpdateTag": "[parameters('forceUpdateTag')]", + "settings": "[parameters('settings')]", + "protectedSettings": "[parameters('protectedSettings')]", "suppressFailures": "[parameters('supressFailures')]" }, "dependsOn": [ @@ -3834,7 +3843,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "10332103716678024514" + "templateHash": "13562327621635125722" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3886,21 +3895,21 @@ }, "forceUpdateTag": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." } }, "settings": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } }, "protectedSettings": { "type": "secureObject", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific protected settings." } @@ -3945,9 +3954,9 @@ "typeHandlerVersion": "[parameters('typeHandlerVersion')]", "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", - "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", - "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", - "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", + "forceUpdateTag": "[parameters('forceUpdateTag')]", + "settings": "[parameters('settings')]", + "protectedSettings": "[parameters('protectedSettings')]", "suppressFailures": "[parameters('supressFailures')]" }, "dependsOn": [ @@ -4035,7 +4044,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "10332103716678024514" + "templateHash": "13562327621635125722" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -4087,21 +4096,21 @@ }, "forceUpdateTag": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." } }, "settings": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } }, "protectedSettings": { "type": "secureObject", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific protected settings." } @@ -4146,9 +4155,9 @@ "typeHandlerVersion": "[parameters('typeHandlerVersion')]", "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", - "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", - "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", - "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", + "forceUpdateTag": "[parameters('forceUpdateTag')]", + "settings": "[parameters('settings')]", + "protectedSettings": "[parameters('protectedSettings')]", "suppressFailures": "[parameters('supressFailures')]" }, "dependsOn": [ From 8fd904b9ce78e169bf6f942e754fab958eb67b21 Mon Sep 17 00:00:00 2001 From: Rainer Halanek <61878316+rahalan@users.noreply.github.com> Date: Thu, 4 Jan 2024 16:22:26 +0100 Subject: [PATCH 69/96] Update avm/res/compute/virtual-machine/modules/nic-configuration.bicep Co-authored-by: Alexander Sehr --- .../compute/virtual-machine/modules/nic-configuration.bicep | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/avm/res/compute/virtual-machine/modules/nic-configuration.bicep b/avm/res/compute/virtual-machine/modules/nic-configuration.bicep index b0119f00fe..770d924a7d 100644 --- a/avm/res/compute/virtual-machine/modules/nic-configuration.bicep +++ b/avm/res/compute/virtual-machine/modules/nic-configuration.bicep @@ -5,8 +5,9 @@ param tags object? param enableIPForwarding bool = false param enableAcceleratedNetworking bool = false param dnsServers array = [] -@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') -param enableTelemetry bool = true + +@description('Required. Enable telemetry via a Globally Unique Identifier (GUID).') +param enableTelemetry bool @description('Optional. The network security group (NSG) to attach to the network interface.') param networkSecurityGroupResourceId string = '' From d5bbd0c3172ed16894d9aa207c24d1208dc10bfe Mon Sep 17 00:00:00 2001 From: Rainer Halanek <61878316+rahalan@users.noreply.github.com> Date: Thu, 4 Jan 2024 16:22:40 +0100 Subject: [PATCH 70/96] Update avm/res/compute/virtual-machine/main.bicep Co-authored-by: Alexander Sehr --- avm/res/compute/virtual-machine/main.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/res/compute/virtual-machine/main.bicep b/avm/res/compute/virtual-machine/main.bicep index 5b72ddc2fa..592f78b862 100644 --- a/avm/res/compute/virtual-machine/main.bicep +++ b/avm/res/compute/virtual-machine/main.bicep @@ -743,7 +743,7 @@ type diagnosticSettingType = { categoryGroup: string? }[]? - @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to \'\' to disable log collection.') + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to \'\' to disable metric collection.') metricCategories: { @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to \'AllMetrics\' to collect all metrics.') category: string From e6f8a78351634ef15ca7864320c41171591b0719 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 4 Jan 2024 16:24:34 +0100 Subject: [PATCH 71/96] update json --- avm/res/compute/virtual-machine/main.json | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/avm/res/compute/virtual-machine/main.json b/avm/res/compute/virtual-machine/main.json index 9f8f0c17f3..f250d7a74f 100644 --- a/avm/res/compute/virtual-machine/main.json +++ b/avm/res/compute/virtual-machine/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "3906813880748579145" + "templateHash": "12654761906125877338" }, "name": "Virtual Machines", "description": "This module deploys a Virtual Machine with one or multiple NICs and optionally one or multiple public IPs.", @@ -180,7 +180,7 @@ }, "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." + "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": { @@ -992,7 +992,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "18013796946460477676" + "templateHash": "12547036605618417253" } }, "definitions": { @@ -1222,9 +1222,8 @@ }, "enableTelemetry": { "type": "bool", - "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Required. Enable telemetry via a Globally Unique Identifier (GUID)." } }, "networkSecurityGroupResourceId": { From 6173a15a7a2856c938b9158bf1c9d667da79a6d3 Mon Sep 17 00:00:00 2001 From: Rainer Halanek <61878316+rahalan@users.noreply.github.com> Date: Thu, 4 Jan 2024 16:25:16 +0100 Subject: [PATCH 72/96] Update avm/res/compute/virtual-machine/modules/nic-configuration.bicep Co-authored-by: Alexander Sehr --- avm/res/compute/virtual-machine/modules/nic-configuration.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/res/compute/virtual-machine/modules/nic-configuration.bicep b/avm/res/compute/virtual-machine/modules/nic-configuration.bicep index 770d924a7d..ad423b2418 100644 --- a/avm/res/compute/virtual-machine/modules/nic-configuration.bicep +++ b/avm/res/compute/virtual-machine/modules/nic-configuration.bicep @@ -40,7 +40,7 @@ module networkInterface_publicIPAddresses 'br/public:avm/res/network/public-ip-a '2' '3' ] - enableTelemetry: enableTelemetry + enableTelemetry: ipConfiguration.?enableTelemetry ?? enableTelemetry } }] From 287db7739312269558f98e5592994bfed76fe112 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 4 Jan 2024 16:30:31 +0100 Subject: [PATCH 73/96] rename test --- avm/res/compute/virtual-machine/main.bicep | 2 +- avm/res/compute/virtual-machine/main.json | 8 ++++---- .../tests/e2e/{linux.atmg => atmg}/dependencies.bicep | 0 .../tests/e2e/{linux.atmg => atmg}/main.test.bicep | 0 4 files changed, 5 insertions(+), 5 deletions(-) rename avm/res/compute/virtual-machine/tests/e2e/{linux.atmg => atmg}/dependencies.bicep (100%) rename avm/res/compute/virtual-machine/tests/e2e/{linux.atmg => atmg}/main.test.bicep (100%) diff --git a/avm/res/compute/virtual-machine/main.bicep b/avm/res/compute/virtual-machine/main.bicep index 592f78b862..ce2a4bee8d 100644 --- a/avm/res/compute/virtual-machine/main.bicep +++ b/avm/res/compute/virtual-machine/main.bicep @@ -353,7 +353,7 @@ module vm_nic 'modules/nic-configuration.bicep' = [for (nicConfiguration, index) tags: nicConfiguration.?tags ?? tags diagnosticSettings: nicConfiguration.?diagnosticSettings roleAssignments: nicConfiguration.?roleAssignments - enableTelemetry: nicConfiguration.?enableTelemetry ?? enableTelemetry + enableTelemetry: enableTelemetry } }] diff --git a/avm/res/compute/virtual-machine/main.json b/avm/res/compute/virtual-machine/main.json index f250d7a74f..06f4ac7bb4 100644 --- a/avm/res/compute/virtual-machine/main.json +++ b/avm/res/compute/virtual-machine/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "12654761906125877338" + "templateHash": "3546053203260205642" }, "name": "Virtual Machines", "description": "This module deploys a Virtual Machine with one or multiple NICs and optionally one or multiple public IPs.", @@ -981,7 +981,7 @@ "value": "[tryGet(parameters('nicConfigurations')[copyIndex()], 'roleAssignments')]" }, "enableTelemetry": { - "value": "[coalesce(tryGet(parameters('nicConfigurations')[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]" + "value": "[parameters('enableTelemetry')]" } }, "template": { @@ -992,7 +992,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "12547036605618417253" + "templateHash": "11195047658552178426" } }, "definitions": { @@ -1291,7 +1291,7 @@ }, "zones": "[if(contains(parameters('ipConfigurations')[copyIndex()], 'zones'), createObject('value', parameters('ipConfigurations')[copyIndex()].zones), createObject('value', createArray('1', '2', '3')))]", "enableTelemetry": { - "value": "[parameters('enableTelemetry')]" + "value": "[coalesce(tryGet(parameters('ipConfigurations')[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]" } }, "template": { diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux.atmg/dependencies.bicep b/avm/res/compute/virtual-machine/tests/e2e/atmg/dependencies.bicep similarity index 100% rename from avm/res/compute/virtual-machine/tests/e2e/linux.atmg/dependencies.bicep rename to avm/res/compute/virtual-machine/tests/e2e/atmg/dependencies.bicep diff --git a/avm/res/compute/virtual-machine/tests/e2e/linux.atmg/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/atmg/main.test.bicep similarity index 100% rename from avm/res/compute/virtual-machine/tests/e2e/linux.atmg/main.test.bicep rename to avm/res/compute/virtual-machine/tests/e2e/atmg/main.test.bicep From 1bbf22ae01645605be01bc239c15f6272521eb38 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 4 Jan 2024 19:42:26 +0100 Subject: [PATCH 74/96] update readme --- .../compute/virtual-machine/extension/README.md | 3 --- .../compute/virtual-machine/extension/main.json | 16 ++++++++-------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/avm/res/compute/virtual-machine/extension/README.md b/avm/res/compute/virtual-machine/extension/README.md index dccac4e45c..05debff23e 100644 --- a/avm/res/compute/virtual-machine/extension/README.md +++ b/avm/res/compute/virtual-machine/extension/README.md @@ -100,7 +100,6 @@ How the extension handler should be forced to update even if the extension confi - Required: No - Type: string -- Default: `''` ### Parameter: `location` @@ -116,7 +115,6 @@ Any object that contains the extension specific protected settings. - Required: No - Type: secureObject -- Default: `{}` ### Parameter: `settings` @@ -124,7 +122,6 @@ Any object that contains the extension specific settings. - Required: No - Type: object -- Default: `{}` ### Parameter: `supressFailures` diff --git a/avm/res/compute/virtual-machine/extension/main.json b/avm/res/compute/virtual-machine/extension/main.json index a078645aa8..47147c70f7 100644 --- a/avm/res/compute/virtual-machine/extension/main.json +++ b/avm/res/compute/virtual-machine/extension/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "9445653680126696241" + "version": "0.24.24.22086", + "templateHash": "13562327621635125722" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -58,21 +58,21 @@ }, "forceUpdateTag": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." } }, "settings": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } }, "protectedSettings": { "type": "secureObject", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific protected settings." } @@ -117,9 +117,9 @@ "typeHandlerVersion": "[parameters('typeHandlerVersion')]", "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", - "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", - "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", - "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", + "forceUpdateTag": "[parameters('forceUpdateTag')]", + "settings": "[parameters('settings')]", + "protectedSettings": "[parameters('protectedSettings')]", "suppressFailures": "[parameters('supressFailures')]" }, "dependsOn": [ From 136a09dd97f706b9f7c6c1ae87be9cffbd63fe72 Mon Sep 17 00:00:00 2001 From: Rainer Halanek <61878316+rahalan@users.noreply.github.com> Date: Thu, 4 Jan 2024 19:43:22 +0100 Subject: [PATCH 75/96] Update avm/res/compute/virtual-machine/main.bicep Co-authored-by: Alexander Sehr --- avm/res/compute/virtual-machine/main.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/res/compute/virtual-machine/main.bicep b/avm/res/compute/virtual-machine/main.bicep index ce2a4bee8d..e4bc4dedb4 100644 --- a/avm/res/compute/virtual-machine/main.bicep +++ b/avm/res/compute/virtual-machine/main.bicep @@ -720,7 +720,7 @@ type roleAssignmentType = { @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"') + @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.') From c2ec05d97f74dd531e12f07895dfa9a43ff6efc3 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Thu, 4 Jan 2024 19:54:15 +0100 Subject: [PATCH 76/96] update json & readme --- avm/res/compute/virtual-machine/README.md | 4 ++-- avm/res/compute/virtual-machine/main.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/avm/res/compute/virtual-machine/README.md b/avm/res/compute/virtual-machine/README.md index deeb7b539f..3830dba94a 100644 --- a/avm/res/compute/virtual-machine/README.md +++ b/avm/res/compute/virtual-machine/README.md @@ -2419,7 +2419,7 @@ Array of role assignments to create. | Parameter | Type | Description | | :-- | :-- | :-- | -| [`condition`](#parameter-roleassignmentscondition) | string | 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`](#parameter-roleassignmentscondition) | string | 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`](#parameter-roleassignmentsconditionversion) | string | Version of the condition. | | [`delegatedManagedIdentityResourceId`](#parameter-roleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | | [`description`](#parameter-roleassignmentsdescription) | string | The description of the role assignment. | @@ -2441,7 +2441,7 @@ The role to assign. You can provide either the display name of the role definiti ### Parameter: `roleAssignments.condition` -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" +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". - Required: No - Type: string diff --git a/avm/res/compute/virtual-machine/main.json b/avm/res/compute/virtual-machine/main.json index 06f4ac7bb4..3a3a6c0315 100644 --- a/avm/res/compute/virtual-machine/main.json +++ b/avm/res/compute/virtual-machine/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "3546053203260205642" + "templateHash": "6007219315806176277" }, "name": "Virtual Machines", "description": "This module deploys a Virtual Machine with one or multiple NICs and optionally one or multiple public IPs.", @@ -103,7 +103,7 @@ "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\"" + "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": { From 1c4e674dc46f1fd7075100817fb5c21891bb0b82 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Fri, 5 Jan 2024 12:00:35 +0100 Subject: [PATCH 77/96] Test --- avm/res/compute/virtual-machine/extension/README.md | 1 + avm/res/compute/virtual-machine/extension/main.bicep | 4 ++-- avm/res/compute/virtual-machine/extension/main.json | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/avm/res/compute/virtual-machine/extension/README.md b/avm/res/compute/virtual-machine/extension/README.md index 05debff23e..3d61579c60 100644 --- a/avm/res/compute/virtual-machine/extension/README.md +++ b/avm/res/compute/virtual-machine/extension/README.md @@ -122,6 +122,7 @@ Any object that contains the extension specific settings. - Required: No - Type: object +- Default: `{}` ### Parameter: `supressFailures` diff --git a/avm/res/compute/virtual-machine/extension/main.bicep b/avm/res/compute/virtual-machine/extension/main.bicep index 359f99cffd..7218f2c201 100644 --- a/avm/res/compute/virtual-machine/extension/main.bicep +++ b/avm/res/compute/virtual-machine/extension/main.bicep @@ -27,7 +27,7 @@ param autoUpgradeMinorVersion bool param forceUpdateTag string? @description('Optional. Any object that contains the extension specific settings.') -param settings object? +param settings object = {} @description('Optional. Any object that contains the extension specific protected settings.') @secure() @@ -57,7 +57,7 @@ resource extension 'Microsoft.Compute/virtualMachines/extensions@2022-11-01' = { typeHandlerVersion: typeHandlerVersion autoUpgradeMinorVersion: autoUpgradeMinorVersion enableAutomaticUpgrade: enableAutomaticUpgrade - forceUpdateTag:forceUpdateTag + forceUpdateTag: forceUpdateTag settings: settings protectedSettings: protectedSettings suppressFailures: supressFailures diff --git a/avm/res/compute/virtual-machine/extension/main.json b/avm/res/compute/virtual-machine/extension/main.json index 47147c70f7..b0ff83bf4d 100644 --- a/avm/res/compute/virtual-machine/extension/main.json +++ b/avm/res/compute/virtual-machine/extension/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "13562327621635125722" + "templateHash": "8321444505520440538" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -65,7 +65,7 @@ }, "settings": { "type": "object", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } From e721602afd70698cba3c4f6ab2ee8f9f9290e9f5 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Fri, 5 Jan 2024 12:07:03 +0100 Subject: [PATCH 78/96] update json --- avm/res/compute/virtual-machine/main.json | 38 +++++++++++------------ 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/avm/res/compute/virtual-machine/main.json b/avm/res/compute/virtual-machine/main.json index 3a3a6c0315..b2292fd41e 100644 --- a/avm/res/compute/virtual-machine/main.json +++ b/avm/res/compute/virtual-machine/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "6007219315806176277" + "templateHash": "18390989428405426226" }, "name": "Virtual Machines", "description": "This module deploys a Virtual Machine with one or multiple NICs and optionally one or multiple public IPs.", @@ -2439,7 +2439,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "13562327621635125722" + "templateHash": "8321444505520440538" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -2498,7 +2498,7 @@ }, "settings": { "type": "object", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } @@ -2645,7 +2645,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "13562327621635125722" + "templateHash": "8321444505520440538" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -2704,7 +2704,7 @@ }, "settings": { "type": "object", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } @@ -2846,7 +2846,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "13562327621635125722" + "templateHash": "8321444505520440538" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -2905,7 +2905,7 @@ }, "settings": { "type": "object", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } @@ -3042,7 +3042,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "13562327621635125722" + "templateHash": "8321444505520440538" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3101,7 +3101,7 @@ }, "settings": { "type": "object", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } @@ -3238,7 +3238,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "13562327621635125722" + "templateHash": "8321444505520440538" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3297,7 +3297,7 @@ }, "settings": { "type": "object", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } @@ -3434,7 +3434,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "13562327621635125722" + "templateHash": "8321444505520440538" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3493,7 +3493,7 @@ }, "settings": { "type": "object", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } @@ -3634,7 +3634,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "13562327621635125722" + "templateHash": "8321444505520440538" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3693,7 +3693,7 @@ }, "settings": { "type": "object", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } @@ -3842,7 +3842,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "13562327621635125722" + "templateHash": "8321444505520440538" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3901,7 +3901,7 @@ }, "settings": { "type": "object", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } @@ -4043,7 +4043,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "13562327621635125722" + "templateHash": "8321444505520440538" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -4102,7 +4102,7 @@ }, "settings": { "type": "object", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } From c5e0c0cef7f0aa3fa46ff991ed8fc7ade938d3a7 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Fri, 5 Jan 2024 13:48:14 +0100 Subject: [PATCH 79/96] revert back --- .../virtual-machine/extension/README.md | 1 - .../virtual-machine/extension/main.bicep | 2 +- .../virtual-machine/extension/main.json | 4 +- avm/res/compute/virtual-machine/main.json | 38 +++++++++---------- 4 files changed, 22 insertions(+), 23 deletions(-) diff --git a/avm/res/compute/virtual-machine/extension/README.md b/avm/res/compute/virtual-machine/extension/README.md index 3d61579c60..05debff23e 100644 --- a/avm/res/compute/virtual-machine/extension/README.md +++ b/avm/res/compute/virtual-machine/extension/README.md @@ -122,7 +122,6 @@ Any object that contains the extension specific settings. - Required: No - Type: object -- Default: `{}` ### Parameter: `supressFailures` diff --git a/avm/res/compute/virtual-machine/extension/main.bicep b/avm/res/compute/virtual-machine/extension/main.bicep index 7218f2c201..2822faa437 100644 --- a/avm/res/compute/virtual-machine/extension/main.bicep +++ b/avm/res/compute/virtual-machine/extension/main.bicep @@ -27,7 +27,7 @@ param autoUpgradeMinorVersion bool param forceUpdateTag string? @description('Optional. Any object that contains the extension specific settings.') -param settings object = {} +param settings object? @description('Optional. Any object that contains the extension specific protected settings.') @secure() diff --git a/avm/res/compute/virtual-machine/extension/main.json b/avm/res/compute/virtual-machine/extension/main.json index b0ff83bf4d..47147c70f7 100644 --- a/avm/res/compute/virtual-machine/extension/main.json +++ b/avm/res/compute/virtual-machine/extension/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "8321444505520440538" + "templateHash": "13562327621635125722" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -65,7 +65,7 @@ }, "settings": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } diff --git a/avm/res/compute/virtual-machine/main.json b/avm/res/compute/virtual-machine/main.json index b2292fd41e..3a3a6c0315 100644 --- a/avm/res/compute/virtual-machine/main.json +++ b/avm/res/compute/virtual-machine/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "18390989428405426226" + "templateHash": "6007219315806176277" }, "name": "Virtual Machines", "description": "This module deploys a Virtual Machine with one or multiple NICs and optionally one or multiple public IPs.", @@ -2439,7 +2439,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "8321444505520440538" + "templateHash": "13562327621635125722" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -2498,7 +2498,7 @@ }, "settings": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } @@ -2645,7 +2645,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "8321444505520440538" + "templateHash": "13562327621635125722" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -2704,7 +2704,7 @@ }, "settings": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } @@ -2846,7 +2846,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "8321444505520440538" + "templateHash": "13562327621635125722" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -2905,7 +2905,7 @@ }, "settings": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } @@ -3042,7 +3042,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "8321444505520440538" + "templateHash": "13562327621635125722" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3101,7 +3101,7 @@ }, "settings": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } @@ -3238,7 +3238,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "8321444505520440538" + "templateHash": "13562327621635125722" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3297,7 +3297,7 @@ }, "settings": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } @@ -3434,7 +3434,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "8321444505520440538" + "templateHash": "13562327621635125722" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3493,7 +3493,7 @@ }, "settings": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } @@ -3634,7 +3634,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "8321444505520440538" + "templateHash": "13562327621635125722" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3693,7 +3693,7 @@ }, "settings": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } @@ -3842,7 +3842,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "8321444505520440538" + "templateHash": "13562327621635125722" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3901,7 +3901,7 @@ }, "settings": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } @@ -4043,7 +4043,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "8321444505520440538" + "templateHash": "13562327621635125722" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -4102,7 +4102,7 @@ }, "settings": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } From 440532f81006465095fcd1fc5080a11d2999f67f Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Fri, 5 Jan 2024 14:14:02 +0100 Subject: [PATCH 80/96] add MI & RBAC to waf aligned test --- .../tests/e2e/waf-aligned/dependencies.bicep | 43 +++++++++++++++++++ .../tests/e2e/waf-aligned/main.test.bicep | 38 ++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/dependencies.bicep index 4d6d69ed7a..e198bcd227 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/dependencies.bicep @@ -4,6 +4,9 @@ param virtualNetworkName string @description('Required. The name of the Application Security Group to create.') param applicationSecurityGroupName string +@description('Required. The name of the Managed Identity to create.') +param managedIdentityName string + @description('Required. The name of the Load Balancer to create.') param loadBalancerName string @@ -53,6 +56,21 @@ resource applicationSecurityGroup 'Microsoft.Network/applicationSecurityGroups@2 location: location } +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: location +} + +resource msiRGContrRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(resourceGroup().id, 'Contributor', managedIdentity.id) + scope: resourceGroup() + properties: { + principalId: managedIdentity.properties.principalId + roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor + principalType: 'ServicePrincipal' + } +} + resource loadBalancer 'Microsoft.Network/loadBalancers@2023-04-01' = { name: loadBalancerName location: location @@ -193,6 +211,16 @@ resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = { } } +resource msiKVReadRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid('msi-${keyVault::key.id}-${location}-${managedIdentity.id}-KeyVault-Key-Read-RoleAssignment') + scope: keyVault::key + properties: { + principalId: managedIdentity.properties.principalId + roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') // Key Vault Crypto User + principalType: 'ServicePrincipal' + } +} + resource storageAccount 'Microsoft.Storage/storageAccounts@2021-09-01' = { name: storageAccountName location: location @@ -214,12 +242,21 @@ resource storageUpload 'Microsoft.Resources/deploymentScripts@2020-10-01' = { name: storageUploadDeploymentScriptName location: location kind: 'AzurePowerShell' + identity: { + type: 'UserAssigned' + userAssignedIdentities: { + '${managedIdentity.id}': {} + } + } properties: { azPowerShellVersion: '9.0' retentionInterval: 'P1D' arguments: '-StorageAccountName "${storageAccount.name}" -ResourceGroupName "${resourceGroup().name}" -ContainerName "${storageAccount::blobService::container.name}" -FileName "${storageAccountCSEFileName}"' scriptContent: loadTextContent('../../../../../../utilities/e2e-template-assets/scripts/Set-BlobContent.ps1') } + dependsOn: [ + msiRGContrRoleAssignment + ] } resource proximityPlacementGroup 'Microsoft.Compute/proximityPlacementGroups@2022-03-01' = { @@ -233,6 +270,12 @@ output subnetResourceId string = virtualNetwork.properties.subnets[0].id @description('The resource ID of the created Application Security Group.') output applicationSecurityGroupResourceId string = applicationSecurityGroup.id +@description('The principal ID of the created Managed Identity.') +output managedIdentityPrincipalId string = managedIdentity.properties.principalId + +@description('The resource ID of the created Managed Identity.') +output managedIdentityResourceId string = managedIdentity.id + @description('The resource ID of the created Load Balancer Backend Pool.') output loadBalancerBackendPoolResourceId string = loadBalancer.properties.backendAddressPools[0].id diff --git a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep index 21c55ad87c..21719dfecb 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep @@ -42,6 +42,7 @@ module nestedDependencies 'dependencies.bicep' = { location: location virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' applicationSecurityGroupName: 'dep-${namePrefix}-asg-${serviceShort}' + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}' loadBalancerName: 'dep-${namePrefix}-lb-${serviceShort}' recoveryServicesVaultName: 'dep-${namePrefix}-rsv-${serviceShort}' @@ -102,6 +103,13 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: 'ipconfig01' pipConfiguration: { publicIpNameSuffix: '-pip-01' + // roleAssignments: [ + // { + // roleDefinitionIdOrName: 'Reader' + // principalId: nestedDependencies.outputs.managedIdentityPrincipalId + // principalType: 'ServicePrincipal' + // } + // ] } zones: [ '1' @@ -126,6 +134,13 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' } ] nicSuffix: '-nic-01' + // roleAssignments: [ + // { + // roleDefinitionIdOrName: 'Reader' + // principalId: nestedDependencies.outputs.managedIdentityPrincipalId + // principalType: 'ServicePrincipal' + // } + // ] diagnosticSettings: [ { name: 'customSetting' @@ -284,6 +299,29 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: 'myCustomLockName' } proximityPlacementGroupResourceId: nestedDependencies.outputs.proximityPlacementGroupResourceId + // roleAssignments: [ + // { + // roleDefinitionIdOrName: 'Owner' + // principalId: nestedDependencies.outputs.managedIdentityPrincipalId + // principalType: 'ServicePrincipal' + // } + // { + // roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + // principalId: nestedDependencies.outputs.managedIdentityPrincipalId + // principalType: 'ServicePrincipal' + // } + // { + // roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + // principalId: nestedDependencies.outputs.managedIdentityPrincipalId + // principalType: 'ServicePrincipal' + // } + // ] + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] + } tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' From 3a9fc9af4cd06806faaa12bea9863be882fbd2c6 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Fri, 5 Jan 2024 14:22:04 +0100 Subject: [PATCH 81/96] update readme --- avm/res/compute/virtual-machine/README.md | 82 ++++++++++++++++++- .../tests/e2e/waf-aligned/main.test.bicep | 62 +++++++------- 2 files changed, 111 insertions(+), 33 deletions(-) diff --git a/avm/res/compute/virtual-machine/README.md b/avm/res/compute/virtual-machine/README.md index 3830dba94a..bfd0338873 100644 --- a/avm/res/compute/virtual-machine/README.md +++ b/avm/res/compute/virtual-machine/README.md @@ -427,6 +427,13 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { name: 'ipconfig01' pipConfiguration: { publicIpNameSuffix: '-pip-01' + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Reader' + } + ] } subnetResourceId: '' zones: [ @@ -437,6 +444,13 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { } ] nicSuffix: '-nic-01' + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Reader' + } + ] } ] osDisk: { @@ -582,8 +596,31 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { kind: 'CanNotDelete' name: 'myCustomLockName' } + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + '' + ] + } patchMode: 'AutomaticByPlatform' proximityPlacementGroupResourceId: '' + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Owner' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: '' + } + ] tags: { Environment: 'Non-Prod' 'hidden-title': 'This is visible in the resource name' @@ -666,7 +703,14 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { ], "name": "ipconfig01", "pipConfiguration": { - "publicIpNameSuffix": "-pip-01" + "publicIpNameSuffix": "-pip-01", + "roleAssignments": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Reader" + } + ] }, "subnetResourceId": "", "zones": [ @@ -676,7 +720,14 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { ] } ], - "nicSuffix": "-nic-01" + "nicSuffix": "-nic-01", + "roleAssignments": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Reader" + } + ] } ] }, @@ -869,12 +920,39 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { "name": "myCustomLockName" } }, + "managedIdentities": { + "value": { + "systemAssigned": true, + "userAssignedResourceIds": [ + "" + ] + } + }, "patchMode": { "value": "AutomaticByPlatform" }, "proximityPlacementGroupResourceId": { "value": "" }, + "roleAssignments": { + "value": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Owner" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "" + } + ] + }, "tags": { "value": { "Environment": "Non-Prod", diff --git a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep index 21719dfecb..ee093a7c96 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep @@ -103,13 +103,13 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: 'ipconfig01' pipConfiguration: { publicIpNameSuffix: '-pip-01' - // roleAssignments: [ - // { - // roleDefinitionIdOrName: 'Reader' - // principalId: nestedDependencies.outputs.managedIdentityPrincipalId - // principalType: 'ServicePrincipal' - // } - // ] + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] } zones: [ '1' @@ -134,13 +134,13 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' } ] nicSuffix: '-nic-01' - // roleAssignments: [ - // { - // roleDefinitionIdOrName: 'Reader' - // principalId: nestedDependencies.outputs.managedIdentityPrincipalId - // principalType: 'ServicePrincipal' - // } - // ] + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] diagnosticSettings: [ { name: 'customSetting' @@ -299,23 +299,23 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: 'myCustomLockName' } proximityPlacementGroupResourceId: nestedDependencies.outputs.proximityPlacementGroupResourceId - // roleAssignments: [ - // { - // roleDefinitionIdOrName: 'Owner' - // principalId: nestedDependencies.outputs.managedIdentityPrincipalId - // principalType: 'ServicePrincipal' - // } - // { - // roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - // principalId: nestedDependencies.outputs.managedIdentityPrincipalId - // principalType: 'ServicePrincipal' - // } - // { - // roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - // principalId: nestedDependencies.outputs.managedIdentityPrincipalId - // principalType: 'ServicePrincipal' - // } - // ] + roleAssignments: [ + { + roleDefinitionIdOrName: 'Owner' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] managedIdentities: { systemAssigned: true userAssignedResourceIds: [ From 15f4a4b2c94457cb2457a045a5c14a1d05a6f4cc Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Fri, 5 Jan 2024 17:30:30 +0100 Subject: [PATCH 82/96] revert back --- avm/res/compute/virtual-machine/README.md | 82 +------------------ .../tests/e2e/waf-aligned/dependencies.bicep | 43 ---------- .../tests/e2e/waf-aligned/main.test.bicep | 38 --------- 3 files changed, 2 insertions(+), 161 deletions(-) diff --git a/avm/res/compute/virtual-machine/README.md b/avm/res/compute/virtual-machine/README.md index bfd0338873..3830dba94a 100644 --- a/avm/res/compute/virtual-machine/README.md +++ b/avm/res/compute/virtual-machine/README.md @@ -427,13 +427,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { name: 'ipconfig01' pipConfiguration: { publicIpNameSuffix: '-pip-01' - roleAssignments: [ - { - principalId: '' - principalType: 'ServicePrincipal' - roleDefinitionIdOrName: 'Reader' - } - ] } subnetResourceId: '' zones: [ @@ -444,13 +437,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { } ] nicSuffix: '-nic-01' - roleAssignments: [ - { - principalId: '' - principalType: 'ServicePrincipal' - roleDefinitionIdOrName: 'Reader' - } - ] } ] osDisk: { @@ -596,31 +582,8 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { kind: 'CanNotDelete' name: 'myCustomLockName' } - managedIdentities: { - systemAssigned: true - userAssignedResourceIds: [ - '' - ] - } patchMode: 'AutomaticByPlatform' proximityPlacementGroupResourceId: '' - roleAssignments: [ - { - principalId: '' - principalType: 'ServicePrincipal' - roleDefinitionIdOrName: 'Owner' - } - { - principalId: '' - principalType: 'ServicePrincipal' - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - } - { - principalId: '' - principalType: 'ServicePrincipal' - roleDefinitionIdOrName: '' - } - ] tags: { Environment: 'Non-Prod' 'hidden-title': 'This is visible in the resource name' @@ -703,14 +666,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { ], "name": "ipconfig01", "pipConfiguration": { - "publicIpNameSuffix": "-pip-01", - "roleAssignments": [ - { - "principalId": "", - "principalType": "ServicePrincipal", - "roleDefinitionIdOrName": "Reader" - } - ] + "publicIpNameSuffix": "-pip-01" }, "subnetResourceId": "", "zones": [ @@ -720,14 +676,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { ] } ], - "nicSuffix": "-nic-01", - "roleAssignments": [ - { - "principalId": "", - "principalType": "ServicePrincipal", - "roleDefinitionIdOrName": "Reader" - } - ] + "nicSuffix": "-nic-01" } ] }, @@ -920,39 +869,12 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { "name": "myCustomLockName" } }, - "managedIdentities": { - "value": { - "systemAssigned": true, - "userAssignedResourceIds": [ - "" - ] - } - }, "patchMode": { "value": "AutomaticByPlatform" }, "proximityPlacementGroupResourceId": { "value": "" }, - "roleAssignments": { - "value": [ - { - "principalId": "", - "principalType": "ServicePrincipal", - "roleDefinitionIdOrName": "Owner" - }, - { - "principalId": "", - "principalType": "ServicePrincipal", - "roleDefinitionIdOrName": "b24988ac-6180-42a0-ab88-20f7382dd24c" - }, - { - "principalId": "", - "principalType": "ServicePrincipal", - "roleDefinitionIdOrName": "" - } - ] - }, "tags": { "value": { "Environment": "Non-Prod", diff --git a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/dependencies.bicep index e198bcd227..4d6d69ed7a 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/dependencies.bicep @@ -4,9 +4,6 @@ param virtualNetworkName string @description('Required. The name of the Application Security Group to create.') param applicationSecurityGroupName string -@description('Required. The name of the Managed Identity to create.') -param managedIdentityName string - @description('Required. The name of the Load Balancer to create.') param loadBalancerName string @@ -56,21 +53,6 @@ resource applicationSecurityGroup 'Microsoft.Network/applicationSecurityGroups@2 location: location } -resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { - name: managedIdentityName - location: location -} - -resource msiRGContrRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid(resourceGroup().id, 'Contributor', managedIdentity.id) - scope: resourceGroup() - properties: { - principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor - principalType: 'ServicePrincipal' - } -} - resource loadBalancer 'Microsoft.Network/loadBalancers@2023-04-01' = { name: loadBalancerName location: location @@ -211,16 +193,6 @@ resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = { } } -resource msiKVReadRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid('msi-${keyVault::key.id}-${location}-${managedIdentity.id}-KeyVault-Key-Read-RoleAssignment') - scope: keyVault::key - properties: { - principalId: managedIdentity.properties.principalId - roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') // Key Vault Crypto User - principalType: 'ServicePrincipal' - } -} - resource storageAccount 'Microsoft.Storage/storageAccounts@2021-09-01' = { name: storageAccountName location: location @@ -242,21 +214,12 @@ resource storageUpload 'Microsoft.Resources/deploymentScripts@2020-10-01' = { name: storageUploadDeploymentScriptName location: location kind: 'AzurePowerShell' - identity: { - type: 'UserAssigned' - userAssignedIdentities: { - '${managedIdentity.id}': {} - } - } properties: { azPowerShellVersion: '9.0' retentionInterval: 'P1D' arguments: '-StorageAccountName "${storageAccount.name}" -ResourceGroupName "${resourceGroup().name}" -ContainerName "${storageAccount::blobService::container.name}" -FileName "${storageAccountCSEFileName}"' scriptContent: loadTextContent('../../../../../../utilities/e2e-template-assets/scripts/Set-BlobContent.ps1') } - dependsOn: [ - msiRGContrRoleAssignment - ] } resource proximityPlacementGroup 'Microsoft.Compute/proximityPlacementGroups@2022-03-01' = { @@ -270,12 +233,6 @@ output subnetResourceId string = virtualNetwork.properties.subnets[0].id @description('The resource ID of the created Application Security Group.') output applicationSecurityGroupResourceId string = applicationSecurityGroup.id -@description('The principal ID of the created Managed Identity.') -output managedIdentityPrincipalId string = managedIdentity.properties.principalId - -@description('The resource ID of the created Managed Identity.') -output managedIdentityResourceId string = managedIdentity.id - @description('The resource ID of the created Load Balancer Backend Pool.') output loadBalancerBackendPoolResourceId string = loadBalancer.properties.backendAddressPools[0].id diff --git a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep index ee093a7c96..21c55ad87c 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep @@ -42,7 +42,6 @@ module nestedDependencies 'dependencies.bicep' = { location: location virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' applicationSecurityGroupName: 'dep-${namePrefix}-asg-${serviceShort}' - managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}' loadBalancerName: 'dep-${namePrefix}-lb-${serviceShort}' recoveryServicesVaultName: 'dep-${namePrefix}-rsv-${serviceShort}' @@ -103,13 +102,6 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: 'ipconfig01' pipConfiguration: { publicIpNameSuffix: '-pip-01' - roleAssignments: [ - { - roleDefinitionIdOrName: 'Reader' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - ] } zones: [ '1' @@ -134,13 +126,6 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' } ] nicSuffix: '-nic-01' - roleAssignments: [ - { - roleDefinitionIdOrName: 'Reader' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - ] diagnosticSettings: [ { name: 'customSetting' @@ -299,29 +284,6 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: 'myCustomLockName' } proximityPlacementGroupResourceId: nestedDependencies.outputs.proximityPlacementGroupResourceId - roleAssignments: [ - { - roleDefinitionIdOrName: 'Owner' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - { - roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - { - roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - principalId: nestedDependencies.outputs.managedIdentityPrincipalId - principalType: 'ServicePrincipal' - } - ] - managedIdentities: { - systemAssigned: true - userAssignedResourceIds: [ - nestedDependencies.outputs.managedIdentityResourceId - ] - } tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' From fb643616c9d2ba6044ddb9c54b95233a965d4eaa Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Fri, 5 Jan 2024 18:22:45 +0100 Subject: [PATCH 83/96] Revert "revert back" --- avm/res/compute/virtual-machine/README.md | 82 ++++++++++++++++++- .../tests/e2e/waf-aligned/dependencies.bicep | 43 ++++++++++ .../tests/e2e/waf-aligned/main.test.bicep | 38 +++++++++ 3 files changed, 161 insertions(+), 2 deletions(-) diff --git a/avm/res/compute/virtual-machine/README.md b/avm/res/compute/virtual-machine/README.md index 3830dba94a..bfd0338873 100644 --- a/avm/res/compute/virtual-machine/README.md +++ b/avm/res/compute/virtual-machine/README.md @@ -427,6 +427,13 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { name: 'ipconfig01' pipConfiguration: { publicIpNameSuffix: '-pip-01' + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Reader' + } + ] } subnetResourceId: '' zones: [ @@ -437,6 +444,13 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { } ] nicSuffix: '-nic-01' + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Reader' + } + ] } ] osDisk: { @@ -582,8 +596,31 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { kind: 'CanNotDelete' name: 'myCustomLockName' } + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + '' + ] + } patchMode: 'AutomaticByPlatform' proximityPlacementGroupResourceId: '' + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Owner' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: '' + } + ] tags: { Environment: 'Non-Prod' 'hidden-title': 'This is visible in the resource name' @@ -666,7 +703,14 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { ], "name": "ipconfig01", "pipConfiguration": { - "publicIpNameSuffix": "-pip-01" + "publicIpNameSuffix": "-pip-01", + "roleAssignments": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Reader" + } + ] }, "subnetResourceId": "", "zones": [ @@ -676,7 +720,14 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { ] } ], - "nicSuffix": "-nic-01" + "nicSuffix": "-nic-01", + "roleAssignments": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Reader" + } + ] } ] }, @@ -869,12 +920,39 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { "name": "myCustomLockName" } }, + "managedIdentities": { + "value": { + "systemAssigned": true, + "userAssignedResourceIds": [ + "" + ] + } + }, "patchMode": { "value": "AutomaticByPlatform" }, "proximityPlacementGroupResourceId": { "value": "" }, + "roleAssignments": { + "value": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Owner" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "" + } + ] + }, "tags": { "value": { "Environment": "Non-Prod", diff --git a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/dependencies.bicep index 4d6d69ed7a..e198bcd227 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/dependencies.bicep @@ -4,6 +4,9 @@ param virtualNetworkName string @description('Required. The name of the Application Security Group to create.') param applicationSecurityGroupName string +@description('Required. The name of the Managed Identity to create.') +param managedIdentityName string + @description('Required. The name of the Load Balancer to create.') param loadBalancerName string @@ -53,6 +56,21 @@ resource applicationSecurityGroup 'Microsoft.Network/applicationSecurityGroups@2 location: location } +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: location +} + +resource msiRGContrRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(resourceGroup().id, 'Contributor', managedIdentity.id) + scope: resourceGroup() + properties: { + principalId: managedIdentity.properties.principalId + roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') // Contributor + principalType: 'ServicePrincipal' + } +} + resource loadBalancer 'Microsoft.Network/loadBalancers@2023-04-01' = { name: loadBalancerName location: location @@ -193,6 +211,16 @@ resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = { } } +resource msiKVReadRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid('msi-${keyVault::key.id}-${location}-${managedIdentity.id}-KeyVault-Key-Read-RoleAssignment') + scope: keyVault::key + properties: { + principalId: managedIdentity.properties.principalId + roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') // Key Vault Crypto User + principalType: 'ServicePrincipal' + } +} + resource storageAccount 'Microsoft.Storage/storageAccounts@2021-09-01' = { name: storageAccountName location: location @@ -214,12 +242,21 @@ resource storageUpload 'Microsoft.Resources/deploymentScripts@2020-10-01' = { name: storageUploadDeploymentScriptName location: location kind: 'AzurePowerShell' + identity: { + type: 'UserAssigned' + userAssignedIdentities: { + '${managedIdentity.id}': {} + } + } properties: { azPowerShellVersion: '9.0' retentionInterval: 'P1D' arguments: '-StorageAccountName "${storageAccount.name}" -ResourceGroupName "${resourceGroup().name}" -ContainerName "${storageAccount::blobService::container.name}" -FileName "${storageAccountCSEFileName}"' scriptContent: loadTextContent('../../../../../../utilities/e2e-template-assets/scripts/Set-BlobContent.ps1') } + dependsOn: [ + msiRGContrRoleAssignment + ] } resource proximityPlacementGroup 'Microsoft.Compute/proximityPlacementGroups@2022-03-01' = { @@ -233,6 +270,12 @@ output subnetResourceId string = virtualNetwork.properties.subnets[0].id @description('The resource ID of the created Application Security Group.') output applicationSecurityGroupResourceId string = applicationSecurityGroup.id +@description('The principal ID of the created Managed Identity.') +output managedIdentityPrincipalId string = managedIdentity.properties.principalId + +@description('The resource ID of the created Managed Identity.') +output managedIdentityResourceId string = managedIdentity.id + @description('The resource ID of the created Load Balancer Backend Pool.') output loadBalancerBackendPoolResourceId string = loadBalancer.properties.backendAddressPools[0].id diff --git a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep index 21c55ad87c..ee093a7c96 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep @@ -42,6 +42,7 @@ module nestedDependencies 'dependencies.bicep' = { location: location virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' applicationSecurityGroupName: 'dep-${namePrefix}-asg-${serviceShort}' + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}' loadBalancerName: 'dep-${namePrefix}-lb-${serviceShort}' recoveryServicesVaultName: 'dep-${namePrefix}-rsv-${serviceShort}' @@ -102,6 +103,13 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: 'ipconfig01' pipConfiguration: { publicIpNameSuffix: '-pip-01' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] } zones: [ '1' @@ -126,6 +134,13 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' } ] nicSuffix: '-nic-01' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] diagnosticSettings: [ { name: 'customSetting' @@ -284,6 +299,29 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: 'myCustomLockName' } proximityPlacementGroupResourceId: nestedDependencies.outputs.proximityPlacementGroupResourceId + roleAssignments: [ + { + roleDefinitionIdOrName: 'Owner' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] + } tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' From df2607d42bac3bf10e048f7567839075835b9c13 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Fri, 5 Jan 2024 18:25:52 +0100 Subject: [PATCH 84/96] test --- avm/res/compute/virtual-machine/README.md | 36 ------------------- .../tests/e2e/waf-aligned/main.test.bicep | 16 ++++----- .../tests/e2e/windows.max/main.test.bicep | 16 ++++----- 3 files changed, 16 insertions(+), 52 deletions(-) diff --git a/avm/res/compute/virtual-machine/README.md b/avm/res/compute/virtual-machine/README.md index bfd0338873..88ac4a66f0 100644 --- a/avm/res/compute/virtual-machine/README.md +++ b/avm/res/compute/virtual-machine/README.md @@ -493,14 +493,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { ] enableAutomaticUpdates: true encryptionAtHost: false - extensionAadJoinConfig: { - enabled: true - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } extensionAntiMalwareConfig: { enabled: true settings: { @@ -795,16 +787,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { "encryptionAtHost": { "value": false }, - "extensionAadJoinConfig": { - "value": { - "enabled": true, - "tags": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - }, "extensionAntiMalwareConfig": { "value": { "enabled": true, @@ -1219,14 +1201,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { ] enableAutomaticUpdates: true encryptionAtHost: false - extensionAadJoinConfig: { - enabled: true - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } - } extensionAntiMalwareConfig: { enabled: true settings: { @@ -1521,16 +1495,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { "encryptionAtHost": { "value": false }, - "extensionAadJoinConfig": { - "value": { - "enabled": true, - "tags": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } - } - }, "extensionAntiMalwareConfig": { "value": { "enabled": true, diff --git a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep index ee093a7c96..99e6ff41c7 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep @@ -262,14 +262,14 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' } } } - extensionAadJoinConfig: { - enabled: true - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - } + // extensionAadJoinConfig: { + // enabled: true + // tags: { + // 'hidden-title': 'This is visible in the resource name' + // Environment: 'Non-Prod' + // Role: 'DeploymentValidation' + // } + // } extensionDSCConfig: { enabled: true tags: { diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep index 51e19418b8..c6d744e465 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep @@ -262,14 +262,14 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' } } } - extensionAadJoinConfig: { - enabled: true - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } - } + // extensionAadJoinConfig: { + // enabled: true + // tags: { + // 'hidden-title': 'This is visible in the resource name' + // Environment: 'Non-Prod' + // Role: 'DeploymentValidation' + // } + // } extensionDSCConfig: { enabled: true tags: { From 4f32abca6554addc807b5a624259693f91d3e1c2 Mon Sep 17 00:00:00 2001 From: Rainer Halanek <61878316+rahalan@users.noreply.github.com> Date: Fri, 5 Jan 2024 18:28:15 +0100 Subject: [PATCH 85/96] Update avm/res/compute/virtual-machine/main.bicep Co-authored-by: Alexander Sehr --- avm/res/compute/virtual-machine/main.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/res/compute/virtual-machine/main.bicep b/avm/res/compute/virtual-machine/main.bicep index e4bc4dedb4..27de7a8634 100644 --- a/avm/res/compute/virtual-machine/main.bicep +++ b/avm/res/compute/virtual-machine/main.bicep @@ -353,7 +353,7 @@ module vm_nic 'modules/nic-configuration.bicep' = [for (nicConfiguration, index) tags: nicConfiguration.?tags ?? tags diagnosticSettings: nicConfiguration.?diagnosticSettings roleAssignments: nicConfiguration.?roleAssignments - enableTelemetry: enableTelemetry + enableTelemetry: enableTelemetry: nicConfiguration.?enableTelemetry ?? enableTelemetry } }] From 42492213800923fb98bde649aa0be8bdfe9bc775 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Fri, 5 Jan 2024 18:34:45 +0100 Subject: [PATCH 86/96] fix --- avm/res/compute/virtual-machine/main.bicep | 2 +- avm/res/compute/virtual-machine/main.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/avm/res/compute/virtual-machine/main.bicep b/avm/res/compute/virtual-machine/main.bicep index 27de7a8634..14df51540e 100644 --- a/avm/res/compute/virtual-machine/main.bicep +++ b/avm/res/compute/virtual-machine/main.bicep @@ -353,7 +353,7 @@ module vm_nic 'modules/nic-configuration.bicep' = [for (nicConfiguration, index) tags: nicConfiguration.?tags ?? tags diagnosticSettings: nicConfiguration.?diagnosticSettings roleAssignments: nicConfiguration.?roleAssignments - enableTelemetry: enableTelemetry: nicConfiguration.?enableTelemetry ?? enableTelemetry + enableTelemetry: nicConfiguration.?enableTelemetry ?? enableTelemetry } }] diff --git a/avm/res/compute/virtual-machine/main.json b/avm/res/compute/virtual-machine/main.json index 3a3a6c0315..eecadb02cc 100644 --- a/avm/res/compute/virtual-machine/main.json +++ b/avm/res/compute/virtual-machine/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "6007219315806176277" + "templateHash": "6179948266138972780" }, "name": "Virtual Machines", "description": "This module deploys a Virtual Machine with one or multiple NICs and optionally one or multiple public IPs.", @@ -981,7 +981,7 @@ "value": "[tryGet(parameters('nicConfigurations')[copyIndex()], 'roleAssignments')]" }, "enableTelemetry": { - "value": "[parameters('enableTelemetry')]" + "value": "[coalesce(tryGet(parameters('nicConfigurations')[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]" } }, "template": { From 58c8adcb070dfe65ff3e74e2115cc00684c37113 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Fri, 5 Jan 2024 19:29:04 +0100 Subject: [PATCH 87/96] test --- avm/res/compute/virtual-machine/README.md | 36 +++++ .../virtual-machine/extension/README.md | 3 + .../virtual-machine/extension/main.bicep | 12 +- .../virtual-machine/extension/main.json | 14 +- avm/res/compute/virtual-machine/main.json | 128 +++++++++--------- .../tests/e2e/waf-aligned/main.test.bicep | 16 +-- .../tests/e2e/windows.max/main.test.bicep | 16 +-- 7 files changed, 132 insertions(+), 93 deletions(-) diff --git a/avm/res/compute/virtual-machine/README.md b/avm/res/compute/virtual-machine/README.md index 88ac4a66f0..bfd0338873 100644 --- a/avm/res/compute/virtual-machine/README.md +++ b/avm/res/compute/virtual-machine/README.md @@ -493,6 +493,14 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { ] enableAutomaticUpdates: true encryptionAtHost: false + extensionAadJoinConfig: { + enabled: true + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } extensionAntiMalwareConfig: { enabled: true settings: { @@ -787,6 +795,16 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { "encryptionAtHost": { "value": false }, + "extensionAadJoinConfig": { + "value": { + "enabled": true, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, "extensionAntiMalwareConfig": { "value": { "enabled": true, @@ -1201,6 +1219,14 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { ] enableAutomaticUpdates: true encryptionAtHost: false + extensionAadJoinConfig: { + enabled: true + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } extensionAntiMalwareConfig: { enabled: true settings: { @@ -1495,6 +1521,16 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { "encryptionAtHost": { "value": false }, + "extensionAadJoinConfig": { + "value": { + "enabled": true, + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + }, "extensionAntiMalwareConfig": { "value": { "enabled": true, diff --git a/avm/res/compute/virtual-machine/extension/README.md b/avm/res/compute/virtual-machine/extension/README.md index 05debff23e..dccac4e45c 100644 --- a/avm/res/compute/virtual-machine/extension/README.md +++ b/avm/res/compute/virtual-machine/extension/README.md @@ -100,6 +100,7 @@ How the extension handler should be forced to update even if the extension confi - Required: No - Type: string +- Default: `''` ### Parameter: `location` @@ -115,6 +116,7 @@ Any object that contains the extension specific protected settings. - Required: No - Type: secureObject +- Default: `{}` ### Parameter: `settings` @@ -122,6 +124,7 @@ Any object that contains the extension specific settings. - Required: No - Type: object +- Default: `{}` ### Parameter: `supressFailures` diff --git a/avm/res/compute/virtual-machine/extension/main.bicep b/avm/res/compute/virtual-machine/extension/main.bicep index 2822faa437..51e12982c7 100644 --- a/avm/res/compute/virtual-machine/extension/main.bicep +++ b/avm/res/compute/virtual-machine/extension/main.bicep @@ -24,14 +24,14 @@ param typeHandlerVersion string param autoUpgradeMinorVersion bool @description('Optional. How the extension handler should be forced to update even if the extension configuration has not changed.') -param forceUpdateTag string? +param forceUpdateTag string = '' @description('Optional. Any object that contains the extension specific settings.') -param settings object? +param settings object = {} @description('Optional. Any object that contains the extension specific protected settings.') @secure() -param protectedSettings object? +param protectedSettings object = {} @description('Optional. Indicates whether failures stemming from the extension will be suppressed (Operational failures such as not connecting to the VM will not be suppressed regardless of this value). The default is false.') param supressFailures bool = false @@ -57,9 +57,9 @@ resource extension 'Microsoft.Compute/virtualMachines/extensions@2022-11-01' = { typeHandlerVersion: typeHandlerVersion autoUpgradeMinorVersion: autoUpgradeMinorVersion enableAutomaticUpgrade: enableAutomaticUpgrade - forceUpdateTag: forceUpdateTag - settings: settings - protectedSettings: protectedSettings + forceUpdateTag: !empty(forceUpdateTag) ? forceUpdateTag : null + settings: !empty(settings) ? settings : null + protectedSettings: !empty(protectedSettings) ? protectedSettings : null suppressFailures: supressFailures } } diff --git a/avm/res/compute/virtual-machine/extension/main.json b/avm/res/compute/virtual-machine/extension/main.json index 47147c70f7..c10328f8ac 100644 --- a/avm/res/compute/virtual-machine/extension/main.json +++ b/avm/res/compute/virtual-machine/extension/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "13562327621635125722" + "templateHash": "10332103716678024514" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -58,21 +58,21 @@ }, "forceUpdateTag": { "type": "string", - "nullable": true, + "defaultValue": "", "metadata": { "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." } }, "settings": { "type": "object", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } }, "protectedSettings": { "type": "secureObject", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific protected settings." } @@ -117,9 +117,9 @@ "typeHandlerVersion": "[parameters('typeHandlerVersion')]", "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", - "forceUpdateTag": "[parameters('forceUpdateTag')]", - "settings": "[parameters('settings')]", - "protectedSettings": "[parameters('protectedSettings')]", + "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", + "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", + "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", "suppressFailures": "[parameters('supressFailures')]" }, "dependsOn": [ diff --git a/avm/res/compute/virtual-machine/main.json b/avm/res/compute/virtual-machine/main.json index eecadb02cc..69228b672a 100644 --- a/avm/res/compute/virtual-machine/main.json +++ b/avm/res/compute/virtual-machine/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "6179948266138972780" + "templateHash": "10795179531307040793" }, "name": "Virtual Machines", "description": "This module deploys a Virtual Machine with one or multiple NICs and optionally one or multiple public IPs.", @@ -2439,7 +2439,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "13562327621635125722" + "templateHash": "10332103716678024514" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -2491,21 +2491,21 @@ }, "forceUpdateTag": { "type": "string", - "nullable": true, + "defaultValue": "", "metadata": { "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." } }, "settings": { "type": "object", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } }, "protectedSettings": { "type": "secureObject", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific protected settings." } @@ -2550,9 +2550,9 @@ "typeHandlerVersion": "[parameters('typeHandlerVersion')]", "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", - "forceUpdateTag": "[parameters('forceUpdateTag')]", - "settings": "[parameters('settings')]", - "protectedSettings": "[parameters('protectedSettings')]", + "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", + "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", + "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", "suppressFailures": "[parameters('supressFailures')]" }, "dependsOn": [ @@ -2645,7 +2645,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "13562327621635125722" + "templateHash": "10332103716678024514" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -2697,21 +2697,21 @@ }, "forceUpdateTag": { "type": "string", - "nullable": true, + "defaultValue": "", "metadata": { "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." } }, "settings": { "type": "object", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } }, "protectedSettings": { "type": "secureObject", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific protected settings." } @@ -2756,9 +2756,9 @@ "typeHandlerVersion": "[parameters('typeHandlerVersion')]", "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", - "forceUpdateTag": "[parameters('forceUpdateTag')]", - "settings": "[parameters('settings')]", - "protectedSettings": "[parameters('protectedSettings')]", + "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", + "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", + "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", "suppressFailures": "[parameters('supressFailures')]" }, "dependsOn": [ @@ -2846,7 +2846,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "13562327621635125722" + "templateHash": "10332103716678024514" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -2898,21 +2898,21 @@ }, "forceUpdateTag": { "type": "string", - "nullable": true, + "defaultValue": "", "metadata": { "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." } }, "settings": { "type": "object", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } }, "protectedSettings": { "type": "secureObject", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific protected settings." } @@ -2957,9 +2957,9 @@ "typeHandlerVersion": "[parameters('typeHandlerVersion')]", "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", - "forceUpdateTag": "[parameters('forceUpdateTag')]", - "settings": "[parameters('settings')]", - "protectedSettings": "[parameters('protectedSettings')]", + "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", + "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", + "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", "suppressFailures": "[parameters('supressFailures')]" }, "dependsOn": [ @@ -3042,7 +3042,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "13562327621635125722" + "templateHash": "10332103716678024514" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3094,21 +3094,21 @@ }, "forceUpdateTag": { "type": "string", - "nullable": true, + "defaultValue": "", "metadata": { "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." } }, "settings": { "type": "object", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } }, "protectedSettings": { "type": "secureObject", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific protected settings." } @@ -3153,9 +3153,9 @@ "typeHandlerVersion": "[parameters('typeHandlerVersion')]", "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", - "forceUpdateTag": "[parameters('forceUpdateTag')]", - "settings": "[parameters('settings')]", - "protectedSettings": "[parameters('protectedSettings')]", + "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", + "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", + "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", "suppressFailures": "[parameters('supressFailures')]" }, "dependsOn": [ @@ -3238,7 +3238,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "13562327621635125722" + "templateHash": "10332103716678024514" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3290,21 +3290,21 @@ }, "forceUpdateTag": { "type": "string", - "nullable": true, + "defaultValue": "", "metadata": { "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." } }, "settings": { "type": "object", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } }, "protectedSettings": { "type": "secureObject", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific protected settings." } @@ -3349,9 +3349,9 @@ "typeHandlerVersion": "[parameters('typeHandlerVersion')]", "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", - "forceUpdateTag": "[parameters('forceUpdateTag')]", - "settings": "[parameters('settings')]", - "protectedSettings": "[parameters('protectedSettings')]", + "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", + "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", + "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", "suppressFailures": "[parameters('supressFailures')]" }, "dependsOn": [ @@ -3434,7 +3434,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "13562327621635125722" + "templateHash": "10332103716678024514" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3486,21 +3486,21 @@ }, "forceUpdateTag": { "type": "string", - "nullable": true, + "defaultValue": "", "metadata": { "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." } }, "settings": { "type": "object", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } }, "protectedSettings": { "type": "secureObject", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific protected settings." } @@ -3545,9 +3545,9 @@ "typeHandlerVersion": "[parameters('typeHandlerVersion')]", "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", - "forceUpdateTag": "[parameters('forceUpdateTag')]", - "settings": "[parameters('settings')]", - "protectedSettings": "[parameters('protectedSettings')]", + "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", + "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", + "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", "suppressFailures": "[parameters('supressFailures')]" }, "dependsOn": [ @@ -3634,7 +3634,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "13562327621635125722" + "templateHash": "10332103716678024514" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3686,21 +3686,21 @@ }, "forceUpdateTag": { "type": "string", - "nullable": true, + "defaultValue": "", "metadata": { "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." } }, "settings": { "type": "object", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } }, "protectedSettings": { "type": "secureObject", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific protected settings." } @@ -3745,9 +3745,9 @@ "typeHandlerVersion": "[parameters('typeHandlerVersion')]", "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", - "forceUpdateTag": "[parameters('forceUpdateTag')]", - "settings": "[parameters('settings')]", - "protectedSettings": "[parameters('protectedSettings')]", + "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", + "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", + "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", "suppressFailures": "[parameters('supressFailures')]" }, "dependsOn": [ @@ -3842,7 +3842,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "13562327621635125722" + "templateHash": "10332103716678024514" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -3894,21 +3894,21 @@ }, "forceUpdateTag": { "type": "string", - "nullable": true, + "defaultValue": "", "metadata": { "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." } }, "settings": { "type": "object", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } }, "protectedSettings": { "type": "secureObject", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific protected settings." } @@ -3953,9 +3953,9 @@ "typeHandlerVersion": "[parameters('typeHandlerVersion')]", "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", - "forceUpdateTag": "[parameters('forceUpdateTag')]", - "settings": "[parameters('settings')]", - "protectedSettings": "[parameters('protectedSettings')]", + "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", + "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", + "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", "suppressFailures": "[parameters('supressFailures')]" }, "dependsOn": [ @@ -4043,7 +4043,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "13562327621635125722" + "templateHash": "10332103716678024514" }, "name": "Virtual Machine Extensions", "description": "This module deploys a Virtual Machine Extension.", @@ -4095,21 +4095,21 @@ }, "forceUpdateTag": { "type": "string", - "nullable": true, + "defaultValue": "", "metadata": { "description": "Optional. How the extension handler should be forced to update even if the extension configuration has not changed." } }, "settings": { "type": "object", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific settings." } }, "protectedSettings": { "type": "secureObject", - "nullable": true, + "defaultValue": {}, "metadata": { "description": "Optional. Any object that contains the extension specific protected settings." } @@ -4154,9 +4154,9 @@ "typeHandlerVersion": "[parameters('typeHandlerVersion')]", "autoUpgradeMinorVersion": "[parameters('autoUpgradeMinorVersion')]", "enableAutomaticUpgrade": "[parameters('enableAutomaticUpgrade')]", - "forceUpdateTag": "[parameters('forceUpdateTag')]", - "settings": "[parameters('settings')]", - "protectedSettings": "[parameters('protectedSettings')]", + "forceUpdateTag": "[if(not(empty(parameters('forceUpdateTag'))), parameters('forceUpdateTag'), null())]", + "settings": "[if(not(empty(parameters('settings'))), parameters('settings'), null())]", + "protectedSettings": "[if(not(empty(parameters('protectedSettings'))), parameters('protectedSettings'), null())]", "suppressFailures": "[parameters('supressFailures')]" }, "dependsOn": [ diff --git a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep index 99e6ff41c7..ee093a7c96 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/waf-aligned/main.test.bicep @@ -262,14 +262,14 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' } } } - // extensionAadJoinConfig: { - // enabled: true - // tags: { - // 'hidden-title': 'This is visible in the resource name' - // Environment: 'Non-Prod' - // Role: 'DeploymentValidation' - // } - // } + extensionAadJoinConfig: { + enabled: true + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } extensionDSCConfig: { enabled: true tags: { diff --git a/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep index c6d744e465..51e19418b8 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/windows.max/main.test.bicep @@ -262,14 +262,14 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' } } } - // extensionAadJoinConfig: { - // enabled: true - // tags: { - // 'hidden-title': 'This is visible in the resource name' - // Environment: 'Non-Prod' - // Role: 'DeploymentValidation' - // } - // } + extensionAadJoinConfig: { + enabled: true + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } extensionDSCConfig: { enabled: true tags: { From df74845fa779fe63bd0d95d00dda0fa2c1c22734 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Sat, 6 Jan 2024 10:39:17 +0100 Subject: [PATCH 88/96] remove tags --- .../compute/virtual-machine/tests/e2e/atmg/main.test.bicep | 5 ----- 1 file changed, 5 deletions(-) diff --git a/avm/res/compute/virtual-machine/tests/e2e/atmg/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/atmg/main.test.bicep index b506288b88..5dd80ec7c3 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/atmg/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/atmg/main.test.bicep @@ -111,11 +111,6 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' path: '/home/localAdminUser/.ssh/authorized_keys' } ] - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } } dependsOn: [ nestedDependencies // Required to leverage `existing` SSH key reference From 0f2e6c2ec2683eb11bf2d8ea5c0cf28cf23090b3 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Sat, 6 Jan 2024 10:40:04 +0100 Subject: [PATCH 89/96] remove tags --- .../compute/virtual-machine/tests/e2e/atmg/main.test.bicep | 5 ----- 1 file changed, 5 deletions(-) diff --git a/avm/res/compute/virtual-machine/tests/e2e/atmg/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/atmg/main.test.bicep index 5dd80ec7c3..31150d8801 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/atmg/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/atmg/main.test.bicep @@ -88,11 +88,6 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' } ] nicSuffix: '-nic-01' - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } } ] osDisk: { From a194e6bba7ed44fd580bfbc718654a4f3551acea Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Sat, 6 Jan 2024 10:41:32 +0100 Subject: [PATCH 90/96] update readme --- avm/res/compute/virtual-machine/README.md | 24 +---------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/avm/res/compute/virtual-machine/README.md b/avm/res/compute/virtual-machine/README.md index bfd0338873..68a5dc2c2c 100644 --- a/avm/res/compute/virtual-machine/README.md +++ b/avm/res/compute/virtual-machine/README.md @@ -83,11 +83,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { } ] nicSuffix: '-nic-01' - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } } ] osDisk: { @@ -108,11 +103,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { path: '/home/localAdminUser/.ssh/authorized_keys' } ] - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } } } ``` @@ -166,12 +156,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { ] } ], - "nicSuffix": "-nic-01", - "tags": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } + "nicSuffix": "-nic-01" } ] }, @@ -206,13 +191,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { "path": "/home/localAdminUser/.ssh/authorized_keys" } ] - }, - "tags": { - "value": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } } } } From 2476c6c716fc9ce5d56bb47583240f99fc8c461b Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Sat, 6 Jan 2024 10:44:02 +0100 Subject: [PATCH 91/96] remove tags --- avm/res/compute/virtual-machine/README.md | 12 +----------- .../virtual-machine/tests/e2e/atmg/main.test.bicep | 5 ----- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/avm/res/compute/virtual-machine/README.md b/avm/res/compute/virtual-machine/README.md index 68a5dc2c2c..198f321bdc 100644 --- a/avm/res/compute/virtual-machine/README.md +++ b/avm/res/compute/virtual-machine/README.md @@ -68,11 +68,6 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { name: 'ipconfig01' pipConfiguration: { publicIpNameSuffix: '-pip-01' - tags: { - Environment: 'Non-Prod' - 'hidden-title': 'This is visible in the resource name' - Role: 'DeploymentValidation' - } } subnetResourceId: '' zones: [ @@ -141,12 +136,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { { "name": "ipconfig01", "pipConfiguration": { - "publicIpNameSuffix": "-pip-01", - "tags": { - "Environment": "Non-Prod", - "hidden-title": "This is visible in the resource name", - "Role": "DeploymentValidation" - } + "publicIpNameSuffix": "-pip-01" }, "subnetResourceId": "", "zones": [ diff --git a/avm/res/compute/virtual-machine/tests/e2e/atmg/main.test.bicep b/avm/res/compute/virtual-machine/tests/e2e/atmg/main.test.bicep index 31150d8801..e4b55f3329 100644 --- a/avm/res/compute/virtual-machine/tests/e2e/atmg/main.test.bicep +++ b/avm/res/compute/virtual-machine/tests/e2e/atmg/main.test.bicep @@ -73,11 +73,6 @@ module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' name: 'ipconfig01' pipConfiguration: { publicIpNameSuffix: '-pip-01' - tags: { - 'hidden-title': 'This is visible in the resource name' - Environment: 'Non-Prod' - Role: 'DeploymentValidation' - } } zones: [ '1' From 5a2f2c10a241bb9a2237fee459992b47552bc185 Mon Sep 17 00:00:00 2001 From: Rainer Halanek <61878316+rahalan@users.noreply.github.com> Date: Sun, 7 Jan 2024 10:42:30 +0100 Subject: [PATCH 92/96] Update .github/workflows/avm.res.compute.virtual-machine.yml Co-authored-by: Erika Gressi <56914614+eriqua@users.noreply.github.com> --- .github/workflows/avm.res.compute.virtual-machine.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/avm.res.compute.virtual-machine.yml b/.github/workflows/avm.res.compute.virtual-machine.yml index 5c4a56625e..7127a3fdd8 100644 --- a/.github/workflows/avm.res.compute.virtual-machine.yml +++ b/.github/workflows/avm.res.compute.virtual-machine.yml @@ -44,7 +44,7 @@ jobs: # Initialize pipeline # ########################### job_initialize_pipeline: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest name: "Initialize pipeline" steps: - name: "Checkout" From 8afd3b62ee8e0cae465c1f17dc25446aabed1e60 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Mon, 8 Jan 2024 11:54:36 +0100 Subject: [PATCH 93/96] update readme --- avm/res/compute/virtual-machine/README.md | 5 +++++ avm/res/compute/virtual-machine/extension/README.md | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/avm/res/compute/virtual-machine/README.md b/avm/res/compute/virtual-machine/README.md index 198f321bdc..f76c8d0217 100644 --- a/avm/res/compute/virtual-machine/README.md +++ b/avm/res/compute/virtual-machine/README.md @@ -9,6 +9,7 @@ This module deploys a Virtual Machine with one or multiple NICs and optionally o - [Parameters](#Parameters) - [Outputs](#Outputs) - [Cross-referenced modules](#Cross-referenced-modules) +- [Data Collection](#Data-Collection) ## Resource Types @@ -2621,3 +2622,7 @@ Do not provide a value! This date value is used to generate a registration token ## Cross-referenced modules _None_ + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/res/compute/virtual-machine/extension/README.md b/avm/res/compute/virtual-machine/extension/README.md index dccac4e45c..649fa463f8 100644 --- a/avm/res/compute/virtual-machine/extension/README.md +++ b/avm/res/compute/virtual-machine/extension/README.md @@ -8,6 +8,7 @@ This module deploys a Virtual Machine Extension. - [Parameters](#Parameters) - [Outputs](#Outputs) - [Cross-referenced modules](#Cross-referenced-modules) +- [Data Collection](#Data-Collection) ## Resource Types @@ -154,3 +155,7 @@ Tags of the resource. ## Cross-referenced modules _None_ + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. From 1aa0b8fb4e8654174e7ae1746ee474e822bf7ea4 Mon Sep 17 00:00:00 2001 From: Rainer Halanek <61878316+rahalan@users.noreply.github.com> Date: Mon, 8 Jan 2024 14:56:20 +0100 Subject: [PATCH 94/96] Update avm/res/compute/virtual-machine/main.bicep Co-authored-by: Alexander Sehr --- avm/res/compute/virtual-machine/main.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/res/compute/virtual-machine/main.bicep b/avm/res/compute/virtual-machine/main.bicep index 14df51540e..700fcad6b1 100644 --- a/avm/res/compute/virtual-machine/main.bicep +++ b/avm/res/compute/virtual-machine/main.bicep @@ -192,7 +192,7 @@ param roleAssignments roleAssignmentType @description('Optional. Tags of the resource.') param tags object? -@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') +@description('Optional. Enable/Disable usage telemetry for module.') param enableTelemetry bool = true @description('Generated. Do not provide a value! This date value is used to generate a registration token.') From 7539f60d1998f97e22a5ac2d761e99205f62f1f2 Mon Sep 17 00:00:00 2001 From: Rainer Halanek <61878316+rahalan@users.noreply.github.com> Date: Mon, 8 Jan 2024 14:56:34 +0100 Subject: [PATCH 95/96] Update avm/res/compute/virtual-machine/main.bicep Co-authored-by: Alexander Sehr --- avm/res/compute/virtual-machine/main.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avm/res/compute/virtual-machine/main.bicep b/avm/res/compute/virtual-machine/main.bicep index 700fcad6b1..ff4eee802c 100644 --- a/avm/res/compute/virtual-machine/main.bicep +++ b/avm/res/compute/virtual-machine/main.bicep @@ -524,7 +524,7 @@ module vm_azureMonitoringAgentExtension 'extension/main.bicep' = if (extensionMo name: '${uniqueString(deployment().name, location)}-VM-AzureMonitoringAgent' params: { virtualMachineName: vm.name - name: 'AzureMonitoringAgent' + name: 'AzureMonitorAgent' location: location publisher: 'Microsoft.Azure.Monitor' type: osType == 'Windows' ? 'AzureMonitorWindowsAgent' : 'AzureMonitorLinuxAgent' From 7c162cb82d220e6c17297f60cd0651036a9d0d88 Mon Sep 17 00:00:00 2001 From: Rainer Halanek Date: Mon, 8 Jan 2024 14:58:39 +0100 Subject: [PATCH 96/96] update json/readme --- avm/res/compute/virtual-machine/README.md | 4 ++-- avm/res/compute/virtual-machine/main.json | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/avm/res/compute/virtual-machine/README.md b/avm/res/compute/virtual-machine/README.md index f76c8d0217..54974f09ce 100644 --- a/avm/res/compute/virtual-machine/README.md +++ b/avm/res/compute/virtual-machine/README.md @@ -1847,7 +1847,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:' = { | [`disablePasswordAuthentication`](#parameter-disablepasswordauthentication) | bool | Specifies whether password authentication should be disabled. | | [`enableAutomaticUpdates`](#parameter-enableautomaticupdates) | bool | Indicates whether Automatic Updates is enabled for the Windows virtual machine. Default value is true. When patchMode is set to Manual, this parameter must be set to false. For virtual machine scale sets, this property can be updated and updates will take effect on OS reprovisioning. | | [`enableEvictionPolicy`](#parameter-enableevictionpolicy) | bool | Specifies the eviction policy for the low priority virtual machine. Will result in 'Deallocate' eviction policy. | -| [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable telemetry via a Globally Unique Identifier (GUID). | +| [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | | [`encryptionAtHost`](#parameter-encryptionathost) | bool | This property can be used by user in the request to enable or disable the Host Encryption for the virtual machine. This will enable the encryption for all the disks including Resource/Temp disk at host itself. For security reasons, it is recommended to set encryptionAtHost to True. Restrictions: Cannot be enabled if Azure Disk Encryption (guest-VM encryption using bitlocker/DM-Crypt) is enabled on your VMs. | | [`extensionAadJoinConfig`](#parameter-extensionaadjoinconfig) | object | The configuration for the [AAD Join] extension. Must at least contain the ["enabled": true] property to be executed. | | [`extensionAntiMalwareConfig`](#parameter-extensionantimalwareconfig) | object | The configuration for the [Anti Malware] extension. Must at least contain the ["enabled": true] property to be executed. | @@ -2123,7 +2123,7 @@ Specifies the eviction policy for the low priority virtual machine. Will result ### Parameter: `enableTelemetry` -Enable telemetry via a Globally Unique Identifier (GUID). +Enable/Disable usage telemetry for module. - Required: No - Type: bool diff --git a/avm/res/compute/virtual-machine/main.json b/avm/res/compute/virtual-machine/main.json index 69228b672a..c7e9ccdbe1 100644 --- a/avm/res/compute/virtual-machine/main.json +++ b/avm/res/compute/virtual-machine/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.24.24.22086", - "templateHash": "10795179531307040793" + "templateHash": "7458372846706074174" }, "name": "Virtual Machines", "description": "This module deploys a Virtual Machine with one or multiple NICs and optionally one or multiple public IPs.", @@ -608,7 +608,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } }, "baseTime": { @@ -3018,7 +3018,7 @@ "value": "[parameters('name')]" }, "name": { - "value": "AzureMonitoringAgent" + "value": "AzureMonitorAgent" }, "location": { "value": "[parameters('location')]"