From d46712c1edfac5fcbf3f3029a7af13c9ac3481f1 Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Mon, 6 Dec 2021 09:12:05 +1100 Subject: [PATCH 01/15] test all md's --- .github/workflows/linter.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 1284dbd68c..05e966a2ae 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -1,6 +1,6 @@ name: '.Platform: Linter' -on: [pull_request] +on: workflow_dispatch jobs: build: @@ -27,3 +27,10 @@ jobs: DEFAULT_BRANCH: ${{ github.base_ref }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} FILTER_REGEX_EXCLUDE: '[global.module.tests.ps1|Get\-ModulesAsMarkdownTable.ps1]' + + - name: Link Checker + uses: lycheeverse/lychee-action@v1.1.1 + with: + args: --verbose --no-progress **/*.md **/*.html + env: + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} From 72f63505107556cf84db56a607ca66d5f55724f4 Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Mon, 6 Dec 2021 15:23:03 +1100 Subject: [PATCH 02/15] reverted --- .github/workflows/linter.yml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 05e966a2ae..1284dbd68c 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -1,6 +1,6 @@ name: '.Platform: Linter' -on: workflow_dispatch +on: [pull_request] jobs: build: @@ -27,10 +27,3 @@ jobs: DEFAULT_BRANCH: ${{ github.base_ref }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} FILTER_REGEX_EXCLUDE: '[global.module.tests.ps1|Get\-ModulesAsMarkdownTable.ps1]' - - - name: Link Checker - uses: lycheeverse/lychee-action@v1.1.1 - with: - args: --verbose --no-progress **/*.md **/*.html - env: - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} From 40af98d0e120444e85bd4827b6b444f1a2df2c79 Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Mon, 6 Dec 2021 15:27:03 +1100 Subject: [PATCH 03/15] Merging from Fork to Branch (#745) --- .github/workflows/linter.yml | 13 +++++++++ .lycheeignore | 8 +++++ .../virtualMachineScaleSets/readme.md | 29 +++++++------------ .../virtualMachines/readme.md | 8 ++--- .../managedClusters/agentPools/readme.md | 2 +- .../managedClusters/readme.md | 4 +-- .../securityAlertPolicies/deploy.bicep | 2 +- .../servers/securityAlertPolicies/readme.md | 2 +- docs/wiki/ModulesUsage.md | 4 +-- docs/wiki/TestingDesign.md | 2 +- 10 files changed, 43 insertions(+), 31 deletions(-) create mode 100644 .lycheeignore diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 1284dbd68c..75ec6283bd 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -27,3 +27,16 @@ jobs: DEFAULT_BRANCH: ${{ github.base_ref }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} FILTER_REGEX_EXCLUDE: '[global.module.tests.ps1|Get\-ModulesAsMarkdownTable.ps1]' + + - name: Link Checker + if: always() + id: checker + uses: lycheeverse/lychee-action@v1.1.1 + with: + args: --verbose --no-progress **/*.md --exclude-file .lycheeignore --accept 200,201,403,429 + env: + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + + - name: Link Checker Results + if: always() + run: exit ${{ steps.checker.outputs.exit_code }} diff --git a/.lycheeignore b/.lycheeignore new file mode 100644 index 0000000000..62214a16db --- /dev/null +++ b/.lycheeignore @@ -0,0 +1,8 @@ +https://foo.psd1/ +file:///github +https://mystorageaccount.blob.core.windows.net +https://mykeyvault.vault.azure.net +https://www.powershellgallery.com +https://github.com/myProject +http://validURLToConfigLocation/ +https://myCustomDependencyLocation/ diff --git a/arm/Microsoft.Compute/virtualMachineScaleSets/readme.md b/arm/Microsoft.Compute/virtualMachineScaleSets/readme.md index 4f1e419349..691dc568e6 100644 --- a/arm/Microsoft.Compute/virtualMachineScaleSets/readme.md +++ b/arm/Microsoft.Compute/virtualMachineScaleSets/readme.md @@ -197,25 +197,16 @@ The following resources are required to be able to deploy this resource. ```json -"extensionDomainJoinConfig": { - "value": { - "settings": { - "Name": ".onmicrosoft.com", - "User": "domainJoinUser02@.onmicrosoft.com", - "OUPath": "OU=Template-Test; DC=; DC=onmicrosoft; DC=com", - "Restart": true, - "Options": "" - } - } -} -``` - -Should be configured alongside: -```json -"extensionDomainJoinPassword": { - "reference": { - "keyVault": { - "id": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.KeyVault/vaults/" +"windowsScriptExtensionFileData": { + "value": [ + //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" }, "secretName": "domainJoinUser-Password" } diff --git a/arm/Microsoft.Compute/virtualMachines/readme.md b/arm/Microsoft.Compute/virtualMachines/readme.md index 125f6fd3dd..5b2abb2edf 100644 --- a/arm/Microsoft.Compute/virtualMachines/readme.md +++ b/arm/Microsoft.Compute/virtualMachines/readme.md @@ -343,9 +343,9 @@ Only for OSType Windows "diskEncryptionSettings": { "value": { "EncryptionOperation": "EnableEncryption", - "KeyVaultURL": "https://adp-sxx-az-kv-x-001.vault.azure.net/", + "KeyVaultURL": "https://mykeyvault.vault.azure.net/", "KeyVaultResourceId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.KeyVault/vaults/adp-sxx-az-kv-x-001", - "KeyEncryptionKeyURL": "https://adp-sxx-az-kv-x-001.vault.azure.net/keys/keyEncryptionKey/685153483a1140e3856f004a753e1ab4", + "KeyEncryptionKeyURL": "https://mykeyvault.vault.azure.net/keys/keyEncryptionKey/685153483a1140e3856f004a753e1ab4", "KekVaultResourceId": "/subscriptions/<>/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' @@ -409,11 +409,11 @@ Only for OSType Windows "value": [ //storage accounts with SAS token requirement { - "uri": "https://storageAccount.blob.core.windows.net/avdscripts/File1.ps1", + "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://storageAccount.blob.core.windows.net/avdscripts/File2.ps1", + "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) diff --git a/arm/Microsoft.ContainerService/managedClusters/agentPools/readme.md b/arm/Microsoft.ContainerService/managedClusters/agentPools/readme.md index 929311fc88..fa853264e1 100644 --- a/arm/Microsoft.ContainerService/managedClusters/agentPools/readme.md +++ b/arm/Microsoft.ContainerService/managedClusters/agentPools/readme.md @@ -48,7 +48,7 @@ For available properties check Date: Tue, 7 Dec 2021 16:36:39 +1100 Subject: [PATCH 04/15] Merge from Fork (Ahmad) (#758) --- .github/workflows/linter.yml | 4 +- .../automationAccounts/deploy.bicep | 4 +- .../availabilitySets/deploy.bicep | 2 +- .../diskEncryptionSets/deploy.bicep | 2 +- arm/Microsoft.Compute/galleries/deploy.bicep | 4 +- .../galleries/images/deploy.bicep | 2 +- arm/Microsoft.Compute/images/deploy.bicep | 2 +- .../proximityPlacementGroups/deploy.bicep | 2 +- .../virtualMachineScaleSets/deploy.bicep | 18 ++--- .../.bicep/nested_networkInterface.bicep | 4 +- ...ted_networkInterface_publicIPAddress.bicep | 2 +- .../virtualMachines/deploy.bicep | 22 ++--- .../registries/deploy.bicep | 6 +- arm/Microsoft.EventGrid/topics/deploy.bicep | 4 +- .../actionGroups/deploy.bicep | 2 +- .../activityLogAlerts/deploy.bicep | 2 +- .../components/deploy.bicep | 2 +- .../metricAlerts/deploy.bicep | 2 +- .../privateLinkScopes/deploy.bicep | 6 +- .../scheduledQueryRules/deploy.bicep | 2 +- .../virtualNetworks/deploy.bicep | 6 +- .../virtualNetworks/readme.md | 1 + .../vaults/.parameters/parameters.json | 6 ++ .../backupConfig/.bicep/nested_cuaId.bicep | 1 + .../vaults/backupConfig/deploy.bicep | 81 +++++++++++++++++++ .../vaults/backupConfig/readme.md | 35 ++++++++ .../vaults/backupPolicies/deploy.bicep | 5 +- .../vaults/backupPolicies/readme.md | 4 +- .../vaults/backupStorageConfig/deploy.bicep | 1 - .../vaults/deploy.bicep | 24 +++++- .../vaults/protectionContainers/deploy.bicep | 1 - .../vaults/readme.md | 9 ++- docs/wiki/Context.md | 6 +- docs/wiki/ContributionGuide.md | 6 +- docs/wiki/GettingStarted.md | 6 +- docs/wiki/Home.md | 38 ++++----- docs/wiki/Modules.md | 14 ++-- docs/wiki/ModulesDesign.md | 6 +- docs/wiki/ParameterFileTokens.md | 2 +- docs/wiki/Pipelines.md | 4 +- docs/wiki/PipelinesDesign.md | 6 +- docs/wiki/PipelinesUsage.md | 20 ++--- docs/wiki/Testing.md | 12 +-- docs/wiki/TestingDesign.md | 4 +- docs/wiki/TestingUsage.md | 2 +- docs/wiki/_Sidebar.md | 30 +++---- 46 files changed, 284 insertions(+), 140 deletions(-) create mode 100644 arm/Microsoft.RecoveryServices/vaults/backupConfig/.bicep/nested_cuaId.bicep create mode 100644 arm/Microsoft.RecoveryServices/vaults/backupConfig/deploy.bicep create mode 100644 arm/Microsoft.RecoveryServices/vaults/backupConfig/readme.md diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 75ec6283bd..7fbd58562d 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -1,6 +1,6 @@ name: '.Platform: Linter' -on: [pull_request] +on: workflow_dispatch jobs: build: @@ -33,7 +33,7 @@ jobs: id: checker uses: lycheeverse/lychee-action@v1.1.1 with: - args: --verbose --no-progress **/*.md --exclude-file .lycheeignore --accept 200,201,403,429 + args: --verbose --no-progress **/docs/**/*.md --accept 200,201,403,429 env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/arm/Microsoft.Automation/automationAccounts/deploy.bicep b/arm/Microsoft.Automation/automationAccounts/deploy.bicep index c925a453bf..7a475462d6 100644 --- a/arm/Microsoft.Automation/automationAccounts/deploy.bicep +++ b/arm/Microsoft.Automation/automationAccounts/deploy.bicep @@ -198,7 +198,7 @@ module automationAccount_jobSchedules 'jobSchedules/deploy.bicep' = [for (jobSch }] module automationAccount_variables 'variables/deploy.bicep' = [for (variable, index) in variables: { - name: '${uniqueString(deployment().name, location)}-AutoAccount-variable-${index}' + name: '${uniqueString(deployment().name, location)}-AutoAccount-Variable-${index}' params: { automationAccountName: automationAccount.name name: variable.name @@ -310,7 +310,7 @@ resource automationAccount_diagnosticSettings 'Microsoft.Insights/diagnosticSett } module automationAccount_privateEndpoints '.bicep/nested_privateEndpoint.bicep' = [for (endpoint, index) in privateEndpoints: if (!empty(privateEndpoints)) { - name: '${uniqueString(deployment().name, location)}-AutoAccount-PrivateEndpoints-${index}' + name: '${uniqueString(deployment().name, location)}-AutoAccount-PrivateEndpoint-${index}' params: { privateEndpointResourceId: automationAccount.id privateEndpointVnetLocation: (empty(privateEndpoints) ? 'dummy' : reference(split(endpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location) diff --git a/arm/Microsoft.Compute/availabilitySets/deploy.bicep b/arm/Microsoft.Compute/availabilitySets/deploy.bicep index 7df4ffd083..687c53f292 100644 --- a/arm/Microsoft.Compute/availabilitySets/deploy.bicep +++ b/arm/Microsoft.Compute/availabilitySets/deploy.bicep @@ -62,7 +62,7 @@ resource availabilitySet_lock 'Microsoft.Authorization/locks@2016-09-01' = if (l } module availabilitySet_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: { - name: '${deployment().name}-rbac-${index}' + name: '${uniqueString(deployment().name, location)}-AvSet-Rbac-${index}' params: { principalIds: roleAssignment.principalIds roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName diff --git a/arm/Microsoft.Compute/diskEncryptionSets/deploy.bicep b/arm/Microsoft.Compute/diskEncryptionSets/deploy.bicep index 106668ce83..332fd6cae3 100644 --- a/arm/Microsoft.Compute/diskEncryptionSets/deploy.bicep +++ b/arm/Microsoft.Compute/diskEncryptionSets/deploy.bicep @@ -63,7 +63,7 @@ resource diskEncryptionSet 'Microsoft.Compute/diskEncryptionSets@2020-12-01' = { } module diskEncryptionSet_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: { - name: '${deployment().name}-rbac-${index}' + name: '${uniqueString(deployment().name, location)}-DiskEncrSet-Rbac-${index}' params: { principalIds: roleAssignment.principalIds roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName diff --git a/arm/Microsoft.Compute/galleries/deploy.bicep b/arm/Microsoft.Compute/galleries/deploy.bicep index 38cc47dc08..fa4d9e153f 100644 --- a/arm/Microsoft.Compute/galleries/deploy.bicep +++ b/arm/Microsoft.Compute/galleries/deploy.bicep @@ -53,7 +53,7 @@ resource gallery_lock 'Microsoft.Authorization/locks@2016-09-01' = if (lock != ' } module gallery_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: { - name: '${uniqueString(deployment().name, location)}-rbac-${index}' + name: '${uniqueString(deployment().name, location)}-Gallery-Rbac-${index}' params: { principalIds: roleAssignment.principalIds roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName @@ -63,7 +63,7 @@ module gallery_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in // Images module galleries_images 'images/deploy.bicep' = [for (image, index) in images: { - name: '${uniqueString(deployment().name, location)}-Image-${index}' + name: '${uniqueString(deployment().name, location)}-Gallery-Image-${index}' params: { name: image.name galleryName: gallery.name diff --git a/arm/Microsoft.Compute/galleries/images/deploy.bicep b/arm/Microsoft.Compute/galleries/images/deploy.bicep index 8f1d89d38f..1b8d10d798 100644 --- a/arm/Microsoft.Compute/galleries/images/deploy.bicep +++ b/arm/Microsoft.Compute/galleries/images/deploy.bicep @@ -144,7 +144,7 @@ resource image 'Microsoft.Compute/galleries/images@2020-09-30' = { } module galleryImage_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: { - name: '${deployment().name}-rbac-${index}' + name: '${deployment().name}-Rbac-${index}' params: { principalIds: roleAssignment.principalIds roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName diff --git a/arm/Microsoft.Compute/images/deploy.bicep b/arm/Microsoft.Compute/images/deploy.bicep index ab230818fe..eb3a19bf7e 100644 --- a/arm/Microsoft.Compute/images/deploy.bicep +++ b/arm/Microsoft.Compute/images/deploy.bicep @@ -56,7 +56,7 @@ resource image 'Microsoft.Compute/images@2021-04-01' = { } module image_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: { - name: '${deployment().name}-rbac-${index}' + name: '${uniqueString(deployment().name, location)}-Image-Rbac-${index}' params: { principalIds: roleAssignment.principalIds roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName diff --git a/arm/Microsoft.Compute/proximityPlacementGroups/deploy.bicep b/arm/Microsoft.Compute/proximityPlacementGroups/deploy.bicep index ee15ee087f..152fa60727 100644 --- a/arm/Microsoft.Compute/proximityPlacementGroups/deploy.bicep +++ b/arm/Microsoft.Compute/proximityPlacementGroups/deploy.bicep @@ -52,7 +52,7 @@ resource proximityPlacementGroup_lock 'Microsoft.Authorization/locks@2016-09-01' } module proximityPlacementGroup_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: { - name: '${deployment().name}-rbac-${index}' + name: '${uniqueString(deployment().name, location)}-ProxPlaceGroup-Rbac-${index}' params: { principalIds: roleAssignment.principalIds roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName diff --git a/arm/Microsoft.Compute/virtualMachineScaleSets/deploy.bicep b/arm/Microsoft.Compute/virtualMachineScaleSets/deploy.bicep index 7f8af299b9..bef0dd1e46 100644 --- a/arm/Microsoft.Compute/virtualMachineScaleSets/deploy.bicep +++ b/arm/Microsoft.Compute/virtualMachineScaleSets/deploy.bicep @@ -447,7 +447,7 @@ resource vmss 'Microsoft.Compute/virtualMachineScaleSets@2021-04-01' = { } module vmss_domainJoinExtension 'extensions/deploy.bicep' = if (extensionDomainJoinConfig.enabled) { - name: '${uniqueString(deployment().name, location)}-vmss-DomainJoin' + name: '${uniqueString(deployment().name, location)}-VMSS-DomainJoin' params: { virtualMachineScaleSetName: vmss.name name: 'DomainJoin' @@ -464,7 +464,7 @@ module vmss_domainJoinExtension 'extensions/deploy.bicep' = if (extensionDomainJ } module vmss_microsoftAntiMalwareExtension 'extensions/deploy.bicep' = if (extensionAntiMalwareConfig.enabled) { - name: '${uniqueString(deployment().name, location)}-vmss-MicrosoftAntiMalware' + name: '${uniqueString(deployment().name, location)}-VMSS-MicrosoftAntiMalware' params: { virtualMachineScaleSetName: vmss.name name: 'MicrosoftAntiMalware' @@ -483,7 +483,7 @@ resource vmss_logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@20 } module vmss_microsoftMonitoringAgentExtension 'extensions/deploy.bicep' = if (extensionMonitoringAgentConfig.enabled) { - name: '${uniqueString(deployment().name, location)}-vmss-MicrosoftMonitoringAgent' + name: '${uniqueString(deployment().name, location)}-VMSS-MicrosoftMonitoringAgent' params: { virtualMachineScaleSetName: vmss.name name: 'MicrosoftMonitoringAgent' @@ -502,7 +502,7 @@ module vmss_microsoftMonitoringAgentExtension 'extensions/deploy.bicep' = if (ex } module vmss_dependencyAgentExtension 'extensions/deploy.bicep' = if (extensionDependencyAgentConfig.enabled) { - name: '${uniqueString(deployment().name, location)}-vmss-DependencyAgent' + name: '${uniqueString(deployment().name, location)}-VMSS-DependencyAgent' params: { virtualMachineScaleSetName: vmss.name name: 'DependencyAgent' @@ -515,7 +515,7 @@ module vmss_dependencyAgentExtension 'extensions/deploy.bicep' = if (extensionDe } module vmss_networkWatcherAgentExtension 'extensions/deploy.bicep' = if (extensionNetworkWatcherAgentConfig.enabled) { - name: '${uniqueString(deployment().name, location)}-vmss-NetworkWatcherAgent' + name: '${uniqueString(deployment().name, location)}-VMSS-NetworkWatcherAgent' params: { virtualMachineScaleSetName: vmss.name name: 'NetworkWatcherAgent' @@ -528,7 +528,7 @@ module vmss_networkWatcherAgentExtension 'extensions/deploy.bicep' = if (extensi } module vmss_desiredStateConfigurationExtension 'extensions/deploy.bicep' = if (extensionDSCConfig.enabled) { - name: '${uniqueString(deployment().name, location)}-vmss-DesiredStateConfiguration' + name: '${uniqueString(deployment().name, location)}-VMSS-DesiredStateConfiguration' params: { virtualMachineScaleSetName: vmss.name name: 'DesiredStateConfiguration' @@ -543,7 +543,7 @@ module vmss_desiredStateConfigurationExtension 'extensions/deploy.bicep' = if (e } module vmss_customScriptExtension 'extensions/deploy.bicep' = if (extensionCustomScriptConfig.enabled) { - name: '${uniqueString(deployment().name, location)}-vmss-CustomScriptExtension' + name: '${uniqueString(deployment().name, location)}-VMSS-CustomScriptExtension' params: { virtualMachineScaleSetName: vmss.name name: 'CustomScriptExtension' @@ -563,7 +563,7 @@ module vmss_customScriptExtension 'extensions/deploy.bicep' = if (extensionCusto } module vmss_diskEncryptionExtension 'extensions/deploy.bicep' = if (extensionDiskEncryptionConfig.enabled) { - name: '${uniqueString(deployment().name, location)}-vmss-DiskEncryption' + name: '${uniqueString(deployment().name, location)}-VMSS-DiskEncryption' params: { virtualMachineScaleSetName: vmss.name name: 'DiskEncryption' @@ -603,7 +603,7 @@ resource vmss_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05- } module vmss_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: { - name: '${deployment().name}-rbac-${index}' + name: '${uniqueString(deployment().name, location)}-VMSS-Rbac-${index}' params: { principalIds: roleAssignment.principalIds roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName diff --git a/arm/Microsoft.Compute/virtualMachines/.bicep/nested_networkInterface.bicep b/arm/Microsoft.Compute/virtualMachines/.bicep/nested_networkInterface.bicep index 69e81d6bb5..dc9e755dab 100644 --- a/arm/Microsoft.Compute/virtualMachines/.bicep/nested_networkInterface.bicep +++ b/arm/Microsoft.Compute/virtualMachines/.bicep/nested_networkInterface.bicep @@ -37,7 +37,7 @@ var networkSecurityGroup = { } module networkInterface_publicIPConfigurations 'nested_networkInterface_publicIPAddress.bicep' = [for (ipConfiguration, index) in ipConfigurationArray: if (contains(ipConfiguration, 'pipconfiguration')) { - name: '${deployment().name}-pip-${index}' + name: '${deployment().name}-PIP-${index}' params: { publicIPAddressName: '${virtualMachineName}${ipConfiguration.pipconfiguration.publicIpNameSuffix}' publicIPPrefixId: (contains(ipConfiguration.pipconfiguration, 'publicIPPrefixId') ? (!(empty(ipConfiguration.pipconfiguration.publicIPPrefixId)) ? ipConfiguration.pipconfiguration.publicIPPrefixId : '') : '') @@ -107,7 +107,7 @@ resource networkInterface_diagnosticSettings 'Microsoft.Insights/diagnosticsetti } module networkInterface_rbac 'nested_networkInterface_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: { - name: '${deployment().name}-rbac-${index}' + name: '${deployment().name}-Rbac-${index}' params: { principalIds: roleAssignment.principalIds roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName diff --git a/arm/Microsoft.Compute/virtualMachines/.bicep/nested_networkInterface_publicIPAddress.bicep b/arm/Microsoft.Compute/virtualMachines/.bicep/nested_networkInterface_publicIPAddress.bicep index ff4721a213..5f98e281b5 100644 --- a/arm/Microsoft.Compute/virtualMachines/.bicep/nested_networkInterface_publicIPAddress.bicep +++ b/arm/Microsoft.Compute/virtualMachines/.bicep/nested_networkInterface_publicIPAddress.bicep @@ -75,7 +75,7 @@ resource publicIpAddress_diagnosticSettings 'Microsoft.Insights/diagnosticsettin } module publicIpAddress_rbac 'nested_networkInterface_publicIPAddress_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: { - name: '${deployment().name}-rbac-${index}' + name: '${deployment().name}-Rbac-${index}' params: { principalIds: roleAssignment.principalIds roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName diff --git a/arm/Microsoft.Compute/virtualMachines/deploy.bicep b/arm/Microsoft.Compute/virtualMachines/deploy.bicep index 722b6463ef..8d6e028ddd 100644 --- a/arm/Microsoft.Compute/virtualMachines/deploy.bicep +++ b/arm/Microsoft.Compute/virtualMachines/deploy.bicep @@ -303,7 +303,7 @@ module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) { } module virtualMachine_nic '.bicep/nested_networkInterface.bicep' = [for (nicConfiguration, index) in nicConfigurations: { - name: '${uniqueString(deployment().name, location)}-vm-nic-${index}' + name: '${uniqueString(deployment().name, location)}-VM-Nic-${index}' params: { networkInterfaceName: '${name}${nicConfiguration.nicSuffix}' virtualMachineName: name @@ -403,7 +403,7 @@ resource virtualMachine 'Microsoft.Compute/virtualMachines@2021-07-01' = { } module vm_domainJoinExtension 'extensions/deploy.bicep' = if (extensionDomainJoinConfig.enabled) { - name: '${uniqueString(deployment().name, location)}-vm-DomainJoin' + name: '${uniqueString(deployment().name, location)}-VM-DomainJoin' params: { virtualMachineName: virtualMachine.name name: 'DomainJoin' @@ -420,7 +420,7 @@ module vm_domainJoinExtension 'extensions/deploy.bicep' = if (extensionDomainJoi } module vm_microsoftAntiMalwareExtension 'extensions/deploy.bicep' = if (extensionAntiMalwareConfig.enabled) { - name: '${uniqueString(deployment().name, location)}-vm-MicrosoftAntiMalware' + name: '${uniqueString(deployment().name, location)}-VM-MicrosoftAntiMalware' params: { virtualMachineName: virtualMachine.name name: 'MicrosoftAntiMalware' @@ -439,7 +439,7 @@ resource vm_logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2021 } module vm_microsoftMonitoringAgentExtension 'extensions/deploy.bicep' = if (extensionMonitoringAgentConfig.enabled) { - name: '${uniqueString(deployment().name, location)}-vm-MicrosoftMonitoringAgent' + name: '${uniqueString(deployment().name, location)}-VM-MicrosoftMonitoringAgent' params: { virtualMachineName: virtualMachine.name name: 'MicrosoftMonitoringAgent' @@ -458,7 +458,7 @@ module vm_microsoftMonitoringAgentExtension 'extensions/deploy.bicep' = if (exte } module vm_dependencyAgentExtension 'extensions/deploy.bicep' = if (extensionDependencyAgentConfig.enabled) { - name: '${uniqueString(deployment().name, location)}-vm-DependencyAgent' + name: '${uniqueString(deployment().name, location)}-VM-DependencyAgent' params: { virtualMachineName: virtualMachine.name name: 'DependencyAgent' @@ -471,7 +471,7 @@ module vm_dependencyAgentExtension 'extensions/deploy.bicep' = if (extensionDepe } module vm_networkWatcherAgentExtension 'extensions/deploy.bicep' = if (extensionNetworkWatcherAgentConfig.enabled) { - name: '${uniqueString(deployment().name, location)}-vm-NetworkWatcherAgent' + name: '${uniqueString(deployment().name, location)}-VM-NetworkWatcherAgent' params: { virtualMachineName: virtualMachine.name name: 'NetworkWatcherAgent' @@ -484,7 +484,7 @@ module vm_networkWatcherAgentExtension 'extensions/deploy.bicep' = if (extension } module vm_desiredStateConfigurationExtension 'extensions/deploy.bicep' = if (extensionDSCConfig.enabled) { - name: '${uniqueString(deployment().name, location)}-vm-DesiredStateConfiguration' + name: '${uniqueString(deployment().name, location)}-VM-DesiredStateConfiguration' params: { virtualMachineName: virtualMachine.name name: 'DesiredStateConfiguration' @@ -499,7 +499,7 @@ module vm_desiredStateConfigurationExtension 'extensions/deploy.bicep' = if (ext } module vm_customScriptExtension 'extensions/deploy.bicep' = if (extensionCustomScriptConfig.enabled) { - name: '${uniqueString(deployment().name, location)}-vm-CustomScriptExtension' + name: '${uniqueString(deployment().name, location)}-VM-CustomScriptExtension' params: { virtualMachineName: virtualMachine.name name: 'CustomScriptExtension' @@ -519,7 +519,7 @@ module vm_customScriptExtension 'extensions/deploy.bicep' = if (extensionCustomS } module vm_diskEncryptionExtension 'extensions/deploy.bicep' = if (extensionDiskEncryptionConfig.enabled) { - name: '${uniqueString(deployment().name, location)}-vm-DiskEncryption' + name: '${uniqueString(deployment().name, location)}-VM-DiskEncryption' params: { virtualMachineName: virtualMachine.name name: 'DiskEncryption' @@ -538,7 +538,7 @@ module vm_diskEncryptionExtension 'extensions/deploy.bicep' = if (extensionDiskE } module virtualMachine_backup '.bicep/nested_backup.bicep' = if (!empty(backupVaultName)) { - name: '${uniqueString(deployment().name, location)}-vm-backup' + name: '${uniqueString(deployment().name, location)}-VM-Backup' params: { backupResourceName: '${backupVaultName}/Azure/iaasvmcontainer;iaasvmcontainerv2;${resourceGroup().name};${virtualMachine.name}/vm;iaasvmcontainerv2;${resourceGroup().name};${virtualMachine.name}' protectedItemType: 'Microsoft.Compute/virtualMachines' @@ -568,7 +568,7 @@ resource virtualMachine_lock 'Microsoft.Authorization/locks@2017-04-01' = if (lo } module virtualMachine_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: { - name: '${uniqueString(deployment().name, location)}-vm-rbac-${index}' + name: '${uniqueString(deployment().name, location)}-VM-Rbac-${index}' params: { principalIds: roleAssignment.principalIds roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName diff --git a/arm/Microsoft.ContainerRegistry/registries/deploy.bicep b/arm/Microsoft.ContainerRegistry/registries/deploy.bicep index 6c72ecf73b..b0167f3a6b 100644 --- a/arm/Microsoft.ContainerRegistry/registries/deploy.bicep +++ b/arm/Microsoft.ContainerRegistry/registries/deploy.bicep @@ -182,7 +182,7 @@ resource registry_diagnosticSettingName 'Microsoft.Insights/diagnosticsettings@2 } module registry_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: { - name: '${deployment().name}-rbac-${index}' + name: '${uniqueString(deployment().name, location)}-ContainerRegistry-Rbac-${index}' params: { principalIds: roleAssignment.principalIds roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName @@ -190,8 +190,8 @@ module registry_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) i } }] -module registry_privateEndpoints '.bicep/nested_privateEndpoints.bicep' = [for privateEndpoint in privateEndpoints: { - name: '${uniqueString(deployment().name, privateEndpoint.name)}-privateEndpoint' +module registry_privateEndpoints '.bicep/nested_privateEndpoints.bicep' = [for (privateEndpoint, index) in privateEndpoints: { + name: '${uniqueString(deployment().name, location)}-ContainerRegistry-PrivateEndpoint-${index}' params: { privateEndpointResourceId: registry.id privateEndpointVnetLocation: empty(privateEndpoints) ? 'dummy' : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location diff --git a/arm/Microsoft.EventGrid/topics/deploy.bicep b/arm/Microsoft.EventGrid/topics/deploy.bicep index a66830ec83..ef3158da9f 100644 --- a/arm/Microsoft.EventGrid/topics/deploy.bicep +++ b/arm/Microsoft.EventGrid/topics/deploy.bicep @@ -122,7 +122,7 @@ resource eventGrid_diagnosticSettings 'Microsoft.Insights/diagnosticsettings@201 } module eventGrid_privateEndpoints '.bicep/nested_privateEndpoint.bicep' = [for (privateEndpoint, index) in privateEndpoints: if (!empty(privateEndpoints)) { - name: '${uniqueString(deployment().name, location)}-EventGrid-PrivateEndpoints-${index}' + name: '${uniqueString(deployment().name, location)}-EventGrid-PrivateEndpoint-${index}' params: { privateEndpointResourceId: eventGrid.id privateEndpointVnetLocation: (empty(privateEndpoints) ? 'dummy' : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location) @@ -132,7 +132,7 @@ module eventGrid_privateEndpoints '.bicep/nested_privateEndpoint.bicep' = [for ( }] module eventGrid_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: { - name: '${deployment().name}-rbac-${index}' + name: '${uniqueString(deployment().name, location)}-EventGrid-Rbac-${index}' params: { principalIds: roleAssignment.principalIds roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName diff --git a/arm/Microsoft.Insights/actionGroups/deploy.bicep b/arm/Microsoft.Insights/actionGroups/deploy.bicep index e0474a0671..08c650ab9b 100644 --- a/arm/Microsoft.Insights/actionGroups/deploy.bicep +++ b/arm/Microsoft.Insights/actionGroups/deploy.bicep @@ -75,7 +75,7 @@ resource actionGroup 'microsoft.insights/actionGroups@2019-06-01' = { } module actionGroup_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: { - name: '${deployment().name}-rbac-${index}' + name: '${uniqueString(deployment().name, location)}-ActionGroup-Rbac-${index}' params: { principalIds: roleAssignment.principalIds roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName diff --git a/arm/Microsoft.Insights/activityLogAlerts/deploy.bicep b/arm/Microsoft.Insights/activityLogAlerts/deploy.bicep index 34b01321c3..404c0d8f50 100644 --- a/arm/Microsoft.Insights/activityLogAlerts/deploy.bicep +++ b/arm/Microsoft.Insights/activityLogAlerts/deploy.bicep @@ -58,7 +58,7 @@ resource activityLogAlert 'Microsoft.Insights/activityLogAlerts@2020-10-01' = { } module activityLogAlert_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: { - name: '${deployment().name}-rbac-${index}' + name: '${uniqueString(deployment().name, location)}-ActivityLogAlert-Rbac-${index}' params: { principalIds: roleAssignment.principalIds roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName diff --git a/arm/Microsoft.Insights/components/deploy.bicep b/arm/Microsoft.Insights/components/deploy.bicep index bcfd1f2934..a9fac14def 100644 --- a/arm/Microsoft.Insights/components/deploy.bicep +++ b/arm/Microsoft.Insights/components/deploy.bicep @@ -59,7 +59,7 @@ resource appInsights 'Microsoft.Insights/components@2020-02-02' = { } module appInsights_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: { - name: '${deployment().name}-rbac-${index}' + name: '${uniqueString(deployment().name, location)}-AppInsights-Rbac-${index}' params: { principalIds: roleAssignment.principalIds roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName diff --git a/arm/Microsoft.Insights/metricAlerts/deploy.bicep b/arm/Microsoft.Insights/metricAlerts/deploy.bicep index 071eb9ae53..47e9428de0 100644 --- a/arm/Microsoft.Insights/metricAlerts/deploy.bicep +++ b/arm/Microsoft.Insights/metricAlerts/deploy.bicep @@ -113,7 +113,7 @@ resource metricAlert 'Microsoft.Insights/metricAlerts@2018-03-01' = { } module metricAlert_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: { - name: '${deployment().name}-rbac-${index}' + name: '${uniqueString(deployment().name, location)}-MetricAlert-Rbac-${index}' params: { principalIds: roleAssignment.principalIds roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName diff --git a/arm/Microsoft.Insights/privateLinkScopes/deploy.bicep b/arm/Microsoft.Insights/privateLinkScopes/deploy.bicep index 5a95a5f04c..da84b93f41 100644 --- a/arm/Microsoft.Insights/privateLinkScopes/deploy.bicep +++ b/arm/Microsoft.Insights/privateLinkScopes/deploy.bicep @@ -41,7 +41,7 @@ resource privateLinkScope 'Microsoft.Insights/privateLinkScopes@2019-10-17-previ } module privateLinkScope_scopedResource 'scopedResources/deploy.bicep' = [for (scopedResource, index) in scopedResources: { - name: '${uniqueString(deployment().name, location)}-Insights-ScpdRes-${index}' + name: '${uniqueString(deployment().name, location)}-PvtLinkScope-ScopedRes-${index}' params: { name: scopedResource.name privateLinkScopeName: privateLinkScope.name @@ -59,7 +59,7 @@ resource privateLinkScope_lock 'Microsoft.Authorization/locks@2016-09-01' = if ( } module privateLinkScope_privateEndpoints '.bicep/nested_privateEndpoint.bicep' = [for (endpoint, index) in privateEndpoints: { - name: '${uniqueString(deployment().name, location)}-Insights-PvtEndPnt-${index}' + name: '${uniqueString(deployment().name, location)}-PvtLinkScope-PrivateEndpoint-${index}' params: { privateEndpointResourceId: privateLinkScope.id privateEndpointVnetLocation: reference(split(endpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location @@ -69,7 +69,7 @@ module privateLinkScope_privateEndpoints '.bicep/nested_privateEndpoint.bicep' = }] module privateLinkScope_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: { - name: '${deployment().name}-rbac-${index}' + name: '${uniqueString(deployment().name, location)}-PvtLinkScope-Rbac-${index}' params: { principalIds: roleAssignment.principalIds roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName diff --git a/arm/Microsoft.Insights/scheduledQueryRules/deploy.bicep b/arm/Microsoft.Insights/scheduledQueryRules/deploy.bicep index f7be392ff3..6dbc6368bc 100644 --- a/arm/Microsoft.Insights/scheduledQueryRules/deploy.bicep +++ b/arm/Microsoft.Insights/scheduledQueryRules/deploy.bicep @@ -99,7 +99,7 @@ resource queryRule 'Microsoft.Insights/scheduledQueryRules@2021-02-01-preview' = } module queryRule_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: { - name: '${deployment().name}-rbac-${index}' + name: '${uniqueString(deployment().name, location)}-QueryRule-Rbac-${index}' params: { principalIds: roleAssignment.principalIds roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName diff --git a/arm/Microsoft.Network/virtualNetworks/deploy.bicep b/arm/Microsoft.Network/virtualNetworks/deploy.bicep index e72405a788..ed5faeeb6d 100644 --- a/arm/Microsoft.Network/virtualNetworks/deploy.bicep +++ b/arm/Microsoft.Network/virtualNetworks/deploy.bicep @@ -11,6 +11,10 @@ param addressPrefixes array @minLength(1) param subnets array +@description('Optional. Resource Group where NSGs are deployed, if different than VNET Resource Group.') +@minLength(1) +param nsgResourceGroup string = resourceGroup().name + @description('Optional. DNS Servers associated to the Virtual Network.') param dnsServers array = [] @@ -116,7 +120,7 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2021-05-01' = { name: item.name properties: { addressPrefix: item.addressPrefix - networkSecurityGroup: contains(item, 'networkSecurityGroupName') ? (empty(item.networkSecurityGroupName) ? null : json('{"id": "${resourceId('Microsoft.Network/networkSecurityGroups', item.networkSecurityGroupName)}"}')) : null + networkSecurityGroup: contains(item, 'networkSecurityGroupName') ? (empty(item.networkSecurityGroupName) ? null : json('{"id": "${resourceId(nsgResourceGroup, 'Microsoft.Network/networkSecurityGroups', item.networkSecurityGroupName)}"}')) : null routeTable: contains(item, 'routeTableName') ? (empty(item.routeTableName) ? null : json('{"id": "${resourceId('Microsoft.Network/routeTables', item.routeTableName)}"}')) : null serviceEndpoints: contains(item, 'serviceEndpoints') ? (empty(item.serviceEndpoints) ? null : item.serviceEndpoints) : null delegations: contains(item, 'delegations') ? (empty(item.delegations) ? null : item.delegations) : null diff --git a/arm/Microsoft.Network/virtualNetworks/readme.md b/arm/Microsoft.Network/virtualNetworks/readme.md index 7c5811cb68..4fe7f5e8bd 100644 --- a/arm/Microsoft.Network/virtualNetworks/readme.md +++ b/arm/Microsoft.Network/virtualNetworks/readme.md @@ -31,6 +31,7 @@ This template deploys a virtual network (vNet). | `name` | string | | | Required. The Virtual Network (vNet) Name. | | `roleAssignments` | array | `[]` | | 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' | | `subnets` | array | | | Required. An Array of subnets to deploy to the Virual Network. | +| `nsgResourceGroup` | string | `[resourceGroup().name]` | | Optional. Resource Group where NSGs are deployed, if different than VNET Resource Group. | | `tags` | object | `{object}` | | Optional. Tags of the resource. | | `virtualNetworkPeerings` | _[virtualNetworkPeerings](virtualNetworkPeerings/readme.md)_ array | `[]` | | Optional. Virtual Network Peerings configurations | | `workspaceId` | string | | | Optional. Resource ID of log analytics. | diff --git a/arm/Microsoft.RecoveryServices/vaults/.parameters/parameters.json b/arm/Microsoft.RecoveryServices/vaults/.parameters/parameters.json index a575657a6e..dd44b491a5 100644 --- a/arm/Microsoft.RecoveryServices/vaults/.parameters/parameters.json +++ b/arm/Microsoft.RecoveryServices/vaults/.parameters/parameters.json @@ -5,6 +5,12 @@ "name": { "value": "sxx-az-rsv-x-001" }, + "backupConfig": { + "value": { + "enhancedSecurityState": "Disabled", + "softDeleteFeatureState": "Disabled" + } + }, "backupPolicies": { "value": [ { diff --git a/arm/Microsoft.RecoveryServices/vaults/backupConfig/.bicep/nested_cuaId.bicep b/arm/Microsoft.RecoveryServices/vaults/backupConfig/.bicep/nested_cuaId.bicep new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/arm/Microsoft.RecoveryServices/vaults/backupConfig/.bicep/nested_cuaId.bicep @@ -0,0 +1 @@ + diff --git a/arm/Microsoft.RecoveryServices/vaults/backupConfig/deploy.bicep b/arm/Microsoft.RecoveryServices/vaults/backupConfig/deploy.bicep new file mode 100644 index 0000000000..aaa8464dc0 --- /dev/null +++ b/arm/Microsoft.RecoveryServices/vaults/backupConfig/deploy.bicep @@ -0,0 +1,81 @@ +@description('Required. Name of the Azure Recovery Service Vault') +param recoveryVaultName string + +@description('Optional. Name of the Azure Recovery Service Vault Backup Policy') +param name string = 'vaultconfig' + +@description('Optional. Enable this setting to protect hybrid backups against accidental deletes and add additional layer of authentication for critical operations.') +@allowed([ + 'Disabled' + 'Enabled' +]) +param enhancedSecurityState string = 'Enabled' + +@description('Optional. ResourceGuard Operation Requests') +param resourceGuardOperationRequests array = [] + +@description('Optional. Enable this setting to protect backup data for Azure VM, SQL Server in Azure VM and SAP HANA in Azure VM from accidental deletes') +@allowed([ + 'Disabled' + 'Enabled' +]) +param softDeleteFeatureState string = 'Enabled' + +@description('Optional. Storage type') +@allowed([ + 'GeoRedundant' + 'LocallyRedundant' + 'ReadAccessGeoZoneRedundant' + 'ZoneRedundant' +]) +param storageModelType string = 'GeoRedundant' + +@description('Optional. Storage type') +@allowed([ + 'GeoRedundant' + 'LocallyRedundant' + 'ReadAccessGeoZoneRedundant' + 'ZoneRedundant' +]) +param storageType string = 'GeoRedundant' + +@description('Optional. Once a machine is registered against a resource, the storageTypeState is always Locked.') +@allowed([ + 'Locked' + 'Unlocked' +]) +param storageTypeState string = 'Locked' + +@description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered') +param cuaId string = '' + +module pid_cuaId './.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) { + name: 'pid-${cuaId}' + params: {} +} + +resource rsv 'Microsoft.RecoveryServices/vaults@2021-08-01' existing = { + name: recoveryVaultName +} + +resource backupConfig 'Microsoft.RecoveryServices/vaults/backupconfig@2021-08-01' = { + name: name + parent: rsv + properties: { + enhancedSecurityState: enhancedSecurityState + resourceGuardOperationRequests: resourceGuardOperationRequests + softDeleteFeatureState: softDeleteFeatureState + storageModelType: storageModelType + storageType: storageType + storageTypeState: storageTypeState + } +} + +@description('The name of the backup config') +output backupConfigName string = backupConfig.name + +@description('The resource ID of the backup config') +output backupConfigResourceId string = backupConfig.id + +@description('The name of the resource group the backup config was created in.') +output backupConfigResourceGroup string = resourceGroup().name diff --git a/arm/Microsoft.RecoveryServices/vaults/backupConfig/readme.md b/arm/Microsoft.RecoveryServices/vaults/backupConfig/readme.md new file mode 100644 index 0000000000..530d35af21 --- /dev/null +++ b/arm/Microsoft.RecoveryServices/vaults/backupConfig/readme.md @@ -0,0 +1,35 @@ +# Recovery Services Vault Backup Config `[Microsoft.RecoveryServices/vaults/backupconfig]` + +This module deploys recovery services vault backup config. + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.RecoveryServices/vaults/backupconfig` | 2021-08-01 | + +## Parameters + +| Parameter Name | Type | Default Value | Possible Values | Description | +| :-- | :-- | :-- | :-- | :-- | +| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered | +| `enhancedSecurityState` | string | `Enabled` | `[Disabled, Enabled]` | Optional. Enable this setting to protect hybrid backups against accidental deletes and add additional layer of authentication for critical operations. | +| `name` | string | `vaultconfig` | | Optional. Name of the Azure Recovery Service Vault Backup Policy | +| `recoveryVaultName` | string | | | Required. Name of the Azure Recovery Service Vault | +| `resourceGuardOperationRequests` | array | `[]` | | Optional. ResourceGuard Operation Requests | +| `softDeleteFeatureState` | string | `Enabled` | `[Disabled, Enabled]` | Optional. Enable this setting to protect backup data for Azure VM, SQL Server in Azure VM and SAP HANA in Azure VM from accidental deletes | +| `storageModelType` | string | `GeoRedundant` | `[GeoRedundant, LocallyRedundant, ReadAccessGeoZoneRedundant, ZoneRedundant]` | Optional. Storage type | +| `storageType` | string | `GeoRedundant` | `[GeoRedundant, LocallyRedundant, ReadAccessGeoZoneRedundant, ZoneRedundant]` | Optional. Storage type | +| `storageTypeState` | string | `Locked` | `[Locked, Unlocked]` | Optional. Once a machine is registered against a resource, the storageTypeState is always Locked. | + +## Outputs + +| Output Name | Type | Description | +| :-- | :-- | :-- | +| `backupConfigName` | string | The name of the backup config | +| `backupConfigResourceGroup` | string | The name of the resource group the backup config was created in. | +| `backupConfigResourceId` | string | The resource ID of the backup config | + +## Template references + +- [Vaults/Backupconfig](https://docs.microsoft.com/en-us/azure/templates/Microsoft.RecoveryServices/2021-08-01/vaults/backupconfig) diff --git a/arm/Microsoft.RecoveryServices/vaults/backupPolicies/deploy.bicep b/arm/Microsoft.RecoveryServices/vaults/backupPolicies/deploy.bicep index 60596e5caf..de18d25358 100644 --- a/arm/Microsoft.RecoveryServices/vaults/backupPolicies/deploy.bicep +++ b/arm/Microsoft.RecoveryServices/vaults/backupPolicies/deploy.bicep @@ -1,5 +1,4 @@ @description('Required. Name of the Azure Recovery Service Vault') -@minLength(1) param recoveryVaultName string @description('Required. Name of the Azure Recovery Service Vault Backup Policy') @@ -29,8 +28,8 @@ resource backupPolicy 'Microsoft.RecoveryServices/vaults/backupPolicies@2021-08- @description('The name of the backup policy') output backupPolicyName string = backupPolicy.name -@description('The Resource ID of the backup policy') +@description('The resource ID of the backup policy') output backupPolicyResourceId string = backupPolicy.id -@description('The name of the Resource Group the backup policy was created in.') +@description('The name of the resource group the backup policy was created in.') output backupPolicyResourceGroup string = resourceGroup().name diff --git a/arm/Microsoft.RecoveryServices/vaults/backupPolicies/readme.md b/arm/Microsoft.RecoveryServices/vaults/backupPolicies/readme.md index 781229bbad..237b87fbfd 100644 --- a/arm/Microsoft.RecoveryServices/vaults/backupPolicies/readme.md +++ b/arm/Microsoft.RecoveryServices/vaults/backupPolicies/readme.md @@ -110,8 +110,8 @@ Object continaining the configuration for backup policies. It needs to be proper | Output Name | Type | Description | | :-- | :-- | :-- | | `backupPolicyName` | string | The name of the backup policy | -| `backupPolicyResourceGroup` | string | The name of the Resource Group the backup policy was created in. | -| `backupPolicyResourceId` | string | The Resource ID of the backup policy | +| `backupPolicyResourceGroup` | string | The name of the resource group the backup policy was created in. | +| `backupPolicyResourceId` | string | The resource ID of the backup policy | ## Template references diff --git a/arm/Microsoft.RecoveryServices/vaults/backupStorageConfig/deploy.bicep b/arm/Microsoft.RecoveryServices/vaults/backupStorageConfig/deploy.bicep index a22171776d..f8fa588a87 100644 --- a/arm/Microsoft.RecoveryServices/vaults/backupStorageConfig/deploy.bicep +++ b/arm/Microsoft.RecoveryServices/vaults/backupStorageConfig/deploy.bicep @@ -1,5 +1,4 @@ @description('Required. Name of the Azure Recovery Service Vault') -@minLength(1) param recoveryVaultName string @description('Optional. The name of the backup storage config') diff --git a/arm/Microsoft.RecoveryServices/vaults/deploy.bicep b/arm/Microsoft.RecoveryServices/vaults/deploy.bicep index 8ec2d1e4e7..866f57ad00 100644 --- a/arm/Microsoft.RecoveryServices/vaults/deploy.bicep +++ b/arm/Microsoft.RecoveryServices/vaults/deploy.bicep @@ -1,5 +1,4 @@ @description('Required. Name of the Azure Recovery Service Vault') -@minLength(1) param name string @description('Optional. The storage configuration for the Azure Recovery Service Vault') @@ -14,6 +13,9 @@ param location string = resourceGroup().location @description('Optional. List of all backup policies.') param backupPolicies array = [] +@description('Optional. The backup configuration.') +param backupConfig object = {} + @description('Optional. List of all protection containers.') @minLength(0) param protectionContainers array = [] @@ -170,6 +172,20 @@ module rsv_backupPolicies 'backupPolicies/deploy.bicep' = [for (backupPolicy, in } }] +module rsv_backupConfig 'backupConfig/deploy.bicep' = if (!empty(backupConfig)) { + name: '${uniqueString(deployment().name, location)}-RSV-BackupConfig' + params: { + recoveryVaultName: rsv.name + name: contains(backupConfig, 'name') ? backupConfig.name : 'vaultconfig' + enhancedSecurityState: contains(backupConfig, 'enhancedSecurityState') ? backupConfig.enhancedSecurityState : 'Enabled' + resourceGuardOperationRequests: contains(backupConfig, 'resourceGuardOperationRequests') ? backupConfig.resourceGuardOperationRequests : [] + softDeleteFeatureState: contains(backupConfig, 'softDeleteFeatureState') ? backupConfig.softDeleteFeatureState : 'Enabled' + storageModelType: contains(backupConfig, 'storageModelType') ? backupConfig.storageModelType : 'GeoRedundant' + storageType: contains(backupConfig, 'storageType') ? backupConfig.storageType : 'GeoRedundant' + storageTypeState: contains(backupConfig, 'storageTypeState') ? backupConfig.storageTypeState : 'Locked' + } +} + resource rsv_lock 'Microsoft.Authorization/locks@2016-09-01' = if (lock != 'NotSpecified') { name: '${rsv.name}-${lock}-lock' properties: { @@ -201,13 +217,13 @@ module rsv_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in rol } }] -@description('The resource ID of the Recovery Services Vault') +@description('The resource ID of the recovery services vault') output recoveryServicesVaultResourceId string = rsv.id -@description('The name of the Resource Group the Recovery Services Vault was created in') +@description('The name of the resource group the recovery services vault was created in') output recoveryServicesVaultResourceGroup string = resourceGroup().name -@description('The Name of the Recovery Services Vault') +@description('The Name of the recovery services vault') output recoveryServicesVaultName string = rsv.name @description('The principal ID of the system assigned identity.') diff --git a/arm/Microsoft.RecoveryServices/vaults/protectionContainers/deploy.bicep b/arm/Microsoft.RecoveryServices/vaults/protectionContainers/deploy.bicep index 5ba15da6e3..36d5c8aa0b 100644 --- a/arm/Microsoft.RecoveryServices/vaults/protectionContainers/deploy.bicep +++ b/arm/Microsoft.RecoveryServices/vaults/protectionContainers/deploy.bicep @@ -1,5 +1,4 @@ @description('Required. Name of the Azure Recovery Service Vault') -@minLength(1) param recoveryVaultName string @description('Required. Name of the Azure Recovery Service Vault Protection Container') diff --git a/arm/Microsoft.RecoveryServices/vaults/readme.md b/arm/Microsoft.RecoveryServices/vaults/readme.md index bef829c61f..78c7dfd2fd 100644 --- a/arm/Microsoft.RecoveryServices/vaults/readme.md +++ b/arm/Microsoft.RecoveryServices/vaults/readme.md @@ -10,6 +10,7 @@ This module deploys a recovery service vault. | `Microsoft.Authorization/roleAssignments` | 2020-04-01-preview | | `Microsoft.Insights/diagnosticSettings` | 2021-05-01-preview | | `Microsoft.RecoveryServices/vaults` | 2021-08-01 | +| `Microsoft.RecoveryServices/vaults/backupconfig` | 2021-08-01 | | `Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers` | 2021-08-01 | | `Microsoft.RecoveryServices/vaults/backupPolicies` | 2021-08-01 | | `Microsoft.RecoveryServices/vaults/backupstorageconfig` | 2021-08-01 | @@ -18,6 +19,7 @@ This module deploys a recovery service vault. | Parameter Name | Type | Default Value | Possible Values | Description | | :-- | :-- | :-- | :-- | :-- | +| `backupConfig` | _[backupConfig](backupConfig/readme.md)_ object | `{object}` | | Optional. The backup configuration. | | `backupPolicies` | _[backupPolicies](backupPolicies/readme.md)_ array | `[]` | | Optional. List of all backup policies. | | `backupStorageConfig` | _[backupStorageConfig](backupStorageConfig/readme.md)_ object | `{object}` | | Optional. The storage configuration for the Azure Recovery Service Vault | | `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered | @@ -346,9 +348,9 @@ You can specify multiple user assigned identities to a resource by providing add | Output Name | Type | Description | | :-- | :-- | :-- | -| `recoveryServicesVaultName` | string | The Name of the Recovery Services Vault | -| `recoveryServicesVaultResourceGroup` | string | The name of the Resource Group the Recovery Services Vault was created in | -| `recoveryServicesVaultResourceId` | string | The resource ID of the Recovery Services Vault | +| `recoveryServicesVaultName` | string | The Name of the recovery services vault | +| `recoveryServicesVaultResourceGroup` | string | The name of the resource group the recovery services vault was created in | +| `recoveryServicesVaultResourceId` | string | The resource ID of the recovery services vault | | `systemAssignedPrincipalId` | string | The principal ID of the system assigned identity. | ## Template references @@ -357,6 +359,7 @@ You can specify multiple user assigned identities to a resource by providing add - [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) - [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) - [Vaults](https://docs.microsoft.com/en-us/azure/templates/Microsoft.RecoveryServices/2021-08-01/vaults) +- [Vaults/Backupconfig](https://docs.microsoft.com/en-us/azure/templates/Microsoft.RecoveryServices/2021-08-01/vaults/backupconfig) - [Vaults/Backupfabrics/Protectioncontainers](https://docs.microsoft.com/en-us/azure/templates/Microsoft.RecoveryServices/2021-08-01/vaults/backupFabrics/protectionContainers) - [Vaults/Backuppolicies](https://docs.microsoft.com/en-us/azure/templates/Microsoft.RecoveryServices/2021-08-01/vaults/backupPolicies) - [Vaults/Backupstorageconfig](https://docs.microsoft.com/en-us/azure/templates/Microsoft.RecoveryServices/2021-08-01/vaults/backupstorageconfig) diff --git a/docs/wiki/Context.md b/docs/wiki/Context.md index 281bb43f13..0238798df0 100644 --- a/docs/wiki/Context.md +++ b/docs/wiki/Context.md @@ -118,14 +118,14 @@ Deploying resources by referencing their corresponding modules from source contr ## Where does this platform fit in? -The _CARML_ platform hosts a collection of [resource modules](./Modules) with the intend to cover as many Azure resources and their child-resources as possible. +The _CARML_ platform hosts a collection of [resource modules](./Modules.md) with the intend to cover as many Azure resources and their child-resources as possible. As such, users can use the modules as they are, alter them and or use them to deploy their environments. -To ensure the modules are valid and can perform the intended deployments, the repository comes with a [validation & test](./Testing) [pipeline](./Pipelines) for each module. If successful it will also publish them in one or multiple target locations. +To ensure the modules are valid and can perform the intended deployments, the repository comes with a [validation & test](./Testing.md) [pipeline](./Pipelines.md) for each module. If successful it will also publish them in one or multiple target locations. As such, _CARML_ covers the `bottom box` of the [deployment model](#what-is-the-intended-the-deployment-model) section and `Phase #1` & `Phase #2` of the [deployment flow](#what-is-the-intended-deployment-flow) section. Complete deployment flow filtered -As we want to enable any user of this repository's content to not only leverage its modules but actually also re-use the platform, the platform itself is set up so that you can plug it into your own environment with just a few basic steps described in the [Getting Started](./GettingStarted) section. You may choose to add or remove modules, define your own locations you want to publish to and as such create your own open- or inner-source library. +As we want to enable any user of this repository's content to not only leverage its modules but actually also re-use the platform, the platform itself is set up so that you can plug it into your own environment with just a few basic steps described in the [Getting Started](./GettingStarted.md) section. You may choose to add or remove modules, define your own locations you want to publish to and as such create your own open- or inner-source library. diff --git a/docs/wiki/ContributionGuide.md b/docs/wiki/ContributionGuide.md index b54a1600d2..e21b366657 100644 --- a/docs/wiki/ContributionGuide.md +++ b/docs/wiki/ContributionGuide.md @@ -13,13 +13,13 @@ This section outlines how you can contribute to the repository. # Set your environment up -The preferred method of contribution requires you to create your own fork and create pull requests into the source repository from there. To set the fork up, please follow the process described in the ['Getting Started'](./GettingStarted#Option-1-Use-it-as-a-basis-to-set-up-your-own-inner-source-project) section. +The preferred method of contribution requires you to create your own fork and create pull requests into the source repository from there. To set the fork up, please follow the process described in the ['Getting Started'](./GettingStarted.md#Option-1-Use-it-as-a-basis-to-set-up-your-own-inner-source-project) section. # How to contribute? You can contribute to the Wiki in different ways depending on your own interests, bugs you see or IP you want to add. -For starters it is highly recommended to consult and understand the ['Modules Design'](./ModulesDesign) section of the wiki. +For starters it is highly recommended to consult and understand the ['Modules Design'](./ModulesDesign.md) section of the wiki. How you proceed from here depends on your particular situation: @@ -36,4 +36,4 @@ To contribute to the modules, set your environment up, test the updated/added mo Status Badge -Please make sure to set your environment up and also consult the ['Pipeline Design'](./PipelinesDesign) and ['Pipeline Usage'](.\PipelinesUsage) sections. +Please make sure to set your environment up and also consult the ['Pipeline Design'](./PipelinesDesign.md) and ['Pipeline Usage'](./PipelinesUsage.md) sections. diff --git a/docs/wiki/GettingStarted.md b/docs/wiki/GettingStarted.md index 36e3896863..e6f9d89b43 100644 --- a/docs/wiki/GettingStarted.md +++ b/docs/wiki/GettingStarted.md @@ -117,7 +117,7 @@ Please refer to [this list][AzureNames] to check which services have a global sc ### Dependencies -As the modules we test often times have dependencies to other services, we created a pipeline to deploys several standard services like VirtualNetworks and KeyVaults (alongside dummy secrets) for the modules to use. This _dependency_ pipeline should be prepared and executed before you start running any pipelines on your own. In case you need to rename any services there (for example because a certain globally unique resource name was already taken) make sure to update any references to this name in the module parameter files. You can find further details about this pipeline [here](.\TestingDesign#Module-Dependencies). +As the modules we test often times have dependencies to other services, we created a pipeline to deploys several standard services like VirtualNetworks and KeyVaults (alongside dummy secrets) for the modules to use. This _dependency_ pipeline should be prepared and executed before you start running any pipelines on your own. In case you need to rename any services there (for example because a certain globally unique resource name was already taken) make sure to update any references to this name in the module parameter files. You can find further details about this pipeline [here](./TestingDesign.md#Module-Dependencies). ### GitHub-specific prerequisites @@ -173,7 +173,7 @@ In case you would like to simply contribute because you, for example, want to ad ## Parameter File Tokens -If you are forking or cloning the repository, you can use 'tokens' inside your parameter files. Tokens allow you to test deploying modules in your own environment (i.e. using tokens for your naming conventions), or apply other customizations to your resources (i.e. using your own subscription ID inside a Resource ID string). See details in the [Parameter File Tokens Design](./ParameterFileTokens). +If you are forking or cloning the repository, you can use 'tokens' inside your parameter files. Tokens allow you to test deploying modules in your own environment (i.e. using tokens for your naming conventions), or apply other customizations to your resources (i.e. using your own subscription ID inside a Resource ID string). See details in the [Parameter File Tokens Design](./ParameterFileTokens.md). The repository contains a [Settings.json](https://github.com/Azure/ResourceModules/blob/main/settings.json) that enables you to define local tokens and store them in source control. The token format is a `name` and `value` pair as shown in the following example: @@ -203,7 +203,7 @@ Once the Key Vault is deployed, you'll notice that the Key Vault name in Azure w > The token prefix `<<` and suffix `>>` in the above example are also configurable in the [Settings.json](https://github.com/Azure/ResourceModules/blob/main/settings.json) file. They are however the default used in the CARML main repository. --- -Note: There are default tokens that can be enabled on any resource that leverages the [GitHub specific prerequisites](GettingStarted#github-specific-prerequisites) secrets. +Note: There are default tokens that can be enabled on any resource that leverages the [GitHub specific prerequisites](GettingStarted.md#github-specific-prerequisites) secrets. - `<>`: Will point to the Azure subscription. - `<>`: Will point to the Azure an Azure Management Group. diff --git a/docs/wiki/Home.md b/docs/wiki/Home.md index c900a946b7..4d2e2ae0fa 100644 --- a/docs/wiki/Home.md +++ b/docs/wiki/Home.md @@ -4,27 +4,27 @@ The objective of this repository is to provide a template library that can be re This wiki describes the content of this repository, the modules, pipelines, possible options on how to use them and how to contribute to this project. -If you're unfamiliar with Infrastructure as Code, or wonder how you can use the contents of this repository in your deployments please check out the [context](./Context) section of this wiki. +If you're unfamiliar with Infrastructure as Code, or wonder how you can use the contents of this repository in your deployments please check out the [context](./Context.md) section of this wiki. ### _Navigation_ -- [Context](./Context) - - [Infrastructure as Code](./Context#infrastructure-as-code-iac) - - [Where does this platform fit in?](./Context#where-does-this-platform-fit-in) -- [Getting Started](./GettingStarted) - - [General prerequisites](./GettingStarted#General-prerequisites) - - [Where to start](./GettingStarted#Where-to-start) -- [Modules](./Modules) - - [Design](./ModulesDesign) - - [Usage](./ModulesUsage) -- [Testing](./Testing) - - [Design](./TestingDesign) - - [Usage](./TestingUsage) -- [Pipelines](./Pipelines) - - [Design](./PipelinesDesign) - - [Usage](./PipelinesUsage) -- [Contribution Guide](./ContributionGuide) -- [Known Issues](./KnownIssues) +- [Context](./Context.md) + - [Infrastructure as Code](./Context.md#infrastructure-as-code-iac) + - [Where does this platform fit in?](./Context.md#where-does-this-platform-fit-in.md) +- [Getting Started](./GettingStarted.md) + - [General prerequisites](./GettingStarted.md#General-prerequisites.md) + - [Where to start](./GettingStarted.md#Where-to-start.md) +- [Modules](./Modules.md) + - [Design](./ModulesDesign.md) + - [Usage](./ModulesUsage.md) +- [Testing](./Testing.md) + - [Design](./TestingDesign.md) + - [Usage](./TestingUsage.md) +- [Pipelines](./Pipelines.md) + - [Design](./PipelinesDesign.md) + - [Usage](./PipelinesUsage.md) +- [Contribution Guide](./ContributionGuide.md) +- [Known Issues](./KnownIssues.md) # Scope @@ -33,7 +33,7 @@ Following you can find an abstract overview of everything in- and out-of-scope o ## In Scope - **Modules:** Rich library of resource modules - the foundation for workload or entire environments deployments - **Platform:** Pipelines to validate modules & publish to those that pass to a location of your choice. Available with GitHub Workflows. -- **Documentation:** A rich documentation of best practices on [module](./Modules) design, the [platforms](./Context) and its [context](./Context), [testing](./Testing) and [pipelines](./Pipelines) +- **Documentation:** A rich documentation of best practices on [module](./Modules.md) design, the [platforms](./Context.md) and its [context](./Context.md), [testing](./Testing.md) and [pipelines](./Pipelines.md) ## Out of Scope - **Orchestration:** Orchestrated solutions such as workloads or entire environments intended for production environments diff --git a/docs/wiki/Modules.md b/docs/wiki/Modules.md index 8f47239754..2b0bbad7d8 100644 --- a/docs/wiki/Modules.md +++ b/docs/wiki/Modules.md @@ -6,12 +6,12 @@ This section and its sub-sections give you an overview of the principals the mod ### _Navigation_ -- [Module Design](./ModulesDesign) - - [General guidelines](./ModulesDesign#general-guidelines) - - [File & folder structure](./ModulesDesign#file--folder-structure) - - [Bicep template guidelines](./ModulesDesign#bicep-template-guidelines) -- [Module Usage](./ModulesUsage) - - [Deploy local template](./ModulesUsage#deploy-local-template) - - [Deploy remote template](./ModulesUsage#deploy-remote-template) +- [Module Design](./ModulesDesign.md) + - [General guidelines](./ModulesDesign.md#general-guidelines) + - [File & folder structure](./ModulesDesign.md#file--folder-structure) + - [Bicep template guidelines](./ModulesDesign.md#bicep-template-guidelines) +- [Module Usage](./ModulesUsage.md) + - [Deploy local template](./ModulesUsage.md#deploy-local-template) + - [Deploy remote template](./ModulesUsage.md#deploy-remote-template) --- diff --git a/docs/wiki/ModulesDesign.md b/docs/wiki/ModulesDesign.md index 273caa453e..67b87ab93e 100644 --- a/docs/wiki/ModulesDesign.md +++ b/docs/wiki/ModulesDesign.md @@ -144,7 +144,7 @@ Microsoft.Sql In this folder we recommend to place the child-resource-template alongside a ReadMe (that can be generated via the `.github\workflows\scripts\Set-ModuleReadMe.ps1` script) and optionally further nest additional folders for it's child-resources. -The parent template should reference all it's direct child-templates to allow for an end to end deployment experience while allowing any user to also reference 'just' the child-resource itself. In the case of the SQL-server example the server template would reference the database module and encapsulate it it in a loop to allow for the deployment of n-amount of databases. For example +The parent template should reference all it's direct child-templates to allow for an end-to-end deployment experience while allowing any user to also reference 'just' the child-resource itself. In the case of the SQL-server example the server template would reference the database module and encapsulate it it in a loop to allow for the deployment of n-amount of databases. For example ```Bicep @description('Optional. The databases to create in the server') @@ -476,7 +476,7 @@ Within a bicep file, follow the following conventions: ``` - Bicep `modules`: - camel_Snake_Case, i.e `resourceGroup_rbac` ? - - File name for nested module is structured as follows: `nested_.bicep` i.e: + - Filename for nested module is structured as follows: `nested_.bicep` i.e: - `nested_rbac.bicep` @@ -493,7 +493,7 @@ Within a bicep file, follow the following conventions: # ReadMe -Each module must come with a ReadMe markdown file that outlines what the module contains and 'how' it can be used. +Each module must come with a ReadMe Markdown file that outlines what the module contains and 'how' it can be used. It primary components are - A title with a reference to the primary resource (for example KeyVault `[Microsoft.KeyVault/vaults]`) - A description diff --git a/docs/wiki/ParameterFileTokens.md b/docs/wiki/ParameterFileTokens.md index 12523b7acc..2004a2576b 100644 --- a/docs/wiki/ParameterFileTokens.md +++ b/docs/wiki/ParameterFileTokens.md @@ -30,7 +30,7 @@ There are (2) Token types that can be applied on a Parameter File: #### 1. Default Tokens (Environment Variables) [Default] -These are tokens constructed from Environment Variables, which are defined in the Workflow (Pipeline). Review [Getting Started - GitHub specific prerequisites](./GettingStarted) for more information on these Environment Variables. +These are tokens constructed from Environment Variables, which are defined in the Workflow (Pipeline). Review [Getting Started - GitHub specific prerequisites](./GettingStarted.md) for more information on these Environment Variables. #### 2. Local Custom Tokens (Source Control) [Optional] diff --git a/docs/wiki/Pipelines.md b/docs/wiki/Pipelines.md index 5a4a421ec7..540dc80467 100644 --- a/docs/wiki/Pipelines.md +++ b/docs/wiki/Pipelines.md @@ -8,7 +8,7 @@ This section and its sub-sections give you an overview of the principals the pip ### _Navigation_ -- [Pipelines Design](./PipelinesDesign) -- [Pipelines Usage](./PipelinesUsage) +- [Pipelines Design](./PipelinesDesign.md) +- [Pipelines Usage](./PipelinesUsage.md) --- diff --git a/docs/wiki/PipelinesDesign.md b/docs/wiki/PipelinesDesign.md index 87e787d57d..4d00b20b09 100644 --- a/docs/wiki/PipelinesDesign.md +++ b/docs/wiki/PipelinesDesign.md @@ -76,7 +76,7 @@ The validation phase performs all test outside of a test deployment. This includ #### Static module validation -This static validation executes the tests documented in the [testing](./Testing) section. Without diving into to much detail, we test aspects like a proper ReadMe documentation, a proper module folder structure, a minimum number of refresh of the leveraged of API versions and the like. +This static validation executes the tests documented in the [testing](./Testing.md) section. Without diving into to much detail, we test aspects like a proper ReadMe documentation, a proper module folder structure, a minimum number of refresh of the leveraged of API versions and the like. #### Simulated deployment validation @@ -159,7 +159,7 @@ Dynamic parameters that do not need to be hardcoded in the parameter file, and t For example, some modules require referencing Azure resources with the Resource ID. This ID typically contains the `subscriptionId` in the format of `/subscriptions/<>/...`. This task substitutes the `<>` with the correct value, based on the different token types. -Please review the Parameter File Tokens [Design](./ParameterFileTokens) for more details on the different token types and how you can use them to remove hardcoded values from your parameter files. +Please review the Parameter File Tokens [Design](./ParameterFileTokens.md) for more details on the different token types and how you can use them to remove hardcoded values from your parameter files. --- @@ -173,7 +173,7 @@ Outside of the previously described platform pipelines we implemented several ad ## Dependencies pipeline -As the modules we test often times have dependencies to other services, we created a pipeline to deploys several standard services like VirtualNetworks and KeyVaults (alongside dummy secrets) for the modules to use. This _dependency_ pipeline should be prepared and executed before you start running any pipelines on your own. In case you need to rename any services there (for example because a certain globally unique resource name was already taken) make sure to update any references to this name in the module parameter files. You can find further details about this pipeline [here](.\TestingDesign#Module-Dependencies). +As the modules we test often times have dependencies to other services, we created a pipeline to deploys several standard services like VirtualNetworks and KeyVaults (alongside dummy secrets) for the modules to use. This _dependency_ pipeline should be prepared and executed before you start running any pipelines on your own. In case you need to rename any services there (for example because a certain globally unique resource name was already taken) make sure to update any references to this name in the module parameter files. You can find further details about this pipeline [here](./TestingDesign.md#Module-Dependencies). ### Dependencies pipeline inputs diff --git a/docs/wiki/PipelinesUsage.md b/docs/wiki/PipelinesUsage.md index 45e652c650..8f9a6f1594 100644 --- a/docs/wiki/PipelinesUsage.md +++ b/docs/wiki/PipelinesUsage.md @@ -19,14 +19,14 @@ This section gives you an overview of how to interact with the platform pipeline When working with this platform's pipelines it is important to understand first which pipelines serve which purpose, when they are triggered and how you can use them to test your modules. -As described in the [Pipelines Design](./PipelinesDesign) section we offer the following pipelines: +As described in the [Pipelines Design](./PipelinesDesign.md) section we offer the following pipelines: | Pipeline | Target | Trigger | Notes | | - | - | - | - | -| [Module Pipelines](./PipelinesDesign#module-pipelines) | Module | Changes to [module\|workflow] files in branch [main\|master] or manual | Used to test & publish modules. This is the most common pipeline you will interact with when working on modules. | -| [Dependencies pipeline](./PipelinesDesign#dependencies-pipeline) | All required dependency resources | Manual | Deploys resources we reference in the module tests. Should be run once before testing modules. | -| [ReadMe pipeline](./PipelinesDesign#readme-pipeline) | `README.md` in `` & `/arm` | Changes to [template files] in branch [main\|master] | Keeps the target ReadMe files aligned with the modules in the repository. | -| [Wiki pipeline](./PipelinesDesign#wiki-pipeline) | Wiki | Changes in [docs/wiki] in branch [main\|master] | Keeps the Wiki-repository in sync with the wiki folder in the modules repository | +| [Module Pipelines](./PipelinesDesign.md#module-pipelines) | Module | Changes to [module\|workflow] files in branch [main\|master] or manual | Used to test & publish modules. This is the most common pipeline you will interact with when working on modules. | +| [Dependencies pipeline](./PipelinesDesign.md#dependencies-pipeline) | All required dependency resources | Manual | Deploys resources we reference in the module tests. Should be run once before testing modules. | +| [ReadMe pipeline](./PipelinesDesign.md#readme-pipeline) | `README.md` in `` & `/arm` | Changes to [template files] in branch [main\|master] | Keeps the target ReadMe files aligned with the modules in the repository. | +| [Wiki pipeline](./PipelinesDesign.md#wiki-pipeline) | Wiki | Changes in [docs/wiki] in branch [main\|master] | Keeps the Wiki-repository in sync with the wiki folder in the modules repository | --- @@ -49,7 +49,7 @@ To validate any updates you did to a module template you can perform the followi Once the pipeline concluded, it will either be in a green (success) or red (failed) state, depending on how the module performed. -If you open the pipeline's run, you should be able to investigate the logs and investigate the execution. In case any of the [validation](./PipelinesDesign#Validate) steps failed, the pipeline should give you detailed information of any error. In some cases in which Pester tests failed, you may only see the failed test and need to `expand` the error message. How this looks like depends on the [DevOps platform](#devops-tool-specific-considerations) you use. +If you open the pipeline's run, you should be able to investigate the logs and investigate the execution. In case any of the [validation](./PipelinesDesign.md#Validate) steps failed, the pipeline should give you detailed information of any error. In some cases in which Pester tests failed, you may only see the failed test and need to `expand` the error message. How this looks like depends on the [DevOps platform](#devops-tool-specific-considerations) you use. ## Operate the dependency pipeline @@ -57,13 +57,13 @@ As described previously, the dependency pipeline must be triggered manually and Triggering the pipeline is as easy as navigating to it in your corresponding DevOps tool and running the pipeline. No additional steps or input parameters are required. -> **Note:** While operating the dependency pipeline is simple, make sure to set it up in the way it is described [here](./GettingStarted#Dependencies). Especially the globally unique names must be accounted for, before executing the pipeline. +> **Note:** While operating the dependency pipeline is simple, make sure to set it up in the way it is described [here](./GettingStarted.md#Dependencies). Especially the globally unique names must be accounted for, before executing the pipeline. -Depending on what you want to test in your module pipeline, you may want to add additional dependencies to your dependency pipeline. If so, make sure to add an additional parameter file for each service you require under `utilities/pipelines/dependencies`. Once done, you just need to add the deployment to the pipeline itself in the correct location in the pipeline. The different deployment waves are documented [here](./TestingDesign#module-dependencies). The implementation depends on the [DevOps tool](#devops-tool-specific-considerations) you're using. +Depending on what you want to test in your module pipeline, you may want to add additional dependencies to your dependency pipeline. If so, make sure to add an additional parameter file for each service you require under `utilities/pipelines/dependencies`. Once done, you just need to add the deployment to the pipeline itself in the correct location in the pipeline. The different deployment waves are documented [here](./TestingDesign.md#module-dependencies). The implementation depends on the [DevOps tool](#devops-tool-specific-considerations) you're using. ## Add a new module pipeline -To add a new module pipeline we recommend to create a copy of a currently existing module pipeline and adjust all module-specific properties documented [here](./PipelinesDesign#component-workflows). The registration of the pipeline will differ depending on the DevOps tool you're using. For further information, please review the [DevOps-Tool-specific guidance](#devops-tool-specific-guidance) below. +To add a new module pipeline we recommend to create a copy of a currently existing module pipeline and adjust all module-specific properties documented [here](./PipelinesDesign.md#component-workflows). The registration of the pipeline will differ depending on the DevOps tool you're using. For further information, please review the [DevOps-Tool-specific guidance](#devops-tool-specific-guidance) below. --- @@ -86,7 +86,7 @@ then select the pipeline of your choice from the list on the left, followed by ' Run workflow Depending on the pipeline you selected you may have additional input parameters you can provide aside from the branch: -- [Module pipeline](./TestingDesign#module-pipeline-inputs) inputs +- [Module pipeline](./TestingDesign.md#module-pipeline-inputs) inputs ### Register a pipeline diff --git a/docs/wiki/Testing.md b/docs/wiki/Testing.md index 7383346162..4d9a0dbc66 100644 --- a/docs/wiki/Testing.md +++ b/docs/wiki/Testing.md @@ -6,11 +6,11 @@ This section and its sub-sections give you an overview of the principles the tes ### _Navigation_ -- [Testing Design](./TestingDesign) - - [Approach](./TestingDesign#approach) - - [API version validation](./TestingDesign#api-version-validation) - - [Template validation](./TestingDesign#template-validation) - - [Deployment validation](./TestingDesign#deployment-validation) -- [Testing Usage](./TestingUsage) +- [Testing Design](./TestingDesign.md) + - [Approach](./TestingDesign.md#approach) + - [API version validation](./TestingDesign.md#api-version-validation) + - [Template validation](./TestingDesign.md#template-validation) + - [Deployment validation](./TestingDesign.md#deployment-validation) +- [Testing Usage](./TestingUsage.md) --- diff --git a/docs/wiki/TestingDesign.md b/docs/wiki/TestingDesign.md index 33eccf42f8..5b09fbab31 100644 --- a/docs/wiki/TestingDesign.md +++ b/docs/wiki/TestingDesign.md @@ -81,9 +81,9 @@ The template validation tests execute a dry-run with each parameter file provide # Deployment validation -If all other tests passed, the deployment tests are the ultimate module validation. Using the available & configured parameter files for a module, each is deployed to Azure (in parallel) and verifies if the deployment works end to end. +If all other tests passed, the deployment tests are the ultimate module validation. Using the available & configured parameter files for a module, each is deployed to Azure (in parallel) and verifies if the deployment works end-to-end. -Most of the resources are deleted by default after their deployment, to keep costs down and to be able to retest resource modules from scratch in the next run. However, the removal step can be skipped in case further investigation on the deployed resource is needed. For further details, please refer to the (./PipelinesUsage) section. +Most of the resources are deleted by default after their deployment, to keep costs down and to be able to retest resource modules from scratch in the next run. However, the removal step can be skipped in case further investigation on the deployed resource is needed. For further details, please refer to the (./PipelinesUsage.md) section. This happens using the `.github/actions/templates/validateModuleDeploy/scripts/Test-TemplateWithParameterFile.ps1` script. diff --git a/docs/wiki/TestingUsage.md b/docs/wiki/TestingUsage.md index 8f3ac509ef..7cb753b281 100644 --- a/docs/wiki/TestingUsage.md +++ b/docs/wiki/TestingUsage.md @@ -73,7 +73,7 @@ $TestModuleLocallyInput = @{ ## Handling Parameters that require or contain a value that should be tokenized -The following scenarios are common to when to use a token value in the parameter file. Refer to [Parameter File Tokens Design](./ParameterFileTokens) for more details. +The following scenarios are common to when to use a token value in the parameter file. Refer to [Parameter File Tokens Design](./ParameterFileTokens.md) for more details. - Scenarios where resources have dependencies on other resources, which may require to be linked using `resourceId` references. diff --git a/docs/wiki/_Sidebar.md b/docs/wiki/_Sidebar.md index 93fb2cee55..3e90ad12a4 100644 --- a/docs/wiki/_Sidebar.md +++ b/docs/wiki/_Sidebar.md @@ -1,17 +1,17 @@ # Wiki content -- [Home](./Home) -- [Context](./Context) -- [Getting Started](./GettingStarted) -- [Modules](./Modules) - - [Design](./ModulesDesign) - - [Usage](./ModulesUsage) -- [Testing](./Testing) - - [Design](./TestingDesign) - - [Usage](./TestingUsage) -- [Pipelines](./Pipelines) - - [Design](./PipelinesDesign) - - [Parameter File Tokens](./ParameterFileTokens) - - [Usage](./PipelinesUsage) -- [Contribution Guide](./ContributionGuide) -- [Known Issues](./KnownIssues) +- [Home](./Home.md) +- [Context](./Context.md) +- [Getting Started](./GettingStarted.md) +- [Modules](./Modules.md) + - [Design](./ModulesDesign.md) + - [Usage](./ModulesUsage.md) +- [Testing](./Testing.md) + - [Design](./TestingDesign.md) + - [Usage](./TestingUsage.md) +- [Pipelines](./Pipelines.md) + - [Design](./PipelinesDesign.md) + - [Parameter File Tokens](./ParameterFileTokens.md) + - [Usage](./PipelinesUsage.md) +- [Contribution Guide](./ContributionGuide.md) +- [Known Issues](./KnownIssues.md) From 0e73e6a77ef9290ad4b0fd15c13b235f3b4f806c Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Tue, 7 Dec 2021 16:39:25 +1100 Subject: [PATCH 05/15] removed ignore file --- .lycheeignore | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 .lycheeignore diff --git a/.lycheeignore b/.lycheeignore deleted file mode 100644 index 62214a16db..0000000000 --- a/.lycheeignore +++ /dev/null @@ -1,8 +0,0 @@ -https://foo.psd1/ -file:///github -https://mystorageaccount.blob.core.windows.net -https://mykeyvault.vault.azure.net -https://www.powershellgallery.com -https://github.com/myProject -http://validURLToConfigLocation/ -https://myCustomDependencyLocation/ From bbe54a6f1ee799907a4ada50ad52c485b7b14e3b Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Wed, 8 Dec 2021 10:00:37 +1100 Subject: [PATCH 06/15] Users/ahmad/links (#15) --- .github/workflows/linter.yml | 15 +---------- .github/workflows/platform.linkcheck.yml | 33 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 14 deletions(-) create mode 100644 .github/workflows/platform.linkcheck.yml diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 7fbd58562d..1284dbd68c 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -1,6 +1,6 @@ name: '.Platform: Linter' -on: workflow_dispatch +on: [pull_request] jobs: build: @@ -27,16 +27,3 @@ jobs: DEFAULT_BRANCH: ${{ github.base_ref }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} FILTER_REGEX_EXCLUDE: '[global.module.tests.ps1|Get\-ModulesAsMarkdownTable.ps1]' - - - name: Link Checker - if: always() - id: checker - uses: lycheeverse/lychee-action@v1.1.1 - with: - args: --verbose --no-progress **/docs/**/*.md --accept 200,201,403,429 - env: - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - - - name: Link Checker Results - if: always() - run: exit ${{ steps.checker.outputs.exit_code }} diff --git a/.github/workflows/platform.linkcheck.yml b/.github/workflows/platform.linkcheck.yml new file mode 100644 index 0000000000..1af93b9dd8 --- /dev/null +++ b/.github/workflows/platform.linkcheck.yml @@ -0,0 +1,33 @@ +name: '.Platform: Links Check' + +on: + push: + branches: + - main + paths: + - 'docs/wiki/**' + workflow_dispatch: + +jobs: + build: + name: Linter + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v2 + with: + # Full git history is needed to get a proper list of changed files within `super-linter` + fetch-depth: 0 + + - name: Link Checker + if: always() + id: checker + uses: lycheeverse/lychee-action@v1.1.1 + with: + args: --verbose --no-progress **/docs/**/*.md --accept 200,201,403,429 + env: + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + + - name: Link Checker Results + if: always() + run: exit ${{ steps.checker.outputs.exit_code }} From 11d50baa7e49731af61128d6f9d3b0fadc9c8274 Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Wed, 8 Dec 2021 10:22:26 +1100 Subject: [PATCH 07/15] Users/ahmad/links (#16) --- .github/workflows/platform.linkcheck.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/platform.linkcheck.yml b/.github/workflows/platform.linkcheck.yml index 1af93b9dd8..e134d292d6 100644 --- a/.github/workflows/platform.linkcheck.yml +++ b/.github/workflows/platform.linkcheck.yml @@ -1,16 +1,16 @@ -name: '.Platform: Links Check' +name: '.Platform: Broken Links Check' on: - push: + workflow_dispatch: + pull_request: branches: - main paths: - 'docs/wiki/**' - workflow_dispatch: jobs: build: - name: Linter + name: Broken Links Check runs-on: ubuntu-latest steps: - name: Checkout Code @@ -19,7 +19,7 @@ jobs: # Full git history is needed to get a proper list of changed files within `super-linter` fetch-depth: 0 - - name: Link Checker + - name: Check Broken Links if: always() id: checker uses: lycheeverse/lychee-action@v1.1.1 @@ -28,6 +28,6 @@ jobs: env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - - name: Link Checker Results + - name: Publish Results if: always() run: exit ${{ steps.checker.outputs.exit_code }} From 9a0bd4190cffac8869728f896f7d51dc7d88d3f2 Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Wed, 8 Dec 2021 11:33:38 +1100 Subject: [PATCH 08/15] Merge from Fork (Link Check) (#764) --- .github/workflows/linter.yml | 15 +---------- .github/workflows/platform.linkcheck.yml | 33 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 14 deletions(-) create mode 100644 .github/workflows/platform.linkcheck.yml diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 7fbd58562d..1284dbd68c 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -1,6 +1,6 @@ name: '.Platform: Linter' -on: workflow_dispatch +on: [pull_request] jobs: build: @@ -27,16 +27,3 @@ jobs: DEFAULT_BRANCH: ${{ github.base_ref }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} FILTER_REGEX_EXCLUDE: '[global.module.tests.ps1|Get\-ModulesAsMarkdownTable.ps1]' - - - name: Link Checker - if: always() - id: checker - uses: lycheeverse/lychee-action@v1.1.1 - with: - args: --verbose --no-progress **/docs/**/*.md --accept 200,201,403,429 - env: - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - - - name: Link Checker Results - if: always() - run: exit ${{ steps.checker.outputs.exit_code }} diff --git a/.github/workflows/platform.linkcheck.yml b/.github/workflows/platform.linkcheck.yml new file mode 100644 index 0000000000..e134d292d6 --- /dev/null +++ b/.github/workflows/platform.linkcheck.yml @@ -0,0 +1,33 @@ +name: '.Platform: Broken Links Check' + +on: + workflow_dispatch: + pull_request: + branches: + - main + paths: + - 'docs/wiki/**' + +jobs: + build: + name: Broken Links Check + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v2 + with: + # Full git history is needed to get a proper list of changed files within `super-linter` + fetch-depth: 0 + + - name: Check Broken Links + if: always() + id: checker + uses: lycheeverse/lychee-action@v1.1.1 + with: + args: --verbose --no-progress **/docs/**/*.md --accept 200,201,403,429 + env: + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + + - name: Publish Results + if: always() + run: exit ${{ steps.checker.outputs.exit_code }} From 6caab064d65d3c1cd5abd6186a240b43a0382f67 Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Fri, 10 Dec 2021 08:47:05 +1100 Subject: [PATCH 09/15] Users/ahmad/links (#18) --- .../workflows/ms.network.firewallpolicies.yml | 180 ++++++++++++++ .github/workflows/platform.linkcheck.yml | 4 +- .lycheeignore | 9 + README.md | 1 + .../service/portalsettings/readme.md | 2 +- arm/Microsoft.ApiManagement/service/readme.md | 8 +- arm/Microsoft.Automanage/accounts/readme.md | 3 +- .../.parameters/parameters.json | 158 ++++++------ .../accounts/readme.md | 6 +- .../virtualMachineScaleSets/readme.md | 4 +- .../virtualMachines/readme.md | 2 +- arm/Microsoft.EventGrid/topics/readme.md | 6 +- arm/Microsoft.HealthBot/healthBots/readme.md | 2 +- arm/Microsoft.KeyVault/vaults/readme.md | 6 +- .../workspaces/readme.md | 6 +- .../registrationDefinitions/readme.md | 3 +- .../azureFirewalls/deploy.bicep | 4 +- .../azureFirewalls/readme.md | 4 +- .../.bicep/nested_cuaId.bicep | 1 + .../.parameters/min.parameters.json | 9 + .../.parameters/parameters.json | 49 ++++ .../firewallPolicies/deploy.bicep | 189 ++++++++++++++ .../firewallPolicies/readme.md | 86 +++++++ .../.bicep/nested_cuaId.bicep | 1 + .../ruleCollectionGroups/deploy.bicep | 41 ++++ .../ruleCollectionGroups/readme.md | 46 ++++ .../ruleGroups/.bicep/nested_cuaId.bicep | 1 + .../firewallPolicies/ruleGroups/deploy.bicep | 41 ++++ .../firewallPolicies/ruleGroups/readme.md | 46 ++++ .../virtualNetworks/readme.md | 6 +- .../workspaces/.parameters/parameters.json | 15 ++ .../workspaces/deploy.bicep | 65 +++++ .../workspaces/readme.md | 9 + .../namespaces/queues/readme.md | 2 +- arm/Microsoft.ServiceBus/namespaces/readme.md | 8 +- .../servers/.parameters/parameters.json | 7 +- .../servers/databases/deploy.bicep | 81 ++++++ arm/Microsoft.Sql/servers/databases/readme.md | 9 + arm/Microsoft.Sql/servers/deploy.bicep | 7 + arm/Microsoft.Sql/servers/readme.md | 2 + .../.parameters/parameters.json | 35 +++ .../storageAccounts/blobServices/deploy.bicep | 69 ++++++ .../storageAccounts/blobServices/readme.md | 9 + .../storageAccounts/deploy.bicep | 75 ++++++ .../storageAccounts/fileServices/deploy.bicep | 69 ++++++ .../storageAccounts/fileServices/readme.md | 9 + .../queueServices/deploy.bicep | 69 ++++++ .../queueServices/queues/deploy.bicep | 4 +- .../queueServices/queues/readme.md | 4 +- .../storageAccounts/queueServices/readme.md | 10 + .../storageAccounts/readme.md | 11 +- .../tableServices/deploy.bicep | 69 ++++++ .../storageAccounts/tableServices/readme.md | 10 +- .../imageTemplates/readme.md | 2 +- arm/Microsoft.Web/sites/config/readme.md | 2 +- arm/Microsoft.Web/sites/readme.md | 2 +- arm/README.md | 1 + docs/wiki/Context.md | 6 +- docs/wiki/ContributionGuide.md | 6 +- docs/wiki/GettingStarted.md | 8 +- docs/wiki/Home.md | 38 +-- docs/wiki/Modules.md | 14 +- docs/wiki/ModulesDesign.md | 232 ++++++++++-------- docs/wiki/ParameterFileTokens.md | 2 +- docs/wiki/Pipelines.md | 4 +- docs/wiki/PipelinesDesign.md | 6 +- docs/wiki/PipelinesUsage.md | 20 +- docs/wiki/Testing.md | 12 +- docs/wiki/TestingDesign.md | 2 +- docs/wiki/TestingUsage.md | 2 +- docs/wiki/_Sidebar.md | 30 +-- .../resourceRemoval/Remove-DeployedModule.ps1 | 12 + .../helper/Remove-AutomationAccount.ps1 | 124 ++++++++++ utilities/tools/Set-ModuleReadMe.ps1 | 26 +- 74 files changed, 1811 insertions(+), 312 deletions(-) create mode 100644 .github/workflows/ms.network.firewallpolicies.yml create mode 100644 .lycheeignore create mode 100644 arm/Microsoft.Network/firewallPolicies/.bicep/nested_cuaId.bicep create mode 100644 arm/Microsoft.Network/firewallPolicies/.parameters/min.parameters.json create mode 100644 arm/Microsoft.Network/firewallPolicies/.parameters/parameters.json create mode 100644 arm/Microsoft.Network/firewallPolicies/deploy.bicep create mode 100644 arm/Microsoft.Network/firewallPolicies/readme.md create mode 100644 arm/Microsoft.Network/firewallPolicies/ruleCollectionGroups/.bicep/nested_cuaId.bicep create mode 100644 arm/Microsoft.Network/firewallPolicies/ruleCollectionGroups/deploy.bicep create mode 100644 arm/Microsoft.Network/firewallPolicies/ruleCollectionGroups/readme.md create mode 100644 arm/Microsoft.Network/firewallPolicies/ruleGroups/.bicep/nested_cuaId.bicep create mode 100644 arm/Microsoft.Network/firewallPolicies/ruleGroups/deploy.bicep create mode 100644 arm/Microsoft.Network/firewallPolicies/ruleGroups/readme.md create mode 100644 utilities/pipelines/resourceRemoval/helper/Remove-AutomationAccount.ps1 diff --git a/.github/workflows/ms.network.firewallpolicies.yml b/.github/workflows/ms.network.firewallpolicies.yml new file mode 100644 index 0000000000..424b2aec2d --- /dev/null +++ b/.github/workflows/ms.network.firewallpolicies.yml @@ -0,0 +1,180 @@ +name: 'Network: FirewallPolicies' + +on: + workflow_dispatch: + inputs: + removeDeployment: + type: boolean + description: 'Remove deployed module' + required: false + default: 'true' + versioningOption: + type: choice + description: 'The mode to handle the version increments [major|minor|patch]' + required: false + default: 'patch' + options: + - major + - minor + - patch + customVersion: + description: 'Custom version to apply. Used only if higher than latest' + required: false + default: '0.0.1' + push: + branches: + - main + paths: + - '.github/actions/templates/**' + - '.github/workflows/ms.network.firewallpolicies.yml' + - 'arm/Microsoft.Network/firewallPolicies/**' + - '!*/**/readme.md' + +env: + modulePath: 'arm/Microsoft.Network/firewallPolicies' + workflowPath: '.github/workflows/ms.network.firewallpolicies.yml' + AZURE_CREDENTIALS: ${{ secrets.AZURE_CREDENTIALS }} + ARM_SUBSCRIPTION_ID: '${{ secrets.ARM_SUBSCRIPTION_ID }}' + ARM_MGMTGROUP_ID: '${{ secrets.ARM_MGMTGROUP_ID }}' + ARM_TENANT_ID: '${{ secrets.ARM_TENANT_ID }}' + DEPLOYMENT_SP_ID: '${{ secrets.DEPLOYMENT_SP_ID }}' + +jobs: + ############################ + # SET INPUT PARAMETERS # + ############################ + job_set_workflow_param: + runs-on: ubuntu-20.04 + name: 'Set input parameters to output variables' + steps: + - name: 'Checkout' + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: 'Set input parameters' + id: get-workflow-param + uses: ./.github/actions/templates/getWorkflowInput + with: + workflowPath: '${{ env.workflowPath}}' + outputs: + removeDeployment: ${{ steps.get-workflow-param.outputs.removeDeployment }} + versioningOption: ${{ steps.get-workflow-param.outputs.versioningOption }} + customVersion: ${{ steps.get-workflow-param.outputs.customVersion }} + + ################## + # UNIT TESTS # + ################## + # Global tests + # ------------ + job_tests_module_global: + runs-on: ubuntu-20.04 + name: 'Run global module tests' + steps: + - name: 'Checkout' + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: 'Test module' + uses: ./.github/actions/templates/validateModuleGeneral + with: + modulePath: '${{ env.modulePath }}' + + # Global API tests + # ---------------- + job_tests_module_global_api: + runs-on: ubuntu-20.04 + name: 'Run global API module tests' + steps: + - name: 'Checkout' + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: 'Test module' + uses: ./.github/actions/templates/validateModuleApis + with: + modulePath: '${{ env.modulePath }}' + + ########################### + # Deployment module tests # + ########################### + job_module_deploy_validation: + runs-on: ubuntu-20.04 + name: 'Run deployment validation module tests' + needs: + - job_set_workflow_param + - job_tests_module_global + - job_tests_module_global_api + strategy: + fail-fast: false + matrix: + parameterFilePaths: ['min.parameters.json', 'parameters.json'] + steps: + - name: 'Checkout' + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Set environment variables + uses: deep-mm/set-variables@v1.0 + with: + # Name of variable file + variableFileName: 'variables.module' # Don't write .json here + # ----------- # + ## Dry Run ## + # ----------- # + - name: 'Test module with parameter file [${{ matrix.parameterFilePaths }}]' + uses: ./.github/actions/templates/validateModuleDeploy + with: + templateFilePath: '${{ env.modulePath }}/deploy.bicep' + parameterFilePath: '${{ env.modulePath }}/.parameters/${{ matrix.parameterFilePaths }}' + location: '${{ env.defaultLocation }}' + resourceGroupName: '${{ env.resourceGroupName }}' + subscriptionId: '${{ secrets.ARM_SUBSCRIPTION_ID }}' + managementGroupId: '${{ secrets.ARM_MGMTGROUP_ID }}' + # ------------------- # + ## Deploy & Remove ## + # ------------------- # + - name: 'Deploy module with parameter file [${{ matrix.parameterFilePaths }}]' + id: step_deploy + uses: ./.github/actions/templates/deployModule + with: + templateFilePath: '${{ env.modulePath }}/deploy.bicep' + parameterFilePath: '${{ env.modulePath }}/.parameters/${{ matrix.parameterFilePaths }}' + location: '${{ env.defaultLocation }}' + resourceGroupName: '${{ env.resourceGroupName }}' + subscriptionId: '${{ secrets.ARM_SUBSCRIPTION_ID }}' + managementGroupId: '${{ secrets.ARM_MGMTGROUP_ID }}' + removeDeployment: '${{ needs.job_set_workflow_param.outputs.removeDeployment }}' + + ############### + # PUBLISH # + ############### + job_publish_module: + name: 'Publish module' + if: contains(fromJson('["refs/heads/main", "refs/heads/master"]'), github.ref) + runs-on: ubuntu-20.04 + needs: + - job_set_workflow_param + - job_module_deploy_validation + steps: + - name: 'Checkout' + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Set environment variables + uses: deep-mm/set-variables@v1.0 + with: + # Name of variable file + variableFileName: 'variables.module' # Don't write .json here + - name: 'Publish module' + uses: ./.github/actions/templates/publishModule + with: + templateFilePath: '${{ env.modulePath }}/deploy.bicep' + versioningOption: '${{ needs.job_set_workflow_param.outputs.versioningOption }}' + customVersion: '${{ needs.job_set_workflow_param.outputs.customVersion }}' + templateSpecsRGName: '${{ env.templateSpecsRGName }}' + templateSpecsRGLocation: '${{ env.templateSpecsRGLocation }}' + templateSpecsDescription: '${{ env.templateSpecsDescription }}' + templateSpecsDoPublish: '${{ env.templateSpecsDoPublish }}' + bicepRegistryName: '${{ env.bicepRegistryName }}' + bicepRegistryRGName: '${{ env.bicepRegistryRGName }}' + bicepRegistryDoPublish: '${{ env.bicepRegistryDoPublish }}' diff --git a/.github/workflows/platform.linkcheck.yml b/.github/workflows/platform.linkcheck.yml index e134d292d6..9a0e8ac807 100644 --- a/.github/workflows/platform.linkcheck.yml +++ b/.github/workflows/platform.linkcheck.yml @@ -6,7 +6,7 @@ on: branches: - main paths: - - 'docs/wiki/**' + - '**/*.md' jobs: build: @@ -24,7 +24,7 @@ jobs: id: checker uses: lycheeverse/lychee-action@v1.1.1 with: - args: --verbose --no-progress **/docs/**/*.md --accept 200,201,403,429 + args: --verbose --no-progress **/*.md --accept 200,201,403,429,401 --exclude-file .lycheeignore env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/.lycheeignore b/.lycheeignore new file mode 100644 index 0000000000..cb8f72b8ec --- /dev/null +++ b/.lycheeignore @@ -0,0 +1,9 @@ +https://foo.psd1/ +file:///github +https://mystorageaccount.blob.core.windows.net +https://mykeyvault.vault.azure.net +https://www.powershellgallery.com +https://github.com/myProject +http://validurltoconfiglocation/ +https://mycustomdependencylocation/ +http://tools.ietf.org/html/rfc6749#section-3.2 diff --git a/README.md b/README.md index 8bc041300b..c354d104cc 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,7 @@ This repository includes a collection of advanced and curated Modules consisting | [Management Groups](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Management/managementGroups) | [!['Management: ManagementGroups'](https://github.com/Azure/ResourceModules/actions/workflows/ms.management.managementgroups.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.management.managementgroups.yml) | | [Metric Alerts](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Insights/metricAlerts) | [!['Insights: MetricAlerts'](https://github.com/Azure/ResourceModules/actions/workflows/ms.insights.metricalerts.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.insights.metricalerts.yml) | | [NAT Gateways](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/natGateways) | [!['Network: NatGateways'](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.natgateways.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.natgateways.yml) | +| [Network Firewall Policies](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/firewallPolicies) | [!['Network: FirewallPolicies'](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.firewallpolicies.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.firewallpolicies.yml) | | [Network Security Groups](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/networkSecurityGroups) | [!['Network: NetworkSecurityGroups'](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.networksecuritygroups.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.networksecuritygroups.yml) | | [Network Watchers](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/networkWatchers) | [!['Network: NetworkWatchers'](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.networkwatchers.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.networkwatchers.yml) | | [Policy Assignments](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Authorization/policyAssignments) | [!['Authorization: PolicyAssignments'](https://github.com/Azure/ResourceModules/actions/workflows/ms.authorization.policyassignments.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.authorization.policyassignments.yml) | diff --git a/arm/Microsoft.ApiManagement/service/portalsettings/readme.md b/arm/Microsoft.ApiManagement/service/portalsettings/readme.md index fe3e8f578d..f6fb9eb86e 100644 --- a/arm/Microsoft.ApiManagement/service/portalsettings/readme.md +++ b/arm/Microsoft.ApiManagement/service/portalsettings/readme.md @@ -27,4 +27,4 @@ This module deploys API Management Service Portal Setting. ## Template references -- [Service/Portalsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2019-12-01/service/portalsettings) +- ['service/portalsettings' Parent Documentation](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/service) diff --git a/arm/Microsoft.ApiManagement/service/readme.md b/arm/Microsoft.ApiManagement/service/readme.md index f8ccc6a603..36768ae46d 100644 --- a/arm/Microsoft.ApiManagement/service/readme.md +++ b/arm/Microsoft.ApiManagement/service/readme.md @@ -151,6 +151,10 @@ You can specify multiple user assigned identities to a resource by providing add ## Template references +- ['service/portalsettings' Parent Documentation](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/service) +- [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) +- [Locks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2016-09-01/locks) +- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) - [Service](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2020-12-01/service) - [Service/Apis](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2020-06-01-preview/service/apis) - [Service/Apis/Policies](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2020-06-01-preview/service/apis/policies) @@ -161,11 +165,7 @@ You can specify multiple user assigned identities to a resource by providing add - [Service/Identityproviders](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2020-06-01-preview/service/identityProviders) - [Service/Namedvalues](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2020-06-01-preview/service/namedValues) - [Service/Policies](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2020-06-01-preview/service/policies) -- [Service/Portalsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2019-12-01/service/portalsettings) - [Service/Products](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2020-06-01-preview/service/products) - [Service/Products/Apis](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2020-06-01-preview/service/products/apis) - [Service/Products/Groups](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2020-06-01-preview/service/products/groups) - [Service/Subscriptions](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2020-06-01-preview/service/subscriptions) -- [Locks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2016-09-01/locks) -- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) -- [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) diff --git a/arm/Microsoft.Automanage/accounts/readme.md b/arm/Microsoft.Automanage/accounts/readme.md index 8260e8b2fa..c6f108b5cf 100644 --- a/arm/Microsoft.Automanage/accounts/readme.md +++ b/arm/Microsoft.Automanage/accounts/readme.md @@ -32,5 +32,4 @@ This module deploys an Automanage account and associates VM with it. ## Template references -- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) -- [Accounts](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Automanage/2020-06-30-preview/accounts) +- [Define resources with Bicep and ARM templates](https://docs.microsoft.com/en-us/azure/templates) diff --git a/arm/Microsoft.Automation/automationAccounts/.parameters/parameters.json b/arm/Microsoft.Automation/automationAccounts/.parameters/parameters.json index 8eb92bdbc8..4284a511cc 100644 --- a/arm/Microsoft.Automation/automationAccounts/.parameters/parameters.json +++ b/arm/Microsoft.Automation/automationAccounts/.parameters/parameters.json @@ -76,85 +76,85 @@ } ] }, - // "linkedWorkspaceId": { - // "value": "/subscriptions/<>/resourcegroups/test-rg/providers/Microsoft.OperationalInsights/workspaces/test-law" - // }, - // "gallerySolutions": { - // "value": [ - // "Updates" - // ] - // }, - // "softwareUpdateConfigurations": { - // "value": [ - // { - // "name": "Windows_ZeroDay", - // "frequency": "Month", - // "operatingSystem": "Windows", - // "rebootSetting": "IfRequired", - // "scopeByTags": { - // "Update": [ - // "Automatic-Wave1" - // ] - // }, - // "maintenanceWindow": "PT4H", - // "updateClassifications": [ - // "Critical", - // "Security", - // "UpdateRollup", - // "FeaturePack", - // "ServicePack", - // "Definition", - // "Tools", - // "Updates" - // ], - // "includeUpdates": [ - // "654321" - // ], - // "excludeUpdates": [ - // "123456" - // ], - // "interval": 1, - // "monthlyOccurrences": [ - // { - // "occurrence": 3, - // "day": "Friday" - // } - // ], - // "startTime": "22:00" - // }, - // { - // "name": "Linux_ZeroDay", - // "frequency": "OneTime", - // "operatingSystem": "Linux", - // "rebootSetting": "IfRequired", - // "maintenanceWindow": "PT4H", - // "updateClassifications": [ - // "Critical", - // "Security", - // "Other" - // ], - // "includeUpdates": [ - // "kernel" - // ], - // "excludeUpdates": [ - // "icacls" - // ], - // "startTime": "2021-12-31T06:00" - // } - // ] - // }, - // "privateEndpoints": { - // "value": [ - // { - // "subnetResourceId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/adp-sxx-az-vnet-x-001/subnets/sxx-az-subnet-x-005-privateEndpoints", - // "service": "Webhook" - // }, - // { - // "subnetResourceId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/adp-sxx-az-vnet-x-001/subnets/sxx-az-subnet-x-005-privateEndpoints", - // "service": "DSCAndHybridWorker" - // } - // ] - // }, + "linkedWorkspaceId": { + "value": "/subscriptions/<>/resourcegroups/validation-rg/providers/microsoft.operationalinsights/workspaces/adp-sxx-az-law-x-001" + }, + "gallerySolutions": { + "value": [ + "Updates" + ] + }, + "softwareUpdateConfigurations": { + "value": [ + { + "name": "Windows_ZeroDay", + "frequency": "Month", + "operatingSystem": "Windows", + "rebootSetting": "IfRequired", + "scopeByTags": { + "Update": [ + "Automatic-Wave1" + ] + }, + "maintenanceWindow": "PT4H", + "updateClassifications": [ + "Critical", + "Security", + "UpdateRollup", + "FeaturePack", + "ServicePack", + "Definition", + "Tools", + "Updates" + ], + "includeUpdates": [ + "654321" + ], + "excludeUpdates": [ + "123456" + ], + "interval": 1, + "monthlyOccurrences": [ + { + "occurrence": 3, + "day": "Friday" + } + ], + "startTime": "22:00" + }, + { + "name": "Linux_ZeroDay", + "frequency": "OneTime", + "operatingSystem": "Linux", + "rebootSetting": "IfRequired", + "maintenanceWindow": "PT4H", + "updateClassifications": [ + "Critical", + "Security", + "Other" + ], + "includeUpdates": [ + "kernel" + ], + "excludeUpdates": [ + "icacls" + ], + "startTime": "2021-12-31T06:00" + } + ] + }, + "privateEndpoints": { + "value": [ + { + "subnetResourceId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/adp-sxx-az-vnet-x-001/subnets/sxx-az-subnet-x-005-privateEndpoints", + "service": "Webhook" + }, + { + "subnetResourceId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/adp-sxx-az-vnet-x-001/subnets/sxx-az-subnet-x-005-privateEndpoints", + "service": "DSCAndHybridWorker" + } + ] + }, "systemAssignedIdentity": { "value": true }, diff --git a/arm/Microsoft.CognitiveServices/accounts/readme.md b/arm/Microsoft.CognitiveServices/accounts/readme.md index af27e495d6..39266f085c 100644 --- a/arm/Microsoft.CognitiveServices/accounts/readme.md +++ b/arm/Microsoft.CognitiveServices/accounts/readme.md @@ -200,9 +200,9 @@ You can specify multiple user assigned identities to a resource by providing add ## Template references -- [Locks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2016-09-01/locks) -- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) - [Accounts](https://docs.microsoft.com/en-us/azure/templates/Microsoft.CognitiveServices/2017-04-18/accounts) - [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) -- [Privateendpoints](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-05-01/privateEndpoints) +- [Locks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2016-09-01/locks) +- [Privateendpoints](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/privateEndpoints) - [Privateendpoints/Privatednszonegroups](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-02-01/privateEndpoints/privateDnsZoneGroups) +- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) diff --git a/arm/Microsoft.Compute/virtualMachineScaleSets/readme.md b/arm/Microsoft.Compute/virtualMachineScaleSets/readme.md index 691dc568e6..b6c47d8e92 100644 --- a/arm/Microsoft.Compute/virtualMachineScaleSets/readme.md +++ b/arm/Microsoft.Compute/virtualMachineScaleSets/readme.md @@ -258,9 +258,9 @@ Only for OSType Windows "enabled": true, "settings": { "EncryptionOperation": "EnableEncryption", - "KeyVaultURL": "https://devopsbaseline.vault.azure.net/", + "KeyVaultURL": "https://mykeyvault.vault.azure.net/", "KeyVaultResourceId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.KeyVault/vaults/adp-sxx-az-kv-x-001", - "KeyEncryptionKeyURL": "https://devopsbaseline.vault.azure.net/keys/keyEncryptionKey/3e13110def0d4a26ac38341c73c059bb", + "KeyEncryptionKeyURL": "https://mykeyvault.vault.azure.net/keys/keyEncryptionKey/3e13110def0d4a26ac38341c73c059bb", "KekVaultResourceId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.KeyVault/vaults/adp-sxx-az-kv-x-001", "KeyEncryptionAlgorithm": "RSA-OAEP", "VolumeType": "All", diff --git a/arm/Microsoft.Compute/virtualMachines/readme.md b/arm/Microsoft.Compute/virtualMachines/readme.md index 5b2abb2edf..1f09345c98 100644 --- a/arm/Microsoft.Compute/virtualMachines/readme.md +++ b/arm/Microsoft.Compute/virtualMachines/readme.md @@ -293,7 +293,7 @@ The field `nicSuffix` and `subnetId` are mandatory. If `enablePublicIP` is set t "domainJoinSettings": { "value": { "domainName": "contoso.com", - "domainJoinUser": "domainJoinUser@contoso.com", + "domainJoinUser": "test.user@testcompany.com", "domainJoinOU": "OU=testOU; DC=contoso; DC=com", "domainJoinRestart": true, "domainJoinOptions": 3 diff --git a/arm/Microsoft.EventGrid/topics/readme.md b/arm/Microsoft.EventGrid/topics/readme.md index dedb4e9184..9d9611da7e 100644 --- a/arm/Microsoft.EventGrid/topics/readme.md +++ b/arm/Microsoft.EventGrid/topics/readme.md @@ -119,9 +119,9 @@ Tag names and tag values can be provided as needed. A tag can be left without a ## Template references +- [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) - [Locks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2016-09-01/locks) +- [Privateendpoints](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/privateEndpoints) +- [Privateendpoints/Privatednszonegroups](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-02-01/privateEndpoints/privateDnsZoneGroups) - [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) - [Topics](https://docs.microsoft.com/en-us/azure/templates/Microsoft.EventGrid/2020-06-01/topics) -- [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) -- [Privateendpoints](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-05-01/privateEndpoints) -- [Privateendpoints/Privatednszonegroups](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-02-01/privateEndpoints/privateDnsZoneGroups) diff --git a/arm/Microsoft.HealthBot/healthBots/readme.md b/arm/Microsoft.HealthBot/healthBots/readme.md index da0612ab4a..60f5b17dbb 100644 --- a/arm/Microsoft.HealthBot/healthBots/readme.md +++ b/arm/Microsoft.HealthBot/healthBots/readme.md @@ -71,6 +71,6 @@ Tag names and tag values can be provided as needed. A tag can be left without a ## Template references +- [Define resources with Bicep and ARM templates](https://docs.microsoft.com/en-us/azure/templates) - [Locks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2016-09-01/locks) - [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) -- [Healthbots](https://docs.microsoft.com/en-us/azure/templates/Microsoft.HealthBot/2020-12-08/healthBots) diff --git a/arm/Microsoft.KeyVault/vaults/readme.md b/arm/Microsoft.KeyVault/vaults/readme.md index 4412b189f8..fff57bff3e 100644 --- a/arm/Microsoft.KeyVault/vaults/readme.md +++ b/arm/Microsoft.KeyVault/vaults/readme.md @@ -186,12 +186,12 @@ To use Private Endpoint the following dependencies must be deployed: ## Template references +- [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) - [Locks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2016-09-01/locks) +- [Privateendpoints](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/privateEndpoints) +- [Privateendpoints/Privatednszonegroups](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-02-01/privateEndpoints/privateDnsZoneGroups) - [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) -- [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) - [Vaults](https://docs.microsoft.com/en-us/azure/templates/Microsoft.KeyVault/2019-09-01/vaults) - [Vaults/Accesspolicies](https://docs.microsoft.com/en-us/azure/templates/Microsoft.KeyVault/2021-06-01-preview/vaults/accessPolicies) - [Vaults/Keys](https://docs.microsoft.com/en-us/azure/templates/Microsoft.KeyVault/2019-09-01/vaults/keys) - [Vaults/Secrets](https://docs.microsoft.com/en-us/azure/templates/Microsoft.KeyVault/2019-09-01/vaults/secrets) -- [Privateendpoints](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-05-01/privateEndpoints) -- [Privateendpoints/Privatednszonegroups](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-02-01/privateEndpoints/privateDnsZoneGroups) diff --git a/arm/Microsoft.MachineLearningServices/workspaces/readme.md b/arm/Microsoft.MachineLearningServices/workspaces/readme.md index c8d247b622..1611babfda 100644 --- a/arm/Microsoft.MachineLearningServices/workspaces/readme.md +++ b/arm/Microsoft.MachineLearningServices/workspaces/readme.md @@ -126,9 +126,9 @@ To use Private Endpoint the following dependencies must be deployed: ## Template references +- [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) - [Locks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2016-09-01/locks) +- [Privateendpoints](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/privateEndpoints) +- [Privateendpoints/Privatednszonegroups](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-02-01/privateEndpoints/privateDnsZoneGroups) - [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) -- [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) - [Workspaces](https://docs.microsoft.com/en-us/azure/templates/Microsoft.MachineLearningServices/2021-04-01/workspaces) -- [Privateendpoints](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-05-01/privateEndpoints) -- [Privateendpoints/Privatednszonegroups](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-02-01/privateEndpoints/privateDnsZoneGroups) diff --git a/arm/Microsoft.ManagedServices/registrationDefinitions/readme.md b/arm/Microsoft.ManagedServices/registrationDefinitions/readme.md index f8f5cf7221..ec82f66d1a 100644 --- a/arm/Microsoft.ManagedServices/registrationDefinitions/readme.md +++ b/arm/Microsoft.ManagedServices/registrationDefinitions/readme.md @@ -118,5 +118,4 @@ There are a couple of limitations that you should be aware of with Lighthouse: ## Template references -- [Registrationassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ManagedServices/2019-09-01/registrationAssignments) -- [Registrationdefinitions](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ManagedServices/2019-09-01/registrationDefinitions) +- [Define resources with Bicep and ARM templates](https://docs.microsoft.com/en-us/azure/templates) diff --git a/arm/Microsoft.Network/azureFirewalls/deploy.bicep b/arm/Microsoft.Network/azureFirewalls/deploy.bicep index bca8a54621..15301cd15a 100644 --- a/arm/Microsoft.Network/azureFirewalls/deploy.bicep +++ b/arm/Microsoft.Network/azureFirewalls/deploy.bicep @@ -74,7 +74,7 @@ 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 Automation Account resource.') +@description('Optional. Tags of the Azure Firewall resource.') param tags object = {} @description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered') @@ -188,7 +188,7 @@ resource azureFirewallPip_diagnosticSettings 'Microsoft.Insights/diagnosticSetti scope: azureFirewallPip } -resource azureFirewall 'Microsoft.Network/azureFirewalls@2021-02-01' = { +resource azureFirewall 'Microsoft.Network/azureFirewalls@2021-03-01' = { name: name location: location zones: length(availabilityZones) == 0 ? null : availabilityZones diff --git a/arm/Microsoft.Network/azureFirewalls/readme.md b/arm/Microsoft.Network/azureFirewalls/readme.md index 3faeb9743a..4e03e4cc3b 100644 --- a/arm/Microsoft.Network/azureFirewalls/readme.md +++ b/arm/Microsoft.Network/azureFirewalls/readme.md @@ -9,7 +9,7 @@ This module deploys a firewall. | `Microsoft.Authorization/locks` | 2016-09-01 | | `Microsoft.Authorization/roleAssignments` | 2020-04-01-preview | | `Microsoft.Insights/diagnosticSettings` | 2021-05-01-preview | -| `Microsoft.Network/azureFirewalls` | 2021-02-01 | +| `Microsoft.Network/azureFirewalls` | 2021-03-01 | | `Microsoft.Network/publicIPAddresses` | 2021-02-01 | ## Parameters @@ -103,5 +103,5 @@ The `networkRuleCollections` parameter accepts a JSON Array of AzureFirewallNetw - [Locks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2016-09-01/locks) - [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) - [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) -- [Azurefirewalls](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-02-01/azureFirewalls) +- [Azurefirewalls](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-03-01/azureFirewalls) - [Publicipaddresses](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-02-01/publicIPAddresses) diff --git a/arm/Microsoft.Network/firewallPolicies/.bicep/nested_cuaId.bicep b/arm/Microsoft.Network/firewallPolicies/.bicep/nested_cuaId.bicep new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/arm/Microsoft.Network/firewallPolicies/.bicep/nested_cuaId.bicep @@ -0,0 +1 @@ + diff --git a/arm/Microsoft.Network/firewallPolicies/.parameters/min.parameters.json b/arm/Microsoft.Network/firewallPolicies/.parameters/min.parameters.json new file mode 100644 index 0000000000..93d66698ea --- /dev/null +++ b/arm/Microsoft.Network/firewallPolicies/.parameters/min.parameters.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "name": { + "value": "sxx-az-fwpol-x-001" + } + } +} diff --git a/arm/Microsoft.Network/firewallPolicies/.parameters/parameters.json b/arm/Microsoft.Network/firewallPolicies/.parameters/parameters.json new file mode 100644 index 0000000000..a3254fca0e --- /dev/null +++ b/arm/Microsoft.Network/firewallPolicies/.parameters/parameters.json @@ -0,0 +1,49 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "name": { + "value": "sxx-az-fwpol-x-002" + }, + "ruleCollectionGroups": { + "value": [ + { + "name": "sxx-rule-001", + "priority": 5000, + "ruleCollections": [ + { + "name": "collection002", + "priority": 5555, + "action": { + "type": "Allow" + }, + "rules": [ + { + "name": "rule002", + "ipProtocols": [ + "TCP", + "UDP" + ], + "destinationPorts": [ + "80" + ], + "sourceAddresses": [ + "*" + ], + "sourceIpGroups": [], + "ruleType": "NetworkRule", + "destinationIpGroups": [], + "destinationAddresses": [ + "*" + ], + "destinationFqdns": [] + } + ], + "ruleCollectionType": "FirewallPolicyFilterRuleCollection" + } + ] + } + ] + } + } +} diff --git a/arm/Microsoft.Network/firewallPolicies/deploy.bicep b/arm/Microsoft.Network/firewallPolicies/deploy.bicep new file mode 100644 index 0000000000..9de4789a19 --- /dev/null +++ b/arm/Microsoft.Network/firewallPolicies/deploy.bicep @@ -0,0 +1,189 @@ +@description('Required. Name of the Firewall Policy.') +param name string + +@description('Optional. Location for all resources.') +param location string = resourceGroup().location + +@description('Optional. Tags of the Firewall policy resource.') +param tags object = {} + +@description('Optional. Enables system assigned managed identity on the resource.') +param systemAssignedIdentity bool = false + +@description('Optional. The ID(s) to assign to the resource.') +param userAssignedIdentities object = {} + +@description('Optional. Resource ID of the base policy.') +param basePolicyResourceId string = '' + +@description('Optional. Enable DNS Proxy on Firewalls attached to the Firewall Policy.') +param enableProxy bool = false + +@description('Optional. FQDNs in Network Rules are supported when set to true.') +param requireProxyForNetworkRules bool = false + +@description('Optional. List of Custom DNS Servers.') +param servers array = [] + +@description('Optional. A flag to indicate if the insights are enabled on the policy.') +param insightsIsEnabled bool = false + +@description('Optional. Default Log Analytics Resource ID for Firewall Policy Insights.') +param defaultWorkspaceId string = '' + +@description('Optional. List of workspaces for Firewall Policy Insights.') +param workspaces array = [] + +@description('Optional. Number of days the insights should be enabled on the policy.') +param retentionDays int = 365 + +@description('Optional. List of rules for traffic to bypass.') +param bypassTrafficSettings array = [] + +@description('Optional. List of specific signatures states.') +param signatureOverrides array = [] + +@description('Optional. The configuring of intrusion detection.') +@allowed([ + 'Alert' + 'Deny' + 'Off' +]) +param mode string = 'Off' + +@description('Optional. Tier of Firewall Policy.') +@allowed([ + 'Premium' + 'Standard' +]) +param tier string = 'Standard' + +@description('Optional. List of private IP addresses/IP address ranges to not be SNAT.') +param privateRanges array = [] + +@description('Optional. The operation mode for Threat Intel.') +@allowed([ + 'Alert' + 'Deny' + 'Off' +]) +param threatIntelMode string = 'Off' + +@description('Optional. List of FQDNs for the ThreatIntel Allowlist.') +param fqdns array = [] + +@description('Optional. List of IP addresses for the ThreatIntel Allowlist.') +param ipAddresses array = [] + +@description('Optional. Secret Id of (base-64 encoded unencrypted pfx) Secret or Certificate object stored in KeyVault. ') +param keyVaultSecretId string = '' + +@description('Optional. Name of the CA certificate.') +param certificateName string = '' + +@description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered') +param cuaId string = '' + +@description('Optional. Rule collection groups.') +param ruleCollectionGroups array = [] + +@description('Optional. Rule groups.') +param ruleGroups array = [] + +var identityType = systemAssignedIdentity ? (!empty(userAssignedIdentities) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') : (!empty(userAssignedIdentities) ? 'UserAssigned' : 'None') + +var identity = identityType != 'None' ? { + type: identityType + userAssignedIdentities: !empty(userAssignedIdentities) ? userAssignedIdentities : null +} : null + +module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) { + name: 'pid-${cuaId}' + params: {} +} + +resource firewallPolicy 'Microsoft.Network/firewallPolicies@2021-03-01' = { + name: name + location: location + tags: tags + identity: identity + properties: { + basePolicy: !empty(basePolicyResourceId) ? { + id: basePolicyResourceId + } : null + dnsSettings: enableProxy ? { + enableProxy: enableProxy + requireProxyForNetworkRules: requireProxyForNetworkRules + servers: servers + } : null + insights: insightsIsEnabled ? { + isEnabled: insightsIsEnabled + logAnalyticsResources: { + defaultWorkspaceId: { + id: !empty(defaultWorkspaceId) ? defaultWorkspaceId : null + } + workspaces: !empty(workspaces) ? workspaces : null + } + retentionDays: retentionDays + } : null + intrusionDetection: (mode != 'Off') ? { + configuration: { + bypassTrafficSettings: !empty(bypassTrafficSettings) ? bypassTrafficSettings : null + signatureOverrides: !empty(signatureOverrides) ? signatureOverrides : null + } + mode: mode + } : null + sku: { + tier: tier + } + snat: !empty(privateRanges) ? { + privateRanges: privateRanges + } : null + threatIntelMode: threatIntelMode + threatIntelWhitelist: { + fqdns: fqdns + ipAddresses: ipAddresses + } + transportSecurity: (!empty(keyVaultSecretId) || !empty(certificateName)) ? { + certificateAuthority: { + keyVaultSecretId: !empty(keyVaultSecretId) ? keyVaultSecretId : null + name: !empty(certificateName) ? certificateName : null + } + } : null + } +} + +module firewallPolicy_ruleCollectionGroups 'ruleCollectionGroups/deploy.bicep' = [for (ruleCollectionGroup, index) in ruleCollectionGroups: { + name: '${uniqueString(deployment().name, location)}-firewallPolicy_ruleCollectionGroups-${index}' + params: { + firewallPolicyName: firewallPolicy.name + name: ruleCollectionGroup.name + priority: ruleCollectionGroup.priority + ruleCollections: ruleCollectionGroup.ruleCollections + } + dependsOn: [ + firewallPolicy + ] +}] + +module firewallPolicy_ruleGroups 'ruleGroups/deploy.bicep' = [for (ruleGroup, index) in ruleGroups: { + name: '${uniqueString(deployment().name, location)}-firewallPolicy_ruleGroups-${index}' + params: { + firewallPolicyName: firewallPolicy.name + name: ruleGroup.name + priority: ruleGroup.priority + rules: ruleGroup.rules + } + dependsOn: [ + firewallPolicy + ] +}] + +@description('The name of the deployed firewall policy') +output firewallPolicyName string = firewallPolicy.name + +@description('The resource ID of the deployed firewall policy') +output firewallPolicyResourceId string = firewallPolicy.id + +@description('The resource group of the deployed firewall policy') +output firewallPolicyResourceGroup string = resourceGroup().name diff --git a/arm/Microsoft.Network/firewallPolicies/readme.md b/arm/Microsoft.Network/firewallPolicies/readme.md new file mode 100644 index 0000000000..b73761e0e2 --- /dev/null +++ b/arm/Microsoft.Network/firewallPolicies/readme.md @@ -0,0 +1,86 @@ +# Network Firewall Policies `[Microsoft.Network/firewallPolicies]` + +This module deploys Network Firewall Policies. + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Network/firewallPolicies` | 2021-03-01 | +| `Microsoft.Network/firewallPolicies/ruleCollectionGroups` | 2021-03-01 | +| `Microsoft.Network/firewallPolicies/ruleGroups` | 2020-04-01 | + +## Parameters + +| Parameter Name | Type | Default Value | Possible Values | Description | +| :-- | :-- | :-- | :-- | :-- | +| `basePolicyResourceId` | string | | | Optional. Resource ID of the base policy. | +| `bypassTrafficSettings` | array | `[]` | | Optional. List of rules for traffic to bypass. | +| `certificateName` | string | | | Optional. Name of the CA certificate. | +| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered | +| `defaultWorkspaceId` | string | | | Optional. Default Log Analytics Resource ID for Firewall Policy Insights. | +| `enableProxy` | bool | | | Optional. Enable DNS Proxy on Firewalls attached to the Firewall Policy. | +| `fqdns` | array | `[]` | | Optional. List of FQDNs for the ThreatIntel Allowlist. | +| `insightsIsEnabled ` | bool | | | Optional. A flag to indicate if the insights are enabled on the policy. | +| `ipAddresses` | array | `[]` | | Optional. List of IP addresses for the ThreatIntel Allowlist. | +| `keyVaultSecretId` | string | | | Optional. Secret Id of (base-64 encoded unencrypted pfx) Secret or Certificate object stored in KeyVault. | +| `location` | string | `[resourceGroup().location]` | | Optional. Location for all resources. | +| `mode` | string | `Off` | `[Alert, Deny, Off]` | Optional. The configuring of intrusion detection. | +| `name` | string | | | Required. Name of the Firewall Policy. | +| `privateRanges` | array | `[]` | | Optional. List of private IP addresses/IP address ranges to not be SNAT. | +| `requireProxyForNetworkRules` | bool | | | Optional. FQDNs in Network Rules are supported when set to true. | +| `retentionDays` | int | `365` | | Optional. Number of days the insights should be enabled on the policy. | +| `ruleCollectionGroups` | _[ruleCollectionGroups](ruleCollectionGroups/readme.md)_ array | `[]` | | Optional. Rule collection groups. | +| `ruleGroups` | _[ruleGroups](ruleGroups/readme.md)_ array | `[]` | | Optional. Rule groups. | +| `servers` | array | `[]` | | Optional. List of Custom DNS Servers. | +| `signatureOverrides` | array | `[]` | | Optional. List of specific signatures states. | +| `systemAssignedIdentity` | bool | | | Optional. Enables system assigned managed identity on the resource. | +| `tags` | object | `{object}` | | Optional. Tags of the Firewall policy resource. | +| `threatIntelMode` | string | `Off` | `[Alert, Deny, Off]` | Optional. The operation mode for Threat Intel. | +| `tier` | string | `Standard` | `[Premium, Standard]` | Optional. Tier of Firewall Policy. | +| `userAssignedIdentities` | object | `{object}` | | Optional. The ID(s) to assign to the resource. | +| `workspaces` | array | `[]` | | Optional. List of workspaces for Firewall Policy Insights. | + +### Parameter Usage: `tags` + +Tag names and tag values can be provided as needed. A tag can be left without a value. + +```json +"tags": { + "value": { + "Environment": "Non-Prod", + "Contact": "test.user@testcompany.com", + "PurchaseOrder": "1234", + "CostCenter": "7890", + "ServiceName": "DeploymentValidation", + "Role": "DeploymentValidation" + } +} +``` + +### Parameter Usage: `userAssignedIdentities` + +You can specify multiple user assigned identities to a resource by providing additional resource IDs using the following format: + +```json +"userAssignedIdentities": { + "value": { + "/subscriptions/12345678-1234-1234-1234-123456789012/resourcegroups/validation-rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/adp-sxx-az-msi-x-001": {}, + "/subscriptions/12345678-1234-1234-1234-123456789012/resourcegroups/validation-rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/adp-sxx-az-msi-x-002": {} + } +}, +``` + +## Outputs + +| Output Name | Type | Description | +| :-- | :-- | :-- | +| `firewallPolicyName` | string | The name of the deployed firewall policy | +| `firewallPolicyResourceGroup` | string | The resource group of the deployed firewall policy | +| `firewallPolicyResourceId` | string | The resource ID of the deployed firewall policy | + +## Template references + +- [Firewallpolicies](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-03-01/firewallPolicies) +- [Firewallpolicies/Rulecollectiongroups](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-03-01/firewallPolicies/ruleCollectionGroups) +- [Firewallpolicies/Rulegroups](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2020-04-01/firewallPolicies/ruleGroups) diff --git a/arm/Microsoft.Network/firewallPolicies/ruleCollectionGroups/.bicep/nested_cuaId.bicep b/arm/Microsoft.Network/firewallPolicies/ruleCollectionGroups/.bicep/nested_cuaId.bicep new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/arm/Microsoft.Network/firewallPolicies/ruleCollectionGroups/.bicep/nested_cuaId.bicep @@ -0,0 +1 @@ + diff --git a/arm/Microsoft.Network/firewallPolicies/ruleCollectionGroups/deploy.bicep b/arm/Microsoft.Network/firewallPolicies/ruleCollectionGroups/deploy.bicep new file mode 100644 index 0000000000..e34b330d2c --- /dev/null +++ b/arm/Microsoft.Network/firewallPolicies/ruleCollectionGroups/deploy.bicep @@ -0,0 +1,41 @@ +@description('Required. Name of the Firewall Policy.') +param firewallPolicyName string + +@description('Required. The name of the rule collection group to deploy') +param name string + +@description('Required. Priority of the Firewall Policy Rule Collection Group resource.') +param priority int + +@description('Optional. Group of Firewall Policy rule collections.') +param ruleCollections array = [] + +@description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered') +param cuaId string = '' + +module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) { + name: 'pid-${cuaId}' + params: {} +} + +resource firewallPolicy 'Microsoft.Network/firewallPolicies@2021-03-01' existing = { + name: firewallPolicyName +} + +resource ruleCollectionGroup 'Microsoft.Network/firewallPolicies/ruleCollectionGroups@2021-03-01' = { + name: name + parent: firewallPolicy + properties: { + priority: priority + ruleCollections: ruleCollections + } +} + +@description('The name of the deployed rule collection group') +output ruleCollectionGroupName string = ruleCollectionGroup.name + +@description('The resource ID of the deployed rule collection group') +output ruleCollectionGroupResourceId string = ruleCollectionGroup.id + +@description('The resource group of the deployed rule collection group') +output ruleCollectionGroupResourceGroup string = resourceGroup().name diff --git a/arm/Microsoft.Network/firewallPolicies/ruleCollectionGroups/readme.md b/arm/Microsoft.Network/firewallPolicies/ruleCollectionGroups/readme.md new file mode 100644 index 0000000000..058596d729 --- /dev/null +++ b/arm/Microsoft.Network/firewallPolicies/ruleCollectionGroups/readme.md @@ -0,0 +1,46 @@ +# Network Firewall Policies Rule Collection Groups `[Microsoft.Network/firewallPolicies/ruleCollectionGroups]` + +This module deploys Network Firewall Policies Rule Collection Groups. + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Network/firewallPolicies/ruleCollectionGroups` | 2021-03-01 | + +## Parameters + +| Parameter Name | Type | Default Value | Possible Values | Description | +| :-- | :-- | :-- | :-- | :-- | +| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered | +| `firewallPolicyName` | string | | | Required. Name of the Firewall Policy. | +| `name` | string | | | Required. The name of the rule collection group to deploy | +| `priority` | int | | | Required. Priority of the Firewall Policy Rule Collection Group resource. | +| `ruleCollections` | array | `[]` | | Optional. Group of Firewall Policy rule collections. | + +### Parameter Usage: `ruleCollections` + +For remaining properties, see [FirewallPolicyRuleCollection objects](https://docs.microsoft.com/en-us/azure/templates/microsoft.network/firewallpolicies/rulecollectiongroups?tabs=json#firewallpolicyrulecollection-objects) + +```json +"ruleCollections": [ + { + "name": "string", + "priority": "int", + "ruleCollectionType": "string" + // For remaining properties, see FirewallPolicyRuleCollection objects + } +] +``` + +## Outputs + +| Output Name | Type | Description | +| :-- | :-- | :-- | +| `ruleCollectionGroupName` | string | The name of the deployed rule collection group | +| `ruleCollectionGroupResourceGroup` | string | The resource group of the deployed rule collection group | +| `ruleCollectionGroupResourceId` | string | The resource ID of the deployed rule collection group | + +## Template references + +- [Firewallpolicies/Rulecollectiongroups](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-03-01/firewallPolicies/ruleCollectionGroups) diff --git a/arm/Microsoft.Network/firewallPolicies/ruleGroups/.bicep/nested_cuaId.bicep b/arm/Microsoft.Network/firewallPolicies/ruleGroups/.bicep/nested_cuaId.bicep new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/arm/Microsoft.Network/firewallPolicies/ruleGroups/.bicep/nested_cuaId.bicep @@ -0,0 +1 @@ + diff --git a/arm/Microsoft.Network/firewallPolicies/ruleGroups/deploy.bicep b/arm/Microsoft.Network/firewallPolicies/ruleGroups/deploy.bicep new file mode 100644 index 0000000000..f5e365f7df --- /dev/null +++ b/arm/Microsoft.Network/firewallPolicies/ruleGroups/deploy.bicep @@ -0,0 +1,41 @@ +@description('Required. Name of the Firewall Policy.') +param firewallPolicyName string + +@description('Required. The name of the rule group to deploy') +param name string + +@description('Required. Priority of the Firewall Policy Rule Group resource.') +param priority int + +@description('Optional. Group of Firewall rules.') +param rules array = [] + +@description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered') +param cuaId string = '' + +module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) { + name: 'pid-${cuaId}' + params: {} +} + +resource firewallPolicy 'Microsoft.Network/firewallPolicies@2021-03-01' existing = { + name: firewallPolicyName +} + +resource ruleGroup 'Microsoft.Network/firewallPolicies/ruleGroups@2020-04-01' = { + name: name + parent: firewallPolicy + properties: { + priority: priority + rules: rules + } +} + +@description('The name of the deployed rule group') +output ruleGroupName string = ruleGroup.name + +@description('The resource ID of the deployed rule group') +output ruleGroupResourceId string = ruleGroup.id + +@description('The resource group of the deployed rule group') +output ruleGroupResourceGroup string = resourceGroup().name diff --git a/arm/Microsoft.Network/firewallPolicies/ruleGroups/readme.md b/arm/Microsoft.Network/firewallPolicies/ruleGroups/readme.md new file mode 100644 index 0000000000..24cdf44aa1 --- /dev/null +++ b/arm/Microsoft.Network/firewallPolicies/ruleGroups/readme.md @@ -0,0 +1,46 @@ +# Network Firewall Policies Rule Groups `[Microsoft.Network/firewallPolicies/ruleGroups]` + +This module deploys Network FirewallPolicies Rule Groups. + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Network/firewallPolicies/ruleGroups` | 2020-04-01 | + +## Parameters + +| Parameter Name | Type | Default Value | Possible Values | Description | +| :-- | :-- | :-- | :-- | :-- | +| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered | +| `firewallPolicyName` | string | | | Required. Name of the Firewall Policy. | +| `name` | string | | | Required. The name of the rule group to deploy | +| `priority` | int | | | Required. Priority of the Firewall Policy Rule Group resource. | +| `rules` | array | `[]` | | Optional. Group of Firewall rules. | + +### Parameter Usage: `rules` + +For remaining properties, see [FirewallPolicyRule objects](https://docs.microsoft.com/en-us/azure/templates/microsoft.network/2020-04-01/firewallpolicies/rulegroups?tabs=json#firewallpolicyrule-objects) + +```json +"rules": [ + { + "name": "string", + "priority": "int", + "ruleType": "string" + // For remaining properties, see FirewallPolicyRule objects + } +] +``` + +## Outputs + +| Output Name | Type | Description | +| :-- | :-- | :-- | +| `ruleGroupName` | string | The name of the deployed rule group | +| `ruleGroupResourceGroup` | string | The resource group of the deployed rule group | +| `ruleGroupResourceId` | string | The resource ID of the deployed rule group | + +## Template references + +- [Firewallpolicies/Rulegroups](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2020-04-01/firewallPolicies/ruleGroups) diff --git a/arm/Microsoft.Network/virtualNetworks/readme.md b/arm/Microsoft.Network/virtualNetworks/readme.md index 6501668eb6..790ac87741 100644 --- a/arm/Microsoft.Network/virtualNetworks/readme.md +++ b/arm/Microsoft.Network/virtualNetworks/readme.md @@ -29,9 +29,9 @@ This template deploys a virtual network (vNet). | `logsToEnable` | array | `[VMProtectionAlerts]` | `[VMProtectionAlerts]` | Optional. The name of logs that will be streamed. | | `metricsToEnable` | array | `[AllMetrics]` | `[AllMetrics]` | Optional. The name of metrics that will be streamed. | | `name` | string | | | Required. The Virtual Network (vNet) Name. | +| `nsgResourceGroup` | string | `[resourceGroup().name]` | | Optional. Resource Group where NSGs are deployed, if different than VNET Resource Group. | | `roleAssignments` | array | `[]` | | 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' | | `subnets` | array | | | Required. An Array of subnets to deploy to the Virual Network. | -| `nsgResourceGroup` | string | `[resourceGroup().name]` | | Optional. Resource Group where NSGs are deployed, if different than VNET Resource Group. | | `tags` | object | `{object}` | | Optional. Tags of the resource. | | `virtualNetworkPeerings` | _[virtualNetworkPeerings](virtualNetworkPeerings/readme.md)_ array | `[]` | | Optional. Virtual Network Peerings configurations | | `workspaceId` | string | | | Optional. Resource ID of log analytics. | @@ -156,8 +156,8 @@ The network security group and route table resources must reside in the same res ## Template references +- [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) - [Locks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2016-09-01/locks) - [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) -- [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) -- [Virtualnetworks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-05-01/virtualNetworks) +- [Virtualnetworks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/virtualNetworks) - [Virtualnetworks/Virtualnetworkpeerings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-02-01/virtualNetworks/virtualNetworkPeerings) diff --git a/arm/Microsoft.OperationalInsights/workspaces/.parameters/parameters.json b/arm/Microsoft.OperationalInsights/workspaces/.parameters/parameters.json index 908b407660..eef49351b9 100644 --- a/arm/Microsoft.OperationalInsights/workspaces/.parameters/parameters.json +++ b/arm/Microsoft.OperationalInsights/workspaces/.parameters/parameters.json @@ -148,6 +148,21 @@ }, "useResourcePermissions": { "value": true + }, + "diagnosticLogsRetentionInDays": { + "value": 7 + }, + "diagnosticStorageAccountId": { + "value": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Storage/storageAccounts/adpsxxazsaweux001" + }, + "workspaceId": { + "value": "/subscriptions/<>/resourcegroups/validation-rg/providers/microsoft.operationalinsights/workspaces/adp-sxx-az-law-x-001" + }, + "eventHubAuthorizationRuleId": { + "value": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.EventHub/namespaces/adp-sxx-az-evhns-x-001/AuthorizationRules/RootManageSharedAccessKey" + }, + "eventHubName": { + "value": "adp-sxx-az-evh-x-001" } } } diff --git a/arm/Microsoft.OperationalInsights/workspaces/deploy.bicep b/arm/Microsoft.OperationalInsights/workspaces/deploy.bicep index 19a13b9143..a5343b7e96 100644 --- a/arm/Microsoft.OperationalInsights/workspaces/deploy.bicep +++ b/arm/Microsoft.OperationalInsights/workspaces/deploy.bicep @@ -54,6 +54,23 @@ param publicNetworkAccessForQuery string = 'Enabled' @description('Optional. Set to \'true\' to use resource or workspace permissions and \'false\' (or leave empty) to require workspace permissions.') param useResourcePermissions bool = false +@description('Optional. 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('Optional. Resource ID of the diagnostic storage account.') +param diagnosticStorageAccountId string = '' + +@description('Optional. Resource ID of a log analytics workspace.') +param workspaceId string = '' + +@description('Optional. Resource ID of the event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to.') +param eventHubAuthorizationRuleId string = '' + +@description('Optional. Name of the event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category.') +param eventHubName string = '' + @allowed([ 'CanNotDelete' 'NotSpecified' @@ -71,6 +88,41 @@ param tags object = {} @description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered') param cuaId string = '' +@description('Optional. The name of logs that will be streamed.') +@allowed([ + 'Audit' +]) +param logsToEnable array = [ + 'Audit' +] + +@description('Optional. The name of metrics that will be streamed.') +@allowed([ + 'AllMetrics' +]) +param metricsToEnable array = [ + 'AllMetrics' +] + +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 logAnalyticsSearchVersion = 1 module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) { @@ -99,6 +151,19 @@ resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2020-08 } } +resource logAnalyticsWorkspace_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if ((!empty(diagnosticStorageAccountId)) || (!empty(workspaceId)) || (!empty(eventHubAuthorizationRuleId)) || (!empty(eventHubName))) { + name: '${logAnalyticsWorkspace.name}-diagnosticSettings' + properties: { + storageAccountId: !empty(diagnosticStorageAccountId) ? diagnosticStorageAccountId : null + workspaceId: !empty(workspaceId) ? workspaceId : null + eventHubAuthorizationRuleId: !empty(eventHubAuthorizationRuleId) ? eventHubAuthorizationRuleId : null + eventHubName: !empty(eventHubName) ? eventHubName : null + metrics: diagnosticsMetrics + logs: diagnosticsLogs + } + scope: logAnalyticsWorkspace +} + module logAnalyticsWorkspace_storageInsightConfigs 'storageInsightConfigs/deploy.bicep' = [for (storageInsightsConfig, index) in storageInsightsConfigs: { name: '${uniqueString(deployment().name, location)}-LAW-StorageInsightsConfig-${index}' params: { diff --git a/arm/Microsoft.OperationalInsights/workspaces/readme.md b/arm/Microsoft.OperationalInsights/workspaces/readme.md index cab8ea6865..8ea13e7fcd 100644 --- a/arm/Microsoft.OperationalInsights/workspaces/readme.md +++ b/arm/Microsoft.OperationalInsights/workspaces/readme.md @@ -8,6 +8,7 @@ This template deploys a log analytics workspace. | :-- | :-- | | `Microsoft.Authorization/locks` | 2016-09-01 | | `Microsoft.Authorization/roleAssignments` | 2020-04-01-preview | +| `Microsoft.Insights/diagnosticSettings` | 2021-05-01-preview | | `Microsoft.OperationalInsights/workspaces` | 2020-08-01 | | `Microsoft.OperationalInsights/workspaces/dataSources` | 2020-08-01 | | `Microsoft.OperationalInsights/workspaces/linkedServices` | 2020-08-01 | @@ -23,10 +24,16 @@ This template deploys a log analytics workspace. | `dailyQuotaGb` | int | `-1` | | Optional. The workspace daily quota for ingestion. | | `dataRetention` | int | `365` | | Required. Number of days data will be retained for | | `dataSources` | _[dataSources](dataSources/readme.md)_ array | `[]` | | Optional. LAW data sources to configure. | +| `diagnosticLogsRetentionInDays` | int | `365` | | Optional. Specifies the number of days that logs will be kept for; a value of 0 will retain data indefinitely. | +| `diagnosticStorageAccountId` | string | | | Optional. Resource ID of the diagnostic storage account. | +| `eventHubAuthorizationRuleId` | string | | | Optional. Resource ID of the event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | +| `eventHubName` | string | | | Optional. Name of the event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. | | `gallerySolutions` | array | `[]` | | Optional. LAW gallerySolutions from the gallery. | | `linkedServices` | _[linkedServices](linkedServices/readme.md)_ array | `[]` | | Optional. List of services to be linked. | | `location` | string | `[resourceGroup().location]` | | Optional. Location for all resources. | | `lock` | string | `NotSpecified` | `[CanNotDelete, NotSpecified, ReadOnly]` | Optional. Specify the type of lock. | +| `logsToEnable` | array | `[Audit]` | `[Audit]` | Optional. The name of logs that will be streamed. | +| `metricsToEnable` | array | `[AllMetrics]` | `[AllMetrics]` | Optional. The name of metrics that will be streamed. | | `name` | string | | | Required. Name of the Log Analytics workspace | | `publicNetworkAccessForIngestion` | string | `Enabled` | `[Enabled, Disabled]` | Optional. The network access type for accessing Log Analytics ingestion. | | `publicNetworkAccessForQuery` | string | `Enabled` | `[Enabled, Disabled]` | Optional. The network access type for accessing Log Analytics query. | @@ -36,6 +43,7 @@ This template deploys a log analytics workspace. | `storageInsightsConfigs` | array | `[]` | | Optional. List of storage accounts to be read by the workspace. | | `tags` | object | `{object}` | | Optional. Tags of the resource. | | `useResourcePermissions` | bool | | | Optional. Set to 'true' to use resource or workspace permissions and 'false' (or leave empty) to require workspace permissions. | +| `workspaceId` | string | | | Optional. Resource ID of a log analytics workspace. | ### Parameter Usage: `gallerySolutions` @@ -123,6 +131,7 @@ Tag names and tag values can be provided as needed. A tag can be left without a - [Locks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2016-09-01/locks) - [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) +- [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) - [Workspaces](https://docs.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2020-08-01/workspaces) - [Workspaces/Datasources](https://docs.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2020-08-01/workspaces/dataSources) - [Workspaces/Linkedservices](https://docs.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2020-08-01/workspaces/linkedServices) diff --git a/arm/Microsoft.ServiceBus/namespaces/queues/readme.md b/arm/Microsoft.ServiceBus/namespaces/queues/readme.md index e3766f6608..3ff8c0f187 100644 --- a/arm/Microsoft.ServiceBus/namespaces/queues/readme.md +++ b/arm/Microsoft.ServiceBus/namespaces/queues/readme.md @@ -67,6 +67,6 @@ This module deploys a queue for a service bus namespace. ## Template references - [Locks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2016-09-01/locks) -- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) - [Namespaces/Queues](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ServiceBus/2021-06-01-preview/namespaces/queues) - [Namespaces/Queues/Authorizationrules](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ServiceBus/2017-04-01/namespaces/queues/authorizationRules) +- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) diff --git a/arm/Microsoft.ServiceBus/namespaces/readme.md b/arm/Microsoft.ServiceBus/namespaces/readme.md index 306afd1c10..ff6f426f4a 100644 --- a/arm/Microsoft.ServiceBus/namespaces/readme.md +++ b/arm/Microsoft.ServiceBus/namespaces/readme.md @@ -150,11 +150,8 @@ You can specify multiple user assigned identities to a resource by providing add ## Template references -- [Locks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2016-09-01/locks) -- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) - [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) -- [Privateendpoints](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-05-01/privateEndpoints) -- [Privateendpoints/Privatednszonegroups](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2020-05-01/privateEndpoints/privateDnsZoneGroups) +- [Locks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2016-09-01/locks) - [Namespaces](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ServiceBus/2021-06-01-preview/namespaces) - [Namespaces/Authorizationrules](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ServiceBus/2017-04-01/namespaces/AuthorizationRules) - [Namespaces/Disasterrecoveryconfigs](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ServiceBus/2017-04-01/namespaces/disasterRecoveryConfigs) @@ -163,3 +160,6 @@ You can specify multiple user assigned identities to a resource by providing add - [Namespaces/Queues](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ServiceBus/2021-06-01-preview/namespaces/queues) - [Namespaces/Queues/Authorizationrules](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ServiceBus/2017-04-01/namespaces/queues/authorizationRules) - [Namespaces/Virtualnetworkrules](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ServiceBus/2018-01-01-preview/namespaces/virtualnetworkrules) +- [Privateendpoints](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/privateEndpoints) +- [Privateendpoints/Privatednszonegroups](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2020-05-01/privateEndpoints/privateDnsZoneGroups) +- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) diff --git a/arm/Microsoft.Sql/servers/.parameters/parameters.json b/arm/Microsoft.Sql/servers/.parameters/parameters.json index d552c246e8..eec0231e4d 100644 --- a/arm/Microsoft.Sql/servers/.parameters/parameters.json +++ b/arm/Microsoft.Sql/servers/.parameters/parameters.json @@ -42,7 +42,12 @@ "tier": "GeneralPurpose", "skuName": "GP_Gen5_2", "maxSizeBytes": 34359738368, - "licenseType": "LicenseIncluded" + "licenseType": "LicenseIncluded", + "diagnosticLogsRetentionInDays": 7, + "diagnosticStorageAccountId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Storage/storageAccounts/adpsxxazsaweux001", + "workspaceId": "/subscriptions/<>/resourcegroups/validation-rg/providers/microsoft.operationalinsights/workspaces/adp-sxx-az-law-x-001", + "eventHubAuthorizationRuleId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.EventHub/namespaces/adp-sxx-az-evhns-x-001/AuthorizationRules/RootManageSharedAccessKey", + "eventHubName": "adp-sxx-az-evh-x-001" } ] }, diff --git a/arm/Microsoft.Sql/servers/databases/deploy.bicep b/arm/Microsoft.Sql/servers/databases/deploy.bicep index 6669798e03..8d7f953ae7 100644 --- a/arm/Microsoft.Sql/servers/databases/deploy.bicep +++ b/arm/Microsoft.Sql/servers/databases/deploy.bicep @@ -50,6 +50,74 @@ param location string = resourceGroup().location @description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered') param cuaId string = '' +@description('Optional. 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('Optional. Resource ID of the diagnostic storage account.') +param diagnosticStorageAccountId string = '' + +@description('Optional. Resource ID of log analytics.') +param workspaceId string = '' + +@description('Optional. Resource ID of the event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to.') +param eventHubAuthorizationRuleId string = '' + +@description('Optional. Name of the event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category.') +param eventHubName string = '' + +@description('Optional. The name of logs that will be streamed.') +@allowed([ + 'SQLInsights' + 'AutomaticTuning' + 'QueryStoreRuntimeStatistics' + 'QueryStoreWaitStatistics' + 'Errors' + 'DatabaseWaitStatistics' + 'Timouts' + 'Blocks' + 'Deadlocks' +]) +param logsToEnable array = [ + 'SQLInsights' + 'AutomaticTuning' + 'QueryStoreRuntimeStatistics' + 'QueryStoreWaitStatistics' + 'Errors' + 'DatabaseWaitStatistics' + 'Timouts' + 'Blocks' + 'Deadlocks' +] + +@description('Optional. The name of metrics that will be streamed.') +@allowed([ + 'Basic' +]) +param metricsToEnable array = [ + 'Basic' +] + +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 + } +}] + @description('Optional. The storage account type to be used to store backups for this database.') @allowed([ 'Geo' @@ -99,6 +167,19 @@ resource database 'Microsoft.Sql/servers/databases@2021-02-01-preview' = { } } +resource database_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if ((!empty(diagnosticStorageAccountId)) || (!empty(workspaceId)) || (!empty(eventHubAuthorizationRuleId)) || (!empty(eventHubName))) { + name: '${last(split(database.name, '/'))}-diagnosticSettings' + properties: { + storageAccountId: !empty(diagnosticStorageAccountId) ? diagnosticStorageAccountId : null + workspaceId: !empty(workspaceId) ? workspaceId : null + eventHubAuthorizationRuleId: !empty(eventHubAuthorizationRuleId) ? eventHubAuthorizationRuleId : null + eventHubName: !empty(eventHubName) ? eventHubName : null + metrics: diagnosticsMetrics + logs: diagnosticsLogs + } + scope: database +} + @description('The name of the deployed database') output databaseName string = database.name diff --git a/arm/Microsoft.Sql/servers/databases/readme.md b/arm/Microsoft.Sql/servers/databases/readme.md index a6ae29e4dd..4a993e8b41 100644 --- a/arm/Microsoft.Sql/servers/databases/readme.md +++ b/arm/Microsoft.Sql/servers/databases/readme.md @@ -6,6 +6,7 @@ This module deploys an Azure SQL Server. | Resource Type | API Version | | :-- | :-- | +| `Microsoft.Insights/diagnosticSettings` | 2021-05-01-preview | | `Microsoft.Sql/servers/databases` | 2021-02-01-preview | ## Parameters @@ -15,12 +16,18 @@ This module deploys an Azure SQL Server. | `autoPauseDelay` | string | | | Optional. Time in minutes after which database is automatically paused. | | `collation` | string | | | Optional. The collation of the database. | | `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered | +| `diagnosticLogsRetentionInDays` | int | `365` | | Optional. Specifies the number of days that logs will be kept for; a value of 0 will retain data indefinitely. | +| `diagnosticStorageAccountId` | string | | | Optional. Resource ID of the diagnostic storage account. | +| `eventHubAuthorizationRuleId` | string | | | Optional. Resource ID of the event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | +| `eventHubName` | string | | | Optional. Name of the event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. | | `highAvailabilityReplicaCount` | int | | | Optional. The number of readonly secondary replicas associated with the database. | | `isLedgerOn` | bool | | | Optional. Whether or not this database is a ledger database, which means all tables in the database are ledger tables. Note: the value of this property cannot be changed after the database has been created. | | `licenseType` | string | | | Optional. The license type to apply for this database. | | `location` | string | `[resourceGroup().location]` | | Optional. Location for all resources. | +| `logsToEnable` | array | `[SQLInsights, AutomaticTuning, QueryStoreRuntimeStatistics, QueryStoreWaitStatistics, Errors, DatabaseWaitStatistics, Timouts, Blocks, Deadlocks]` | `[SQLInsights, AutomaticTuning, QueryStoreRuntimeStatistics, QueryStoreWaitStatistics, Errors, DatabaseWaitStatistics, Timouts, Blocks, Deadlocks]` | Optional. The name of logs that will be streamed. | | `maintenanceConfigurationId` | string | | | Optional. Maintenance configuration ID assigned to the database. This configuration defines the period when the maintenance updates will occur. | | `maxSizeBytes` | int | | | Optional. The max size of the database expressed in bytes. | +| `metricsToEnable` | array | `[Basic]` | `[Basic]` | Optional. The name of metrics that will be streamed. | | `minCapacity` | string | | | Optional. Minimal capacity that database will always have allocated. | | `name` | string | | | Required. The name of the database. | | `readScale` | string | `Disabled` | `[Enabled, Disabled]` | Optional. The state of read-only routing. | @@ -30,6 +37,7 @@ This module deploys an Azure SQL Server. | `skuName` | string | | | Required. The name of the SKU. | | `tags` | object | `{object}` | | Optional. Tags of the resource. | | `tier` | string | | | Optional. The tier or edition of the particular SKU. | +| `workspaceId` | string | | | Optional. Resource ID of log analytics. | | `zoneRedundant` | bool | | | Optional. Whether or not this database is zone redundant. | ### Parameter Usage: `tags` @@ -59,4 +67,5 @@ Tag names and tag values can be provided as needed. A tag can be left without a ## Template references +- [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) - [Servers/Databases](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Sql/2021-02-01-preview/servers/databases) diff --git a/arm/Microsoft.Sql/servers/deploy.bicep b/arm/Microsoft.Sql/servers/deploy.bicep index cd2fc6746e..f511afbb35 100644 --- a/arm/Microsoft.Sql/servers/deploy.bicep +++ b/arm/Microsoft.Sql/servers/deploy.bicep @@ -95,16 +95,23 @@ module server_databases 'databases/deploy.bicep' = [for (database, index) in dat skuName: database.skuName collation: database.collation autoPauseDelay: contains(database, 'autoPauseDelay') ? database.autoPauseDelay : '' + diagnosticLogsRetentionInDays: contains(database, 'diagnosticLogsRetentionInDays') ? database.diagnosticLogsRetentionInDays : 365 + diagnosticStorageAccountId: contains(database, 'diagnosticStorageAccountId') ? database.diagnosticStorageAccountId : '' + eventHubAuthorizationRuleId: contains(database, 'eventHubAuthorizationRuleId') ? database.eventHubAuthorizationRuleId : '' + eventHubName: contains(database, 'eventHubName') ? database.eventHubName : '' isLedgerOn: contains(database, 'isLedgerOn') ? database.isLedgerOn : false location: contains(database, 'location') ? database.location : server.location + logsToEnable: contains(database, 'logsToEnable') ? database.logsToEnable : [] licenseType: contains(database, 'licenseType') ? database.licenseType : '' maintenanceConfigurationId: contains(database, 'maintenanceConfigurationId') ? database.maintenanceConfigurationId : '' minCapacity: contains(database, 'minCapacity') ? database.minCapacity : '' + metricsToEnable: contains(database, 'metricsToEnable') ? database.metricsToEnable : [] highAvailabilityReplicaCount: contains(database, 'highAvailabilityReplicaCount') ? database.highAvailabilityReplicaCount : 0 readScale: contains(database, 'readScale') ? database.readScale : 'Disabled' requestedBackupStorageRedundancy: contains(database, 'requestedBackupStorageRedundancy') ? database.requestedBackupStorageRedundancy : '' sampleName: contains(database, 'sampleName') ? database.sampleName : '' tags: contains(database, 'tags') ? database.tags : {} + workspaceId: contains(database, 'workspaceId') ? database.workspaceId : '' zoneRedundant: contains(database, 'zoneRedundant') ? database.zoneRedundant : false } }] diff --git a/arm/Microsoft.Sql/servers/readme.md b/arm/Microsoft.Sql/servers/readme.md index 8993b04958..a11a2cb394 100644 --- a/arm/Microsoft.Sql/servers/readme.md +++ b/arm/Microsoft.Sql/servers/readme.md @@ -8,6 +8,7 @@ This module deploys a SQL server. | :-- | :-- | | `Microsoft.Authorization/locks` | 2016-09-01 | | `Microsoft.Authorization/roleAssignments` | 2020-04-01-preview | +| `Microsoft.Insights/diagnosticSettings` | 2021-05-01-preview | | `Microsoft.Sql/servers` | 2021-05-01-preview | | `Microsoft.Sql/servers/databases` | 2021-02-01-preview | | `Microsoft.Sql/servers/firewallRules` | 2021-05-01-preview | @@ -96,6 +97,7 @@ You can specify multiple user assigned identities to a resource by providing add - [Locks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2016-09-01/locks) - [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) +- [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) - [Servers](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Sql/2021-05-01-preview/servers) - [Servers/Databases](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Sql/2021-02-01-preview/servers/databases) - [Servers/Firewallrules](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Sql/2021-05-01-preview/servers/firewallRules) diff --git a/arm/Microsoft.Storage/storageAccounts/.parameters/parameters.json b/arm/Microsoft.Storage/storageAccounts/.parameters/parameters.json index 247e0496df..78c725d89c 100644 --- a/arm/Microsoft.Storage/storageAccounts/.parameters/parameters.json +++ b/arm/Microsoft.Storage/storageAccounts/.parameters/parameters.json @@ -13,6 +13,11 @@ }, "blobServices": { "value": { + "diagnosticLogsRetentionInDays": 7, + "diagnosticStorageAccountId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Storage/storageAccounts/adpsxxazsaweux001", + "workspaceId": "/subscriptions/<>/resourcegroups/validation-rg/providers/microsoft.operationalinsights/workspaces/adp-sxx-az-law-x-001", + "eventHubAuthorizationRuleId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.EventHub/namespaces/adp-sxx-az-evhns-x-001/AuthorizationRules/RootManageSharedAccessKey", + "eventHubName": "adp-sxx-az-evh-x-001", "containers": [ { "name": "avdscripts", @@ -38,6 +43,11 @@ }, "fileServices": { "value": { + "diagnosticLogsRetentionInDays": 7, + "diagnosticStorageAccountId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Storage/storageAccounts/adpsxxazsaweux001", + "workspaceId": "/subscriptions/<>/resourcegroups/validation-rg/providers/microsoft.operationalinsights/workspaces/adp-sxx-az-law-x-001", + "eventHubAuthorizationRuleId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.EventHub/namespaces/adp-sxx-az-evhns-x-001/AuthorizationRules/RootManageSharedAccessKey", + "eventHubName": "adp-sxx-az-evh-x-001", "shares": [ { "name": "avdprofiles", @@ -60,6 +70,11 @@ }, "tableServices": { "value": { + "diagnosticLogsRetentionInDays": 7, + "diagnosticStorageAccountId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Storage/storageAccounts/adpsxxazsaweux001", + "workspaceId": "/subscriptions/<>/resourcegroups/validation-rg/providers/microsoft.operationalinsights/workspaces/adp-sxx-az-law-x-001", + "eventHubAuthorizationRuleId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.EventHub/namespaces/adp-sxx-az-evhns-x-001/AuthorizationRules/RootManageSharedAccessKey", + "eventHubName": "adp-sxx-az-evh-x-001", "tables": [ "table1", "table2" @@ -68,6 +83,11 @@ }, "queueServices": { "value": { + "diagnosticLogsRetentionInDays": 7, + "diagnosticStorageAccountId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Storage/storageAccounts/adpsxxazsaweux001", + "workspaceId": "/subscriptions/<>/resourcegroups/validation-rg/providers/microsoft.operationalinsights/workspaces/adp-sxx-az-law-x-001", + "eventHubAuthorizationRuleId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.EventHub/namespaces/adp-sxx-az-evhns-x-001/AuthorizationRules/RootManageSharedAccessKey", + "eventHubName": "adp-sxx-az-evh-x-001", "queues": [ { "name": "queue1", @@ -105,6 +125,21 @@ ] } ] + }, + "diagnosticLogsRetentionInDays": { + "value": 7 + }, + "diagnosticStorageAccountId": { + "value": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Storage/storageAccounts/adpsxxazsaweux001" + }, + "workspaceId": { + "value": "/subscriptions/<>/resourcegroups/validation-rg/providers/microsoft.operationalinsights/workspaces/adp-sxx-az-law-x-001" + }, + "eventHubAuthorizationRuleId": { + "value": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.EventHub/namespaces/adp-sxx-az-evhns-x-001/AuthorizationRules/RootManageSharedAccessKey" + }, + "eventHubName": { + "value": "adp-sxx-az-evh-x-001" } } } diff --git a/arm/Microsoft.Storage/storageAccounts/blobServices/deploy.bicep b/arm/Microsoft.Storage/storageAccounts/blobServices/deploy.bicep index 3f6c6081c2..38973f1598 100644 --- a/arm/Microsoft.Storage/storageAccounts/blobServices/deploy.bicep +++ b/arm/Microsoft.Storage/storageAccounts/blobServices/deploy.bicep @@ -17,9 +17,65 @@ param automaticSnapshotPolicyEnabled bool = false @description('Optional. Blob containers to create.') param containers array = [] +@description('Optional. 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('Optional. Resource ID of the diagnostic storage account.') +param diagnosticStorageAccountId string = '' + +@description('Optional. Resource ID of a log analytics workspace.') +param workspaceId string = '' + +@description('Optional. Resource ID of the event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to.') +param eventHubAuthorizationRuleId string = '' + +@description('Optional. Name of the event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category.') +param eventHubName string = '' + @description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered') param cuaId string = '' +@description('Optional. The name of logs that will be streamed.') +@allowed([ + 'StorageRead' + 'StorageWrite' + 'StorageDelete' +]) +param logsToEnable array = [ + 'StorageRead' + 'StorageWrite' + 'StorageDelete' +] + +@description('Optional. The name of metrics that will be streamed.') +@allowed([ + 'Transaction' +]) +param metricsToEnable array = [ + 'Transaction' +] + +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 + } +}] + module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) { name: 'pid-${cuaId}' params: {} @@ -41,6 +97,19 @@ resource blobServices 'Microsoft.Storage/storageAccounts/blobServices@2021-06-01 } } +resource blobServices_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if ((!empty(diagnosticStorageAccountId)) || (!empty(workspaceId)) || (!empty(eventHubAuthorizationRuleId)) || (!empty(eventHubName))) { + name: '${blobServices.name}-diagnosticSettings' + properties: { + storageAccountId: !empty(diagnosticStorageAccountId) ? diagnosticStorageAccountId : null + workspaceId: !empty(workspaceId) ? workspaceId : null + eventHubAuthorizationRuleId: !empty(eventHubAuthorizationRuleId) ? eventHubAuthorizationRuleId : null + eventHubName: !empty(eventHubName) ? eventHubName : null + metrics: diagnosticsMetrics + logs: diagnosticsLogs + } + scope: blobServices +} + module blobServices_container 'containers/deploy.bicep' = [for (container, index) in containers: { name: '${deployment().name}-Container-${index}' params: { diff --git a/arm/Microsoft.Storage/storageAccounts/blobServices/readme.md b/arm/Microsoft.Storage/storageAccounts/blobServices/readme.md index fea80fa65c..d553636eb1 100644 --- a/arm/Microsoft.Storage/storageAccounts/blobServices/readme.md +++ b/arm/Microsoft.Storage/storageAccounts/blobServices/readme.md @@ -7,6 +7,7 @@ This module can be used to deploy a blob service into a storage account. | Resource Type | API Version | | :-- | :-- | | `Microsoft.Authorization/roleAssignments` | 2020-04-01-preview | +| `Microsoft.Insights/diagnosticSettings` | 2021-05-01-preview | | `Microsoft.Storage/storageAccounts/blobServices` | 2021-06-01 | | `Microsoft.Storage/storageAccounts/blobServices/containers` | 2019-06-01 | | `Microsoft.Storage/storageAccounts/blobServices/containers/immutabilityPolicies` | 2019-06-01 | @@ -20,8 +21,15 @@ This module can be used to deploy a blob service into a storage account. | `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered | | `deleteRetentionPolicy` | bool | `True` | | Optional. Indicates whether DeleteRetentionPolicy is enabled for the Blob service. | | `deleteRetentionPolicyDays` | int | `7` | | Optional. Indicates the number of days that the deleted blob should be retained. The minimum specified value can be 1 and the maximum value can be 365. | +| `diagnosticLogsRetentionInDays` | int | `365` | | Optional. Specifies the number of days that logs will be kept for; a value of 0 will retain data indefinitely. | +| `diagnosticStorageAccountId` | string | | | Optional. Resource ID of the diagnostic storage account. | +| `eventHubAuthorizationRuleId` | string | | | Optional. Resource ID of the event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | +| `eventHubName` | string | | | Optional. Name of the event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. | +| `logsToEnable` | array | `[StorageRead, StorageWrite, StorageDelete]` | `[StorageRead, StorageWrite, StorageDelete]` | Optional. The name of logs that will be streamed. | +| `metricsToEnable` | array | `[Transaction]` | `[Transaction]` | Optional. The name of metrics that will be streamed. | | `name` | string | `default` | | Optional. The name of the blob service | | `storageAccountName` | string | | | Required. Name of the Storage Account. | +| `workspaceId` | string | | | Optional. Resource ID of a log analytics workspace. | ## Outputs @@ -35,6 +43,7 @@ This module can be used to deploy a blob service into a storage account. ## Template references - [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) +- [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) - [Storageaccounts/Blobservices](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-06-01/storageAccounts/blobServices) - [Storageaccounts/Blobservices/Containers](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Storage/2019-06-01/storageAccounts/blobServices/containers) - [Storageaccounts/Blobservices/Containers/Immutabilitypolicies](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Storage/2019-06-01/storageAccounts/blobServices/containers/immutabilityPolicies) diff --git a/arm/Microsoft.Storage/storageAccounts/deploy.bicep b/arm/Microsoft.Storage/storageAccounts/deploy.bicep index d2e4888a19..5d69da5544 100644 --- a/arm/Microsoft.Storage/storageAccounts/deploy.bicep +++ b/arm/Microsoft.Storage/storageAccounts/deploy.bicep @@ -85,6 +85,23 @@ param minimumTlsVersion string = 'TLS1_2' @description('Optional. If true, enables Hierarchical Namespace for the storage account') param enableHierarchicalNamespace bool = false +@description('Optional. 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('Optional. Resource ID of the diagnostic storage account.') +param diagnosticStorageAccountId string = '' + +@description('Optional. Resource ID of a log analytics workspace.') +param workspaceId string = '' + +@description('Optional. Resource ID of the event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to.') +param eventHubAuthorizationRuleId string = '' + +@description('Optional. Name of the event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category.') +param eventHubName string = '' + @allowed([ 'CanNotDelete' 'NotSpecified' @@ -102,6 +119,24 @@ param cuaId string = '' @description('Generated. Do not provide a value! This date value is used to generate a SAS token to access the modules.') param basetime string = utcNow('u') +@description('Optional. The name of metrics that will be streamed.') +@allowed([ + 'Transaction' +]) +param metricsToEnable array = [ + 'Transaction' +] + +var diagnosticsMetrics = [for metric in metricsToEnable: { + category: metric + timeGrain: null + enabled: true + retentionPolicy: { + enabled: true + days: diagnosticLogsRetentionInDays + } +}] + var virtualNetworkRules = [for index in range(0, (empty(networkAcls) ? 0 : length(networkAcls.virtualNetworkRules))): { id: '${vNetId}/subnets/${networkAcls.virtualNetworkRules[index].subnet}' }] @@ -161,6 +196,18 @@ resource storageAccount 'Microsoft.Storage/storageAccounts@2021-06-01' = { properties: saProperties } +resource storageAccount_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if ((!empty(diagnosticStorageAccountId)) || (!empty(workspaceId)) || (!empty(eventHubAuthorizationRuleId)) || (!empty(eventHubName))) { + name: '${storageAccount.name}-diagnosticSettings' + properties: { + storageAccountId: empty(diagnosticStorageAccountId) ? null : diagnosticStorageAccountId + workspaceId: empty(workspaceId) ? null : workspaceId + eventHubAuthorizationRuleId: empty(eventHubAuthorizationRuleId) ? null : eventHubAuthorizationRuleId + eventHubName: empty(eventHubName) ? null : eventHubName + metrics: diagnosticsMetrics + } + scope: storageAccount +} + resource storageAccount_lock 'Microsoft.Authorization/locks@2016-09-01' = if (lock != 'NotSpecified') { name: '${storageAccount.name}-${lock}-lock' properties: { @@ -207,6 +254,13 @@ module storageAccount_blobServices 'blobServices/deploy.bicep' = if (!empty(blob automaticSnapshotPolicyEnabled: contains(blobServices, 'automaticSnapshotPolicyEnabled') ? blobServices.automaticSnapshotPolicyEnabled : false deleteRetentionPolicy: contains(blobServices, 'deleteRetentionPolicy') ? blobServices.deleteRetentionPolicy : true deleteRetentionPolicyDays: contains(blobServices, 'deleteRetentionPolicyDays') ? blobServices.deleteRetentionPolicyDays : 7 + diagnosticLogsRetentionInDays: contains(blobServices, 'diagnosticLogsRetentionInDays') ? blobServices.diagnosticLogsRetentionInDays : 365 + diagnosticStorageAccountId: contains(blobServices, 'diagnosticStorageAccountId') ? blobServices.diagnosticStorageAccountId : '' + eventHubAuthorizationRuleId: contains(blobServices, 'eventHubAuthorizationRuleId') ? blobServices.eventHubAuthorizationRuleId : '' + eventHubName: contains(blobServices, 'eventHubName') ? blobServices.eventHubName : '' + logsToEnable: contains(blobServices, 'logsToEnable') ? blobServices.logsToEnable : [] + metricsToEnable: contains(blobServices, 'metricsToEnable') ? blobServices.metricsToEnable : [] + workspaceId: contains(blobServices, 'workspaceId') ? blobServices.workspaceId : '' } } @@ -215,12 +269,19 @@ module storageAccount_fileServices 'fileServices/deploy.bicep' = if (!empty(file name: '${uniqueString(deployment().name, location)}-Storage-FileServices' params: { storageAccountName: storageAccount.name + diagnosticLogsRetentionInDays: contains(fileServices, 'diagnosticLogsRetentionInDays') ? fileServices.diagnosticLogsRetentionInDays : 365 + diagnosticStorageAccountId: contains(fileServices, 'diagnosticStorageAccountId') ? fileServices.diagnosticStorageAccountId : '' + eventHubAuthorizationRuleId: contains(fileServices, 'eventHubAuthorizationRuleId') ? fileServices.eventHubAuthorizationRuleId : '' + eventHubName: contains(fileServices, 'eventHubName') ? fileServices.eventHubName : '' + logsToEnable: contains(fileServices, 'logsToEnable') ? fileServices.logsToEnable : [] + metricsToEnable: contains(fileServices, 'metricsToEnable') ? fileServices.metricsToEnable : [] protocolSettings: contains(fileServices, 'protocolSettings') ? fileServices.protocolSettings : {} shareDeleteRetentionPolicy: contains(fileServices, 'shareDeleteRetentionPolicy') ? fileServices.shareDeleteRetentionPolicy : { enabled: true days: 7 } shares: contains(fileServices, 'shares') ? fileServices.shares : [] + workspaceId: contains(fileServices, 'workspaceId') ? fileServices.workspaceId : '' } } @@ -229,7 +290,14 @@ module storageAccount_queueServices 'queueServices/deploy.bicep' = if (!empty(qu name: '${uniqueString(deployment().name, location)}-Storage-QueueServices' params: { storageAccountName: storageAccount.name + diagnosticLogsRetentionInDays: contains(queueServices, 'diagnosticLogsRetentionInDays') ? queueServices.diagnosticLogsRetentionInDays : 365 + diagnosticStorageAccountId: contains(queueServices, 'diagnosticStorageAccountId') ? queueServices.diagnosticStorageAccountId : '' + eventHubAuthorizationRuleId: contains(queueServices, 'eventHubAuthorizationRuleId') ? queueServices.eventHubAuthorizationRuleId : '' + eventHubName: contains(queueServices, 'eventHubName') ? queueServices.eventHubName : '' + logsToEnable: contains(queueServices, 'logsToEnable') ? queueServices.logsToEnable : [] + metricsToEnable: contains(queueServices, 'metricsToEnable') ? queueServices.metricsToEnable : [] queues: contains(queueServices, 'queues') ? queueServices.queues : [] + workspaceId: contains(queueServices, 'workspaceId') ? queueServices.workspaceId : '' } } @@ -238,7 +306,14 @@ module storageAccount_tableServices 'tableServices/deploy.bicep' = if (!empty(ta name: '${uniqueString(deployment().name, location)}-Storage-TableServices' params: { storageAccountName: storageAccount.name + diagnosticLogsRetentionInDays: contains(tableServices, 'diagnosticLogsRetentionInDays') ? tableServices.diagnosticLogsRetentionInDays : 365 + diagnosticStorageAccountId: contains(tableServices, 'diagnosticStorageAccountId') ? tableServices.diagnosticStorageAccountId : '' + eventHubAuthorizationRuleId: contains(tableServices, 'eventHubAuthorizationRuleId') ? tableServices.eventHubAuthorizationRuleId : '' + eventHubName: contains(tableServices, 'eventHubName') ? tableServices.eventHubName : '' + logsToEnable: contains(tableServices, 'logsToEnable') ? tableServices.logsToEnable : [] + metricsToEnable: contains(tableServices, 'metricsToEnable') ? tableServices.metricsToEnable : [] tables: contains(tableServices, 'tables') ? tableServices.tables : [] + workspaceId: contains(tableServices, 'workspaceId') ? tableServices.workspaceId : '' } } diff --git a/arm/Microsoft.Storage/storageAccounts/fileServices/deploy.bicep b/arm/Microsoft.Storage/storageAccounts/fileServices/deploy.bicep index 1533ddc584..6282c2e47e 100644 --- a/arm/Microsoft.Storage/storageAccounts/fileServices/deploy.bicep +++ b/arm/Microsoft.Storage/storageAccounts/fileServices/deploy.bicep @@ -14,12 +14,68 @@ param shareDeleteRetentionPolicy object = { days: 7 } +@description('Optional. 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('Optional. Resource ID of the diagnostic storage account.') +param diagnosticStorageAccountId string = '' + +@description('Optional. Resource ID of a log analytics workspace.') +param workspaceId string = '' + +@description('Optional. Resource ID of the event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to.') +param eventHubAuthorizationRuleId string = '' + +@description('Optional. Name of the event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category.') +param eventHubName string = '' + @description('Optional. File shares to create.') param shares array = [] @description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered') param cuaId string = '' +@description('Optional. The name of logs that will be streamed.') +@allowed([ + 'StorageRead' + 'StorageWrite' + 'StorageDelete' +]) +param logsToEnable array = [ + 'StorageRead' + 'StorageWrite' + 'StorageDelete' +] + +@description('Optional. The name of metrics that will be streamed.') +@allowed([ + 'Transaction' +]) +param metricsToEnable array = [ + 'Transaction' +] + +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 + } +}] + module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) { name: 'pid-${cuaId}' params: {} @@ -38,6 +94,19 @@ resource fileServices 'Microsoft.Storage/storageAccounts/fileServices@2021-04-01 } } +resource fileServices_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if ((!empty(diagnosticStorageAccountId)) || (!empty(workspaceId)) || (!empty(eventHubAuthorizationRuleId)) || (!empty(eventHubName))) { + name: '${fileServices.name}-diagnosticSettings' + properties: { + storageAccountId: !empty(diagnosticStorageAccountId) ? diagnosticStorageAccountId : null + workspaceId: !empty(workspaceId) ? workspaceId : null + eventHubAuthorizationRuleId: !empty(eventHubAuthorizationRuleId) ? eventHubAuthorizationRuleId : null + eventHubName: !empty(eventHubName) ? eventHubName : null + metrics: diagnosticsMetrics + logs: diagnosticsLogs + } + scope: fileServices +} + module fileServices_shares 'shares/deploy.bicep' = [for (share, index) in shares: { name: '${deployment().name}-File-${index}' params: { diff --git a/arm/Microsoft.Storage/storageAccounts/fileServices/readme.md b/arm/Microsoft.Storage/storageAccounts/fileServices/readme.md index 3f905df4be..3334761911 100644 --- a/arm/Microsoft.Storage/storageAccounts/fileServices/readme.md +++ b/arm/Microsoft.Storage/storageAccounts/fileServices/readme.md @@ -7,6 +7,7 @@ This module can be used to deploy a file share service into a storage account. | Resource Type | API Version | | :-- | :-- | | `Microsoft.Authorization/roleAssignments` | 2020-04-01-preview | +| `Microsoft.Insights/diagnosticSettings` | 2021-05-01-preview | | `Microsoft.Storage/storageAccounts/fileServices` | 2021-04-01 | | `Microsoft.Storage/storageAccounts/fileServices/shares` | 2019-06-01 | @@ -15,11 +16,18 @@ This module can be used to deploy a file share service into a storage account. | Parameter Name | Type | Default Value | Possible Values | Description | | :-- | :-- | :-- | :-- | :-- | | `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered | +| `diagnosticLogsRetentionInDays` | int | `365` | | Optional. Specifies the number of days that logs will be kept for; a value of 0 will retain data indefinitely. | +| `diagnosticStorageAccountId` | string | | | Optional. Resource ID of the diagnostic storage account. | +| `eventHubAuthorizationRuleId` | string | | | Optional. Resource ID of the event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | +| `eventHubName` | string | | | Optional. Name of the event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. | +| `logsToEnable` | array | `[StorageRead, StorageWrite, StorageDelete]` | `[StorageRead, StorageWrite, StorageDelete]` | Optional. The name of logs that will be streamed. | +| `metricsToEnable` | array | `[Transaction]` | `[Transaction]` | Optional. The name of metrics that will be streamed. | | `name` | string | `default` | | Optional. The name of the file service | | `protocolSettings` | object | `{object}` | | Protocol settings for file service | | `shareDeleteRetentionPolicy` | object | `{object}` | | The service properties for soft delete. | | `shares` | _[shares](shares/readme.md)_ array | `[]` | | Optional. File shares to create. | | `storageAccountName` | string | | | Required. Name of the Storage Account. | +| `workspaceId` | string | | | Optional. Resource ID of a log analytics workspace. | ## Outputs @@ -32,5 +40,6 @@ This module can be used to deploy a file share service into a storage account. ## Template references - [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) +- [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) - [Storageaccounts/Fileservices](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-04-01/storageAccounts/fileServices) - [Storageaccounts/Fileservices/Shares](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Storage/2019-06-01/storageAccounts/fileServices/shares) diff --git a/arm/Microsoft.Storage/storageAccounts/queueServices/deploy.bicep b/arm/Microsoft.Storage/storageAccounts/queueServices/deploy.bicep index 27f7e9d453..5a7ba6cb5c 100644 --- a/arm/Microsoft.Storage/storageAccounts/queueServices/deploy.bicep +++ b/arm/Microsoft.Storage/storageAccounts/queueServices/deploy.bicep @@ -8,9 +8,65 @@ param name string = 'default' @description('Optional. Queues to create.') param queues array = [] +@description('Optional. 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('Optional. Resource ID of the diagnostic storage account.') +param diagnosticStorageAccountId string = '' + +@description('Optional. Resource ID of a log analytics workspace.') +param workspaceId string = '' + +@description('Optional. Resource ID of the event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to.') +param eventHubAuthorizationRuleId string = '' + +@description('Optional. Name of the event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category.') +param eventHubName string = '' + @description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered') param cuaId string = '' +@description('Optional. The name of logs that will be streamed.') +@allowed([ + 'StorageRead' + 'StorageWrite' + 'StorageDelete' +]) +param logsToEnable array = [ + 'StorageRead' + 'StorageWrite' + 'StorageDelete' +] + +@description('Optional. The name of metrics that will be streamed.') +@allowed([ + 'Transaction' +]) +param metricsToEnable array = [ + 'Transaction' +] + +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 + } +}] + module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) { name: 'pid-${cuaId}' params: {} @@ -26,6 +82,19 @@ resource queueServices 'Microsoft.Storage/storageAccounts/queueServices@2021-04- properties: {} } +resource queueServices_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if ((!empty(diagnosticStorageAccountId)) || (!empty(workspaceId)) || (!empty(eventHubAuthorizationRuleId)) || (!empty(eventHubName))) { + name: '${queueServices.name}-diagnosticSettings' + properties: { + storageAccountId: !empty(diagnosticStorageAccountId) ? diagnosticStorageAccountId : null + workspaceId: !empty(workspaceId) ? workspaceId : null + eventHubAuthorizationRuleId: !empty(eventHubAuthorizationRuleId) ? eventHubAuthorizationRuleId : null + eventHubName: !empty(eventHubName) ? eventHubName : null + metrics: diagnosticsMetrics + logs: diagnosticsLogs + } + scope: queueServices +} + module queueServices_queues 'queues/deploy.bicep' = [for (queue, index) in queues: { name: '${deployment().name}-Queue-${index}' params: { diff --git a/arm/Microsoft.Storage/storageAccounts/queueServices/queues/deploy.bicep b/arm/Microsoft.Storage/storageAccounts/queueServices/queues/deploy.bicep index 946f15b004..0a7841ac89 100644 --- a/arm/Microsoft.Storage/storageAccounts/queueServices/queues/deploy.bicep +++ b/arm/Microsoft.Storage/storageAccounts/queueServices/queues/deploy.bicep @@ -5,10 +5,10 @@ param storageAccountName string @description('Optional. The name of the queue service') param queueServicesName string = 'default' -@description('The name of the storage queue to deploy') +@description('Required. The name of the storage queue to deploy') param name string -@description('A name-value pair that represents queue metadata.') +@description('Required. A name-value pair that represents queue metadata.') param metadata object = {} @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 it\'s fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'') diff --git a/arm/Microsoft.Storage/storageAccounts/queueServices/queues/readme.md b/arm/Microsoft.Storage/storageAccounts/queueServices/queues/readme.md index 3104ca58c9..0664c92dc1 100644 --- a/arm/Microsoft.Storage/storageAccounts/queueServices/queues/readme.md +++ b/arm/Microsoft.Storage/storageAccounts/queueServices/queues/readme.md @@ -14,8 +14,8 @@ This module deployes a storage account queue | Parameter Name | Type | Default Value | Possible Values | Description | | :-- | :-- | :-- | :-- | :-- | | `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered | -| `metadata` | object | `{object}` | | A name-value pair that represents queue metadata. | -| `name` | string | | | The name of the storage queue to deploy | +| `metadata` | object | `{object}` | | Required. A name-value pair that represents queue metadata. | +| `name` | string | | | Required. The name of the storage queue to deploy | | `queueServicesName` | string | `default` | | Optional. The name of the queue service | | `roleAssignments` | array | `[]` | | 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 it's fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11' | | `storageAccountName` | string | | | Required. Name of the Storage Account. | diff --git a/arm/Microsoft.Storage/storageAccounts/queueServices/readme.md b/arm/Microsoft.Storage/storageAccounts/queueServices/readme.md index dbcd3a6b61..32afcf82d4 100644 --- a/arm/Microsoft.Storage/storageAccounts/queueServices/readme.md +++ b/arm/Microsoft.Storage/storageAccounts/queueServices/readme.md @@ -7,6 +7,7 @@ This module can be used to deploy a file share service into a storage account. | Resource Type | API Version | | :-- | :-- | | `Microsoft.Authorization/roleAssignments` | 2020-04-01-preview | +| `Microsoft.Insights/diagnosticSettings` | 2021-05-01-preview | | `Microsoft.Storage/storageAccounts/queueServices` | 2021-04-01 | | `Microsoft.Storage/storageAccounts/queueServices/queues` | 2019-06-01 | @@ -15,9 +16,17 @@ This module can be used to deploy a file share service into a storage account. | Parameter Name | Type | Default Value | Possible Values | Description | | :-- | :-- | :-- | :-- | :-- | | `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered | +| `diagnosticLogsRetentionInDays` | int | `365` | | Optional. Specifies the number of days that logs will be kept for; a value of 0 will retain data indefinitely. | +| `diagnosticStorageAccountId` | string | | | Optional. Resource ID of the diagnostic storage account. | +| `eventHubAuthorizationRuleId` | string | | | Optional. Resource ID of the event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | +| `eventHubName` | string | | | Optional. Name of the event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. | +| `logsToEnable` | array | `[StorageRead, StorageWrite, StorageDelete]` | `[StorageRead, StorageWrite, StorageDelete]` | Optional. The name of logs that will be streamed. | +| `metricsToEnable` | array | `[Transaction]` | `[Transaction]` | Optional. The name of metrics that will be streamed. | | `name` | string | `default` | | Optional. The name of the queue service | | `queues` | _[queues](queues/readme.md)_ array | `[]` | | Optional. Queues to create. | | `storageAccountName` | string | | | Required. Name of the Storage Account. | +| `workspaceId` | string | | | Optional. Resource ID of a log analytics workspace. | + ## Outputs @@ -30,5 +39,6 @@ This module can be used to deploy a file share service into a storage account. ## Template references - [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) +- [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) - [Storageaccounts/Queueservices](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-04-01/storageAccounts/queueServices) - [Storageaccounts/Queueservices/Queues](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Storage/2019-06-01/storageAccounts/queueServices/queues) diff --git a/arm/Microsoft.Storage/storageAccounts/readme.md b/arm/Microsoft.Storage/storageAccounts/readme.md index 286e6647a0..187e9a0628 100644 --- a/arm/Microsoft.Storage/storageAccounts/readme.md +++ b/arm/Microsoft.Storage/storageAccounts/readme.md @@ -8,6 +8,7 @@ This module is used to deploy a storage account, with the ability to deploy 1 or | :-- | :-- | | `Microsoft.Authorization/locks` | 2016-09-01 | | `Microsoft.Authorization/roleAssignments` | 2020-04-01-preview | +| `Microsoft.Insights/diagnosticSettings` | 2021-05-01-preview | | `Microsoft.Network/privateEndpoints` | 2021-05-01 | | `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | 2021-02-01 | | `Microsoft.Storage/storageAccounts` | 2021-06-01 | @@ -31,11 +32,16 @@ This module is used to deploy a storage account, with the ability to deploy 1 or | `basetime` | string | `[utcNow('u')]` | | Generated. Do not provide a value! This date value is used to generate a SAS token to access the modules. | | `blobServices` | _[blobServices](blobServices/readme.md)_ object | `{object}` | | Optional. Blob service and containers to deploy | | `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered | +| `diagnosticLogsRetentionInDays` | int | `365` | | Optional. Specifies the number of days that logs will be kept for; a value of 0 will retain data indefinitely. | +| `diagnosticStorageAccountId` | string | | | Optional. Resource ID of the diagnostic storage account. | | `enableHierarchicalNamespace` | bool | | | Optional. If true, enables Hierarchical Namespace for the storage account | +| `eventHubAuthorizationRuleId` | string | | | Optional. Resource ID of the event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | +| `eventHubName` | string | | | Optional. Name of the event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. | | `fileServices` | _[fileServices](fileServices/readme.md)_ object | `{object}` | | Optional. File service and shares to deploy | | `location` | string | `[resourceGroup().location]` | | Optional. Location for all resources. | | `lock` | string | `NotSpecified` | `[CanNotDelete, NotSpecified, ReadOnly]` | Optional. Specify the type of lock. | | `managementPolicyRules` | array | `[]` | | Optional. The Storage Account ManagementPolicies Rules. | +| `metricsToEnable` | array | `[Transaction]` | `[Transaction]` | Optional. The name of metrics that will be streamed. | | `minimumTlsVersion` | string | `TLS1_2` | `[TLS1_0, TLS1_1, TLS1_2]` | Optional. Set the minimum TLS version on request to storage. | | `name` | string | | | Optional. Name of the Storage Account. | | `networkAcls` | object | `{object}` | | Optional. Networks ACLs, this value contains IPs to whitelist and/or Subnet information. | @@ -50,6 +56,7 @@ This module is used to deploy a storage account, with the ability to deploy 1 or | `tags` | object | `{object}` | | Optional. Tags of the resource. | | `userAssignedIdentities` | object | `{object}` | | Optional. The ID(s) to assign to the resource. | | `vNetId` | string | | | Optional. Virtual Network Identifier used to create a service endpoint. | +| `workspaceId` | string | | | Optional. Resource ID of a log analytics workspace. | ### Parameter Usage: `roleAssignments` @@ -174,9 +181,9 @@ The hierarchical namespace of the storage account (see parameter `enableHierarch ## Template references - [Locks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2016-09-01/locks) -- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) -- [Privateendpoints](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-05-01/privateEndpoints) +- [Privateendpoints](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/privateEndpoints) - [Privateendpoints/Privatednszonegroups](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-02-01/privateEndpoints/privateDnsZoneGroups) +- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) - [Storageaccounts](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-06-01/storageAccounts) - [Storageaccounts/Blobservices](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-06-01/storageAccounts/blobServices) - [Storageaccounts/Blobservices/Containers](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Storage/2019-06-01/storageAccounts/blobServices/containers) diff --git a/arm/Microsoft.Storage/storageAccounts/tableServices/deploy.bicep b/arm/Microsoft.Storage/storageAccounts/tableServices/deploy.bicep index 90e1ce5712..bd8d531e66 100644 --- a/arm/Microsoft.Storage/storageAccounts/tableServices/deploy.bicep +++ b/arm/Microsoft.Storage/storageAccounts/tableServices/deploy.bicep @@ -8,9 +8,65 @@ param name string = 'default' @description('Optional. tables to create.') param tables array = [] +@description('Optional. 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('Optional. Resource ID of the diagnostic storage account.') +param diagnosticStorageAccountId string = '' + +@description('Optional. Resource ID of a log analytics workspace.') +param workspaceId string = '' + +@description('Optional. Resource ID of the event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to.') +param eventHubAuthorizationRuleId string = '' + +@description('Optional. Name of the event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category.') +param eventHubName string = '' + @description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered') param cuaId string = '' +@description('Optional. The name of logs that will be streamed.') +@allowed([ + 'StorageRead' + 'StorageWrite' + 'StorageDelete' +]) +param logsToEnable array = [ + 'StorageRead' + 'StorageWrite' + 'StorageDelete' +] + +@description('Optional. The name of metrics that will be streamed.') +@allowed([ + 'Transaction' +]) +param metricsToEnable array = [ + 'Transaction' +] + +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 + } +}] + module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) { name: 'pid-${cuaId}' params: {} @@ -26,6 +82,19 @@ resource tableServices 'Microsoft.Storage/storageAccounts/tableServices@2021-04- properties: {} } +resource tableServices_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if ((!empty(diagnosticStorageAccountId)) || (!empty(workspaceId)) || (!empty(eventHubAuthorizationRuleId)) || (!empty(eventHubName))) { + name: '${tableServices.name}-diagnosticSettings' + properties: { + storageAccountId: !empty(diagnosticStorageAccountId) ? diagnosticStorageAccountId : null + workspaceId: !empty(workspaceId) ? workspaceId : null + eventHubAuthorizationRuleId: !empty(eventHubAuthorizationRuleId) ? eventHubAuthorizationRuleId : null + eventHubName: !empty(eventHubName) ? eventHubName : null + metrics: diagnosticsMetrics + logs: diagnosticsLogs + } + scope: tableServices +} + module tableServices_tables 'tables/deploy.bicep' = [for (tableName, index) in tables: { name: '${deployment().name}-Table-${index}' params: { diff --git a/arm/Microsoft.Storage/storageAccounts/tableServices/readme.md b/arm/Microsoft.Storage/storageAccounts/tableServices/readme.md index 53352bc756..499eea50a0 100644 --- a/arm/Microsoft.Storage/storageAccounts/tableServices/readme.md +++ b/arm/Microsoft.Storage/storageAccounts/tableServices/readme.md @@ -6,6 +6,7 @@ This module deploys a storage account table service | Resource Type | API Version | | :-- | :-- | +| `Microsoft.Insights/diagnosticSettings` | 2021-05-01-preview | | `Microsoft.Storage/storageAccounts/tableServices` | 2021-04-01 | | `Microsoft.Storage/storageAccounts/tableServices/tables` | 2021-06-01 | @@ -14,10 +15,16 @@ This module deploys a storage account table service | Parameter Name | Type | Default Value | Possible Values | Description | | :-- | :-- | :-- | :-- | :-- | | `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered | +| `diagnosticLogsRetentionInDays` | int | `365` | | Optional. Specifies the number of days that logs will be kept for; a value of 0 will retain data indefinitely. | +| `diagnosticStorageAccountId` | string | | | Optional. Resource ID of the diagnostic storage account. | +| `eventHubAuthorizationRuleId` | string | | | Optional. Resource ID of the event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | +| `eventHubName` | string | | | Optional. Name of the event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. | +| `logsToEnable` | array | `[StorageRead, StorageWrite, StorageDelete]` | `[StorageRead, StorageWrite, StorageDelete]` | Optional. The name of logs that will be streamed. | +| `metricsToEnable` | array | `[Transaction]` | `[Transaction]` | Optional. The name of metrics that will be streamed. | | `name` | string | `default` | | Optional. The name of the table service | | `storageAccountName` | string | | | Required. Name of the Storage Account. | | `tables` | _[tables](tables/readme.md)_ array | `[]` | | Optional. tables to create. | - +| `workspaceId` | string | | | Optional. Resource ID of a log analytics workspace. | ## Outputs @@ -29,5 +36,6 @@ This module deploys a storage account table service ## Template references +- [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) - [Storageaccounts/Tableservices](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-04-01/storageAccounts/tableServices) - [Storageaccounts/Tableservices/Tables](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Storage/2021-06-01/storageAccounts/tableServices/tables) diff --git a/arm/Microsoft.VirtualMachineImages/imageTemplates/readme.md b/arm/Microsoft.VirtualMachineImages/imageTemplates/readme.md index 6c13311655..e3d402878d 100644 --- a/arm/Microsoft.VirtualMachineImages/imageTemplates/readme.md +++ b/arm/Microsoft.VirtualMachineImages/imageTemplates/readme.md @@ -120,4 +120,4 @@ Tag names and tag values can be provided as needed. A tag can be left without a - [Locks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2016-09-01/locks) - [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) -- [Imagetemplates](https://docs.microsoft.com/en-us/azure/templates/Microsoft.VirtualMachineImages/2020-02-14/imageTemplates) +- [Define resources with Bicep and ARM templates](https://docs.microsoft.com/en-us/azure/templates) diff --git a/arm/Microsoft.Web/sites/config/readme.md b/arm/Microsoft.Web/sites/config/readme.md index 35932b9bd2..cb8a04a913 100644 --- a/arm/Microsoft.Web/sites/config/readme.md +++ b/arm/Microsoft.Web/sites/config/readme.md @@ -30,4 +30,4 @@ This module deploys a site config resource. ## Template references -- [Sites/Config](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Web/2021-02-01/sites/config) +- ['sites/config' Parent Documentation](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Web/sites) diff --git a/arm/Microsoft.Web/sites/readme.md b/arm/Microsoft.Web/sites/readme.md index fa7cb09d85..0b20f3f1de 100644 --- a/arm/Microsoft.Web/sites/readme.md +++ b/arm/Microsoft.Web/sites/readme.md @@ -192,4 +192,4 @@ You can specify multiple user assigned identities to a resource by providing add - [Privateendpoints/Privatednszonegroups](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-03-01/privateEndpoints/privateDnsZoneGroups) - [Serverfarms](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Web/2021-02-01/serverfarms) - [Sites](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Web/2020-12-01/sites) -- [Sites/Config](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Web/2021-02-01/sites/config) +- ['sites/config' Parent Documentation](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Web/sites) diff --git a/arm/README.md b/arm/README.md index bcc43eb2e0..fe4c59a150 100644 --- a/arm/README.md +++ b/arm/README.md @@ -57,6 +57,7 @@ In this section you can find useful information regarding the Modules that are c | [Virtual Network Gateway Connections](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/connections) | | [connections](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/connections) | | [DDoS Protection Plans](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/ddosProtectionPlans) | | [ddosProtectionPlans](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/ddosProtectionPlans) | | [ExpressRoute Circuits](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/expressRouteCircuits) | | [expressRouteCircuits](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/expressRouteCircuits) | +| [Network Firewall Policies](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/firewallPolicies) | | [firewallPolicies](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/firewallPolicies) | | [IP Groups](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/ipGroups) | | [ipGroups](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/ipGroups) | | [Load Balancers](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/loadBalancers) | | [loadBalancers](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/loadBalancers) | | [Local Network Gateways](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/localNetworkGateways) | | [localNetworkGateways](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/localNetworkGateways) | diff --git a/docs/wiki/Context.md b/docs/wiki/Context.md index 0238798df0..281bb43f13 100644 --- a/docs/wiki/Context.md +++ b/docs/wiki/Context.md @@ -118,14 +118,14 @@ Deploying resources by referencing their corresponding modules from source contr ## Where does this platform fit in? -The _CARML_ platform hosts a collection of [resource modules](./Modules.md) with the intend to cover as many Azure resources and their child-resources as possible. +The _CARML_ platform hosts a collection of [resource modules](./Modules) with the intend to cover as many Azure resources and their child-resources as possible. As such, users can use the modules as they are, alter them and or use them to deploy their environments. -To ensure the modules are valid and can perform the intended deployments, the repository comes with a [validation & test](./Testing.md) [pipeline](./Pipelines.md) for each module. If successful it will also publish them in one or multiple target locations. +To ensure the modules are valid and can perform the intended deployments, the repository comes with a [validation & test](./Testing) [pipeline](./Pipelines) for each module. If successful it will also publish them in one or multiple target locations. As such, _CARML_ covers the `bottom box` of the [deployment model](#what-is-the-intended-the-deployment-model) section and `Phase #1` & `Phase #2` of the [deployment flow](#what-is-the-intended-deployment-flow) section. Complete deployment flow filtered -As we want to enable any user of this repository's content to not only leverage its modules but actually also re-use the platform, the platform itself is set up so that you can plug it into your own environment with just a few basic steps described in the [Getting Started](./GettingStarted.md) section. You may choose to add or remove modules, define your own locations you want to publish to and as such create your own open- or inner-source library. +As we want to enable any user of this repository's content to not only leverage its modules but actually also re-use the platform, the platform itself is set up so that you can plug it into your own environment with just a few basic steps described in the [Getting Started](./GettingStarted) section. You may choose to add or remove modules, define your own locations you want to publish to and as such create your own open- or inner-source library. diff --git a/docs/wiki/ContributionGuide.md b/docs/wiki/ContributionGuide.md index e21b366657..a9d7d04583 100644 --- a/docs/wiki/ContributionGuide.md +++ b/docs/wiki/ContributionGuide.md @@ -13,13 +13,13 @@ This section outlines how you can contribute to the repository. # Set your environment up -The preferred method of contribution requires you to create your own fork and create pull requests into the source repository from there. To set the fork up, please follow the process described in the ['Getting Started'](./GettingStarted.md#Option-1-Use-it-as-a-basis-to-set-up-your-own-inner-source-project) section. +The preferred method of contribution requires you to create your own fork and create pull requests into the source repository from there. To set the fork up, please follow the process described in the ['Getting Started'](./GettingStarted#Option-1-Use-it-as-a-basis-to-set-up-your-own-inner-source-project) section. # How to contribute? You can contribute to the Wiki in different ways depending on your own interests, bugs you see or IP you want to add. -For starters it is highly recommended to consult and understand the ['Modules Design'](./ModulesDesign.md) section of the wiki. +For starters it is highly recommended to consult and understand the ['Modules Design'](./ModulesDesign) section of the wiki. How you proceed from here depends on your particular situation: @@ -36,4 +36,4 @@ To contribute to the modules, set your environment up, test the updated/added mo Status Badge -Please make sure to set your environment up and also consult the ['Pipeline Design'](./PipelinesDesign.md) and ['Pipeline Usage'](./PipelinesUsage.md) sections. +Please make sure to set your environment up and also consult the ['Pipeline Design'](./PipelinesDesign) and ['Pipeline Usage'](./PipelinesUsage) sections. diff --git a/docs/wiki/GettingStarted.md b/docs/wiki/GettingStarted.md index e6f9d89b43..36b41917c0 100644 --- a/docs/wiki/GettingStarted.md +++ b/docs/wiki/GettingStarted.md @@ -117,7 +117,7 @@ Please refer to [this list][AzureNames] to check which services have a global sc ### Dependencies -As the modules we test often times have dependencies to other services, we created a pipeline to deploys several standard services like VirtualNetworks and KeyVaults (alongside dummy secrets) for the modules to use. This _dependency_ pipeline should be prepared and executed before you start running any pipelines on your own. In case you need to rename any services there (for example because a certain globally unique resource name was already taken) make sure to update any references to this name in the module parameter files. You can find further details about this pipeline [here](./TestingDesign.md#Module-Dependencies). +As the modules we test often times have dependencies to other services, we created a pipeline to deploys several standard services like VirtualNetworks and KeyVaults (alongside dummy secrets) for the modules to use. This _dependency_ pipeline should be prepared and executed before you start running any pipelines on your own. In case you need to rename any services there (for example because a certain globally unique resource name was already taken) make sure to update any references to this name in the module parameter files. You can find further details about this pipeline [here](./TestingDesign#Module-Dependencies). ### GitHub-specific prerequisites @@ -173,7 +173,7 @@ In case you would like to simply contribute because you, for example, want to ad ## Parameter File Tokens -If you are forking or cloning the repository, you can use 'tokens' inside your parameter files. Tokens allow you to test deploying modules in your own environment (i.e. using tokens for your naming conventions), or apply other customizations to your resources (i.e. using your own subscription ID inside a Resource ID string). See details in the [Parameter File Tokens Design](./ParameterFileTokens.md). +If you are forking or cloning the repository, you can use 'tokens' inside your parameter files. Tokens allow you to test deploying modules in your own environment (i.e. using tokens for your naming conventions), or apply other customizations to your resources (i.e. using your own subscription ID inside a Resource ID string). See details in the [Parameter File Tokens Design](./ParameterFileTokens). The repository contains a [Settings.json](https://github.com/Azure/ResourceModules/blob/main/settings.json) that enables you to define local tokens and store them in source control. The token format is a `name` and `value` pair as shown in the following example: @@ -203,7 +203,7 @@ Once the Key Vault is deployed, you'll notice that the Key Vault name in Azure w > The token prefix `<<` and suffix `>>` in the above example are also configurable in the [Settings.json](https://github.com/Azure/ResourceModules/blob/main/settings.json) file. They are however the default used in the CARML main repository. --- -Note: There are default tokens that can be enabled on any resource that leverages the [GitHub specific prerequisites](GettingStarted.md#github-specific-prerequisites) secrets. +Note: There are default tokens that can be enabled on any resource that leverages the [GitHub specific prerequisites](GettingStarted#github-specific-prerequisites) secrets. - `<>`: Will point to the Azure subscription. - `<>`: Will point to the Azure an Azure Management Group. @@ -211,7 +211,7 @@ Note: There are default tokens that can be enabled on any resource that leverage - `<>`: Will point to the Service Principal ID used for deployments. - `<>`: Will point to the Azure Resource Group where the resources are being deployed to. (This isn't defined in the secrets section but is injected at runtime) -Review [Parameter File Tokens Design](./ParameterFileTokens.md) for more details. +Review [Parameter File Tokens Design](./ParameterFileTokens) for more details. --- diff --git a/docs/wiki/Home.md b/docs/wiki/Home.md index 4d2e2ae0fa..c900a946b7 100644 --- a/docs/wiki/Home.md +++ b/docs/wiki/Home.md @@ -4,27 +4,27 @@ The objective of this repository is to provide a template library that can be re This wiki describes the content of this repository, the modules, pipelines, possible options on how to use them and how to contribute to this project. -If you're unfamiliar with Infrastructure as Code, or wonder how you can use the contents of this repository in your deployments please check out the [context](./Context.md) section of this wiki. +If you're unfamiliar with Infrastructure as Code, or wonder how you can use the contents of this repository in your deployments please check out the [context](./Context) section of this wiki. ### _Navigation_ -- [Context](./Context.md) - - [Infrastructure as Code](./Context.md#infrastructure-as-code-iac) - - [Where does this platform fit in?](./Context.md#where-does-this-platform-fit-in.md) -- [Getting Started](./GettingStarted.md) - - [General prerequisites](./GettingStarted.md#General-prerequisites.md) - - [Where to start](./GettingStarted.md#Where-to-start.md) -- [Modules](./Modules.md) - - [Design](./ModulesDesign.md) - - [Usage](./ModulesUsage.md) -- [Testing](./Testing.md) - - [Design](./TestingDesign.md) - - [Usage](./TestingUsage.md) -- [Pipelines](./Pipelines.md) - - [Design](./PipelinesDesign.md) - - [Usage](./PipelinesUsage.md) -- [Contribution Guide](./ContributionGuide.md) -- [Known Issues](./KnownIssues.md) +- [Context](./Context) + - [Infrastructure as Code](./Context#infrastructure-as-code-iac) + - [Where does this platform fit in?](./Context#where-does-this-platform-fit-in) +- [Getting Started](./GettingStarted) + - [General prerequisites](./GettingStarted#General-prerequisites) + - [Where to start](./GettingStarted#Where-to-start) +- [Modules](./Modules) + - [Design](./ModulesDesign) + - [Usage](./ModulesUsage) +- [Testing](./Testing) + - [Design](./TestingDesign) + - [Usage](./TestingUsage) +- [Pipelines](./Pipelines) + - [Design](./PipelinesDesign) + - [Usage](./PipelinesUsage) +- [Contribution Guide](./ContributionGuide) +- [Known Issues](./KnownIssues) # Scope @@ -33,7 +33,7 @@ Following you can find an abstract overview of everything in- and out-of-scope o ## In Scope - **Modules:** Rich library of resource modules - the foundation for workload or entire environments deployments - **Platform:** Pipelines to validate modules & publish to those that pass to a location of your choice. Available with GitHub Workflows. -- **Documentation:** A rich documentation of best practices on [module](./Modules.md) design, the [platforms](./Context.md) and its [context](./Context.md), [testing](./Testing.md) and [pipelines](./Pipelines.md) +- **Documentation:** A rich documentation of best practices on [module](./Modules) design, the [platforms](./Context) and its [context](./Context), [testing](./Testing) and [pipelines](./Pipelines) ## Out of Scope - **Orchestration:** Orchestrated solutions such as workloads or entire environments intended for production environments diff --git a/docs/wiki/Modules.md b/docs/wiki/Modules.md index 2b0bbad7d8..8f47239754 100644 --- a/docs/wiki/Modules.md +++ b/docs/wiki/Modules.md @@ -6,12 +6,12 @@ This section and its sub-sections give you an overview of the principals the mod ### _Navigation_ -- [Module Design](./ModulesDesign.md) - - [General guidelines](./ModulesDesign.md#general-guidelines) - - [File & folder structure](./ModulesDesign.md#file--folder-structure) - - [Bicep template guidelines](./ModulesDesign.md#bicep-template-guidelines) -- [Module Usage](./ModulesUsage.md) - - [Deploy local template](./ModulesUsage.md#deploy-local-template) - - [Deploy remote template](./ModulesUsage.md#deploy-remote-template) +- [Module Design](./ModulesDesign) + - [General guidelines](./ModulesDesign#general-guidelines) + - [File & folder structure](./ModulesDesign#file--folder-structure) + - [Bicep template guidelines](./ModulesDesign#bicep-template-guidelines) +- [Module Usage](./ModulesUsage) + - [Deploy local template](./ModulesUsage#deploy-local-template) + - [Deploy remote template](./ModulesUsage#deploy-remote-template) --- diff --git a/docs/wiki/ModulesDesign.md b/docs/wiki/ModulesDesign.md index 4c57ba5478..3bfe0cd8af 100644 --- a/docs/wiki/ModulesDesign.md +++ b/docs/wiki/ModulesDesign.md @@ -20,7 +20,7 @@ This section gives you an overview of the design principals the bicep modules fo --- -Modules are written in an quite flexible way, therefore you don’t need to modify them from project to project, as the aim is to cover most of the functionality that a given resource type can provide, in a way that you can interact with any module just by sending the required parameters to it – i.e. you don’t have to know how the template of the particular module works inside, just take a look at the `readme.md` file of the given module to consume it. +Modules are written in a quite flexible way, therefore you don’t need to modify them from project to project, as the aim is to cover most of the functionality that a given resource type can provide, in a way that you can interact with any module just by sending the required parameters to it – i.e. you don’t have to know how the template of the particular module works inside, just take a look at the `readme.md` file of the given module to consume it. The modules are multi-purpose, therefore contain a lot of dynamic expressions (functions, variables, etc.), so there’s no need to maintain multiple instances for different use cases. @@ -43,15 +43,15 @@ They can be deployed in different configurations just by changing the input para # File & folder structure -- [Naming](#naming) - [Structure](#structure) +- [Naming](#naming) - [Patterns](#patterns) -A **Module** consists of +A **CARML module** consists of -- the bicep template deployment file (`deploy.bicep`) -- one or multiple template parameters files (`*parameters.json`) that will be used for testing – located in the `parameters` sub-folder -- a `readme.md` file which describes the module itself +- The bicep template deployment file (`deploy.bicep`). +- One or multiple template parameters files (`*parameters.json`) that will be used for testing, located in the `.parameters` sub-folder. +- A `readme.md` file which describes the module itself. A module usually represents a single resource or a set of closely related resources. For example, a storage account and the associated lock or virtual machine and network interfaces. Modules are located in the `arm` folder. @@ -61,73 +61,6 @@ Also, each module should be implemented with all capabilities it and its childre - `Diagnostic Settings` - and ideally also `Private Endpoints`. -## Naming - -Use the following naming standard for module files and folders: - -- Modules name reflect the resource type -- Files and folders within the module folder are all in lower case -- Child-resource modules (in .bicep sub-folder) are named `nested_.bicep` - -``` txt -Microsoft. -└─ - ├─ .bicep - | ├─ nested_providerResource1.bicep - | └─ nested_providerResource2.bicep - ├─parameters - | └─ parameters.json - ├─ deploy.bicep - └─ readme.md -``` - -for example - -``` txt -Microsoft.Web -└─ sites - ├─ .bicep - | ├─ nested_rbac.bicep - | └─ nested_cuaId.bicep - ├─parameters - | └─ parameters.json - ├─ deploy.bicep - └─ readme.md -``` - -### Child resources naming - -When creating child-resources from parent resources you will need to specify a name that, when deployed, will be used to assign the deployment name. - -There are some constraints that needs to be considered when naming the deployment: - -- Deployment name length can't exceed 64 chars -- Two deployments with the same name created in different location will fail -- Using the same deployment name mode than once, will surface only the last one in the Azure Portal -- If more than one deployment with the same name runs at the same time, race condition might happen -- Human-readable names would be preferable, even if not necessary - -While exceptions might be needed, the following guidance should be followed as much as possible: - -- For child-resources of the top-level resource inside the top-level template (for example the `blobServices` deployment inside the `storageAccount` template) use the following naming structure - -``` -'${uniqueString(deployment().name, location)}-' -``` - -- In child-resource templates (for example inside for `containers` in the `blobServices` template), use the following naming structure - -``` -'${deployment().name}-[-${index}]' -``` - -Examples: - -``` -name: '${uniqueString(deployment().name, location)}-TableSvc' -name: '${deployment().name}-Table-${index}' -``` - ## Structure Modules in the repository are structured via the module's main resource provider (for example `Microsoft.Web`) and resource type (for example `serverfarms`) where each section of the path corresponds to its place in the hierarchy. However, for cases that do not fit into this schema we provide the following guidance: @@ -155,9 +88,44 @@ module server_databases 'databases/deploy.bicep' = [for (database, index) in dat Each module should come with a `.bicep` folder with a least the `nested_cuaId.bicep` file in it +## Naming + +Use the following naming standard for module files and folders: + +- Module folders are in camelCase and their name reflects the main resource type of the Bicep module they are hosting (e.g. `storageAccounts`, `virtualMachines`). +- Cross-referenced and extension resource modules are placed in the `.bicep` subfolder and named `nested_.bicep` + + ``` txt + Microsoft. + └─ + ├─ .bicep + | ├─ nested_crossReferencedResource1.bicep + | └─ nested_crossReferencedResource2.bicep + ├─ .parameters + | └─ parameters.json + ├─ deploy.bicep + └─ readme.md + ``` + + >**Example**: `nested_serverfarms.bicep` in the `Microsoft.Web\sites\.bicep` folder contains the cross-referenced `serverfarm` module leveraged by the top level `site` resource. + >``` txt + >Microsoft.Web + >└─ sites + > ├─ .bicep + > | ├─ nested_components.bicep + > | ├─ nested_cuaId.bicep + > | ├─ nested_privateEndpoint.bicep + > | ├─ nested_rbac.bicep + > | └─ nested_serverfarms.bicep + > ├─ .parameters + > | └─ parameters.json + > ├─ deploy.bicep + > └─ readme.md + >``` + ## Patterns -This sections shows you a few common patterns among resources that are usually very similar (e.g. providers) +This section details patterns among extension resources that are usually very similar in their structure among all modules supporting them: - [Locks](#locks) - [RBAC](#rbac) @@ -166,7 +134,7 @@ This sections shows you a few common patterns among resources that are usually v ### Locks -The locks provider can be added as a `resource` to the resource template directly. +The locks extension can be added as a `resource` to the resource template directly. ```bicep @allowed([ @@ -208,7 +176,10 @@ module _rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, in #### 2nd Element as nested `.bicep/nested_rbac.bicep` file -Here you specify the platform roles available for the main resource. You can find further information in the [variables](#variables) section. +Here you specify the platform roles available for the main resource. + +The `builtInRoleNames` variable contains the list of applicable roles for the specific resource to which the nested_rbac.bicep module applies. +>**Note**: You can find a helper script `Get-FormattedRBACRoles.ps1` in the `utilities\tools` folder of the repository. You can use this script to extract a formatted list of RBAC roles used in the CARML modules based on the RBAC lists in Azure. The element requires you to provide both the `principalIds` & `roleDefinitionOrIdName` to assign to the principal IDs. Also, the `resourceId` is target resource's resource ID that allows us to reference it as an `existing` resource. Note, the implementation of the `split` in the resource reference becomes longer the deeper you go in the child-resource hierarchy. @@ -305,10 +276,10 @@ var diagnosticsMetrics = [for metric in metricsToEnable: { resource _diagnosticSettings 'Microsoft.Insights/diagnosticsettings@2021-05-01-preview' = if (!empty(diagnosticStorageAccountId) || !empty(workspaceId) || !empty(eventHubAuthorizationRuleId) || !empty(eventHubName)) { name: '${.name}-diagnosticSettings' properties: { - storageAccountId: empty(diagnosticStorageAccountId) ? null : diagnosticStorageAccountId - workspaceId: empty(workspaceId) ? null : workspaceId - eventHubAuthorizationRuleId: empty(eventHubAuthorizationRuleId) ? null : eventHubAuthorizationRuleId - eventHubName: empty(eventHubName) ? null : eventHubName + storageAccountId: !empty(diagnosticStorageAccountId) ? diagnosticStorageAccountId : null + workspaceId: !empty(workspaceId) ? workspaceId : null + eventHubAuthorizationRuleId: !empty(eventHubAuthorizationRuleId) ? eventHubAuthorizationRuleId : null + eventHubName: !empty(eventHubName) ? eventHubName : null metrics: diagnosticsMetrics logs: diagnosticsLogs } @@ -396,16 +367,17 @@ resource privateDnsZoneGroups 'Microsoft.Network/privateEndpoints/privateDnsZone # Bicep template guidelines -Within a bicep file, follow the following conventions: +Within a bicep file, use the following conventions: - [Parameters](#parameters) - [Variables](#variables) -- [Resource](#resource) +- [Resources](#resources) +- [Modules](#modules) - [Outputs](#outputs) ## Parameters -- camelCase, i.e `resourceGroupName` +- Parameter names are in camelCase, e.g. `allowBlobPublicAccess`. - Descriptions contain type of requirement: - `Optional` - Is not needed at any point. Module contains default values. - `Required` - Is required to be provided. Module does not have a default value and will expect input. @@ -414,17 +386,16 @@ Within a bicep file, follow the following conventions: ## Variables -- camelCase, i.e `builtInRoleNames` -- For modules that manage roleAssignments, update the list of roles to only be the applicable roles. You can find a helper script `Get-FormattedRBACRoles.ps1` in the `tools` folder of the repository. +- Variable names are in camelCase, e.g. `builtInRoleNames`. -## Resource +## Resources -- camelCase, i.e `resourceGroup` +- Resource names are in camelCase, e.g. `resourceGroup`. - The name used as a reference is the singular name of the resource that it deploys, i.e: - `resource storageAccount 'Microsoft.Storage/storageAccounts@2019-06-01'` - `resource virtualMachine 'Microsoft.Compute/virtualMachines@2020-06-01'` - Parent reference - - If working on a child-resource, refrain from string concatenation and instead us the parent reference via the `existing` keyword. + - If working on a child-resource, refrain from string concatenation and instead use the parent reference via the `existing` keyword. - The way this is implemented differs slightly the lower you go in the hierarchy. Note the following examples: - 1st level child resource (example _storageAccount/blobService_) ```bicep @@ -474,34 +445,85 @@ Within a bicep file, follow the following conventions: properties: {...} } ``` -- Bicep `modules`: - - camel_Snake_Case, i.e `resourceGroup_rbac` ? - - Filename for nested module is structured as follows: `nested_.bicep` i.e: - - `nested_rbac.bicep` +## Modules + + - Module symbolic names are in camel_Snake_Case, following the schema `_` e.g. `storageAccount_fileServices`, `virtualMachine_nic`, `resourceGroup_rbac`. + - Modules enable you to reuse code from a Bicep file in other Bicep files. As such they're normally leveraged for deploying child resources (e.g. file services in a storage account), cross referenced resources (e.g. network interface in a virtual machine) or extension resources (e.g. role assignment in a resource group). + +### Deployment names + +When using modules from parent resources you will need to specify a name that, when deployed, will be used to assign the deployment name. + +There are some constraints that needs to be considered when naming the deployment: + +- Deployment name length can't exceed 64 chars. +- Two deployments with the same name created in different Azure locations (e.g. WestEurope & EastUS) in the same scope (e.g. resource group deployments) will fail. +- Using the same deployment name more than once, will surface only the most recent deployed one in the Azure Portal. +- If more than one deployment with the same name runs at the same time to the same scope, race condition might happen. +- Human-readable names are preferable, even if not necessary. + +While exceptions might be needed, the following guidance should be followed as much as possible: + +- When deploying more than one resource of the same referenced module is needed, we leverage loops using integer index and items in an array as per [Bicep loop syntax](https://docs.microsoft.com/en-us/azure/azure-resource-manager/bicep/loops#loop-syntax). In this case we also use `-${index}` as a suffix of the deployment name to avoid race condition: + + ``` + module symbolic_name 'path/to/referenced/module/deploy.bicep' = [for (, ) in : { + name: '-${index}' + ... + }] + ``` + > **Example**: for the `roleAssignment` deployment in the key vault `secrets` template + > ``` + > module secret_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: { + > name: '${deployment().name}-Rbac-${index}' + > ``` + +- For referenced resources of the top-level resource inside the top-level template use the following naming structure: + + ``` + '${uniqueString(deployment().name, location)}--' + ``` + > **Example**: for the `tableServices` deployment inside the `storageAccount` template + > ``` + > name: '${uniqueString(deployment().name, location)}-Storage-TableServices' + > ``` + +- In the referenced resource template use the following naming structure: + + ``` + '${deployment().name}-[-${index}]' + ``` + > **Example**: for the `tables` deployment in the `tableServices` template + > ``` + > name: '${deployment().name}-Table-${index}' + > ``` + ## Outputs -- camelCase, i.e `resourceGroupResourceId` +- Output names are in camelCase, i.e `storageAccountResourceId` - At a minimum, reference the following: - - `Name`, i.e. `resourceGroupName` - - `ResourceId`, i.e. `resourceGroupResourceId` -- Add a `@description('...')` annotation with meaningful description to each output + - `Name`, e.g. `storageAccountName`. + - `ResourceId`, e.g. `storageAccountResourceId`. + - `ResourceGroup` for resources deployed at resource group scope, e.g. `storageAccountResourceGroup`. + - `systemAssignedPrincipalId` for all resources supporting a managed identity. +- Add a `@description('...')` annotation with meaningful description to each output. --- # ReadMe -Each module must come with a ReadMe Markdown file that outlines what the module contains and 'how' it can be used. -It primary components are -- A title with a reference to the primary resource (for example KeyVault `[Microsoft.KeyVault/vaults]`) -- A description -- A table that outlines all resources that can be deployed as part of the module (Resource Types) -- A table that shows all parameters, what they are used for, what values they allow, etc. (Parameters) -- A custom 'Parameter Usage' section that show how to use special types of characters (e.g. roleAssignments) -- A table that describes all outputs the module template returns -- A references table to directly jump to the resources [ARM template reference](https://docs.microsoft.com/en-us/azure/templates) +Each module must come with a ReadMe markdown file that outlines what the module contains and 'how' it can be used. +Its primary components are in order: +- A title with a reference to the primary resource in Start Case followed by the primary resource namespace e.g. Key Vaults `[Microsoft.KeyVault/vaults]`. +- A short description +- A **Resource types** section with a table that outlines all resources that can be deployed as part of the module. +- A **Parameters** section with a table containing all parameters, their type, default and allowed values if any, and their description. +- Optionally, a **Parameter Usage** section that shows how to use complex structures such as parameter objects or array of objects, e.g. roleAssignments, tags, privateEndpoints. +- An **Outputs** section with a table that describes all outputs the module template returns. +- A **Template references** section listing relevant resources [ARM template reference](https://docs.microsoft.com/en-us/azure/templates). Note the following recommendations - Use our module generation script `Set-ModuleReadMe` that will do most of the work for you. Currently you can find it at 'utilities\tools\Set-ModuleReadMe.ps1'. Just load the file and invoke the function like this `Set-ModuleReadMe -TemplateFilePath '/deploy.bicep'` diff --git a/docs/wiki/ParameterFileTokens.md b/docs/wiki/ParameterFileTokens.md index 2004a2576b..12523b7acc 100644 --- a/docs/wiki/ParameterFileTokens.md +++ b/docs/wiki/ParameterFileTokens.md @@ -30,7 +30,7 @@ There are (2) Token types that can be applied on a Parameter File: #### 1. Default Tokens (Environment Variables) [Default] -These are tokens constructed from Environment Variables, which are defined in the Workflow (Pipeline). Review [Getting Started - GitHub specific prerequisites](./GettingStarted.md) for more information on these Environment Variables. +These are tokens constructed from Environment Variables, which are defined in the Workflow (Pipeline). Review [Getting Started - GitHub specific prerequisites](./GettingStarted) for more information on these Environment Variables. #### 2. Local Custom Tokens (Source Control) [Optional] diff --git a/docs/wiki/Pipelines.md b/docs/wiki/Pipelines.md index 540dc80467..5a4a421ec7 100644 --- a/docs/wiki/Pipelines.md +++ b/docs/wiki/Pipelines.md @@ -8,7 +8,7 @@ This section and its sub-sections give you an overview of the principals the pip ### _Navigation_ -- [Pipelines Design](./PipelinesDesign.md) -- [Pipelines Usage](./PipelinesUsage.md) +- [Pipelines Design](./PipelinesDesign) +- [Pipelines Usage](./PipelinesUsage) --- diff --git a/docs/wiki/PipelinesDesign.md b/docs/wiki/PipelinesDesign.md index 4d00b20b09..7cc9060349 100644 --- a/docs/wiki/PipelinesDesign.md +++ b/docs/wiki/PipelinesDesign.md @@ -76,7 +76,7 @@ The validation phase performs all test outside of a test deployment. This includ #### Static module validation -This static validation executes the tests documented in the [testing](./Testing.md) section. Without diving into to much detail, we test aspects like a proper ReadMe documentation, a proper module folder structure, a minimum number of refresh of the leveraged of API versions and the like. +This static validation executes the tests documented in the [testing](./Testing) section. Without diving into to much detail, we test aspects like a proper ReadMe documentation, a proper module folder structure, a minimum number of refresh of the leveraged of API versions and the like. #### Simulated deployment validation @@ -159,7 +159,7 @@ Dynamic parameters that do not need to be hardcoded in the parameter file, and t For example, some modules require referencing Azure resources with the Resource ID. This ID typically contains the `subscriptionId` in the format of `/subscriptions/<>/...`. This task substitutes the `<>` with the correct value, based on the different token types. -Please review the Parameter File Tokens [Design](./ParameterFileTokens.md) for more details on the different token types and how you can use them to remove hardcoded values from your parameter files. +Please review the Parameter File Tokens [Design](./ParameterFileTokens) for more details on the different token types and how you can use them to remove hardcoded values from your parameter files. --- @@ -173,7 +173,7 @@ Outside of the previously described platform pipelines we implemented several ad ## Dependencies pipeline -As the modules we test often times have dependencies to other services, we created a pipeline to deploys several standard services like VirtualNetworks and KeyVaults (alongside dummy secrets) for the modules to use. This _dependency_ pipeline should be prepared and executed before you start running any pipelines on your own. In case you need to rename any services there (for example because a certain globally unique resource name was already taken) make sure to update any references to this name in the module parameter files. You can find further details about this pipeline [here](./TestingDesign.md#Module-Dependencies). +As the modules we test often times have dependencies to other services, we created a pipeline to deploys several standard services like VirtualNetworks and KeyVaults (alongside dummy secrets) for the modules to use. This _dependency_ pipeline should be prepared and executed before you start running any pipelines on your own. In case you need to rename any services there (for example because a certain globally unique resource name was already taken) make sure to update any references to this name in the module parameter files. You can find further details about this pipeline [here](./TestingDesign#Module-Dependencies). ### Dependencies pipeline inputs diff --git a/docs/wiki/PipelinesUsage.md b/docs/wiki/PipelinesUsage.md index 8f9a6f1594..45e652c650 100644 --- a/docs/wiki/PipelinesUsage.md +++ b/docs/wiki/PipelinesUsage.md @@ -19,14 +19,14 @@ This section gives you an overview of how to interact with the platform pipeline When working with this platform's pipelines it is important to understand first which pipelines serve which purpose, when they are triggered and how you can use them to test your modules. -As described in the [Pipelines Design](./PipelinesDesign.md) section we offer the following pipelines: +As described in the [Pipelines Design](./PipelinesDesign) section we offer the following pipelines: | Pipeline | Target | Trigger | Notes | | - | - | - | - | -| [Module Pipelines](./PipelinesDesign.md#module-pipelines) | Module | Changes to [module\|workflow] files in branch [main\|master] or manual | Used to test & publish modules. This is the most common pipeline you will interact with when working on modules. | -| [Dependencies pipeline](./PipelinesDesign.md#dependencies-pipeline) | All required dependency resources | Manual | Deploys resources we reference in the module tests. Should be run once before testing modules. | -| [ReadMe pipeline](./PipelinesDesign.md#readme-pipeline) | `README.md` in `` & `/arm` | Changes to [template files] in branch [main\|master] | Keeps the target ReadMe files aligned with the modules in the repository. | -| [Wiki pipeline](./PipelinesDesign.md#wiki-pipeline) | Wiki | Changes in [docs/wiki] in branch [main\|master] | Keeps the Wiki-repository in sync with the wiki folder in the modules repository | +| [Module Pipelines](./PipelinesDesign#module-pipelines) | Module | Changes to [module\|workflow] files in branch [main\|master] or manual | Used to test & publish modules. This is the most common pipeline you will interact with when working on modules. | +| [Dependencies pipeline](./PipelinesDesign#dependencies-pipeline) | All required dependency resources | Manual | Deploys resources we reference in the module tests. Should be run once before testing modules. | +| [ReadMe pipeline](./PipelinesDesign#readme-pipeline) | `README.md` in `` & `/arm` | Changes to [template files] in branch [main\|master] | Keeps the target ReadMe files aligned with the modules in the repository. | +| [Wiki pipeline](./PipelinesDesign#wiki-pipeline) | Wiki | Changes in [docs/wiki] in branch [main\|master] | Keeps the Wiki-repository in sync with the wiki folder in the modules repository | --- @@ -49,7 +49,7 @@ To validate any updates you did to a module template you can perform the followi Once the pipeline concluded, it will either be in a green (success) or red (failed) state, depending on how the module performed. -If you open the pipeline's run, you should be able to investigate the logs and investigate the execution. In case any of the [validation](./PipelinesDesign.md#Validate) steps failed, the pipeline should give you detailed information of any error. In some cases in which Pester tests failed, you may only see the failed test and need to `expand` the error message. How this looks like depends on the [DevOps platform](#devops-tool-specific-considerations) you use. +If you open the pipeline's run, you should be able to investigate the logs and investigate the execution. In case any of the [validation](./PipelinesDesign#Validate) steps failed, the pipeline should give you detailed information of any error. In some cases in which Pester tests failed, you may only see the failed test and need to `expand` the error message. How this looks like depends on the [DevOps platform](#devops-tool-specific-considerations) you use. ## Operate the dependency pipeline @@ -57,13 +57,13 @@ As described previously, the dependency pipeline must be triggered manually and Triggering the pipeline is as easy as navigating to it in your corresponding DevOps tool and running the pipeline. No additional steps or input parameters are required. -> **Note:** While operating the dependency pipeline is simple, make sure to set it up in the way it is described [here](./GettingStarted.md#Dependencies). Especially the globally unique names must be accounted for, before executing the pipeline. +> **Note:** While operating the dependency pipeline is simple, make sure to set it up in the way it is described [here](./GettingStarted#Dependencies). Especially the globally unique names must be accounted for, before executing the pipeline. -Depending on what you want to test in your module pipeline, you may want to add additional dependencies to your dependency pipeline. If so, make sure to add an additional parameter file for each service you require under `utilities/pipelines/dependencies`. Once done, you just need to add the deployment to the pipeline itself in the correct location in the pipeline. The different deployment waves are documented [here](./TestingDesign.md#module-dependencies). The implementation depends on the [DevOps tool](#devops-tool-specific-considerations) you're using. +Depending on what you want to test in your module pipeline, you may want to add additional dependencies to your dependency pipeline. If so, make sure to add an additional parameter file for each service you require under `utilities/pipelines/dependencies`. Once done, you just need to add the deployment to the pipeline itself in the correct location in the pipeline. The different deployment waves are documented [here](./TestingDesign#module-dependencies). The implementation depends on the [DevOps tool](#devops-tool-specific-considerations) you're using. ## Add a new module pipeline -To add a new module pipeline we recommend to create a copy of a currently existing module pipeline and adjust all module-specific properties documented [here](./PipelinesDesign.md#component-workflows). The registration of the pipeline will differ depending on the DevOps tool you're using. For further information, please review the [DevOps-Tool-specific guidance](#devops-tool-specific-guidance) below. +To add a new module pipeline we recommend to create a copy of a currently existing module pipeline and adjust all module-specific properties documented [here](./PipelinesDesign#component-workflows). The registration of the pipeline will differ depending on the DevOps tool you're using. For further information, please review the [DevOps-Tool-specific guidance](#devops-tool-specific-guidance) below. --- @@ -86,7 +86,7 @@ then select the pipeline of your choice from the list on the left, followed by ' Run workflow Depending on the pipeline you selected you may have additional input parameters you can provide aside from the branch: -- [Module pipeline](./TestingDesign.md#module-pipeline-inputs) inputs +- [Module pipeline](./TestingDesign#module-pipeline-inputs) inputs ### Register a pipeline diff --git a/docs/wiki/Testing.md b/docs/wiki/Testing.md index 4d9a0dbc66..7383346162 100644 --- a/docs/wiki/Testing.md +++ b/docs/wiki/Testing.md @@ -6,11 +6,11 @@ This section and its sub-sections give you an overview of the principles the tes ### _Navigation_ -- [Testing Design](./TestingDesign.md) - - [Approach](./TestingDesign.md#approach) - - [API version validation](./TestingDesign.md#api-version-validation) - - [Template validation](./TestingDesign.md#template-validation) - - [Deployment validation](./TestingDesign.md#deployment-validation) -- [Testing Usage](./TestingUsage.md) +- [Testing Design](./TestingDesign) + - [Approach](./TestingDesign#approach) + - [API version validation](./TestingDesign#api-version-validation) + - [Template validation](./TestingDesign#template-validation) + - [Deployment validation](./TestingDesign#deployment-validation) +- [Testing Usage](./TestingUsage) --- diff --git a/docs/wiki/TestingDesign.md b/docs/wiki/TestingDesign.md index 5b09fbab31..2dcea11bc3 100644 --- a/docs/wiki/TestingDesign.md +++ b/docs/wiki/TestingDesign.md @@ -83,7 +83,7 @@ The template validation tests execute a dry-run with each parameter file provide If all other tests passed, the deployment tests are the ultimate module validation. Using the available & configured parameter files for a module, each is deployed to Azure (in parallel) and verifies if the deployment works end-to-end. -Most of the resources are deleted by default after their deployment, to keep costs down and to be able to retest resource modules from scratch in the next run. However, the removal step can be skipped in case further investigation on the deployed resource is needed. For further details, please refer to the (./PipelinesUsage.md) section. +Most of the resources are deleted by default after their deployment, to keep costs down and to be able to retest resource modules from scratch in the next run. However, the removal step can be skipped in case further investigation on the deployed resource is needed. For further details, please refer to the (./PipelinesUsage) section. This happens using the `.github/actions/templates/validateModuleDeploy/scripts/Test-TemplateWithParameterFile.ps1` script. diff --git a/docs/wiki/TestingUsage.md b/docs/wiki/TestingUsage.md index 7cb753b281..8f3ac509ef 100644 --- a/docs/wiki/TestingUsage.md +++ b/docs/wiki/TestingUsage.md @@ -73,7 +73,7 @@ $TestModuleLocallyInput = @{ ## Handling Parameters that require or contain a value that should be tokenized -The following scenarios are common to when to use a token value in the parameter file. Refer to [Parameter File Tokens Design](./ParameterFileTokens.md) for more details. +The following scenarios are common to when to use a token value in the parameter file. Refer to [Parameter File Tokens Design](./ParameterFileTokens) for more details. - Scenarios where resources have dependencies on other resources, which may require to be linked using `resourceId` references. diff --git a/docs/wiki/_Sidebar.md b/docs/wiki/_Sidebar.md index 3e90ad12a4..93fb2cee55 100644 --- a/docs/wiki/_Sidebar.md +++ b/docs/wiki/_Sidebar.md @@ -1,17 +1,17 @@ # Wiki content -- [Home](./Home.md) -- [Context](./Context.md) -- [Getting Started](./GettingStarted.md) -- [Modules](./Modules.md) - - [Design](./ModulesDesign.md) - - [Usage](./ModulesUsage.md) -- [Testing](./Testing.md) - - [Design](./TestingDesign.md) - - [Usage](./TestingUsage.md) -- [Pipelines](./Pipelines.md) - - [Design](./PipelinesDesign.md) - - [Parameter File Tokens](./ParameterFileTokens.md) - - [Usage](./PipelinesUsage.md) -- [Contribution Guide](./ContributionGuide.md) -- [Known Issues](./KnownIssues.md) +- [Home](./Home) +- [Context](./Context) +- [Getting Started](./GettingStarted) +- [Modules](./Modules) + - [Design](./ModulesDesign) + - [Usage](./ModulesUsage) +- [Testing](./Testing) + - [Design](./TestingDesign) + - [Usage](./TestingUsage) +- [Pipelines](./Pipelines) + - [Design](./PipelinesDesign) + - [Parameter File Tokens](./ParameterFileTokens) + - [Usage](./PipelinesUsage) +- [Contribution Guide](./ContributionGuide) +- [Known Issues](./KnownIssues) diff --git a/utilities/pipelines/resourceRemoval/Remove-DeployedModule.ps1 b/utilities/pipelines/resourceRemoval/Remove-DeployedModule.ps1 index 3c288be8e8..8398641a2d 100644 --- a/utilities/pipelines/resourceRemoval/Remove-DeployedModule.ps1 +++ b/utilities/pipelines/resourceRemoval/Remove-DeployedModule.ps1 @@ -39,6 +39,18 @@ } Remove-VirtualMachine @inputObject -Verbose } + 'automationAccounts' { + Write-Verbose 'Run automation account removal script' -Verbose + # Load function + . (Join-Path $PSScriptRoot 'helper' 'Remove-AutomationAccount.ps1') + + # Invoke removal + $inputObject = @{ + deploymentName = $deploymentName + ResourceGroupName = $ResourceGroupName + } + Remove-AutomationAccount @inputObject -Verbose + } default { Write-Verbose 'Run default removal script' -Verbose # Load function diff --git a/utilities/pipelines/resourceRemoval/helper/Remove-AutomationAccount.ps1 b/utilities/pipelines/resourceRemoval/helper/Remove-AutomationAccount.ps1 new file mode 100644 index 0000000000..8867a18695 --- /dev/null +++ b/utilities/pipelines/resourceRemoval/helper/Remove-AutomationAccount.ps1 @@ -0,0 +1,124 @@ +<# +.SYNOPSIS +Remove Automation account, Log analytics link and Update solution deployed with a given deployment name. Resources will be removed even if Log Analytics is in a different resource group than the Automation Account + +.DESCRIPTION +Remove Automation account, Log analytics link and Update solution deployed with a given deployment name. Resources will be removed even if Log Analytics is in a different resource group than the Automation Account + +.PARAMETER deploymentName +Mandatory. The deployment name to use and find resources to remove + +.PARAMETER searchRetryLimit +Optional. The maximum times to retry the search for resources via their removal tag + +.PARAMETER searchRetryInterval +Optional. The time to wait in between the search for resources via their remove tags + +.EXAMPLE +Remove-AutomationAccount -deploymentname 'aa-12345' + +Remove Automation account, Log analytics link and Update solution deployed starting with the deployment name 'aa-12345'. +#> +function Remove-AutomationAccount { + + [Cmdletbinding(SupportsShouldProcess)] + param( + [Parameter(Mandatory = $true)] + [string] $deploymentName, + + [Parameter(Mandatory = $false)] + [string] $ResourceGroupName = 'validation-rg', + + [Parameter(Mandatory = $false)] + [int] $searchRetryLimit = 40, + + [Parameter(Mandatory = $false)] + [int] $searchRetryInterval = 60 + ) + + begin { + Write-Debug ('{0} entered' -f $MyInvocation.MyCommand) + + # Load helper + . (Join-Path $PSScriptRoot 'Remove-Resource.ps1') + } + + process { + + # Identify resources + # ------------------ + $searchRetryCount = 1 + do { + $deployments = Get-AzResourceGroupDeploymentOperation -DeploymentName $deploymentName -ResourceGroupName $resourceGroupName -ErrorAction 'SilentlyContinue' + if ($deployments) { + break + } + Write-Verbose ('[Failure] not to find Automation Account deployment resources by name [{0}] in scope [{1}]. Retrying in [{2}] seconds [{3}/{4}]' -f $deploymentName, $deploymentScope, $searchRetryInterval, $searchRetryCount, $searchRetryLimit) -Verbose + Start-Sleep $searchRetryInterval + $searchRetryCount++ + } while ($searchRetryCount -le $searchRetryLimit) + + if (-not $deployments) { + throw "No deployment found for [$deploymentName]" + } + + $resourcesToRemove = @() + $unorderedResourceIds = $deployments.TargetResource | Where-Object { $_ -and $_ -notmatch '/deployments/' } + $childDeploymentsIds = $deployments.TargetResource | Where-Object { $_ -and $_ -match '/deployments/' } + + foreach ($childDeploymentId in $childDeploymentsIds) { + $searchRetryCount = 1 + $childDeploymentTokens = $childDeploymentId.Split('/') + $childDeploymentName = $childDeploymentTokens[8] + $childDeploymentResourceGroup = $childDeploymentTokens[4] + do { + Write-Verbose ('Searching child deployment named [{0}] in resource group [{1}]. Attempt [{2}/{3}]' -f $childDeploymentName, $childDeploymentResourceGroup, $searchRetryCount, $searchRetryLimit) -Verbose + $childDeployment = Get-AzResourceGroupDeploymentOperation -DeploymentName $childDeploymentName -ResourceGroupName $childDeploymentResourceGroup -ErrorAction 'SilentlyContinue' + if ($childDeployment) { + Write-Verbose ('[Success] Child deployment named [{0}] in resource group [{1}] found' -f $childDeploymentName, $childDeploymentResourceGroup) -Verbose + $unorderedResourceIds += $childDeployment.TargetResource + break + } + Write-Verbose ('[Failure] Did not to find child deployment named [{0}] in resource group [{1}]. Retrying in [{2}] seconds [{3}/{4}]' -f $childDeploymentName, $childDeploymentResourceGroup, $searchRetryInterval, $searchRetryCount, $searchRetryLimit) -Verbose + Start-Sleep $searchRetryInterval + $searchRetryCount++ + } while ($searchRetryCount -le $searchRetryLimit) + } + + $unorderedResourceIds = $unorderedResourceIds | Where-Object { $_ ` + -and ($_ -notmatch '/Microsoft.Insights/diagnosticSettings/') ` + -and ($_ -notmatch '/variables/') ` + -and ($_ -notmatch '/softwareUpdateConfigurations/') ` + -and ($_ -notmatch '/jobSchedules/') ` + -and ($_ -notmatch '/schedules/') ` + -and ($_ -notmatch '/runbooks/') ` + -and ($_ -notmatch '/modules/') ` + -and ($_ -notmatch '/Microsoft.Authorization/roleAssignments/') ` + } | Select-Object -Unique + + $orderedResourceIds = @( + $unorderedResourceIds | Where-Object { $_ -match 'Microsoft.OperationsManagement/solutions/Updates' } + $unorderedResourceIds | Where-Object { $_ -match 'linkedServices/automation' } + $unorderedResourceIds | Where-Object { $_ -match 'Microsoft.Insights/diagnosticSettings' } + $unorderedResourceIds | Where-Object { $_ -match 'Microsoft.Automation/automationAccounts' } + ) + + $resourcesToRemove = $orderedResourceIds | ForEach-Object { + @{ + resourceId = $_ + name = $_.Split('/')[-1] + type = $_.Split('/')[6..7] -join '/' + } + } + + # Remove resources + # ---------------- + if ($PSCmdlet.ShouldProcess(('[{0}] resources' -f $resourcesToRemove.Count), 'Remove')) { + Remove-Resource -resourceToRemove $resourcesToRemove -Verbose + } + } + + end { + Write-Debug ('{0} exited' -f $MyInvocation.MyCommand) + } +} diff --git a/utilities/tools/Set-ModuleReadMe.ps1 b/utilities/tools/Set-ModuleReadMe.ps1 index 2ab6f52a55..22042c6af4 100644 --- a/utilities/tools/Set-ModuleReadMe.ps1 +++ b/utilities/tools/Set-ModuleReadMe.ps1 @@ -330,9 +330,29 @@ function Set-TemplateReferencesSection { $TextInfo = (Get-Culture).TextInfo foreach ($resourceType in $relevantResourceTypes) { $Type, $Resource = $resourceType.Type -split '/', 2 - $sectionContent += ('- [{0}](https://docs.microsoft.com/en-us/azure/templates/{1}/{2}/{3})' -f $TextInfo.ToTitleCase($Resource), $Type, $resourceType.ApiVersion, $Resource) + $ResourceReferenceTitle = $TextInfo.ToTitleCase($Resource) + # Validate if Reference URL Is working + $TemplatesBaseUrl = 'https://docs.microsoft.com/en-us/azure/templates' + try { + $ResourceReferenceUrl = '{0}/{1}/{2}/{3}' -f $TemplatesBaseUrl, $Type, $resourceType.ApiVersion, $Resource + Invoke-WebRequest -Uri $ResourceReferenceUrl | Out-Null + } catch { + try { + $ResourceReferenceUrl = '{0}/{1}/{2}' -f $TemplatesBaseUrl, $Type, $Resource + Invoke-WebRequest -Uri $ResourceReferenceUrl | Out-Null + } catch { + if ($Resource.Split('/').length -gt 1) { + $ResourceReferenceUrl = '{0}/{1}/{2}' -f $TemplatesBaseUrl, $Type, $Resource.Split('/')[0] + $ResourceReferenceTitle = "'$Resource' Parent Documentation" + } else { + $ResourceReferenceUrl = '{0}' -f $TemplatesBaseUrl + $ResourceReferenceTitle = 'Define resources with Bicep and ARM templates' + } + } + } + $sectionContent += ('- [{0}]({1})' -f $ResourceReferenceTitle, $ResourceReferenceUrl) } - + $sectionContent = $sectionContent | Sort-Object -Unique # Build result if ($PSCmdlet.ShouldProcess('Original file with new template references content', 'Merge')) { $updatedFileContent = Merge-FileWithNewContent -oldContent $ReadMeFileContent -newContent $sectionContent -SectionStartIdentifier $SectionStartIdentifier -contentType 'list' @@ -422,7 +442,7 @@ function Set-ModuleReadMe { "# $assumedResourceName ``[$fullResourcePath]``", '', "This module deploys $assumedResourceName." - '// TODO: Replace Resource and fill in description', + '/ / TODO: Replace Resource and fill in description', '' '## Resource Types', '', From d92d7b4c5580cd4198066007c09941027bf62e77 Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Fri, 10 Dec 2021 09:06:18 +1100 Subject: [PATCH 10/15] changed set read me script --- utilities/tools/Set-ModuleReadMe.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/tools/Set-ModuleReadMe.ps1 b/utilities/tools/Set-ModuleReadMe.ps1 index 22042c6af4..4b4d5da7cb 100644 --- a/utilities/tools/Set-ModuleReadMe.ps1 +++ b/utilities/tools/Set-ModuleReadMe.ps1 @@ -442,7 +442,7 @@ function Set-ModuleReadMe { "# $assumedResourceName ``[$fullResourcePath]``", '', "This module deploys $assumedResourceName." - '/ / TODO: Replace Resource and fill in description', + '// TODO: Replace Resource and fill in description', '' '## Resource Types', '', From f502c897d9bcf9082e48b05a044ff054c4644c0a Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Fri, 10 Dec 2021 09:08:45 +1100 Subject: [PATCH 11/15] test doco change on PR --- arm/Microsoft.Compute/virtualMachines/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arm/Microsoft.Compute/virtualMachines/readme.md b/arm/Microsoft.Compute/virtualMachines/readme.md index 1f09345c98..3cd8f2bc6f 100644 --- a/arm/Microsoft.Compute/virtualMachines/readme.md +++ b/arm/Microsoft.Compute/virtualMachines/readme.md @@ -512,7 +512,7 @@ You can specify multiple user assigned identities to a resource by providing add ## Template references -- [Locks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2017-04-01/locks) +- [Locks ](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2017-04-01/locks) - [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) - [Virtualmachines](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Compute/2021-07-01/virtualMachines) - [Virtualmachines/Extensions](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Compute/2021-07-01/virtualMachines/extensions) From 349f1ddbbed4b6312fdfeca2041728460895511b Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Sat, 11 Dec 2021 21:21:09 +1100 Subject: [PATCH 12/15] sync --- arm/Microsoft.Network/virtualNetworks/readme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arm/Microsoft.Network/virtualNetworks/readme.md b/arm/Microsoft.Network/virtualNetworks/readme.md index da40ba7fc7..98a1b1f281 100644 --- a/arm/Microsoft.Network/virtualNetworks/readme.md +++ b/arm/Microsoft.Network/virtualNetworks/readme.md @@ -30,7 +30,6 @@ This template deploys a virtual network (vNet). | `logsToEnable` | array | `[VMProtectionAlerts]` | `[VMProtectionAlerts]` | Optional. The name of logs that will be streamed. | | `metricsToEnable` | array | `[AllMetrics]` | `[AllMetrics]` | Optional. The name of metrics that will be streamed. | | `name` | string | | | Required. The Virtual Network (vNet) Name. | -| `nsgResourceGroup` | string | `[resourceGroup().name]` | | Optional. Resource Group where NSGs are deployed, if different than VNET Resource Group. | | `roleAssignments` | array | `[]` | | 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' | | `subnets` | _[subnets](subnets/readme.md)_ array | | | Required. An Array of subnets to deploy to the Virual Network. | | `tags` | object | `{object}` | | Optional. Tags of the resource. | @@ -120,8 +119,9 @@ The network security group and route table resources must reside in the same res ## Template references -- [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) - [Locks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2016-09-01/locks) - [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) -- [Virtualnetworks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/virtualNetworks) +- [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) +- [Virtualnetworks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-05-01/virtualNetworks) +- [Virtualnetworks/Subnets](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-03-01/virtualNetworks/subnets) - [Virtualnetworks/Virtualnetworkpeerings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-02-01/virtualNetworks/virtualNetworkPeerings) From b4d73a9d21089dd7de573bef090d9ec41386733f Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Sun, 12 Dec 2021 19:35:52 +1100 Subject: [PATCH 13/15] Updated Set module readme based on feedback --- utilities/tools/Set-ModuleReadMe.ps1 | 59 +++++++++++++++------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/utilities/tools/Set-ModuleReadMe.ps1 b/utilities/tools/Set-ModuleReadMe.ps1 index 4b4d5da7cb..5fe4e41b37 100644 --- a/utilities/tools/Set-ModuleReadMe.ps1 +++ b/utilities/tools/Set-ModuleReadMe.ps1 @@ -86,22 +86,22 @@ function Set-ResourceTypesSection { ) # Process content - $sectionContent = [System.Collections.ArrayList]@( + $SectionContent = [System.Collections.ArrayList]@( '| Resource Type | API Version |', '| :-- | :-- |' ) - $relevantResourceTypes = Get-NestedResourceList $TemplateFileContent | Where-Object { + $RelevantResourceTypes = Get-NestedResourceList $TemplateFileContent | Where-Object { $_.type -notin $ResourceTypesToExclude -and $_ } | Select-Object 'Type', 'ApiVersion' -Unique | Sort-Object Type -Culture en-US - foreach ($resourceType in $relevantResourceTypes) { - $sectionContent += ('| `{0}` | {1} |' -f $resourceType.type, $resourceType.apiVersion) + foreach ($resourceType in $RelevantResourceTypes) { + $SectionContent += ('| `{0}` | {1} |' -f $resourceType.type, $resourceType.apiVersion) } # Build result if ($PSCmdlet.ShouldProcess('Original file with new resource type content', 'Merge')) { - $updatedFileContent = Merge-FileWithNewContent -oldContent $ReadMeFileContent -newContent $sectionContent -SectionStartIdentifier $SectionStartIdentifier -contentType 'table' + $updatedFileContent = Merge-FileWithNewContent -oldContent $ReadMeFileContent -newContent $SectionContent -SectionStartIdentifier $SectionStartIdentifier -contentType 'table' } return $updatedFileContent } @@ -149,7 +149,7 @@ function Set-ParametersSection { ) # Process content - $sectionContent = [System.Collections.ArrayList]@( + $SectionContent = [System.Collections.ArrayList]@( '| Parameter Name | Type | Default Value | Possible Values | Description |', '| :-- | :-- | :-- | :-- | :-- |' ) @@ -176,12 +176,12 @@ function Set-ParametersSection { $defaultValue = ($param.defaultValue -is [array]) ? ('[{0}]' -f ($param.defaultValue -join ', ')) : (($param.defaultValue -is [hashtable]) ? '{object}' : $param.defaultValue) $allowed = ($param.allowedValues -is [array]) ? ('[{0}]' -f ($param.allowedValues -join ', ')) : (($param.allowedValues -is [hashtable]) ? '{object}' : $param.allowedValues) $description = $param.metadata.description - $sectionContent += ('| `{0}` | {1} | {2} | {3} | {4} |' -f $paramName, $type, (($defaultValue) ? "``$defaultValue``" : ''), (($allowed) ? "``$allowed``" : ''), $description) + $SectionContent += ('| `{0}` | {1} | {2} | {3} | {4} |' -f $paramName, $type, (($defaultValue) ? "``$defaultValue``" : ''), (($allowed) ? "``$allowed``" : ''), $description) } # Build result if ($PSCmdlet.ShouldProcess('Original file with new parameters content', 'Merge')) { - $updatedFileContent = Merge-FileWithNewContent -oldContent $ReadMeFileContent -newContent $sectionContent -SectionStartIdentifier $SectionStartIdentifier -contentType 'table' + $updatedFileContent = Merge-FileWithNewContent -oldContent $ReadMeFileContent -newContent $SectionContent -SectionStartIdentifier $SectionStartIdentifier -contentType 'table' } # Build sub-section 'ParameterUsage' @@ -251,28 +251,28 @@ function Set-OutputsSection { # Process content if ($TemplateFileContent.outputs.Values.metadata) { # Template has output descriptions - $sectionContent = [System.Collections.ArrayList]@( + $SectionContent = [System.Collections.ArrayList]@( '| Output Name | Type | Description |', '| :-- | :-- | :-- |' ) foreach ($outputName in ($templateFileContent.outputs.Keys | Sort-Object -Culture en-US)) { $output = $TemplateFileContent.outputs[$outputName] - $sectionContent += ("| ``{0}`` | {1} | {2} |" -f $outputName, $output.type, $output.metadata.description) + $SectionContent += ("| ``{0}`` | {1} | {2} |" -f $outputName, $output.type, $output.metadata.description) } } else { - $sectionContent = [System.Collections.ArrayList]@( + $SectionContent = [System.Collections.ArrayList]@( '| Output Name | Type |', '| :-- | :-- |' ) foreach ($outputName in ($templateFileContent.outputs.Keys | Sort-Object -Culture en-US)) { $output = $TemplateFileContent.outputs[$outputName] - $sectionContent += ("| ``{0}`` | {1} |" -f $outputName, $output.type) + $SectionContent += ("| ``{0}`` | {1} |" -f $outputName, $output.type) } } # Build result if ($PSCmdlet.ShouldProcess('Original file with new output content', 'Merge')) { - $updatedFileContent = Merge-FileWithNewContent -oldContent $ReadMeFileContent -newContent $sectionContent -SectionStartIdentifier $SectionStartIdentifier -contentType 'table' + $updatedFileContent = Merge-FileWithNewContent -oldContent $ReadMeFileContent -newContent $SectionContent -SectionStartIdentifier $SectionStartIdentifier -contentType 'table' } return $updatedFileContent } @@ -321,41 +321,44 @@ function Set-TemplateReferencesSection { ) # Process content - $sectionContent = [System.Collections.ArrayList]@() + $SectionContent = [System.Collections.ArrayList]@() - $relevantResourceTypes = Get-NestedResourceList $TemplateFileContent | Where-Object { + $RelevantResourceTypes = Get-NestedResourceList $TemplateFileContent | Where-Object { $_.type -notin $ResourceTypesToExclude -and $_ -and $_.type -notlike '*/providers/*' } | Select-Object 'Type', 'ApiVersion' -Unique | Sort-Object Type -Culture en-US $TextInfo = (Get-Culture).TextInfo - foreach ($resourceType in $relevantResourceTypes) { - $Type, $Resource = $resourceType.Type -split '/', 2 - $ResourceReferenceTitle = $TextInfo.ToTitleCase($Resource) + foreach ($RelevantResourceType in $RelevantResourceTypes) { + $ProviderNamespace, $ResourceType = $RelevantResourceType.Type -split '/', 2 + $ResourceReferenceTitle = $TextInfo.ToTitleCase($ResourceType) # Validate if Reference URL Is working $TemplatesBaseUrl = 'https://docs.microsoft.com/en-us/azure/templates' try { - $ResourceReferenceUrl = '{0}/{1}/{2}/{3}' -f $TemplatesBaseUrl, $Type, $resourceType.ApiVersion, $Resource - Invoke-WebRequest -Uri $ResourceReferenceUrl | Out-Null + $ResourceReferenceUrl = '{0}/{1}/{2}/{3}' -f $TemplatesBaseUrl, $ProviderNamespace, $RelevantResourceType.ApiVersion, $ResourceType + $null = Invoke-WebRequest -Uri $ResourceReferenceUrl } catch { + # Validate if Reference URL is working using the latest documented API version (with no API version in the URL) try { - $ResourceReferenceUrl = '{0}/{1}/{2}' -f $TemplatesBaseUrl, $Type, $Resource - Invoke-WebRequest -Uri $ResourceReferenceUrl | Out-Null + $ResourceReferenceUrl = '{0}/{1}/{2}' -f $TemplatesBaseUrl, $ProviderNamespace, $ResourceType + $null = Invoke-WebRequest -Uri $ResourceReferenceUrl } catch { - if ($Resource.Split('/').length -gt 1) { - $ResourceReferenceUrl = '{0}/{1}/{2}' -f $TemplatesBaseUrl, $Type, $Resource.Split('/')[0] - $ResourceReferenceTitle = "'$Resource' Parent Documentation" + # Check if the resource is a child resource + if ($ResourceType.Split('/').length -gt 1) { + $ResourceReferenceUrl = '{0}/{1}/{2}' -f $TemplatesBaseUrl, $ProviderNamespace, $ResourceType.Split('/')[0] + $ResourceReferenceTitle = "'$ResourceType' Parent Documentation" } else { + # Use the default Templates URL (Last resort) $ResourceReferenceUrl = '{0}' -f $TemplatesBaseUrl $ResourceReferenceTitle = 'Define resources with Bicep and ARM templates' } } } - $sectionContent += ('- [{0}]({1})' -f $ResourceReferenceTitle, $ResourceReferenceUrl) + $SectionContent += ('- [{0}]({1})' -f $ResourceReferenceTitle, $ResourceReferenceUrl) } - $sectionContent = $sectionContent | Sort-Object -Unique + $SectionContent = $SectionContent | Sort-Object -Unique # Build result if ($PSCmdlet.ShouldProcess('Original file with new template references content', 'Merge')) { - $updatedFileContent = Merge-FileWithNewContent -oldContent $ReadMeFileContent -newContent $sectionContent -SectionStartIdentifier $SectionStartIdentifier -contentType 'list' + $updatedFileContent = Merge-FileWithNewContent -oldContent $ReadMeFileContent -newContent $SectionContent -SectionStartIdentifier $SectionStartIdentifier -contentType 'list' } return $updatedFileContent } From 3413cc4425863c68693551b70a8f293754ff7f60 Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Sun, 12 Dec 2021 19:40:56 +1100 Subject: [PATCH 14/15] Updated virtual network readme --- arm/Microsoft.Network/virtualNetworks/readme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arm/Microsoft.Network/virtualNetworks/readme.md b/arm/Microsoft.Network/virtualNetworks/readme.md index 98a1b1f281..5737b655a8 100644 --- a/arm/Microsoft.Network/virtualNetworks/readme.md +++ b/arm/Microsoft.Network/virtualNetworks/readme.md @@ -9,7 +9,7 @@ This template deploys a virtual network (vNet). | `Microsoft.Authorization/locks` | 2016-09-01 | | `Microsoft.Authorization/roleAssignments` | 2020-04-01-preview | | `Microsoft.Insights/diagnosticSettings` | 2021-05-01-preview | -| `Microsoft.Network/virtualNetworks` | 2021-05-01 | +| `Microsoft.Network/virtualNetworks` | 2021-03-01 | | `Microsoft.Network/virtualNetworks/subnets` | 2021-03-01 | | `Microsoft.Network/virtualNetworks/virtualNetworkPeerings` | 2021-02-01 | @@ -119,9 +119,9 @@ The network security group and route table resources must reside in the same res ## Template references +- [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) - [Locks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2016-09-01/locks) - [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-04-01-preview/roleAssignments) -- [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) -- [Virtualnetworks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-05-01/virtualNetworks) +- [Virtualnetworks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-03-01/virtualNetworks) - [Virtualnetworks/Subnets](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-03-01/virtualNetworks/subnets) - [Virtualnetworks/Virtualnetworkpeerings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-02-01/virtualNetworks/virtualNetworkPeerings) From d1f4d642a4becec863e63394caeca00f515200cc Mon Sep 17 00:00:00 2001 From: Ahmad Abdalla <28486158+ahmadabdalla@users.noreply.github.com> Date: Tue, 14 Dec 2021 08:03:00 +1100 Subject: [PATCH 15/15] Fixed GitHub doco Secret Broken URL --- docs/wiki/PipelinesDesign.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/wiki/PipelinesDesign.md b/docs/wiki/PipelinesDesign.md index 81e6ab4c90..bb38d4b378 100644 --- a/docs/wiki/PipelinesDesign.md +++ b/docs/wiki/PipelinesDesign.md @@ -229,7 +229,7 @@ In the following sub-sections we will take a deeper look into each element. ### **GitHub Component:** GitHub secrets -The GitHub repository secrets can be set up in the repositories _'Settings'_ as described [here](https://docs.github.com/en/actions/security-guides/encrypted-secret). +The GitHub repository secrets can be set up in the repositories _'Settings'_ as described [here](https://docs.github.com/en/actions/security-guides/encrypted-secrets). For _GitHub_ in particular we need the following secrets in addition to those described in the shared [pipeline secrets](#pipeline-secrets) section: