diff --git a/.azuredevops/ado/deploy-template-sub.yml b/.azuredevops/ado/deploy-template-sub.yml
new file mode 100644
index 000000000..6d308154e
--- /dev/null
+++ b/.azuredevops/ado/deploy-template-sub.yml
@@ -0,0 +1,83 @@
+parameters:
+ - name: location
+ - name: templateFile
+ - name: workingDir
+ type: string
+ - name: deployOperation
+ type: string
+ default: 'create'
+ - name: parameterArray
+ type: object
+ default: []
+ - name: jobName
+ default: Deploy_Bicep_Main_Module_Sub_level
+ - name: preDeploySteps
+ type: stepList
+ default: []
+ - name: postDeploySteps
+ type: stepList
+ default: []
+ - name: variableOverrides
+ type: object
+ default: {}
+
+jobs:
+ - job: ${{ parameters.jobName }}
+ displayName: Deploy ${{ parameters.templateFile }}
+ variables:
+ ${{ insert }}: ${{ parameters.variableOverrides }}
+
+ steps:
+ - ${{ parameters.preDeploySteps }}
+
+ - task: PowerShell@2
+ displayName: Converting parameters array
+ inputs:
+ targetType: 'inline'
+ script: |
+ $myArray = ConvertFrom-Json $Env:PARAMETER_ARRAY
+ # Need to add depth for embedded json arrays.
+ $jsonmyArray = $myArray | ConvertTo-Json -Compress -Depth 100
+ Write-Host "json_my_Array is: $jsonmyArray"
+ # Converting into json into hash array to extract the string array
+ $hasharray=@{}
+ $jsonObjmyArray= ConvertFrom-Json $jsonmyArray
+ foreach ( $property in $jsonObjmyArray.PSObject.Properties ) {
+ $hasharray[$property.Name]=$property.Value
+ }
+ # Getting values from the hash array into string array
+ $stringmyArray=@()
+ foreach ($parameter in $hasharray.SyncRoot) {
+ $stringmyArray += $parameter
+ }
+ Write-Host "Here is our string array: $stringmyArray"
+ # Formatting for the bicep deployment
+ $stringparameterArray=@()
+ foreach ( $string in $stringmyArray) {
+ $string1 = $string -replace ' ', '='
+ $stringparameterArray += $string1
+ }
+ Write-Host "Here is final format of parameters for deployment with Bicep"
+ $stringparameterArray
+ $stringparameters=[string]::Join(" ", $stringparameterArray)
+ $stringparameters
+ Write-Host "##vso[task.setvariable variable=bicep_parameters]$stringparameters"
+ env:
+ PARAMETER_ARRAY: ${{convertToJson(parameters.parameterArray)}}
+
+ - task: AzureCLI@2
+ displayName: Resource deployment at subscription scope
+ inputs:
+ azureSubscription: $(serviceConnection)
+ scriptType: 'bash'
+ scriptLocation: 'inlineScript'
+ inlineScript: |
+ $(var-bashPreInjectScript)
+ ls
+ echo "Deploying ${{ parameters.templateFile }} using ${{ parameters.deployOperation}} operation..."
+ az deployment sub ${{ parameters.deployOperation }} \
+ --location ${{ parameters.location }} \
+ --name $(Build.BuildNumber) \
+ --template-file ${{ parameters.templateFile}} \
+ --parameters $(bicep_parameters)
+ workingDirectory: ${{ parameters.workingDir }}
diff --git a/.azuredevops/ado/main-ado-avd-accelerator.yml b/.azuredevops/ado/main-ado-avd-accelerator.yml
new file mode 100644
index 000000000..89421bf69
--- /dev/null
+++ b/.azuredevops/ado/main-ado-avd-accelerator.yml
@@ -0,0 +1,85 @@
+trigger:
+ - none
+
+pr:
+ - none
+
+variables:
+ - name: deploymentRegion
+ value: canadacentral
+ - name: serviceConnection
+ value: AzureLabCACN-Sponosored
+ - name: vmWinImage
+ value: windows-latest
+ - name: vmImage
+ value: ubuntu-latest
+ - name: deployOperation
+ value: create
+ - name: var-bashPostInjectScript
+ value: ':'
+ - name: var-bashPreInjectScript
+ value: 'set -E; function catch { echo "##vso[task.logissue type=error]Caller: $(caller), LineNo: $LINENO, Command: $BASH_COMMAND" ; exit 1 ; } ; echo ; echo "Current working directory: $(pwd)" ; echo ; trap catch ERR'
+ - name: avdShrdlSubsId
+ value: a165ed8a-0e83-46f1-9994-b216229c2da7
+ - name: avdWrklSubsId
+ value: a165ed8a-0e83-46f1-9994-b216229c2da7
+ - name: avdWrklSecretAccess
+ value: 8e23a491-5178-4c69-9fce-1377e52a29c6
+ - name: createAvdVnet
+ value: false
+ - name: useSharedImage
+ value: false
+ - name: avdOsImage
+ #value: win11_21h2_office
+ #value: win10_21h2
+ value: win10_21h2_office
+ #value: win11_21h2
+ - name: avdIdentityDomainName
+ value: azureminilab.com
+ - name: avdDomainJoinUserName
+ value: 'azadmin@azureminilab.com'
+ - name: avdDomainJoinUserPassword
+ value: '!V0ipc@123'
+ - name: avdVmLocalUserName
+ value: azadmin
+ - name: avdVmLocalUserPassword
+ value: '!R37fallacy1505'
+
+
+stages:
+ - stage: Deploy_AVD_Accelerator
+ displayName: Deploy AVD Accelerator
+ jobs:
+ # Deploy template deploy-baseline.bicep for AVD Accelerator
+ - template: deploy-template-sub.yml
+ parameters:
+ jobName: Deploy_AVD_Accelerator
+ location: $(deploymentRegion)
+ workingDir: $(System.DefaultWorkingDirectory)/workload
+ templateFile: deploy-baseline.bicep
+ parameterArray:
+ - deploymentPrefix 'app1'
+ - avdDeploySessionHostsCount 1
+ - avdWorkloadSubsId $(avdWrklSubsId)
+ - avdEnterpriseAppObjectId '82205950-fef1-4f88-8801-86e60c2e9318'
+ - avdManagementPlaneLocation $(deploymentRegion)
+ - avdSessionHostLocation $(deploymentRegion)
+ - fsLogixstorageSku 'Standard_LRS'
+ # - avdWrklSecretAccess $(avdWrklSecretAccess)
+ - existingVnetSubnetResourceId '/subscriptions/a165ed8a-0e83-46f1-9994-b216229c2da7/resourceGroups/azurelab-avd-networking/providers/Microsoft.Network/virtualNetworks/vnet-avd-canadacentral/subnets/subnet1'
+ - existingHubVnetResourceId '/subscriptions/4f6c98e1-04a4-49f0-abce-6240b1726c3f/resourceGroups/pubsec-hub-networking-rg/providers/Microsoft.Network/virtualNetworks/hub-vnet'
+ - useSharedImage $(useSharedImage)
+ - avdOsImage $(avdOsImage)
+ - createAvdVnet $(createAvdVnet)
+ - avdIdentityDomainName $(avdIdentityDomainName)
+ - avdDomainJoinUserName $(avdDomainJoinUserName)
+ - avdDomainJoinUserPassword $(avdDomainJoinUserPassword)
+ - avdVmLocalUserName $(avdVmLocalUserName)
+ - avdVmLocalUserPassword $(avdVmLocalUserPassword)
+ - avdDeployRAppGroup true
+ - avdDeploySessionHosts true
+ - avdStartVMOnConnect true
+ - createStartVmOnConnectCustomRole true
+ - vNetworkGatewayOnHub false
+ - createOUforStorage true
+ - storageOUName 'FsLogix User Profiles'
diff --git a/.azuredevops/modulePipelines/ms.analysisservices.servers.yml b/.azuredevops/modulePipelines/ms.analysisservices.servers.yml
new file mode 100644
index 000000000..625a1186c
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.analysisservices.servers.yml
@@ -0,0 +1,52 @@
+name: 'AnalysisServices - Servers'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.analysisservices.servers.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.AnalysisServices/servers/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.AnalysisServices/servers'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/min.parameters.json
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.apimanagement.service.yml b/.azuredevops/modulePipelines/ms.apimanagement.service.yml
new file mode 100644
index 000000000..43ae45a01
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.apimanagement.service.yml
@@ -0,0 +1,52 @@
+name: 'ApiManagement - Service'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: false # Soft-delete prevents re-deployment
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.apimanagement.service.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.ApiManagement/service/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.ApiManagement/service'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/max.parameters.json
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.authorization.policyassignments.yml b/.azuredevops/modulePipelines/ms.authorization.policyassignments.yml
new file mode 100644
index 000000000..7e045cf88
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.authorization.policyassignments.yml
@@ -0,0 +1,62 @@
+name: 'Authorization - PolicyAssignments'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.authorization.policyassignments.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Authorization/policyAssignments/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Authorization/policyAssignments'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/mg.min.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+ - path: $(modulePath)/.parameters/mg.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+ - path: $(modulePath)/.parameters/sub.min.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+ - path: $(modulePath)/.parameters/sub.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+ - path: $(modulePath)/.parameters/rg.min.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+ - path: $(modulePath)/.parameters/rg.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.authorization.policydefinitions.yml b/.azuredevops/modulePipelines/ms.authorization.policydefinitions.yml
new file mode 100644
index 000000000..41bfa990d
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.authorization.policydefinitions.yml
@@ -0,0 +1,58 @@
+name: 'Authorization - PolicyDefinitions'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.authorization.policydefinitions.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Authorization/policyDefinitions/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Authorization/policyDefinitions'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/mg.min.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+ - path: $(modulePath)/.parameters/mg.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+ - path: $(modulePath)/.parameters/sub.min.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+ - path: $(modulePath)/.parameters/sub.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.authorization.policyexemptions.yml b/.azuredevops/modulePipelines/ms.authorization.policyexemptions.yml
new file mode 100644
index 000000000..f43f19850
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.authorization.policyexemptions.yml
@@ -0,0 +1,62 @@
+name: 'Authorization - PolicyExemptions'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.authorization.policyexemptions.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Authorization/policyExemptions/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Authorization/policyExemptions'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/mg.min.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+ - path: $(modulePath)/.parameters/mg.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+ - path: $(modulePath)/.parameters/sub.min.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+ - path: $(modulePath)/.parameters/sub.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+ - path: $(modulePath)/.parameters/rg.min.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+ - path: $(modulePath)/.parameters/rg.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.authorization.policysetdefinitions.yml b/.azuredevops/modulePipelines/ms.authorization.policysetdefinitions.yml
new file mode 100644
index 000000000..56bade6ae
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.authorization.policysetdefinitions.yml
@@ -0,0 +1,58 @@
+name: 'Authorization - PolicySetDefinitions'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.authorization.policysetdefinitions.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Authorization/policySetDefinitions/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Authorization/policySetDefinitions'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/mg.min.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+ - path: $(modulePath)/.parameters/mg.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+ - path: $(modulePath)/.parameters/sub.min.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+ - path: $(modulePath)/.parameters/sub.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.authorization.roleassignments.yml b/.azuredevops/modulePipelines/ms.authorization.roleassignments.yml
new file mode 100644
index 000000000..b4ad7d6ad
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.authorization.roleassignments.yml
@@ -0,0 +1,62 @@
+name: 'Authorization - RoleAssignments'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.authorization.roleassignments.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Authorization/roleAssignments/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Authorization/roleAssignments'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/mg.min.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+ - path: $(modulePath)/.parameters/mg.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+ - path: $(modulePath)/.parameters/sub.min.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+ - path: $(modulePath)/.parameters/sub.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+ - path: $(modulePath)/.parameters/rg.min.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+ - path: $(modulePath)/.parameters/rg.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.authorization.roledefinitions.yml b/.azuredevops/modulePipelines/ms.authorization.roledefinitions.yml
new file mode 100644
index 000000000..044f4f0ad
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.authorization.roledefinitions.yml
@@ -0,0 +1,62 @@
+name: 'Authorization - RoleDefinitions'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.authorization.roledefinitions.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Authorization/roleDefinitions/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Authorization/roleDefinitions'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/mg.min.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+ - path: $(modulePath)/.parameters/mg.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+ - path: $(modulePath)/.parameters/sub.min.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+ - path: $(modulePath)/.parameters/sub.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+ - path: $(modulePath)/.parameters/rg.min.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+ - path: $(modulePath)/.parameters/rg.parameters.json
+ templateFilePath: $(modulePath)/deploy.bicep
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.automation.automationaccounts.yml b/.azuredevops/modulePipelines/ms.automation.automationaccounts.yml
new file mode 100644
index 000000000..b379d53d3
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.automation.automationaccounts.yml
@@ -0,0 +1,52 @@
+name: 'Automation - AutomationAccounts'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.automation.automationaccounts.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Automation/automationAccounts/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Automation/automationAccounts'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/min.parameters.json
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.batch.batchaccounts.yml b/.azuredevops/modulePipelines/ms.batch.batchaccounts.yml
new file mode 100644
index 000000000..7c10f8bad
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.batch.batchaccounts.yml
@@ -0,0 +1,51 @@
+name: 'Batch - BatchAccounts'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.batch.batchaccounts.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Batch/batchAccounts/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Batch/batchAccounts'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.cognitiveservices.accounts.yml b/.azuredevops/modulePipelines/ms.cognitiveservices.accounts.yml
new file mode 100644
index 000000000..b95d423f8
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.cognitiveservices.accounts.yml
@@ -0,0 +1,51 @@
+name: 'CognitiveServices - Accounts'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: false # Soft-delete prevents re-deployment
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.cognitiveservices.accounts.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.CognitiveServices/accounts/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.CognitiveServices/accounts'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.compute.availabilitysets.yml b/.azuredevops/modulePipelines/ms.compute.availabilitysets.yml
new file mode 100644
index 000000000..13f0d8bfb
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.compute.availabilitysets.yml
@@ -0,0 +1,51 @@
+name: 'Compute - AvailabilitySets'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.compute.availabilitysets.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Compute/availabilitySets/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Compute/availabilitySets'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.compute.diskencryptionsets.yml b/.azuredevops/modulePipelines/ms.compute.diskencryptionsets.yml
new file mode 100644
index 000000000..ab1a408aa
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.compute.diskencryptionsets.yml
@@ -0,0 +1,51 @@
+name: 'Compute - DiskEncryptionSets'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.compute.diskencryptionsets.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Compute/diskEncryptionSets/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Compute/diskEncryptionSets'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.compute.disks.yml b/.azuredevops/modulePipelines/ms.compute.disks.yml
new file mode 100644
index 000000000..d63fbedbe
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.compute.disks.yml
@@ -0,0 +1,54 @@
+name: 'Compute - Disks'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.compute.disks.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Compute/disks/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Compute/disks'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+ - path: $(modulePath)/.parameters/min.parameters.json
+ - path: $(modulePath)/.parameters/image.parameters.json
+ - path: $(modulePath)/.parameters/import.parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.compute.galleries.yml b/.azuredevops/modulePipelines/ms.compute.galleries.yml
new file mode 100644
index 000000000..df5e4455b
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.compute.galleries.yml
@@ -0,0 +1,56 @@
+name: 'Compute - Galleries'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.compute.galleries.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Compute/galleries/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Compute/galleries'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+ parameters:
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/images.parameters.json
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/images.parameters.json
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.compute.images.yml b/.azuredevops/modulePipelines/ms.compute.images.yml
new file mode 100644
index 000000000..fcd28cee5
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.compute.images.yml
@@ -0,0 +1,51 @@
+name: 'Compute - Images'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.compute.images.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Compute/images/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Compute/images'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.compute.proximityplacementgroups.yml b/.azuredevops/modulePipelines/ms.compute.proximityplacementgroups.yml
new file mode 100644
index 000000000..21ce3f518
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.compute.proximityplacementgroups.yml
@@ -0,0 +1,51 @@
+name: 'Compute - ProximityPlacementGroups'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.compute.proximityplacementgroups.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Compute/proximityPlacementGroups/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Compute/proximityPlacementGroups'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.compute.virtualmachines.yml b/.azuredevops/modulePipelines/ms.compute.virtualmachines.yml
new file mode 100644
index 000000000..ec6e767fa
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.compute.virtualmachines.yml
@@ -0,0 +1,54 @@
+name: 'Compute - VirtualMachines'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.compute.virtualmachines.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Compute/virtualMachines/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Compute/virtualMachines'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/linux.min.parameters.json
+ - path: $(modulePath)/.parameters/linux.parameters.json
+ - path: $(modulePath)/.parameters/windows.min.parameters.json
+ - path: $(modulePath)/.parameters/windows.parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.compute.virtualmachinescalesets.yml b/.azuredevops/modulePipelines/ms.compute.virtualmachinescalesets.yml
new file mode 100644
index 000000000..b8b9df5d9
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.compute.virtualmachinescalesets.yml
@@ -0,0 +1,54 @@
+name: 'Compute - VirtualMachineScaleSets'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.compute.virtualmachinescalesets.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Compute/virtualMachineScaleSets/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Compute/virtualMachineScaleSets'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/linux.min.parameters.json
+ - path: $(modulePath)/.parameters/linux.parameters.json
+ - path: $(modulePath)/.parameters/windows.min.parameters.json
+ - path: $(modulePath)/.parameters/windows.parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.consumption.budgets.yml b/.azuredevops/modulePipelines/ms.consumption.budgets.yml
new file mode 100644
index 000000000..2889da608
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.consumption.budgets.yml
@@ -0,0 +1,51 @@
+name: 'Consumption - Budgets'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.consumption.budgets.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Consumption/budgets/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Consumption/budgets'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.containerinstance.containergroups.yml b/.azuredevops/modulePipelines/ms.containerinstance.containergroups.yml
new file mode 100644
index 000000000..97c564067
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.containerinstance.containergroups.yml
@@ -0,0 +1,51 @@
+name: 'ContainerInstance - ContainerGroups'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.containerinstance.containergroups.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.ContainerInstance/containerGroups/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.ContainerInstance/containerGroups'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.containerregistry.registries.yml b/.azuredevops/modulePipelines/ms.containerregistry.registries.yml
new file mode 100644
index 000000000..c42b35b3e
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.containerregistry.registries.yml
@@ -0,0 +1,52 @@
+name: 'ContainerRegistry - Registries'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.containerregistry.registries.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.ContainerRegistry/registries/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.ContainerRegistry/registries'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/min.parameters.json
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.containerservice.managedclusters.yml b/.azuredevops/modulePipelines/ms.containerservice.managedclusters.yml
new file mode 100644
index 000000000..9b4f47bf4
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.containerservice.managedclusters.yml
@@ -0,0 +1,52 @@
+name: 'ContainerService - ManagedClusters'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.containerservice.managedclusters.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.ContainerService/managedClusters/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.ContainerService/managedClusters'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/azure.parameters.json
+ - path: $(modulePath)/.parameters/kubenet.parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.databricks.workspaces.yml b/.azuredevops/modulePipelines/ms.databricks.workspaces.yml
new file mode 100644
index 000000000..bca028670
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.databricks.workspaces.yml
@@ -0,0 +1,51 @@
+name: 'Databricks - Workspaces'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.databricks.workspaces.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Databricks/workspaces/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Databricks/workspaces'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.datafactory.factories.yml b/.azuredevops/modulePipelines/ms.datafactory.factories.yml
new file mode 100644
index 000000000..e54b36af1
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.datafactory.factories.yml
@@ -0,0 +1,51 @@
+name: 'DataFactory - Factories'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.datafactory.factories.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.DataFactory/factories/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.DataFactory/factories'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.desktopvirtualization.applicationgroups.yml b/.azuredevops/modulePipelines/ms.desktopvirtualization.applicationgroups.yml
new file mode 100644
index 000000000..16c658a13
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.desktopvirtualization.applicationgroups.yml
@@ -0,0 +1,52 @@
+name: 'DesktopVirtualization - ApplicationGroups'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.desktopvirtualization.applicationgroups.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.DesktopVirtualization/applicationgroups/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.DesktopVirtualization/applicationgroups'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/min.parameters.json
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.desktopvirtualization.hostpools.yml b/.azuredevops/modulePipelines/ms.desktopvirtualization.hostpools.yml
new file mode 100644
index 000000000..ed7bb6b14
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.desktopvirtualization.hostpools.yml
@@ -0,0 +1,51 @@
+name: 'DesktopVirtualization - HostPools'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.desktopvirtualization.hostpools.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.DesktopVirtualization/hostpools/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.DesktopVirtualization/hostpools'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.desktopvirtualization.workspaces.yml b/.azuredevops/modulePipelines/ms.desktopvirtualization.workspaces.yml
new file mode 100644
index 000000000..d00f5b191
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.desktopvirtualization.workspaces.yml
@@ -0,0 +1,51 @@
+name: 'DesktopVirtualization - Workspaces'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.desktopvirtualization.workspaces.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.DesktopVirtualization/workspaces/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.DesktopVirtualization/workspaces'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.documentdb.databaseaccounts.yml b/.azuredevops/modulePipelines/ms.documentdb.databaseaccounts.yml
new file mode 100644
index 000000000..2203a61f3
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.documentdb.databaseaccounts.yml
@@ -0,0 +1,53 @@
+name: 'DocumentDB - DatabaseAccounts'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.documentdb.databaseaccounts.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.DocumentDB/databaseAccounts/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.DocumentDB/databaseAccounts'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/mongodb.parameters.json
+ - path: $(modulePath)/.parameters/plain.parameters.json
+ - path: $(modulePath)/.parameters/sqldb.parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.eventgrid.systemtopics.yml b/.azuredevops/modulePipelines/ms.eventgrid.systemtopics.yml
new file mode 100644
index 000000000..79d013839
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.eventgrid.systemtopics.yml
@@ -0,0 +1,52 @@
+name: 'EventGrid - System Topics'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.eventgrid.systemtopics.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.EventGrid/systemTopics/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.EventGrid/systemTopics'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/min.parameters.json
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.eventgrid.topics.yml b/.azuredevops/modulePipelines/ms.eventgrid.topics.yml
new file mode 100644
index 000000000..ba5ee65db
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.eventgrid.topics.yml
@@ -0,0 +1,51 @@
+name: 'EventGrid - Topics'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.eventgrid.topics.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.EventGrid/topics/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.EventGrid/topics'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.eventhub.namespaces.yml b/.azuredevops/modulePipelines/ms.eventhub.namespaces.yml
new file mode 100644
index 000000000..63b16c5b3
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.eventhub.namespaces.yml
@@ -0,0 +1,52 @@
+name: 'EventHub - Namespaces'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.eventhub.namespaces.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.EventHub/namespaces/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.EventHub/namespaces'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/min.parameters.json
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.healthbot.healthbots.yml b/.azuredevops/modulePipelines/ms.healthbot.healthbots.yml
new file mode 100644
index 000000000..0f8665822
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.healthbot.healthbots.yml
@@ -0,0 +1,51 @@
+name: 'HealthBot - HealthBots'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.healthbot.healthbots.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.HealthBot/healthBots/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.HealthBot/healthBots'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.insights.actiongroups.yml b/.azuredevops/modulePipelines/ms.insights.actiongroups.yml
new file mode 100644
index 000000000..5afa006aa
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.insights.actiongroups.yml
@@ -0,0 +1,51 @@
+name: 'Insights - ActionGroups'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.insights.actiongroups.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Insights/actionGroups/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Insights/actionGroups'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.insights.activitylogalerts.yml b/.azuredevops/modulePipelines/ms.insights.activitylogalerts.yml
new file mode 100644
index 000000000..aaac601f7
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.insights.activitylogalerts.yml
@@ -0,0 +1,51 @@
+name: 'Insights - ActivityLogAlerts'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.insights.activitylogalerts.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Insights/activityLogAlerts/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Insights/activityLogAlerts'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.insights.components.yml b/.azuredevops/modulePipelines/ms.insights.components.yml
new file mode 100644
index 000000000..b2ed16663
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.insights.components.yml
@@ -0,0 +1,51 @@
+name: 'Insights - Components'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.insights.components.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Insights/components/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Insights/components'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.insights.diagnosticsettings.yml b/.azuredevops/modulePipelines/ms.insights.diagnosticsettings.yml
new file mode 100644
index 000000000..5a12f8475
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.insights.diagnosticsettings.yml
@@ -0,0 +1,51 @@
+name: 'Insights - DiagnosticSettings'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: false # Needs custom removals script
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.insights.diagnosticsettings.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Insights/diagnosticSettings/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Insights/diagnosticSettings'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.insights.metricalerts.yml b/.azuredevops/modulePipelines/ms.insights.metricalerts.yml
new file mode 100644
index 000000000..3042e4dab
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.insights.metricalerts.yml
@@ -0,0 +1,51 @@
+name: 'Insights - MetricAlerts'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.insights.metricalerts.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Insights/metricAlerts/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Insights/metricAlerts'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.insights.privatelinkscopes.yml b/.azuredevops/modulePipelines/ms.insights.privatelinkscopes.yml
new file mode 100644
index 000000000..fd71a6746
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.insights.privatelinkscopes.yml
@@ -0,0 +1,51 @@
+name: 'Insights - PrivateLinkScopes'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.insights.privatelinkscopes.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Insights/privateLinkScopes/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Insights/privateLinkScopes'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.insights.scheduledqueryrules.yml b/.azuredevops/modulePipelines/ms.insights.scheduledqueryrules.yml
new file mode 100644
index 000000000..7e83d3b93
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.insights.scheduledqueryrules.yml
@@ -0,0 +1,51 @@
+name: 'Insights - ScheduledQueryRules'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.insights.scheduledqueryrules.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Insights/scheduledQueryRules/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Insights/scheduledQueryRules'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.keyvault.vaults.yml b/.azuredevops/modulePipelines/ms.keyvault.vaults.yml
new file mode 100644
index 000000000..5458a9b78
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.keyvault.vaults.yml
@@ -0,0 +1,52 @@
+name: 'KeyVault - Vaults'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: false # Soft-delete prevents re-deployment
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.keyvault.vaults.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.KeyVault/vaults/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.KeyVault/vaults'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/min.parameters.json
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.logic.workflows.yml b/.azuredevops/modulePipelines/ms.logic.workflows.yml
new file mode 100644
index 000000000..0b8e56730
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.logic.workflows.yml
@@ -0,0 +1,51 @@
+name: 'Logic - Workflows'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.logic.workflows.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Logic/workflows/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Logic/workflows'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.machinelearningservices.workspaces.yml b/.azuredevops/modulePipelines/ms.machinelearningservices.workspaces.yml
new file mode 100644
index 000000000..c831fb4b7
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.machinelearningservices.workspaces.yml
@@ -0,0 +1,51 @@
+name: 'MachineLearningServices - Workspaces'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.machinelearningservices.workspaces.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.MachineLearningServices/workspaces/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.MachineLearningServices/workspaces'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.managedidentity.userassignedidentities.yml b/.azuredevops/modulePipelines/ms.managedidentity.userassignedidentities.yml
new file mode 100644
index 000000000..f20e2d034
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.managedidentity.userassignedidentities.yml
@@ -0,0 +1,51 @@
+name: 'ManagedIdentity - UserAssignedIdentities'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.managedidentity.userassignedidentities.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.ManagedIdentity/userAssignedIdentities/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.ManagedIdentity/userAssignedIdentities'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.managedservices.registrationdefinitions.yml b/.azuredevops/modulePipelines/ms.managedservices.registrationdefinitions.yml
new file mode 100644
index 000000000..76e583bd4
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.managedservices.registrationdefinitions.yml
@@ -0,0 +1,52 @@
+name: 'ManagedServices - RegistrationDefinitions'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: false # Needs a custom removal script
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.managedservices.registrationdefinitions.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.ManagedServices/registrationDefinitions/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.ManagedServices/registrationDefinitions'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+ - path: $(modulePath)/.parameters/rg.parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.management.managementgroups.yml b/.azuredevops/modulePipelines/ms.management.managementgroups.yml
new file mode 100644
index 000000000..cc6f67fd1
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.management.managementgroups.yml
@@ -0,0 +1,51 @@
+name: 'Management - ManagementGroups'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.management.managementgroups.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Management/managementGroups/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Management/managementGroups'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.netapp.netappaccounts.yml b/.azuredevops/modulePipelines/ms.netapp.netappaccounts.yml
new file mode 100644
index 000000000..c0beec10e
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.netapp.netappaccounts.yml
@@ -0,0 +1,53 @@
+name: 'NetApp - NetAppAccounts'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.netapp.netappaccounts.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.NetApp/netAppAccounts/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.NetApp/netAppAccounts'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/min.parameters.json
+ - path: $(modulePath)/.parameters/nfs3.parameters.json
+ - path: $(modulePath)/.parameters/nfs41.parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.network.applicationgateways.yml b/.azuredevops/modulePipelines/ms.network.applicationgateways.yml
new file mode 100644
index 000000000..b680e5787
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.network.applicationgateways.yml
@@ -0,0 +1,51 @@
+name: 'Network - ApplicationGateways'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.network.applicationgateways.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Network/applicationGateways/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Network/applicationGateways'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.network.applicationsecuritygroups.yml b/.azuredevops/modulePipelines/ms.network.applicationsecuritygroups.yml
new file mode 100644
index 000000000..892d102c2
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.network.applicationsecuritygroups.yml
@@ -0,0 +1,51 @@
+name: 'Network - ApplicationSecurityGroups'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.network.applicationsecuritygroups.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Network/applicationSecurityGroups/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Network/applicationSecurityGroups'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.network.azurefirewalls.yml b/.azuredevops/modulePipelines/ms.network.azurefirewalls.yml
new file mode 100644
index 000000000..42a913133
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.network.azurefirewalls.yml
@@ -0,0 +1,51 @@
+name: 'Network - AzureFirewalls'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.network.azurefirewalls.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Network/azureFirewalls/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Network/azureFirewalls'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.network.bastionhosts.yml b/.azuredevops/modulePipelines/ms.network.bastionhosts.yml
new file mode 100644
index 000000000..f94e4c933
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.network.bastionhosts.yml
@@ -0,0 +1,52 @@
+name: 'Network - BastionHosts'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.network.bastionhosts.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Network/bastionHosts/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Network/bastionHosts'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/min.parameters.json
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.network.connections.yml b/.azuredevops/modulePipelines/ms.network.connections.yml
new file mode 100644
index 000000000..43c0f01ec
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.network.connections.yml
@@ -0,0 +1,51 @@
+name: 'Network - Connections'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.network.connections.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Network/connections/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Network/connections'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.network.ddosprotectionplans.yml b/.azuredevops/modulePipelines/ms.network.ddosprotectionplans.yml
new file mode 100644
index 000000000..78e509684
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.network.ddosprotectionplans.yml
@@ -0,0 +1,51 @@
+name: 'Network - DdosProtectionPlans'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.network.ddosprotectionplans.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Network/ddosProtectionPlans/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Network/ddosProtectionPlans'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.network.expressroutecircuits.yml b/.azuredevops/modulePipelines/ms.network.expressroutecircuits.yml
new file mode 100644
index 000000000..d328763a7
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.network.expressroutecircuits.yml
@@ -0,0 +1,51 @@
+name: 'Network - ExpressRouteCircuits'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.network.expressroutecircuits.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Network/expressRouteCircuits/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Network/expressRouteCircuits'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.network.firewallpolicies.yml b/.azuredevops/modulePipelines/ms.network.firewallpolicies.yml
new file mode 100644
index 000000000..ba839cd41
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.network.firewallpolicies.yml
@@ -0,0 +1,51 @@
+name: 'Network - Firewallpolicies'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.network.firewallpolicies.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Network/firewallpolicies/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Network/firewallpolicies'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/module.jobs.validate.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/module.jobs.deploy.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.network.ipgroups.yml b/.azuredevops/modulePipelines/ms.network.ipgroups.yml
new file mode 100644
index 000000000..14c98650b
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.network.ipgroups.yml
@@ -0,0 +1,51 @@
+name: 'Network - IpGroups'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.network.ipgroups.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Network/ipGroups/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Network/ipGroups'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.network.loadbalancers.yml b/.azuredevops/modulePipelines/ms.network.loadbalancers.yml
new file mode 100644
index 000000000..bc5150aee
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.network.loadbalancers.yml
@@ -0,0 +1,52 @@
+name: 'Network - LoadBalancers'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.network.loadbalancers.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Network/loadBalancers/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Network/loadBalancers'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+ - path: $(modulePath)/.parameters/min.parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.network.localnetworkgateways.yml b/.azuredevops/modulePipelines/ms.network.localnetworkgateways.yml
new file mode 100644
index 000000000..6325a2b08
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.network.localnetworkgateways.yml
@@ -0,0 +1,51 @@
+name: 'Network - LocalNetworkGateways'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.network.localnetworkgateways.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Network/localNetworkGateways/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Network/localNetworkGateways'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.network.natgateways.yml b/.azuredevops/modulePipelines/ms.network.natgateways.yml
new file mode 100644
index 000000000..0d8930a1a
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.network.natgateways.yml
@@ -0,0 +1,51 @@
+name: 'Network - NatGateways'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.network.natgateways.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Network/natGateways/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Network/natGateways'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.network.networksecuritygroups.yml b/.azuredevops/modulePipelines/ms.network.networksecuritygroups.yml
new file mode 100644
index 000000000..d2ee2f9cc
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.network.networksecuritygroups.yml
@@ -0,0 +1,51 @@
+name: 'Network - NetworkSecurityGroups'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.network.networksecuritygroups.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Network/networkSecurityGroups/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Network/networkSecurityGroups'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.network.networkwatchers.yml b/.azuredevops/modulePipelines/ms.network.networkwatchers.yml
new file mode 100644
index 000000000..c9befd2ca
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.network.networkwatchers.yml
@@ -0,0 +1,52 @@
+name: 'Network - NetworkWatchers'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: false # Required as a dependency + Only one Network Watcher can exist in the same location. If removed, a default would be created in a dedicated RG
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.network.networkwatchers.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Network/networkWatchers/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Network/networkWatchers'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/min.parameters.json
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.network.privatednszones.yml b/.azuredevops/modulePipelines/ms.network.privatednszones.yml
new file mode 100644
index 000000000..581625a02
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.network.privatednszones.yml
@@ -0,0 +1,51 @@
+name: 'Network - PrivateDnsZones'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.network.privatednszones.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Network/privateDnsZones/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Network/privateDnsZones'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.network.privateendpoints.yml b/.azuredevops/modulePipelines/ms.network.privateendpoints.yml
new file mode 100644
index 000000000..45b3b539a
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.network.privateendpoints.yml
@@ -0,0 +1,52 @@
+name: 'Network - PrivateEndpoints'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.network.privateendpoints.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Network/privateEndpoints/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Network/privateEndpoints'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/min.parameters.json
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.network.publicipaddresses.yml b/.azuredevops/modulePipelines/ms.network.publicipaddresses.yml
new file mode 100644
index 000000000..73bf881d1
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.network.publicipaddresses.yml
@@ -0,0 +1,51 @@
+name: 'Network - PublicIpAddresses'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.network.publicipaddresses.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Network/publicIPAddresses/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Network/publicIPAddresses'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.network.publicipprefixes.yml b/.azuredevops/modulePipelines/ms.network.publicipprefixes.yml
new file mode 100644
index 000000000..1be45a7d4
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.network.publicipprefixes.yml
@@ -0,0 +1,51 @@
+name: 'Network - PublicIpPrefixes'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.network.publicipprefixes.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Network/publicIPPrefixes/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Network/publicIPPrefixes'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.network.routetables.yml b/.azuredevops/modulePipelines/ms.network.routetables.yml
new file mode 100644
index 000000000..c3d0c05fb
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.network.routetables.yml
@@ -0,0 +1,51 @@
+name: 'Network - RouteTables'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.network.routetables.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Network/routeTables/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Network/routeTables'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.network.trafficmanagerprofiles.yml b/.azuredevops/modulePipelines/ms.network.trafficmanagerprofiles.yml
new file mode 100644
index 000000000..32059ca83
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.network.trafficmanagerprofiles.yml
@@ -0,0 +1,51 @@
+name: 'Network - TrafficManagerProfiles'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.network.trafficmanagerprofiles.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Network/trafficmanagerprofiles/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Network/trafficmanagerprofiles'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.network.virtualhubs.yml b/.azuredevops/modulePipelines/ms.network.virtualhubs.yml
new file mode 100644
index 000000000..ba7eb4d6b
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.network.virtualhubs.yml
@@ -0,0 +1,52 @@
+name: 'Network: Virtual Hubs'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.network.virtualHubs.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Network/virtualHubs/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Network/virtualHubs'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/min.parameters.json
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.network.virtualnetworkgateways.yml b/.azuredevops/modulePipelines/ms.network.virtualnetworkgateways.yml
new file mode 100644
index 000000000..c73ac8fa2
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.network.virtualnetworkgateways.yml
@@ -0,0 +1,52 @@
+name: 'Network - VirtualNetworkGateways'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.network.virtualnetworkgateways.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Network/virtualNetworkGateways/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Network/virtualNetworkGateways'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/expressRoute.parameters.json
+ - path: $(modulePath)/.parameters/vpn.parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.network.virtualnetworks.yml b/.azuredevops/modulePipelines/ms.network.virtualnetworks.yml
new file mode 100644
index 000000000..cedac4fbb
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.network.virtualnetworks.yml
@@ -0,0 +1,52 @@
+name: 'Network - VirtualNetworks'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.network.virtualnetworks.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Network/virtualNetworks/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Network/virtualNetworks'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+ - path: $(modulePath)/.parameters/vnetPeering.parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.network.virtualwans.yml b/.azuredevops/modulePipelines/ms.network.virtualwans.yml
new file mode 100644
index 000000000..bef3372da
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.network.virtualwans.yml
@@ -0,0 +1,51 @@
+name: 'Network - VirtualWans'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.network.virtualwans.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Network/virtualWans/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Network/virtualWans'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.operationalinsights.workspaces.yml b/.azuredevops/modulePipelines/ms.operationalinsights.workspaces.yml
new file mode 100644
index 000000000..497dceb9f
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.operationalinsights.workspaces.yml
@@ -0,0 +1,52 @@
+name: 'OperationalInsights - Workspaces'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.operationalinsights.workspaces.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.OperationalInsights/workspaces/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.OperationalInsights/workspaces'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/min.parameters.json
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.recoveryservices.vaults.yml b/.azuredevops/modulePipelines/ms.recoveryservices.vaults.yml
new file mode 100644
index 000000000..77dae89ca
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.recoveryservices.vaults.yml
@@ -0,0 +1,51 @@
+name: 'RecoveryServices - Vaults'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.recoveryservices.vaults.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.RecoveryServices/vaults/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.RecoveryServices/vaults'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.resources.deploymentscripts.yml b/.azuredevops/modulePipelines/ms.resources.deploymentscripts.yml
new file mode 100644
index 000000000..b5e131051
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.resources.deploymentscripts.yml
@@ -0,0 +1,51 @@
+name: 'Resources - DeploymentScripts'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.resources.deploymentscripts.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Resources/deploymentScripts/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Resources/deploymentScripts'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.resources.resourcegroups.yml b/.azuredevops/modulePipelines/ms.resources.resourcegroups.yml
new file mode 100644
index 000000000..02638da8e
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.resources.resourcegroups.yml
@@ -0,0 +1,51 @@
+name: 'Resources - ResourceGroups'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.resources.resourcegroups.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Resources/resourceGroups/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Resources/resourceGroups'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.resources.tags.yml b/.azuredevops/modulePipelines/ms.resources.tags.yml
new file mode 100644
index 000000000..9b33b7cf8
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.resources.tags.yml
@@ -0,0 +1,53 @@
+name: 'Resources - Tags'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.resources.tags.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Resources/tags/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Resources/tags'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/min.parameters.json
+ - path: $(modulePath)/.parameters/rg.parameters.json
+ - path: $(modulePath)/.parameters/sub.parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.security.azuresecuritycenter.yml b/.azuredevops/modulePipelines/ms.security.azuresecuritycenter.yml
new file mode 100644
index 000000000..f5e26899e
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.security.azuresecuritycenter.yml
@@ -0,0 +1,51 @@
+name: 'Security - AzureSecurityCenter'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: false # Needs custom removals script
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.security.azuresecuritycenter.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Security/azureSecurityCenter/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Security/azureSecurityCenter'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.servicebus.namespaces.yml b/.azuredevops/modulePipelines/ms.servicebus.namespaces.yml
new file mode 100644
index 000000000..b75325c71
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.servicebus.namespaces.yml
@@ -0,0 +1,52 @@
+name: 'ServiceBus - Namespaces'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.servicebus.namespaces.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.ServiceBus/namespaces/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.ServiceBus/namespaces'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/min.parameters.json
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.servicefabric.clusters.yml b/.azuredevops/modulePipelines/ms.servicefabric.clusters.yml
new file mode 100644
index 000000000..de23be1ed
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.servicefabric.clusters.yml
@@ -0,0 +1,53 @@
+name: 'Service Fabric - Clusters'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.servicefabric.clusters.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/Microsoft.ServiceFabric/clusters/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.ServiceFabric/clusters'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/module.jobs.validate.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/module.jobs.deploy.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/min.parameters.json
+ - path: $(modulePath)/.parameters/full.parameters.json
+ - path: $(modulePath)/.parameters/cert.parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.sql.managedinstances.yml b/.azuredevops/modulePipelines/ms.sql.managedinstances.yml
new file mode 100644
index 000000000..5734b967c
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.sql.managedinstances.yml
@@ -0,0 +1,52 @@
+name: 'Sql - ManagedInstances'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.sql.managedinstances.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Sql/managedInstances/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Sql/managedInstances'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+ defaultJobTimeoutInMinutes: 360
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.sql.servers.yml b/.azuredevops/modulePipelines/ms.sql.servers.yml
new file mode 100644
index 000000000..4a162b398
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.sql.servers.yml
@@ -0,0 +1,51 @@
+name: 'Sql - Servers'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.sql.servers.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Sql/servers/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Sql/servers'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.storage.storageaccounts.yml b/.azuredevops/modulePipelines/ms.storage.storageaccounts.yml
new file mode 100644
index 000000000..0dafd10e8
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.storage.storageaccounts.yml
@@ -0,0 +1,53 @@
+name: 'Storage - StorageAccounts'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.storage.storageaccounts.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Storage/storageAccounts/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Storage/storageAccounts'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/min.parameters.json
+ - path: $(modulePath)/.parameters/parameters.json
+ - path: $(modulePath)/.parameters/v1.parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.synapse.privatelinkhubs.yml b/.azuredevops/modulePipelines/ms.synapse.privatelinkhubs.yml
new file mode 100644
index 000000000..81d79c3b0
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.synapse.privatelinkhubs.yml
@@ -0,0 +1,52 @@
+name: 'Synapse - PrivateLinkHubs'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.synapse.privatelinkhubs.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Synapse/privateLinkHubs/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Synapse/privateLinkHubs'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/min.parameters.json
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.virtualmachineimages.imagetemplates.yml b/.azuredevops/modulePipelines/ms.virtualmachineimages.imagetemplates.yml
new file mode 100644
index 000000000..99ce80ebb
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.virtualmachineimages.imagetemplates.yml
@@ -0,0 +1,51 @@
+name: 'VirtualMachineImages - ImageTemplates'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.virtualmachineimages.imagetemplates.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.VirtualMachineImages/imageTemplates/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.VirtualMachineImages/imageTemplates'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.web.connections.yml b/.azuredevops/modulePipelines/ms.web.connections.yml
new file mode 100644
index 000000000..b66056377
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.web.connections.yml
@@ -0,0 +1,51 @@
+name: 'Web - Connections'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.web.connections.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Web/connections/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Web/connections'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.web.hostingenvironments.yml b/.azuredevops/modulePipelines/ms.web.hostingenvironments.yml
new file mode 100644
index 000000000..3d51d4a23
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.web.hostingenvironments.yml
@@ -0,0 +1,52 @@
+name: 'Web - HostingEnvironments'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.web.hostingenvironments.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Web/hostingEnvironments/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Web/hostingEnvironments'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+ defaultJobTimeoutInMinutes: 180
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.web.serverfarms.yml b/.azuredevops/modulePipelines/ms.web.serverfarms.yml
new file mode 100644
index 000000000..970239004
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.web.serverfarms.yml
@@ -0,0 +1,51 @@
+name: 'Web - Serverfarms'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.web.serverfarms.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Web/serverfarms/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Web/serverfarms'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/modulePipelines/ms.web.sites.yml b/.azuredevops/modulePipelines/ms.web.sites.yml
new file mode 100644
index 000000000..32c7b7f9a
--- /dev/null
+++ b/.azuredevops/modulePipelines/ms.web.sites.yml
@@ -0,0 +1,54 @@
+name: 'Web - Sites'
+
+parameters:
+ - name: removeDeployment
+ displayName: Remove deployed module
+ type: boolean
+ default: true
+ - name: prerelease
+ displayName: Publish prerelease module
+ type: boolean
+ default: false
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - '/.azuredevops/modulePipelines/ms.web.sites.yml'
+ - '/.azuredevops/pipelineTemplates/module.*.yml'
+ - '/arm/Microsoft.Web/sites/*'
+ exclude:
+ - '/**/*.md'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: modulePath
+ value: '/arm/Microsoft.Web/sites'
+
+stages:
+ - stage: Validation
+ displayName: Pester tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
+
+ - stage: Deployment
+ displayName: Deployment tests
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ removeDeployment: '${{ parameters.removeDeployment }}'
+ deploymentBlocks:
+ - path: $(modulePath)/.parameters/fa.min.parameters.json
+ - path: $(modulePath)/.parameters/fa.parameters.json
+ - path: $(modulePath)/.parameters/wa.min.parameters.json
+ - path: $(modulePath)/.parameters/wa.parameters.json
+
+ - stage: Publishing
+ displayName: Publish module
+ condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true')))
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml
diff --git a/.azuredevops/pipelineTemplates/jobs.publishModule.yml b/.azuredevops/pipelineTemplates/jobs.publishModule.yml
new file mode 100644
index 000000000..cb6298244
--- /dev/null
+++ b/.azuredevops/pipelineTemplates/jobs.publishModule.yml
@@ -0,0 +1,310 @@
+#########################################################
+## PUBLISH PIPELINE ##
+#########################################################
+##
+## This pipeline template contains the logic to publish module data as
+## - A build artifact and/or
+## - As a new version to a given storage account and/or
+## - As a new version as an UniversalPackage to a given artifact-feed
+##
+#########################################################
+
+##---------------------------------------------##
+## TEMPLATE PARAMETERS ##
+##---------------------------------------------##
+##
+## By default it uses the variables specified in the below [parameters] section. However, you can overwrite these variables in the
+## referencing pipeline by providing the parameter explicitly.
+##
+## NOTE: If you don't need to overwrite a shared value, you can IGNORE this section
+##
+## |======================================================================================================================================================================================================================|
+## | Parameter | Default Value | Description | Example |
+## |---------------------------------|--------------------------------------|---------------------------------------------------------------------------------------------------------|-----------------------------------|
+## | displayName | 'Publish module' | Name for the pipeline job | 'Publish KeyVault' |
+## | serviceConnection | '$(serviceConnection)' | The service connection that connects to Azure | 'demo-internal' |
+## | poolName | '$(poolName)' | You can provide either a [poolname] or [vmImage] to run the job on | 'Custom Deployment Pool' |
+## | vmImage | '$(vmImage)' | You can provide either a [poolname] or [vmImage] to run the job on | 'ubuntu20.04' |
+## | defaultJobTimeoutInMinutes | 120 | The timeout for the job in this pipeline | 120 |
+## | modulePath | '$(modulePath)' | The path to the module to deploy. E.g. [c:/KeyVault] | 'c:/KeyVault' |
+## | templateSpecsRGName | '$(templateSpecsRGName)' | Required to publish to template spec. ResourceGroup of the template spec to publish to | 'mgmt-rg' |
+## | templateSpecsRGLocation | '$(templateSpecsRGLocation)' | Required to publish to template spec. Location of the template spec resource group | 'West Europe' |
+## | templateSpecsDescription | '$(templateSpecsDescription)' | Required to publish to template spec. Description of the template spec to publish to | 'IaCs module' |
+## | vstsFeedToken | '$(vstsFeedToken)' | Required to publish to a DevOps feed. Token with access to the feed to publish to. | '...' |
+## | vstsFeedName | '$(vstsFeedName)' | Required to publish to a DevOps feed. Name to the feed to publish to. | 'modules' |
+## | vstsFeedProject | '$(vstsFeedProject)' | Required to publish to a DevOps feed. Name of the project hosting the artifacts feed. May be empty. | 'iacs' |
+## | bicepRegistryName | '$(bicepRegistryName)' | Required to publish to the private bicep registry. Name of the hosting container registry | 'adpsxxazacrx001' |
+## | bicepRegistryRGName | '$(bicepRegistryRGName)' | Required to publish to the private bicep registry. Resource group of the hosting container registry | 'artifacts-rg' |
+## | bicepRegistryRgLocation | '$(bicepRegistryRgLocation)' | Required to publish to the private bicep registry. Location of the RG of the hosting container registry | 'West Europe' |
+## | vstsOrganizationUri | '$(vstsOrganizationUri)' | Required to publish to a DevOps feed. Name of the organization hosting the artifacts feed. | 'servicescode' |
+## | azurePowerShellVersion | '$(azurePowerShellVersion)' | Used for configuring the Azure PowerShell Version, one of the example values. | 'latestVersion' or 'OtherVersion' |
+## | preferredAzurePowerShellVersion | '$(preferredAzurePowerShellVersion)' | Used for configuring the Azure PowerShell Version, either an empty string or specific version. | '4.4.0' |
+## |======================================================================================================================================================================================================================|
+##
+##---------------------------------------------##
+
+parameters:
+ # Pipeline-related parameters
+ checkoutRepositories: ''
+ displayName: 'Publish module'
+ serviceConnection: '$(serviceConnection)'
+ poolName: '$(poolName)'
+ vmImage: '$(vmImage)'
+ defaultJobTimeoutInMinutes: 120
+ modulesRepository: '$(modulesRepository)'
+
+ # Logic-related parameters
+ ## Module-related
+ modulePath: '$(modulePath)'
+
+ ## TemplateSpec-related
+ templateSpecsDoPublish: '$(templateSpecsDoPublish)'
+ templateSpecsRGName: '$(templateSpecsRGName)'
+ templateSpecsRGLocation: '$(templateSpecsRGLocation)'
+ templateSpecsDescription: '$(templateSpecsDescription)'
+
+ ## Artifact-Feed-related
+ artifactsFeedDoPublish: '$(artifactsFeedDoPublish)'
+ vstsOrganizationUri: '$(vstsOrganizationUri)'
+ vstsFeedProject: '$(vstsFeedProject)'
+ vstsFeedName: '$(vstsFeedName)'
+ vstsFeedToken: '$(vstsFeedToken)'
+
+ ## Private-Bicep-Registry-related
+ bicepRegistryDoPublish: '$(bicepRegistryDoPublish)'
+ bicepRegistryName: '$(bicepRegistryName)'
+ bicepRegistryRGName: '$(bicepRegistryRGName)'
+ bicepRegistryRgLocation: '$(bicepRegistryRgLocation)'
+
+##---------------------------------------------##
+## TEMPLATE LOGIC ##
+##---------------------------------------------##
+jobs:
+ - job:
+ displayName: ${{ parameters.displayName }}
+ timeoutInMinutes: ${{ parameters.defaultJobTimeoutInMinutes }}
+ pool:
+ ${{ if ne(parameters.vmImage, '') }}:
+ vmImage: ${{ parameters.vmImage }}
+ ${{ if ne(parameters.poolName, '') }}:
+ name: ${{ parameters.poolName }}
+ steps:
+ # [Checkout Repositories] task(s)
+ #--------------------------------
+ - checkout: self
+ - ${{ if ne(parameters.checkoutRepositories, '') }}:
+ - ${{ each checkoutRepository in parameters.checkoutRepositories }}:
+ - checkout: ${{ checkoutRepository }}
+ fetchDepth: 1 # the depth of commits to ask Git to fetch; if not set defaults to no limit
+ path: 's/${{ checkoutRepository }}'
+
+ # [Agent] Prepare environment
+ #----------------------------
+ - task: PowerShell@2
+ displayName: 'Setup agent'
+ inputs:
+ targetType: inline
+ pwsh: true
+ script: |
+ # Load used functions
+ . (Join-Path '$(System.DefaultWorkingDirectory)' 'utilities' 'pipelines' 'sharedScripts' 'Set-EnvironmentOnAgent.ps1')
+
+ # Define PS modules to install on the runner
+ $Modules = @(
+ @{ Name = 'Az.Accounts' },
+ @{ Name = 'Az.ContainerRegistry' },
+ @{ Name = 'Az.Resources' }
+ )
+
+ # Set agent up
+ Set-EnvironmentOnAgent -PSModules $Modules
+
+ # [Multi Repo] Support task
+ #--------------------------
+ - task: PowerShell@2
+ displayName: Handle Multi-Repo Invocation
+ inputs:
+ targetType: inline
+ pwsh: true
+ script: |
+ # ---------------------------- #
+ # HANDLE MULTI-REPO INVOCATION #
+ # ---------------------------- #
+
+ # Handle multiple-repositories
+ if( "${{ join(';',parameters.checkoutRepositories) }}".length -gt 0) {
+ Write-Verbose "Multi-Repo Checkout" -Verbose
+ $modulePath = Join-Path '$(System.DefaultWorkingDirectory)' '$(modulesRepository)' '${{ parameters.modulePath }}'
+ } else {
+ Write-Verbose "No Multi-Repo Checkout" -Verbose
+ $modulePath = Join-Path '$(System.DefaultWorkingDirectory)' '${{ parameters.modulePath }}'
+ }
+ Write-Output "##vso[task.setvariable variable=ENVMODULEPATH]$modulePath"
+
+ # [Universal Artifact-feed publish] task(s)
+ #------------------------------------------
+ - task: PowerShell@2
+ displayName: 'Publish module to artifacts feed'
+ condition: and(
+ eq(variables['artifactsFeedDoPublish'], true),
+ succeeded()
+ )
+ enabled: true
+ inputs:
+ targetType: inline
+ pwsh: true
+ script: |
+ # Load used functions
+ . (Join-Path '$(System.DefaultWorkingDirectory)' '$(pipelineFunctionsPath)' 'resourcePublish' 'Get-ModulesToPublish.ps1')
+ . (Join-Path '$(System.DefaultWorkingDirectory)' '$(pipelineFunctionsPath)' 'resourcePublish' 'Publish-ModuleToUniversalArtifactFeed.ps1')
+
+ #Prioritizing the bicep file
+ $TemplateFilePath = Join-Path -Path '$(ENVMODULEPATH)' -ChildPath 'deploy.bicep'
+ if (-not (Test-Path $TemplateFilePath)) {
+ $TemplateFilePath = Join-Path -Path '$(ENVMODULEPATH)' -ChildPath 'deploy.json'
+ }
+
+ $functionInput = @{
+ TemplateFilePath = $TemplateFilePath
+ }
+
+ Write-Verbose "Invoke Get-ModulesToPublish with" -Verbose
+ Write-Verbose ($functionInput | ConvertTo-Json | Out-String) -Verbose
+
+ # Get the modified child resources
+ $ModulesToPublish = Get-ModulesToPublish @functionInput -Verbose
+
+ # Publish the modified child resources
+ foreach ($ModuleToPublish in $ModulesToPublish) {
+ $RelPath = (($ModuleToPublish.TemplateFilePath).Split('/arm/')[-1]).Split('/deploy.')[0]
+ Write-Host "##[group]$(' - [{0}] [{1}]' -f $RelPath, $ModuleToPublish.Version)"
+
+ $functionInput = @{
+ TemplateFilePath = $ModuleToPublish.TemplateFilePath
+ VstsOrganizationUri = '${{ parameters.vstsOrganizationUri }}'
+ VstsFeedProject = '${{ parameters.vstsFeedProject }}'
+ VstsFeedName = '${{ parameters.vstsFeedName }}'
+ ModuleVersion = $ModuleToPublish.Version
+ BearerToken = $env:TOKEN
+ }
+
+ Write-Verbose "Invoke Publish-ModuleToUniversalArtifactFeed with" -Verbose
+ Write-Verbose ($functionInput | ConvertTo-Json | Out-String) -Verbose
+
+ Publish-ModuleToUniversalArtifactFeed @functionInput -Verbose
+ Write-Host "##[endgroup]"
+ }
+ env:
+ TOKEN: $(vstsFeedToken)
+
+ # [template-spec publish] task(s)
+ #--------------------------------
+ - task: AzurePowerShell@5
+ displayName: 'Publish module to template specs'
+ condition: and(
+ eq(variables['templateSpecsDoPublish'], true),
+ succeeded()
+ )
+ enabled: true
+ inputs:
+ azureSubscription: '${{ parameters.serviceConnection }}'
+ azurePowerShellVersion: ${{ parameters.azurePowerShellVersion }}
+ preferredAzurePowerShellVersion: ${{ parameters.preferredAzurePowerShellVersion }}
+ pwsh: true
+ ScriptType: InlineScript
+ inline: |
+ # Load used functions
+ . (Join-Path '$(System.DefaultWorkingDirectory)' '$(pipelineFunctionsPath)' 'resourcePublish' 'Get-ModulesToPublish.ps1')
+ . (Join-Path '$(System.DefaultWorkingDirectory)' '$(pipelineFunctionsPath)' 'resourcePublish' 'Publish-ModuleToTemplateSpec.ps1')
+
+ #Prioritizing the bicep file
+ $TemplateFilePath = Join-Path -Path '$(ENVMODULEPATH)' -ChildPath 'deploy.bicep'
+ if (-not (Test-Path $TemplateFilePath)) {
+ $TemplateFilePath = Join-Path -Path '$(ENVMODULEPATH)' -ChildPath 'deploy.json'
+ }
+
+ $functionInput = @{
+ TemplateFilePath = $TemplateFilePath
+ }
+
+ Write-Verbose "Invoke Get-ModulesToPublish with" -Verbose
+ Write-Verbose ($functionInput | ConvertTo-Json | Out-String) -Verbose
+
+ # Get the modified child resources
+ $ModulesToPublish = Get-ModulesToPublish @functionInput -Verbose
+
+ # Publish the modified child resources
+ foreach ($ModuleToPublish in $ModulesToPublish) {
+ $RelPath = (($ModuleToPublish.TemplateFilePath).Split('/arm/')[-1]).Split('/deploy.')[0]
+ Write-Host "##[group]$(' - [{0}] [{1}]' -f $RelPath, $ModuleToPublish.Version)"
+
+ $functionInput = @{
+ TemplateFilePath = $ModuleToPublish.TemplateFilePath
+ TemplateSpecsRgName = '${{ parameters.templateSpecsRgName }}'
+ TemplateSpecsRgLocation = '${{ parameters.templateSpecsRgLocation }}'
+ TemplateSpecsDescription = '${{ parameters.templateSpecsDescription }}'
+ ModuleVersion = $ModuleToPublish.Version
+ }
+
+ Write-Verbose "Invoke Publish-ModuleToTemplateSpec with" -Verbose
+ Write-Verbose ($functionInput | ConvertTo-Json | Out-String) -Verbose
+
+ Publish-ModuleToTemplateSpec @functionInput -Verbose
+ Write-Host "##[endgroup]"
+ }
+
+ # [private bicep registry publish] task(s)
+ #-------------------------------------------
+ - task: AzurePowerShell@5
+ displayName: 'Publish module to private bicep registry'
+ condition: and(
+ eq(variables['bicepRegistryDoPublish'], true),
+ succeeded()
+ )
+ enabled: true
+ inputs:
+ azureSubscription: '${{ parameters.serviceConnection }}'
+ azurePowerShellVersion: ${{ parameters.azurePowerShellVersion }}
+ preferredAzurePowerShellVersion: ${{ parameters.preferredAzurePowerShellVersion }}
+ pwsh: true
+ ScriptType: InlineScript
+ inline: |
+ # Load used functions
+ . (Join-Path '$(System.DefaultWorkingDirectory)' '$(pipelineFunctionsPath)' 'resourcePublish' 'Get-ModulesToPublish.ps1')
+ . (Join-Path '$(System.DefaultWorkingDirectory)' '$(pipelineFunctionsPath)' 'resourcePublish' 'Publish-ModuleToPrivateBicepRegistry.ps1')
+
+ #Prioritizing the bicep file
+ $TemplateFilePath = Join-Path -Path '$(ENVMODULEPATH)' -ChildPath 'deploy.bicep'
+ if (-not (Test-Path $TemplateFilePath)) {
+ $TemplateFilePath = Join-Path -Path '$(ENVMODULEPATH)' -ChildPath 'deploy.json'
+ }
+
+ $functionInput = @{
+ TemplateFilePath = $TemplateFilePath
+ }
+
+ Write-Verbose "Invoke Get-ModulesToPublish with" -Verbose
+ Write-Verbose ($functionInput | ConvertTo-Json | Out-String) -Verbose
+
+ # Get the modified child resources
+ $ModulesToPublish = Get-ModulesToPublish @functionInput -Verbose
+
+ # Publish the modified child resources
+ foreach ($ModuleToPublish in $ModulesToPublish) {
+ $RelPath = (($ModuleToPublish.TemplateFilePath).Split('/arm/')[-1]).Split('/deploy.')[0]
+ Write-Host "##[group]$(' - [{0}] [{1}]' -f $RelPath, $ModuleToPublish.Version)"
+
+ $functionInput = @{
+ TemplateFilePath = $ModuleToPublish.TemplateFilePath
+ BicepRegistryName = '${{ parameters.bicepRegistryName }}'
+ BicepRegistryRgName = '${{ parameters.bicepRegistryRgName }}'
+ BicepRegistryRgLocation = '${{ parameters.bicepRegistryRgLocation }}'
+ ModuleVersion = $ModuleToPublish.Version
+ }
+
+ Write-Verbose "Invoke Publish-ModuleToPrivateBicepRegistry with" -Verbose
+ Write-Verbose ($functionInput | ConvertTo-Json | Out-String) -Verbose
+
+ Publish-ModuleToPrivateBicepRegistry @functionInput -Verbose
+ Write-Host "##[endgroup]"
+ }
diff --git a/.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml b/.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
new file mode 100644
index 000000000..0d263d687
--- /dev/null
+++ b/.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
@@ -0,0 +1,348 @@
+#########################################################
+## DEPLOYMENT PIPELINE ##
+#########################################################
+##
+## This pipeline template contains the logic to deploy a given module's ARM template using the provided parameter file(s)
+##
+## Enabled levels of deployment
+## - Resource-Group-Level
+## - Subscription-Level
+## - Management-Group-Level
+## - Tenant-Level
+##
+########################################################
+##
+##---------------------------------------------##
+## TEMPLATE PARAMETERS ##
+##---------------------------------------------##
+##
+## By default it uses the variables specified in the below [parameters] section. However, you can overwrite these variables in the
+## referencing pipeline by providing the parameter explicitly.
+##
+## NOTE: If you don't need to overwrite a shared value, you can IGNORE this section
+##
+## |=================================================================================================================================================================================================================================|
+## | Parameter | Default Value | Description | Example |
+## |---------------------------------|--------------------------------------|-----------------------------------------------------------------------------------------------------------|--------------------------------------------|
+## | serviceConnection | '$(serviceConnection)' | The service connection that connects to Azure | 'demo-internal' |
+## | removeDeployment | '$(removeDeployment)' | Set to [true] to flag resource for removal. If not provided, defaults to false. | 'true' |
+## | poolName | '$(poolName)' | You can provide either a [poolname] or [vmImage] to run the job on | 'Custom Deployment Pool' |
+## | vmImage | '$(vmImage)' | You can provide either a [poolname] or [vmImage] to run the job on | 'ubuntu20.04' |
+## | defaultJobTimeoutInMinutes | 120 | The timeout for the job in this pipeline | 120 |
+## | checkoutRepositories | '' | An optional list of repositories to check out at the beginning of this job in addition to the source | 'Components' |
+## | modulePath | '$(modulePath)' | The path to the module to deploy. E.g. [c:/KeyVault] | 'c:/KeyVault' |
+## | deploymentBlocks | | The parameter file(s) to deploy with. Must be provided | path: 'C:/parameters.json' |
+## | location | '$(defaultLocation)' | The location to deploy with | 'EastUs2' |
+## | resourceGroupName | '$(defaultResourceGroupName)' | The resourcegroup to deploy into. Required only for Resource-Group-Level deployments | 'validation-rg' |
+## | subscriptionId | '$(ARM_SUBSCRIPTION_ID)' | The id of the subscription to deploy into when using a Management group service connection | 'aed7c000-6387-412e-bed0-24dfddf4bbc6' |
+## | managementGroupId | '$(ARM_MGMTGROUP_ID)' | The id of the management group to deploy into. Required only for Management-Group-Level deployments | '6ycc9620-cb01-454f-9ebc-fc6b1df48d64' |
+## | parametersRepository | '$(Build.Repository.Name)' | The respository with the parameter files. Defaults to the triggering repository | 'Solutions' |
+## | modulesRepository | '$(modulesRepository)' | The respository with the modules. | 'Components' |
+## | azurePowerShellVersion | '$(azurePowerShellVersion)' | Used for configuring the Azure PowerShellModules Version, one of the example values. | 'latestVersion' or 'OtherVersion' |
+## | preferredAzurePowerShellVersion | '$(preferredAzurePowerShellVersion)' | Used for configuring the Azure PowerShellModules Version, either an empty string or the specific version. | '4.4.0' |
+## |=================================================================================================================================================================================================================================|
+##
+##---------------------------------------------##
+
+parameters:
+ # Pipeline-related parameters
+ serviceConnection: '$(serviceConnection)'
+ poolName: '$(poolName)'
+ vmImage: '$(vmImage)'
+ defaultJobTimeoutInMinutes: 120
+ checkoutRepositories: ''
+ dependsOn: []
+ # Logic-related parameters
+ removeDeployment: false
+ modulePath: '$(modulePath)'
+ deploymentBlocks: ''
+ location: '$(defaultLocation)'
+ resourceGroupName: '$(defaultResourceGroupName)'
+ subscriptionId: '$(ARM_SUBSCRIPTION_ID)'
+ managementGroupId: '$(ARM_MGMTGROUP_ID)'
+ parametersRepository: '$(Build.Repository.Name)'
+ modulesRepository: '$(modulesRepository)'
+ # Azure PowerShell Version parameters
+ azurePowerShellVersion: '$(azurePowerShellVersion)'
+ preferredAzurePowerShellVersion: '$(preferredAzurePowerShellVersion)'
+
+##---------------------------------------------##
+## TEMPLATE LOGIC ##
+##---------------------------------------------##
+
+jobs:
+ - ${{ each deploymentBlock in parameters.deploymentBlocks }}:
+ - job: ${{ deploymentBlock.jobName }}
+
+ ${{ if ne( deploymentBlock.displayName, '') }}:
+ displayName: ${{ deploymentBlock.displayName }}
+ ${{ if eq( deploymentBlock.displayName, '') }}:
+ displayName: Deploy with [${{ replace( deploymentBlock.path, '$(modulePath)', '') }}]
+ timeoutInMinutes: ${{ parameters.defaultJobTimeoutInMinutes }}
+ ${{ if ne( parameters.dependsOn, '') }}:
+ dependsOn: ${{ parameters.dependsOn }}
+ pool:
+ ${{ if ne(parameters.vmImage, '') }}:
+ vmImage: ${{ parameters.vmImage }}
+ ${{ if ne(parameters.poolName, '') }}:
+ name: ${{ parameters.poolName }}
+
+ steps:
+ # [Checkout Repositories] task(s)
+ #--------------------------------
+ - checkout: self
+ - ${{ if ne(parameters.checkoutRepositories, '') }}:
+ - ? ${{ each checkoutRepository in parameters.checkoutRepositories }}
+ : - checkout: ${{ checkoutRepository }}
+ fetchDepth: 1 # the depth of commits to ask Git to fetch; if not set defaults to no limit
+ path: 's/${{ checkoutRepository }}'
+
+ # [Agent] Prepare environment
+ #----------------------------
+ - task: PowerShell@2
+ displayName: 'Setup agent'
+ inputs:
+ targetType: inline
+ pwsh: true
+ script: |
+ # Load used functions
+ . (Join-Path '$(System.DefaultWorkingDirectory)' 'utilities' 'pipelines' 'sharedScripts' 'Set-EnvironmentOnAgent.ps1')
+
+ # Define PS modules to install on the runner
+ $Modules = @(
+ @{ Name = 'Az.Accounts' },
+ @{ Name = 'Az.Resources' }
+ )
+
+ # Additional PS modules need to be installed for the removal step in case it is enabled
+ if ('${{ parameters.removeDeployment}}' -eq 'true') {
+ $Modules += @(
+ @{ Name = 'Az.CognitiveServices' },
+ @{ Name = 'Az.Compute' },
+ @{ Name = 'Az.KeyVault' },
+ @{ Name = 'Az.Monitor' },
+ @{ Name = 'Az.OperationalInsights' },
+ @{ Name = 'Az.RecoveryServices' }
+ )
+ }
+
+ # Set agent up
+ Set-EnvironmentOnAgent -PSModules $Modules
+
+ # [Multi Repo] Support task
+ #--------------------------
+ - task: PowerShell@2
+ displayName: Handle Multi-Repo Invocation
+ inputs:
+ targetType: inline
+ pwsh: true
+ script: |
+ # Handle multiple-repositories
+ if( "${{ join(';',parameters.checkoutRepositories) }}".length -gt 0) {
+ Write-Verbose "Multi-Repo Checkout" -Verbose
+ $moduleRepoRoot = Join-Path '$(System.DefaultWorkingDirectory)' '$(modulesRepository)'
+ $parametersRepoRoot = Join-Path '$(System.DefaultWorkingDirectory)' '${{ parameters.parametersRepository }}'
+ } else {
+ Write-Verbose "No Multi-Repo Checkout" -Verbose
+ $moduleRepoRoot = '$(System.DefaultWorkingDirectory)'
+ $parametersRepoRoot = '$(System.DefaultWorkingDirectory)'
+ }
+ Write-Output "##vso[task.setvariable variable=ModuleRepoRoot]$moduleRepoRoot"
+ Write-Output "##vso[task.setvariable variable=parametersRepoRoot]$parametersRepoRoot"
+
+ # [Agent] Replace tokens
+ #-----------------------
+ - task: AzurePowerShell@5
+ displayName: 'Replace Tokens [${{ deploymentBlock.path }}] via connection [${{ parameters.serviceConnection }}]'
+ inputs:
+ azureSubscription: ${{ parameters.serviceConnection }}
+ azurePowerShellVersion: ${{ parameters.azurePowerShellVersion }}
+ preferredAzurePowerShellVersion: ${{ parameters.preferredAzurePowerShellVersion }}
+ ScriptType: InlineScript
+ pwsh: true
+ inline: |
+ # Load used functions
+ . (Join-Path '$(moduleRepoRoot)' 'utilities' 'pipelines' 'tokensReplacement' 'Convert-TokensInFile.ps1')
+
+ # Load Settings File
+ $Settings = Get-Content -Path (Join-Path '$(moduleRepoRoot)' 'settings.json') | ConvertFrom-Json -AsHashTable
+
+ # Construct Token Function Input
+ $ConvertTokensInputs = @{
+ Tokens = @{}
+ FilePath = Join-Path '$(parametersRepoRoot)' '${{ deploymentBlock.path }}'
+ TokenPrefix = $Settings.parameterFileTokens.tokenPrefix
+ TokenSuffix = $Settings.parameterFileTokens.tokenSuffix
+ }
+
+ # Add defaults
+ $ConvertTokensInputs.Tokens += @{
+ resourceGroupName = '${{ parameters.resourceGroupName }}'
+ subscriptionId = '${{ parameters.subscriptionId }}'
+ managementGroupId = '${{ parameters.managementGroupId }}'
+ tenantId = '$(ARM_TENANT_ID)'
+ deploymentSpId = '$(DEPLOYMENT_SP_ID)'
+ }
+
+ # Add local tokens
+ if ($Settings.parameterFileTokens.localTokens) {
+ $tokenMap = @{}
+ foreach ($token in $Settings.parameterFileTokens.localTokens) {
+ $tokenMap += @{ $token.name = $token.value }
+ }
+ Write-Verbose ('Using local tokens [{0}]' -f ($tokenMap.Keys -join ', ')) -Verbose
+ $ConvertTokensInputs.Tokens += $tokenMap
+ }
+
+ # Add custom tokens (passed in via the pipeline)
+ if(-not [String]::IsNullOrEmpty('${{ deploymentBlock.customParameterFileTokens }}')) {
+ $customTokens = '${{ deploymentBlock.customParameterFileTokens }}' | ConvertFrom-Json -AsHashTable
+ Write-Verbose ('Using custom parameter file tokens [{0}]' -f ($customTokens.Keys -join ', ')) -Verbose
+ $ConvertTokensInputs.Tokens += $customTokens
+ }
+
+ # Invoke Token Replacement Functionality
+ $null = Convert-TokensInFile @ConvertTokensInputs
+
+ # [Validation] task(s)
+ #---------------------
+ - task: AzurePowerShell@5
+ displayName: 'Validate [${{ deploymentBlock.path }}] via connection [${{ parameters.serviceConnection }}]'
+ inputs:
+ azureSubscription: ${{ parameters.serviceConnection }}
+ azurePowerShellVersion: ${{ parameters.azurePowerShellVersion }}
+ preferredAzurePowerShellVersion: ${{ parameters.preferredAzurePowerShellVersion }}
+ ScriptType: InlineScript
+ pwsh: true
+ inline: |
+ # Load used functions
+ . (Join-Path '$(moduleRepoRoot)' '$(pipelineFunctionsPath)' 'resourceDeployment' 'Test-TemplateWithParameterFile.ps1')
+
+ if(-not [String]::IsNullOrEmpty('${{ deploymentBlock.templateFilePath }}')) {
+ $templateFilePath = Join-Path '$(moduleRepoRoot)' '${{ deploymentBlock.templateFilePath }}'
+ } else {
+ # Use default path
+ $templateFilePath = (Test-Path (Join-Path '$(ModuleRepoRoot)' '$(modulePath)' 'deploy.bicep')) ?
+ (Join-Path '$(ModuleRepoRoot)' '$(modulePath)' 'deploy.bicep') :
+ (Join-Path '$(ModuleRepoRoot)' '$(modulePath)' 'deploy.json')
+ }
+
+ # ----------- #
+ # INVOKE TEST #
+ # ----------- #
+ $functionInput = @{
+ templateFilePath = $templateFilePath
+ parameterFilePath = Join-Path '$(ParametersRepoRoot)' '${{ deploymentBlock.path }}'
+ location = '${{ parameters.location }}'
+ resourceGroupName = '${{ parameters.resourceGroupName }}'
+ subscriptionId = '${{ parameters.subscriptionId }}'
+ managementGroupId = '${{ parameters.managementGroupId }}'
+ }
+
+ Write-Verbose "Invoke task with" -Verbose
+ Write-Verbose ($functionInput | ConvertTo-Json | Out-String) -Verbose
+
+ Test-TemplateWithParameterFile @functionInput -Verbose
+
+ # [Deployment] task(s)
+ #---------------------
+ - task: AzurePowerShell@5
+ displayName: 'Deploy [${{ deploymentBlock.path }}] via connection [${{ parameters.serviceConnection }}]'
+ name: 'DeployModule'
+ inputs:
+ azureSubscription: ${{ parameters.serviceConnection }}
+ azurePowerShellVersion: ${{ parameters.azurePowerShellVersion }}
+ preferredAzurePowerShellVersion: ${{ parameters.preferredAzurePowerShellVersion }}
+ pwsh: true
+ ScriptType: InlineScript
+ inline: |
+ # Load used functions
+ . (Join-Path '$(moduleRepoRoot)' '$(pipelineFunctionsPath)' 'resourceDeployment' 'New-ModuleDeployment.ps1')
+
+ if(-not [String]::IsNullOrEmpty('${{ deploymentBlock.templateFilePath }}')) {
+ $templateFilePath = Join-Path '$(moduleRepoRoot)' '${{ deploymentBlock.templateFilePath }}'
+ } else {
+ # Use default path
+ $templateFilePath = (Test-Path (Join-Path '$(ModuleRepoRoot)' '$(modulePath)' 'deploy.bicep')) ?
+ (Join-Path '$(ModuleRepoRoot)' '$(modulePath)' 'deploy.bicep') :
+ (Join-Path '$(ModuleRepoRoot)' '$(modulePath)' 'deploy.json')
+ }
+
+ # ----------------- #
+ # INVOKE DEPLOYMENT #
+ # ----------------- #
+ $functionInput = @{
+ templateFilePath = $templateFilePath
+ parameterFilePath = Join-Path '$(parametersRepoRoot)' '${{ deploymentBlock.path }}'
+ location = '${{ parameters.location }}'
+ resourceGroupName = '${{ parameters.resourceGroupName }}'
+ subscriptionId = '${{ parameters.subscriptionId }}'
+ managementGroupId = '${{ parameters.managementGroupId }}'
+ doNotThrow = $true
+ }
+
+ Write-Verbose "Invoke task with" -Verbose
+ Write-Verbose ($functionInput | ConvertTo-Json | Out-String) -Verbose
+
+ # Invoke deployment
+ $res = New-ModuleDeployment @functionInput -Verbose
+
+ # Get deployment name
+ Write-Host ('##vso[task.setvariable variable=deploymentName]{0}' -f $res.deploymentName)
+
+ # Populate further outputs
+ $deploymentOutputHash=@{}
+
+ foreach ($outputKey in $res.deploymentOutput.Keys) {
+ Write-Output ('##vso[task.setvariable variable={0}]{1}' -f $outputKey, $res.deploymentOutput[$outputKey].Value)
+ $deploymentOutputHash.add($outputKey,$res.deploymentOutput[$outputKey].Value)
+ }
+
+ $deploymentOutput = $deploymentOutputHash | ConvertTo-Json -Compress -Depth 100
+ Write-Verbose "Deployment output: $deploymentOutput" -Verbose
+ Write-Output ('##vso[task.setvariable variable={0};isOutput=true]{1}' -f 'deploymentOutput', $deploymentOutput)
+
+ if ($res.ContainsKey('exception')) {
+ # Happens only if there is an exception
+ throw $res.exception
+ }
+
+ # [Removal] task(s)
+ #------------------
+ - task: AzurePowerShell@5
+ displayName: 'Remove deployed resources via [${{ parameters.serviceConnection }}]'
+ condition: and(succeededOrFailed(), eq( '${{ parameters.removeDeployment }}', 'true'), not(eq(variables['deploymentName'],'')))
+ inputs:
+ azureSubscription: ${{ parameters.serviceConnection }}
+ azurePowerShellVersion: ${{ parameters.azurePowerShellVersion }}
+ preferredAzurePowerShellVersion: ${{ parameters.preferredAzurePowerShellVersion }}
+ ScriptType: InlineScript
+ failOnStandardError: false
+ pwsh: true
+ inline: |
+ # Load used function
+ . (Join-Path '$(moduleRepoRoot)' '$(pipelineFunctionsPath)' 'resourceRemoval' 'Initialize-DeploymentRemoval.ps1')
+
+ if(-not [String]::IsNullOrEmpty('${{ deploymentBlock.templateFilePath }}')) {
+ $templateFilePath = Join-Path '$(moduleRepoRoot)' '${{ deploymentBlock.templateFilePath }}'
+ } else {
+ # Use default path
+ $templateFilePath = (Test-Path (Join-Path '$(ModuleRepoRoot)' '$(modulePath)' 'deploy.bicep')) ?
+ (Join-Path '$(ModuleRepoRoot)' '$(modulePath)' 'deploy.bicep') :
+ (Join-Path '$(ModuleRepoRoot)' '$(modulePath)' 'deploy.json')
+ }
+
+ if (-not [String]::IsNullOrEmpty('$(deploymentName)')) {
+ $functionInput = @{
+ DeploymentName = '$(deploymentName)'
+ TemplateFilePath = $templateFilePath
+ ResourceGroupName = '${{ parameters.resourceGroupName }}'
+ ManagementGroupId = '${{ parameters.managementGroupId }}'
+ Verbose = $true
+ }
+
+ Write-Verbose 'Invoke task with' -Verbose
+ Write-Verbose ($functionInput | ConvertTo-Json | Out-String) -Verbose
+
+ Initialize-DeploymentRemoval @functionInput
+ }
diff --git a/.azuredevops/pipelineTemplates/jobs.validateModulePester.yml b/.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
new file mode 100644
index 000000000..f946e0ef4
--- /dev/null
+++ b/.azuredevops/pipelineTemplates/jobs.validateModulePester.yml
@@ -0,0 +1,283 @@
+#########################################################
+## VALIDATION PIPELINE ##
+#########################################################
+##
+## This pipeline template contains the logic to validate a given module's ARM template using the provided parameter file(s)
+##
+## Enabled levels of validation
+## - Resource-Group-Level
+## - Subscription-Level
+## - Management-Group-Level
+## - Tenant-Level
+##
+#########################################################
+##
+##---------------------------------------------##
+## TEMPLATE PARAMETERS ##
+##---------------------------------------------##
+##
+## By default it uses the variables specified in the below [parameters] section. However, you can overwrite these variables in the
+## referencing pipeline by providing the parameter explicitly.
+##
+## NOTE: If you don't need to overwrite a shared value, you can IGNORE this section
+##
+## |=============================================================================================================================================================================================================================|
+## | Parameter | Default Value | Description | Example |
+## |---------------------------------|--------------------------------------|-----------------------------------------------------------------------------------------------------------|----------------------------------------|
+## | serviceConnection | '$(serviceConnection)' | The service connection that connects to Azure | 'demo-internal' |
+## | poolName | '$(poolName)' | You can provide either a [poolname] or [vmImage] to run the job on | 'Custom Deployment Pool' |
+## | vmImage | '$(vmImage)' | You can provide either a [poolname] or [vmImage] to run the job on | 'ubuntu20.04' |
+## | defaultJobTimeoutInMinutes | 120 | The timeout for the job in this pipeline | 120 |
+## | checkoutRepositories | '' | An optional list of repositories to check out at the beginning of this job in addition to the source | 'Components' |
+## | modulePath | '$(modulePath)' | The path to the module to deploy. E.g. [c:/KeyVault] | 'c:/KeyVault' |
+## | location | '$(defaultLocation)' | The location to validate with | 'France Central' |
+## | resourceGroupName | '$(defaultResourceGroupName)' | The resourcegroup to validate into. Required only for Resource-Group-Level validations | 'validation-rg' |
+## | subscriptionId | '$(ARM_SUBSCRIPTION_ID)' | The id of the subscription to validate with when using a Management group service connection | 'aed7c000-6387-412e-bed0-24dfddf4bbc6' |
+## | managementGroupId | '$(ARM_MGMTGROUP_ID)' | The id of the management group to validate with. Required only for Management-Group-Level validations | '477c9620-cb01-454f-9ebc-fc6b1df48c14' |
+## | parametersRepository | '$(Build.Repository.Name)' | The respository with the parameter files. Defaults to the triggering repository | 'Solutions' |
+## | modulesRepository | '$(modulesRepository)' | The respository with the modules. | 'Components' |
+## | azurePowerShellVersion | '$(azurePowerShellVersion)' | Used for configuring the Azure PowerShellModules Version, one of the example values. | 'latestVersion' or 'OtherVersion' |
+## | preferredAzurePowerShellVersion | '$(preferredAzurePowerShellVersion)' | Used for configuring the Azure PowerShellModules Version, either an empty string or the specific version. | '4.4.0' |
+## |=============================================================================================================================================================================================================================|
+##
+##---------------------------------------------##
+
+parameters:
+ # Pipeline-related parameters
+ serviceConnection: '$(serviceConnection)'
+ poolName: '$(poolName)'
+ vmImage: '$(vmImage)'
+ defaultJobTimeoutInMinutes: 120
+ checkoutRepositories: ''
+ # Logic-related parameters
+ modulePath: '$(modulePath)'
+ parametersRepository: '$(Build.Repository.Name)'
+ location: '$(defaultLocation)'
+ resourceGroupName: '$(defaultResourceGroupName)'
+ subscriptionId: '$(ARM_SUBSCRIPTION_ID)'
+ managementGroupId: '$(ARM_MGMTGROUP_ID)'
+ modulesRepository: '$(modulesRepository)'
+ # Azure PowerShell Version parameter
+ azurePowerShellVersion: '$(azurePowerShellVersion)'
+ preferredAzurePowerShellVersion: '$(preferredAzurePowerShellVersion)'
+
+##---------------------------------------------##
+## TEMPLATE LOGIC ##
+##---------------------------------------------##
+jobs:
+ - job:
+ displayName: Run global tests
+ timeoutInMinutes: ${{ parameters.defaultJobTimeoutInMinutes }}
+ pool:
+ ${{ if ne(parameters.vmImage, '') }}:
+ vmImage: ${{ parameters.vmImage }}
+ ${{ if ne(parameters.poolName, '') }}:
+ name: ${{ parameters.poolName }}
+ steps:
+ # [Checkout Repositories] task(s)
+ #--------------------------------
+ - checkout: self
+ - ${{ if ne(parameters.checkoutRepositories, '') }}:
+ - ${{ each checkoutRepository in parameters.checkoutRepositories }}:
+ - checkout: ${{ checkoutRepository }}
+ fetchDepth: 1 # the depth of commits to ask Git to fetch; if not set defaults to no limit
+ path: 's/${{ checkoutRepository }}'
+
+ # [Multi Repo] Support task
+ #--------------------------
+ - task: PowerShell@2
+ displayName: Handle Multi-Repo Invocation
+ inputs:
+ targetType: inline
+ pwsh: true
+ script: |
+ # Handle multiple-repositories
+ if( "${{ join(';',parameters.checkoutRepositories) }}".length -gt 0) {
+ Write-Verbose "Multi-Repo Checkout" -Verbose
+ $moduleRepoRoot = Join-Path '$(System.DefaultWorkingDirectory)' '$(modulesRepository)'
+ $parametersRepoRoot = Join-Path '$(System.DefaultWorkingDirectory)' '${{ parameters.parametersRepository }}'
+ } else {
+ Write-Verbose "No Multi-Repo Checkout" -Verbose
+ $moduleRepoRoot = '$(System.DefaultWorkingDirectory)'
+ $parametersRepoRoot = '$(System.DefaultWorkingDirectory)'
+ }
+ Write-Output "##vso[task.setvariable variable=ModuleRepoRoot]$moduleRepoRoot"
+ Write-Output "##vso[task.setvariable variable=ParametersRepoRoot]$parametersRepoRoot"
+
+ # [Agent] Prepare environment
+ #----------------------------
+ - task: PowerShell@2
+ displayName: 'Setup agent'
+ inputs:
+ targetType: inline
+ pwsh: true
+ script: |
+ # Load used functions
+ . (Join-Path '$(moduleRepoRoot)' 'utilities' 'pipelines' 'sharedScripts' 'Set-EnvironmentOnAgent.ps1')
+
+ # Define PS modules to install on the runner
+ $Modules = @(
+ # This is the latest tested Pester version. Uncomment the next line in case of a future breaking change in the default version installed on the runner.
+ # @{ Name = 'Pester'; Version = '5.3.1' }
+ @{ Name = 'Az.Resources' }
+ )
+
+ # Set agent up
+ Set-EnvironmentOnAgent -PSModules $Modules
+
+ # [Module Pester Test] task(s)
+ #-----------------------------
+ - task: AzurePowerShell@5
+ displayName: 'Run general tests via (Pester) via connection [${{ parameters.serviceConnection }}]'
+ inputs:
+ azureSubscription: ${{ parameters.serviceConnection }}
+ azurePowerShellVersion: ${{ parameters.azurePowerShellVersion }}
+ preferredAzurePowerShellVersion: ${{ parameters.preferredAzurePowerShellVersion }}
+ ScriptType: InlineScript
+ pwsh: true
+ inline: |
+ $moduleFolderPaths = @(Join-Path '$(moduleRepoRoot)' '${{ parameters.modulePath }}')
+ $moduleFolderPaths += (Get-ChildItem $moduleFolderPaths -Recurse -Directory -Force).FullName | Where-Object {
+ (Get-ChildItem $_ -File -Depth 0 -Include @('deploy.json', 'deploy.bicep') -Force).Count -gt 0
+ }
+ Write-Verbose "Execute tests in path(s):" -Verbose
+ foreach($moduleFolderPath in $moduleFolderPaths) {
+ Write-Verbose "- [($moduleFolderPath]" -Verbose
+ }
+
+ Invoke-Pester -Configuration @{
+ Run = @{
+ Container = New-PesterContainer -Path (Join-Path '$(moduleRepoRoot)' 'arm' '.global' 'global.module.tests.ps1') -Data @{
+ moduleFolderPaths = $moduleFolderPaths
+ }
+ }
+ Filter = @{
+ ExcludeTag = 'ApiCheck'
+ }
+ TestResult = @{
+ TestSuiteName = 'Global Module Tests'
+ OutputPath = 'arm/.global/global-testResults.xml'
+ OutputFormat = 'NUnitXml'
+ Enabled = $true
+ }
+ Output = @{
+ Verbosity = 'Detailed'
+ }
+ } -ErrorAction 'Stop'
+ errorActionPreference: continue
+
+ - task: PublishTestResults@2
+ displayName: Publish Test Results
+ inputs:
+ testRunTitle: 'Global Module Tests'
+ testResultsFormat: NUnit
+ testResultsFiles: global-testResults.xml
+ failTaskOnFailedTests: true
+ searchFolder: 'arm/.global'
+ continueOnError: false
+ condition: succeededOrFailed()
+
+ - job:
+ displayName: Run global API tests
+ timeoutInMinutes: ${{ parameters.defaultJobTimeoutInMinutes }}
+ pool:
+ ${{ if ne(parameters.vmImage, '') }}:
+ vmImage: ${{ parameters.vmImage }}
+ ${{ if ne(parameters.poolName, '') }}:
+ name: ${{ parameters.poolName }}
+ steps:
+ # [Checkout Repositories] task(s)
+ #--------------------------------
+ - checkout: self
+ - ${{ if ne(parameters.checkoutRepositories, '') }}:
+ - ${{ each checkoutRepository in parameters.checkoutRepositories }}:
+ - checkout: ${{ checkoutRepository }}
+ fetchDepth: 1 # the depth of commits to ask Git to fetch; if not set defaults to no limit
+ path: 's/${{ checkoutRepository }}'
+
+ # [Multi Repo] Support task
+ #--------------------------
+ - task: PowerShell@2
+ displayName: Handle Multi-Repo Invocation
+ inputs:
+ targetType: inline
+ pwsh: true
+ script: |
+ # Handle multiple-repositories
+ if( "${{ join(';',parameters.checkoutRepositories) }}".length -gt 0) {
+ Write-Verbose "Multi-Repo Checkout" -Verbose
+ $moduleRepoRoot = Join-Path '$(System.DefaultWorkingDirectory)' '$(modulesRepository)'
+ $parametersRepoRoot = Join-Path '$(System.DefaultWorkingDirectory)' '${{ parameters.parametersRepository }}'
+ } else {
+ Write-Verbose "No Multi-Repo Checkout" -Verbose
+ $moduleRepoRoot = '$(System.DefaultWorkingDirectory)'
+ $parametersRepoRoot = '$(System.DefaultWorkingDirectory)'
+ }
+ Write-Output "##vso[task.setvariable variable=ModuleRepoRoot]$moduleRepoRoot"
+ Write-Output "##vso[task.setvariable variable=ParametersRepoRoot]$parametersRepoRoot"
+
+ # [Agent] Prepare environment
+ #----------------------------
+ - task: PowerShell@2
+ displayName: 'Setup agent'
+ inputs:
+ targetType: inline
+ pwsh: true
+ script: |
+ # Load used functions
+ . (Join-Path '$(moduleRepoRoot)' 'utilities' 'pipelines' 'sharedScripts' 'Set-EnvironmentOnAgent.ps1')
+
+ # Set agent up
+ Set-EnvironmentOnAgent
+
+ # [Module Pester Test] task(s)
+ #-----------------------------
+ - task: AzurePowerShell@5
+ displayName: 'Run API tests via (Pester) via connection [${{ parameters.serviceConnection }}]'
+ inputs:
+ azureSubscription: ${{ parameters.serviceConnection }}
+ azurePowerShellVersion: ${{ parameters.azurePowerShellVersion }}
+ preferredAzurePowerShellVersion: ${{ parameters.preferredAzurePowerShellVersion }}
+ ScriptType: InlineScript
+ pwsh: true
+ inline: |
+ $moduleFolderPaths = @(Join-Path '$(moduleRepoRoot)' '${{ parameters.modulePath }}')
+ $moduleFolderPaths += (Get-ChildItem $moduleFolderPaths -Recurse -Directory -Force).FullName | Where-Object {
+ (Get-ChildItem $_ -File -Depth 0 -Include @('deploy.json', 'deploy.bicep') -Force).Count -gt 0
+ }
+ Write-Verbose "Execute tests in path(s):" -Verbose
+ foreach($moduleFolderPath in $moduleFolderPaths) {
+ Write-Verbose "- [($moduleFolderPath]" -Verbose
+ }
+
+ Invoke-Pester -Configuration @{
+ Run = @{
+ Container = New-PesterContainer -Path (Join-Path '$(moduleRepoRoot)' 'arm' '.global' 'global.module.tests.ps1') -Data @{
+ moduleFolderPaths = $moduleFolderPaths
+ }
+ }
+ Filter = @{
+ Tag = 'ApiCheck'
+ }
+ TestResult = @{
+ TestSuiteName = 'Global Module API Tests'
+ OutputPath = 'arm/.global/api-testResults.xml'
+ OutputFormat = 'NUnitXml'
+ Enabled = $true
+ }
+ Output = @{
+ Verbosity = 'Detailed'
+ }
+ } -ErrorAction 'Stop'
+ errorActionPreference: continue
+
+ - task: PublishTestResults@2
+ displayName: Publish Test Results
+ inputs:
+ testRunTitle: 'Global Module API Tests'
+ testResultsFormat: NUnit
+ testResultsFiles: api-testResults.xml
+ failTaskOnFailedTests: true
+ searchFolder: 'arm/.global'
+ continueOnError: false
+ condition: succeededOrFailed()
diff --git a/.azuredevops/pipelineVariables/global.variables.yml b/.azuredevops/pipelineVariables/global.variables.yml
new file mode 100644
index 000000000..7e790694b
--- /dev/null
+++ b/.azuredevops/pipelineVariables/global.variables.yml
@@ -0,0 +1,74 @@
+variables:
+ ######################################
+ # Agent settings
+ ######################################
+
+ vmImage: 'ubuntu-latest' # Use this for Microsoft-hosted agents
+ poolName: '' # Use this for self-hosted agents
+ serviceConnection: 'CARML-CSU-Tenant-Connection'
+
+ ######################################
+ # Source
+ ######################################
+
+ vstsOrganization: servicescode
+ vstsOrganizationURI: '$(System.CollectionUri)' # The URI of the TFS collection or Azure DevOps organization. For example: https://dev.azure.com/fabrikam/.
+ vstsProject: '$(System.TeamProject)'
+ modulesRepository: ResourceModules # The repository hosting the deployment code (i.e. 'Components'). MUST be provided as a variable with every pipeline
+ modulePath: arm/$(moduleName) # only use in module pipelines
+ pipelineFunctionsPath: 'utilities/pipelines'
+
+ ######################################
+ # Validation deployment settings
+ ######################################
+
+ defaultLocation: 'West Europe' # The default location to test deploy resources to
+ defaultResourceGroupName: 'validation-rg' # The default resource group to test deployment resources into
+
+ ######################################
+ # Publish: Template-Spec settings
+ ######################################
+
+ templateSpecsDoPublish: true # Set to true, if you would like to publish module templates as template specs
+ templateSpecsRGName: 'artifacts-rg' # The name of the resource group to publish to. If the resource group does not exist, it will be created.
+ templateSpecsRGLocation: 'West Europe' # The location of the resource group to publish to
+ templateSpecsDescription: components # The description to add to template specs published by this platform
+
+ ######################################
+ # Publish: Universal packages settings
+ ######################################
+
+ artifactsFeedDoPublish: true # Set to true, if you would like to publish modules as Universal Packages (in Azure DevOps Artifacts)
+ vstsFeedName: 'ResourceModules' # The name of the Azure DevOps universal packages feed to publish to
+ vstsFeedProject: '$(System.TeamProject)' # The project that hosts the feed
+ vstsFeedToken: $(System.AccessToken) # The token used to publish universal packages into the feed above
+
+ ######################################
+ # Publish: Private Bicep Registry settings
+ ######################################
+
+ bicepRegistryDoPublish: true # Set to true, if you would like to publish module templates to a bicep registry
+ bicepRegistryName: adpsxxazacrx001 # The name of the bicep registry (ACR) to publish to. If it does not exist, it will be created.
+ bicepRegistryRGName: 'artifacts-rg' # The resource group that hosts the private bicep registry (ACR)
+ bicepRegistryRgLocation: 'West Europe' # The location of the resource group to publish to
+
+ ######################################
+ # Azure PowerShell Version
+ ######################################
+
+ # Should be set to 'latestVersion' unless there is an issue with the Az PowerShell modules.
+ # If a specific version needs to be set azurePowerShellVersion should be changed to 'OtherVersion'.
+ # NOTE: The strings are case sensitive and will not work unless properly entered.
+ azurePowerShellVersion: 'latestVersion'
+ # If using the latest version of the Az PowerShell modules, set `preferredAzurePowerShellVersion` to an empty string ''.
+ # If overriding the Az PowerShell module version, set to the version. Example: '4.4.0'
+ preferredAzurePowerShellVersion: ''
+#
+# NOTE: To override for just an individual template, just add the following to the
+# templates pipeline.yml replacing '4.4.0' with the desired version:
+#
+# - name: azurePowerShellVersion
+# value: 'OtherVersion'
+# - name: preferredAzurePowerShellVersion
+# value: '4.4.0'
+#
diff --git a/.azuredevops/platformPipelines/platform.dependencies.yml b/.azuredevops/platformPipelines/platform.dependencies.yml
new file mode 100644
index 000000000..88bd93488
--- /dev/null
+++ b/.azuredevops/platformPipelines/platform.dependencies.yml
@@ -0,0 +1,886 @@
+name: '.Platform - Dependencies'
+
+parameters:
+ - name: deploySqlMiDependencies
+ displayName: Enable SqlMi dependencies deployment
+ type: boolean
+ default: false
+ - name: deployVhdDependencies
+ displayName: Enable deployment of a vhd stored in a blob container
+ type: boolean
+ default: false
+
+trigger: none
+
+# trigger:
+# batch: true
+# branches:
+# include:
+# - main
+# paths:
+# include:
+# - '.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml'
+# - '.azuredevops/platformPipelines/platform.dependencies.yml'
+# - 'utilities/pipelines/dependencies/**'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - group: 'PLATFORM_VARIABLES'
+ - name: dependencyPath
+ value: 'utilities/pipelines/dependencies'
+ - name: modulesPath
+ value: 'arm'
+ - name: defaultResourceGroupName
+ value: 'validation-rg'
+
+stages:
+ - stage: deploy_rg
+ displayName: Deploy resource group
+ variables:
+ resourceType: 'Microsoft.Resources/resourceGroups'
+ templateFilePath: $(modulesPath)/$(resourceType)/deploy.bicep
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ deploymentBlocks:
+ - path: $(dependencyPath)/$(resourceType)/parameters/validation.parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: Validation Resource Group
+
+ - stage: deploy_msi
+ displayName: Deploy user assigned identity
+ dependsOn:
+ - deploy_rg
+ variables:
+ resourceType: 'Microsoft.ManagedIdentity/userAssignedIdentities'
+ templateFilePath: $(modulesPath)/$(resourceType)/deploy.bicep
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ deploymentBlocks:
+ - path: $(dependencyPath)/$(resourceType)/parameters/parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: User Assigned Identity
+ jobName: job_deploy_msi
+ - job: job_set_msi_id
+ displayName: Set msi principal ID output
+ dependsOn:
+ - job_deploy_msi
+ pool:
+ ${{ if eq(variables['vmImage'], '') }}:
+ name: $(poolName)
+ ${{ if eq(variables['poolName'], '') }}:
+ vmImage: $(vmImage)
+ variables:
+ deploymentOutput: $[ dependencies.job_deploy_msi.outputs['DeployModule.deploymentOutput'] ]
+ steps:
+ - task: PowerShell@2
+ name: print_msi_prinId
+ inputs:
+ targetType: inline
+ pwsh: true
+ script: |
+ # Write-Verbose $(deploymentOutput) -Verbose
+ $msiPrincipalId = (ConvertFrom-Json '$(deploymentOutput)').principalId
+ Write-Verbose "msiPrincipalId: $msiPrincipalId" -Verbose
+ Write-Output ('##vso[task.setvariable variable={0};isOutput=true]{1}' -f 'msiPrincipalId', $msiPrincipalId)
+
+ - stage: deploy_pa
+ displayName: Deploy policy assignment
+ dependsOn:
+ - deploy_rg
+ variables:
+ resourceType: 'Microsoft.Authorization/policyAssignments'
+ templateFilePath: $(modulesPath)/$(resourceType)/subscription/deploy.bicep
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ deploymentBlocks:
+ - path: $(dependencyPath)/$(resourceType)/parameters/parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: Policy assignment
+
+ - stage: deploy_evh
+ displayName: Deploy event hub
+ dependsOn:
+ - deploy_rg
+ variables:
+ resourceType: 'Microsoft.EventHub/namespaces'
+ templateFilePath: $(modulesPath)/$(resourceType)/deploy.bicep
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ deploymentBlocks:
+ - path: $(dependencyPath)/$(resourceType)/parameters/parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: EventHub
+
+ - stage: deploy_law
+ displayName: Deploy log analytics workspace
+ dependsOn:
+ - deploy_rg
+ variables:
+ resourceType: 'Microsoft.OperationalInsights/workspaces'
+ templateFilePath: $(modulesPath)/$(resourceType)/deploy.bicep
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ deploymentBlocks:
+ - path: $(dependencyPath)/$(resourceType)/parameters/parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: Default LAW
+ - path: $(dependencyPath)/$(resourceType)/parameters/aut.parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: Automation account LAW
+ - path: $(dependencyPath)/$(resourceType)/parameters/appi.parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: AppInsights LAW
+
+ - stage: deploy_sa
+ displayName: Deploy storage account
+ dependsOn:
+ - deploy_rg
+ variables:
+ resourceType: 'Microsoft.Storage/storageAccounts'
+ templateFilePath: $(modulesPath)/$(resourceType)/deploy.bicep
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ deploymentBlocks:
+ - path: $(dependencyPath)/$(resourceType)/parameters/parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: Default storage account
+ jobName: default_sa
+ - path: $(dependencyPath)/$(resourceType)/parameters/law.parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: LAW storage account
+ - path: $(dependencyPath)/$(resourceType)/parameters/fa.parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: FunctionApp storage account
+ - job:
+ displayName: Upload files to storage account
+ dependsOn:
+ - default_sa
+ pool:
+ ${{ if eq(variables['vmImage'], '') }}:
+ name: $(poolName)
+ ${{ if eq(variables['poolName'], '') }}:
+ vmImage: $(vmImage)
+ steps:
+ - task: PowerShell@2
+ displayName: 'Setup agent'
+ inputs:
+ targetType: inline
+ pwsh: true
+ script: |
+ # Load used functions
+ . (Join-Path '$(System.DefaultWorkingDirectory)' 'utilities' 'pipelines' 'sharedScripts' 'Set-EnvironmentOnAgent.ps1')
+
+ # Define PS modules to install on the runner
+ $Modules = @(
+ @{ Name = 'Az.Storage' }
+ )
+
+ # Set agent up
+ Set-EnvironmentOnAgent -PSModules $Modules
+ - task: AzurePowerShell@5
+ displayName: Upload files to storage account
+ inputs:
+ azureSubscription: $(serviceConnection)
+ ScriptType: 'InlineScript'
+ Inline: |
+ $parameterFilePath = Join-Path '$(Build.SourcesDirectory)' '$(dependencyPath)' '$(resourceType)' 'parameters' 'parameters.json'
+ # Load used functions
+ . (Join-Path '$(Build.SourcesDirectory)' 'utilities' 'pipelines' 'sharedScripts' 'Export-ContentToBlob.ps1')
+ . (Join-Path '$(Build.SourcesDirectory)' 'utilities' 'pipelines' 'tokensReplacement' 'Convert-TokensInFile.ps1')
+
+ # Replace tokens in parameter file
+ $Settings = Get-Content -Path (Join-Path '$(Build.SourcesDirectory)' 'settings.json') | ConvertFrom-Json -AsHashTable
+ $ConvertTokensInputs = @{
+ FilePath = $parameterFilePath
+ TokenPrefix = $Settings.parameterFileTokens.tokenPrefix
+ TokenSuffix = $Settings.parameterFileTokens.tokenSuffix
+ }
+
+ # Add local tokens
+ if ($Settings.parameterFileTokens.localTokens) {
+ $tokenMap = @{}
+ foreach ($token in $Settings.parameterFileTokens.localTokens) {
+ $tokenMap += @{ $token.name = $token.value }
+ }
+ Write-Verbose ('Using local tokens [{0}]' -f ($tokenMap.Keys -join ', ')) -Verbose
+ $ConvertTokensInputs.Tokens = $tokenMap
+ }
+
+ $null = Convert-TokensInFile @ConvertTokensInputs
+
+ # Get storage account name
+ $storageAccountParameters = (ConvertFrom-Json (Get-Content -path $parameterFilePath -Raw)).parameters
+
+ # Upload files to storage account
+ $functionInput = @{
+ ResourceGroupName = '$(defaultResourceGroupName)'
+ StorageAccountName = $storageAccountParameters.name.value
+ contentDirectories = Join-Path '$(Build.SourcesDirectory)' $(dependencyPath) '$(resourceType)' 'uploads'
+ targetContainer = $storageAccountParameters.blobServices.value.containers[0].name
+ }
+
+ Write-Verbose "Invoke task with" -Verbose
+ Write-Verbose ($functionInput | ConvertTo-Json | Out-String) -Verbose
+
+ Export-ContentToBlob @functionInput -Verbose
+ azurePowerShellVersion: 'LatestVersion'
+ pwsh: true
+
+ - stage: deploy_sig
+ displayName: Deploy shared image gallery and definition
+ dependsOn:
+ - deploy_rg
+ variables:
+ resourceType: 'Microsoft.Compute/galleries'
+ templateFilePath: $(modulesPath)/$(resourceType)/deploy.bicep
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ deploymentBlocks:
+ - path: $(dependencyPath)/$(resourceType)/parameters/parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: Default SIG and SID
+
+ - stage: deploy_imgt
+ displayName: Deploy image template
+ condition: and(succeeded(), eq('${{ parameters.deployVhdDependencies }}', true))
+ dependsOn:
+ - deploy_rolea
+ - deploy_sig
+ - deploy_sa
+ variables:
+ resourceType: 'Microsoft.VirtualMachineImages\imageTemplates'
+ saResourceType: 'Microsoft.Storage\storageAccounts'
+ templateFilePath: $(modulesPath)/$(resourceType)/deploy.bicep
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ deploymentBlocks:
+ - path: $(dependencyPath)/$(resourceType)/parameters/parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: Image template
+ jobName: job_deploy_imgt
+ - job:
+ displayName: Trigger vhd build and store it to a storage account blob container
+ dependsOn:
+ - job_deploy_imgt
+ pool:
+ ${{ if eq(variables['vmImage'], '') }}:
+ name: $(poolName)
+ ${{ if eq(variables['poolName'], '') }}:
+ vmImage: $(vmImage)
+ variables:
+ deploymentOutput: $[ dependencies.job_deploy_imgt.outputs['DeployModule.deploymentOutput'] ]
+ steps:
+ - task: PowerShell@2
+ displayName: 'Setup agent'
+ inputs:
+ targetType: inline
+ pwsh: true
+ script: |
+ # Load used functions
+ . (Join-Path '$(System.DefaultWorkingDirectory)' 'utilities' 'pipelines' 'sharedScripts' 'Set-EnvironmentOnAgent.ps1')
+
+ # Define PS modules to install on the runner
+ $Modules = @(
+ @{ Name = 'Az.ImageBuilder' },
+ @{ Name = 'Az.Storage' }
+ )
+
+ # Set agent up
+ Set-EnvironmentOnAgent -PSModules $Modules
+ - task: AzurePowerShell@5
+ displayName: Trigger building new image
+ inputs:
+ azureSubscription: $(serviceConnection)
+ ScriptType: 'InlineScript'
+ Inline: |
+ # Retrieving parameters from previous job outputs
+ Write-Verbose "Retrieving parameters from previous job outputs" -Verbose
+ $imageTemplateName = (ConvertFrom-Json '$(deploymentOutput)').name
+ $imageTemplateResourceGroup = (ConvertFrom-Json '$(deploymentOutput)').resourceGroupName
+
+ # Trigger new image creation
+ Write-Verbose "Trigger new image creation with imageTemplateName $imageTemplateName and imageTemplateResourceGroup $imageTemplateResourceGroup" -Verbose
+ Start-AzImageBuilderTemplate -ImageTemplateName $imageTemplateName -ResourceGroupName $imageTemplateResourceGroup
+ azurePowerShellVersion: 'LatestVersion'
+ pwsh: true
+ - task: AzurePowerShell@5
+ displayName: Copy baked vhd to a storage account
+ inputs:
+ azureSubscription: $(serviceConnection)
+ ScriptType: 'InlineScript'
+ Inline: |
+
+ # Load used functions
+ . (Join-Path '$(Build.SourcesDirectory)' 'utilities' 'pipelines' 'tokensReplacement' 'Convert-TokensInFile.ps1')
+
+ # Prepare replace tokens in parameter file
+ $Settings = Get-Content -Path (Join-Path '$(Build.SourcesDirectory)' 'settings.json') | ConvertFrom-Json -AsHashTable
+ $ConvertTokensInputs = @{
+ TokenPrefix = $Settings.parameterFileTokens.tokenPrefix
+ TokenSuffix = $Settings.parameterFileTokens.tokenSuffix
+ }
+ if ($Settings.parameterFileTokens.localTokens) {
+ $tokenMap = @{}
+ foreach ($token in $Settings.parameterFileTokens.localTokens) {
+ $tokenMap += @{ $token.name = $token.value }
+ }
+ Write-Verbose ('Using local tokens [{0}]' -f ($tokenMap.Keys -join ', ')) -Verbose
+ $ConvertTokensInputs.Tokens = $tokenMap
+ }
+
+ # Retrieving parameters from previous job outputs and parameter files
+ Write-Verbose "Retrieving parameters from previous job outputs" -Verbose
+ $imageTemplateName = (ConvertFrom-Json '$(deploymentOutput)').name
+ $imageTemplateResourceGroup = (ConvertFrom-Json '$(deploymentOutput)').resourceGroupName
+
+ Write-Verbose "Retrieving parameters from storage account parameter files" -Verbose
+ $parameterFilePath = Join-Path '$(Build.SourcesDirectory)' '$(dependencyPath)' '$(saResourceType)' 'parameters' 'parameters.json'
+ $null = Convert-TokensInFile @ConvertTokensInputs -FilePath $parameterFilePath -Verbose
+ $storageAccountParameters = (ConvertFrom-Json (Get-Content -path $parameterFilePath -Raw)).parameters
+
+ Write-Verbose "Retrieving parameters from image template parameter files" -Verbose
+ $parameterFilePath = Join-Path '$(Build.SourcesDirectory)' '$(dependencyPath)' '$(resourceType)' 'parameters' 'parameters.json'
+ $null = Convert-TokensInFile @ConvertTokensInputs -FilePath $parameterFilePath -Verbose
+ $imageTemplateParameters = (ConvertFrom-Json (Get-Content -path $parameterFilePath -Raw)).parameters
+
+ # Initializing parameters before the blob copy
+ Write-Verbose "Initializing source storage account parameters before the blob copy" -Verbose
+ $imgtRunOutput = Get-AzImageBuilderRunOutput -ImageTemplateName $imageTemplateName -ResourceGroupName $imageTemplateResourceGroup | Where-Object ArtifactUri -NE $null
+ $sourceUri = $imgtRunOutput.ArtifactUri
+ $sourceStorageAccountName = $sourceUri.Split('//')[1].Split('.')[0]
+ $sourceStorageAccount = Get-AzStorageAccount | Where-Object StorageAccountName -EQ $sourceStorageAccountName
+ $sourceStorageAccountContext = $sourceStorageAccount.Context
+ $sourceStorageAccountRGName = $sourceStorageAccount.ResourceGroupName
+ Write-Verbose "Retrieving artifact uri $sourceUri stored in resource group $sourceStorageAccountRGName" -Verbose
+
+ Write-Verbose "Initializing destination storage account parameters before the blob copy" -Verbose
+ $destinationStorageAccountName = $storageAccountParameters.name.value
+ $destinationStorageAccount = Get-AzStorageAccount | Where-Object StorageAccountName -EQ $destinationStorageAccountName
+ $destinationStorageAccountContext = $destinationStorageAccount.Context
+ $destinationContainerName = 'vhds'
+ $destinationBlobName = $imageTemplateParameters.name.value
+ $destinationBlobName = "$destinationBlobName.vhd"
+ Write-Verbose "Planning for destination blob name $destinationBlobName in container $destinationContainerName and storage account $destinationStorageAccountName" -Verbose
+
+ # Copying the vhd to a destination blob container
+ Write-Verbose "Copying the vhd to a destination blob container" -Verbose
+ $resourceActionInputObject = @{
+ AbsoluteUri = $sourceUri
+ Context = $sourceStorageAccountContext
+ DestContext = $destinationStorageAccountContext
+ DestBlob = $destinationBlobName
+ DestContainer = $destinationContainerName
+ Force = $true
+ }
+ Start-AzStorageBlobCopy @resourceActionInputObject
+ azPSVersion: 'latest'
+ azurePowerShellVersion: 'LatestVersion'
+ pwsh: true
+
+ - stage: deploy_ag
+ displayName: Deploy action groups
+ dependsOn:
+ - deploy_rg
+ variables:
+ resourceType: 'Microsoft.Insights/actionGroups'
+ templateFilePath: $(modulesPath)/$(resourceType)/deploy.bicep
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ deploymentBlocks:
+ - path: $(dependencyPath)/$(resourceType)/parameters/parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: Default Action Group
+
+ - stage: deploy_asg
+ displayName: Deploy application security groups
+ dependsOn:
+ - deploy_rg
+ variables:
+ resourceType: 'Microsoft.Network/applicationSecurityGroups'
+ templateFilePath: $(modulesPath)/$(resourceType)/deploy.bicep
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ deploymentBlocks:
+ - path: $(dependencyPath)/$(resourceType)/parameters/parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: Default Application Security Groups
+
+ - stage: deploy_udr
+ displayName: Deploy route tables
+ dependsOn:
+ - deploy_rg
+ variables:
+ resourceType: 'Microsoft.Network/routeTables'
+ templateFilePath: $(modulesPath)/$(resourceType)/deploy.bicep
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ deploymentBlocks:
+ - path: $(dependencyPath)/$(resourceType)/parameters/parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: Default User Defined Routes
+ - ${{ if eq( parameters.deploySqlMiDependencies, true) }}:
+ - path: $(dependencyPath)/$(resourceType)/parameters/sqlMi.parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: SQLMI User Defined Routes
+
+ - stage: deploy_nsg
+ displayName: Deploy network security groups
+ dependsOn:
+ - deploy_sa
+ - deploy_evh
+ - deploy_law
+ variables:
+ resourceType: 'Microsoft.Network/networkSecurityGroups'
+ templateFilePath: $(modulesPath)/$(resourceType)/deploy.bicep
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ deploymentBlocks:
+ - path: $(dependencyPath)/$(resourceType)/parameters/parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: Default NSG
+ - path: $(dependencyPath)/$(resourceType)/parameters/apgw.parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: App Gateway NSG
+ - path: $(dependencyPath)/$(resourceType)/parameters/ase.parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: ASE NSG
+ - path: $(dependencyPath)/$(resourceType)/parameters/bastion.parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: Bastion NSG
+ - ${{ if eq( parameters.deploySqlMiDependencies, true) }}:
+ - path: $(dependencyPath)/$(resourceType)/parameters/sqlmi.parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: SQLMI NSG
+
+ - stage: deploy_pip
+ displayName: Deploy public IP addresses
+ dependsOn:
+ - deploy_sa
+ - deploy_evh
+ - deploy_law
+ variables:
+ resourceType: 'Microsoft.Network\publicIPAddresses'
+ templateFilePath: $(modulesPath)/$(resourceType)/deploy.bicep
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ deploymentBlocks:
+ - path: $(dependencyPath)/$(resourceType)/parameters/apgw.parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: App Gateway Public IP
+ - path: $(dependencyPath)/$(resourceType)/parameters/bas.parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: Bastion Public IP
+ - path: $(dependencyPath)/$(resourceType)/parameters/lb.parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: Load balancer Public IP
+ - path: $(dependencyPath)/$(resourceType)/parameters/lb.min.parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: Min Load balancer Public IP
+ - path: $(dependencyPath)/$(resourceType)/parameters/fw.parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: Firewall Public IP
+
+ - stage: deploy_appi
+ displayName: Deploy application insight
+ dependsOn:
+ - deploy_sa
+ - deploy_evh
+ - deploy_law
+ variables:
+ resourceType: 'Microsoft.Insights/components'
+ templateFilePath: $(modulesPath)/$(resourceType)/deploy.bicep
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ deploymentBlocks:
+ - path: $(dependencyPath)/$(resourceType)/parameters/parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: Default Application Insights
+
+ - stage: deploy_aut
+ displayName: Deploy automation account
+ dependsOn:
+ - deploy_sa
+ - deploy_evh
+ - deploy_law
+ variables:
+ resourceType: 'Microsoft.Automation/automationAccounts'
+ templateFilePath: $(modulesPath)/$(resourceType)/deploy.bicep
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ deploymentBlocks:
+ - path: $(dependencyPath)/$(resourceType)/parameters/parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: Default Automation Account
+
+ - stage: deploy_avdhp
+ displayName: Deploy AVD host pool
+ dependsOn:
+ - deploy_sa
+ - deploy_evh
+ - deploy_law
+ variables:
+ resourceType: 'Microsoft.DesktopVirtualization/hostpools'
+ templateFilePath: $(modulesPath)/$(resourceType)/deploy.bicep
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ deploymentBlocks:
+ - path: $(dependencyPath)/$(resourceType)/parameters/parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: Default AVD Host Pool
+
+ - stage: deploy_rsv
+ displayName: Deploy recovery services vault
+ dependsOn:
+ - deploy_sa
+ - deploy_evh
+ - deploy_law
+ - deploy_msi
+ variables:
+ resourceType: 'Microsoft.RecoveryServices/vaults'
+ templateFilePath: $(modulesPath)/$(resourceType)/deploy.bicep
+ msiPrincipalId: $[ stageDependencies.deploy_msi.job_set_msi_id.outputs['print_msi_prinId.msiPrincipalId'] ]
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ deploymentBlocks:
+ - path: $(dependencyPath)/$(resourceType)/parameters/parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: Default recovery services vault
+ customParameterFileTokens: '{"msiPrincipalId":"$(msiPrincipalId)"}'
+
+ - stage: deploy_kv
+ displayName: Deploy key vaults
+ dependsOn:
+ - deploy_sa
+ - deploy_evh
+ - deploy_law
+ - deploy_msi
+ variables:
+ resourceType: 'Microsoft.KeyVault/vaults'
+ templateFilePath: $(modulesPath)/$(resourceType)/deploy.bicep
+ msiPrincipalId: $[ stageDependencies.deploy_msi.job_set_msi_id.outputs['print_msi_prinId.msiPrincipalId'] ]
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ deploymentBlocks:
+ - path: $(dependencyPath)/$(resourceType)/parameters/parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: Default Key Vault
+ jobName: default_kv
+ customParameterFileTokens: '{"msiPrincipalId":"$(msiPrincipalId)"}'
+ - path: $(dependencyPath)/$(resourceType)/parameters/pe.parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: Private Endpoint Key Vault
+ customParameterFileTokens: '{"msiPrincipalId":"$(msiPrincipalId)"}'
+ - ${{ if eq( parameters.deploySqlMiDependencies, true) }}:
+ - path: $(dependencyPath)/$(resourceType)/parameters/sqlmi.parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: SQLMI key vault
+ jobName: sqlmi_kv
+ customParameterFileTokens: '{"msiPrincipalId":"$(msiPrincipalId)"}'
+ - job:
+ displayName: Set key vault secrets keys and certificates
+ dependsOn:
+ - default_kv
+ pool:
+ ${{ if eq(variables['vmImage'], '') }}:
+ name: $(poolName)
+ ${{ if eq(variables['poolName'], '') }}:
+ vmImage: $(vmImage)
+ steps:
+ - task: PowerShell@2
+ displayName: 'Setup agent'
+ inputs:
+ targetType: inline
+ pwsh: true
+ script: |
+ # Load used functions
+ . (Join-Path '$(System.DefaultWorkingDirectory)' 'utilities' 'pipelines' 'sharedScripts' 'Set-EnvironmentOnAgent.ps1')
+
+ # Define PS modules to install on the runner
+ $Modules = @(
+ @{ Name = 'Az.KeyVault' }
+ )
+
+ # Set agent up
+ Set-EnvironmentOnAgent -PSModules $Modules
+ - task: AzurePowerShell@5
+ displayName: Set key vault secrets keys and certificates
+ inputs:
+ azureSubscription: $(serviceConnection)
+ ScriptType: 'InlineScript'
+ Inline: |
+ $parameterFilePath = Join-Path '$(Build.SourcesDirectory)' '$(dependencyPath)' '$(resourceType)' 'parameters' 'parameters.json'
+ # Load used functions
+ . (Join-Path '$(Build.SourcesDirectory)' 'utilities' 'pipelines' 'tokensReplacement' 'Convert-TokensInFile.ps1')
+
+ # Replace tokens in parameter file
+ $Settings = Get-Content -Path (Join-Path '$(Build.SourcesDirectory)' 'settings.json') | ConvertFrom-Json -AsHashTable
+ $ConvertTokensInputs = @{
+ FilePath = $parameterFilePath
+ TokenPrefix = $Settings.parameterFileTokens.tokenPrefix
+ TokenSuffix = $Settings.parameterFileTokens.tokenSuffix
+ }
+ if ($Settings.parameterFileTokens.localTokens) {
+ $tokenMap = @{}
+ foreach ($token in $Settings.parameterFileTokens.localTokens) {
+ $tokenMap += @{ $token.name = $token.value }
+ }
+ Write-Verbose ('Using local tokens [{0}]' -f ($tokenMap.Keys -join ', ')) -Verbose
+ $ConvertTokensInputs.Tokens = $tokenMap
+ }
+ $null = Convert-TokensInFile @ConvertTokensInputs
+
+ # Get key vault name
+ $keyVaultParameters = (ConvertFrom-Json (Get-Content -Path $parameterFilePath -Raw)).parameters
+ $keyVaultName = $keyVaultParameters.name.value
+
+ # Generate values
+ $usernameString = ( -join ((65..90) + (97..122) | Get-Random -Count 9 -SetSeed 1 | ForEach-Object { [char]$_ + "$_" })).substring(0, 19) # max length
+ $userName = ConvertTo-SecureString -String $usernameString -AsPlainText -Force
+ $passwordString = (New-Guid).Guid.SubString(0, 19)
+ $password = ConvertTo-SecureString -String $passwordString -AsPlainText -Force
+ $vpnSharedKeyString = (New-Guid).Guid.SubString(0, 32)
+ $vpnSharedKey = ConvertTo-SecureString -String $vpnSharedKeyString -AsPlainText -Force
+
+ # Set secrets
+ # -------
+ @(
+ @{ name = 'adminUsername'; secretValue = $username } # VirtualMachines and VMSS
+ @{ name = 'adminPassword'; secretValue = $password } # VirtualMachines and VMSS
+ @{ name = 'administratorLogin'; secretValue = $username } # Azure SQLServer
+ @{ name = 'administratorLoginPassword'; secretValue = $password } # Azure SQLServer
+ @{ name = 'vpnSharedKey'; secretValue = $vpnSharedKey } # VirtualNetworkGateway
+ @{ name = 'apimClientId'; secretValue = $username } # API management
+ @{ name = 'apimClientSecret'; secretValue = $password } # API management
+ ) | ForEach-Object {
+ $null = Set-AzKeyVaultSecret -VaultName $keyVaultName -Name $_.name -SecretValue $_.secretValue
+ Write-Verbose ('Added secret [{0}] to key vault [{1}]' -f $_.name, $keyVaultName) -Verbose
+ }
+
+ # Certificats
+ # -----------
+ $certPolicy = New-AzKeyVaultCertificatePolicy -SecretContentType 'application/x-pkcs12' -SubjectName 'CN=fabrikam.com' -IssuerName 'Self' -ValidityInMonths 12 -ReuseKeyOnRenewal
+ @(
+ @{ name = 'applicationGatewaySslCertificate'; CertificatePolicy = $certPolicy } # ApplicationGateway
+ ) | ForEach-Object {
+ $null = Add-AzKeyVaultCertificate -VaultName $keyVaultName -Name $_.name -CertificatePolicy $_.CertificatePolicy
+ Write-Verbose ('Added certificate [{0}] to key vault [{1}]' -f $_.name, $keyVaultName) -Verbose
+ }
+
+ # Set keys
+ # ----
+ @(
+ @{ name = 'keyEncryptionKey'; Destination = 'Software' } # DiskEncryptionSet, VirtualMachines and VMSS
+ ) | ForEach-Object {
+ $null = Add-AzKeyVaultKey -VaultName $keyVaultName -Name $_.name -Destination $_.Destination
+ Write-Verbose ('Added key [{0}] to key vault [{1}]' -f $_.name, $keyVaultName) -Verbose
+ }
+ azurePowerShellVersion: 'LatestVersion'
+ pwsh: true
+
+ - ${{ if eq( parameters.deploySqlMiDependencies, true) }}:
+ - job:
+ displayName: Set sqlmi key vault secrets and keys
+ condition: eq(${{ parameters.deploySqlMiDependencies }}, true)
+ dependsOn:
+ - sqlmi_kv
+ pool:
+ ${{ if eq(variables['vmImage'], '') }}:
+ name: $(poolName)
+ ${{ if eq(variables['poolName'], '') }}:
+ vmImage: $(vmImage)
+ steps:
+ - task: PowerShell@2
+ displayName: 'Setup agent'
+ inputs:
+ targetType: inline
+ pwsh: true
+ script: |
+ # Load used functions
+ . (Join-Path '$(System.DefaultWorkingDirectory)' 'utilities' 'pipelines' 'sharedScripts' 'Set-EnvironmentOnAgent.ps1')
+
+ # Define PS modules to install on the runner
+ $Modules = @(
+ @{ Name = 'Az.KeyVault' }
+ )
+
+ # Set agent up
+ Set-EnvironmentOnAgent -PSModules $Modules
+ - task: AzurePowerShell@5
+ displayName: Set sqlmi key vault secrets and keys
+ inputs:
+ azureSubscription: $(serviceConnection)
+ ScriptType: 'InlineScript'
+ Inline: |
+
+ $parameterFilePath = Join-Path '$(Build.SourcesDirectory)' '$(dependencyPath)' '$(resourceType)' 'parameters' 'sqlmi.parameters.json'
+ # Load used functions
+ . (Join-Path '$(Build.SourcesDirectory)' 'utilities' 'pipelines' 'tokensReplacement' 'Convert-TokensInFile.ps1')
+
+ # Replace tokens in parameter file
+ $Settings = Get-Content -Path (Join-Path '$(Build.SourcesDirectory)' 'settings.json') | ConvertFrom-Json -AsHashTable
+ $ConvertTokensInputs = @{
+ FilePath = $parameterFilePath
+ TokenPrefix = $Settings.parameterFileTokens.tokenPrefix
+ TokenSuffix = $Settings.parameterFileTokens.tokenSuffix
+ }
+ if ($Settings.parameterFileTokens.localTokens) {
+ $tokenMap = @{}
+ foreach ($token in $Settings.parameterFileTokens.localTokens) {
+ $tokenMap += @{ $token.name = $token.value }
+ }
+ Write-Verbose ('Using local tokens [{0}]' -f ($tokenMap.Keys -join ', ')) -Verbose
+ $ConvertTokensInputs.Tokens = $tokenMap
+ }
+ $null = Convert-TokensInFile @ConvertTokensInputs
+
+ # Get key vault name
+ $keyVaultParameters = (ConvertFrom-Json (Get-Content -Path $parameterFilePath -Raw)).parameters
+ $keyVaultName = $keyVaultParameters.name.value
+
+ # Generate values
+ $usernameString = ( -join ((65..90) + (97..122) | Get-Random -Count 9 -SetSeed 1 | ForEach-Object { [char]$_ + "$_" })).substring(0, 19) # max length
+ $userName = ConvertTo-SecureString -String $usernameString -AsPlainText -Force
+ $passwordString = (New-Guid).Guid.SubString(0, 19)
+ $password = ConvertTo-SecureString -String $passwordString -AsPlainText -Force
+
+ # Set secrets
+ # -------
+ @(
+ @{ name = 'administratorLogin'; secretValue = $username } # SQLManagedInstances
+ @{ name = 'administratorLoginPassword'; secretValue = $password } # SQLManagedInstances
+ ) | ForEach-Object {
+ $null = Set-AzKeyVaultSecret -VaultName $keyVaultName -Name $_.name -SecretValue $_.secretValue
+ Write-Verbose ('Added secret [{0}] to key vault [{1}]' -f $_.name, $keyVaultName) -Verbose
+ }
+
+ # Set keys
+ # ----
+ @(
+ @{ name = 'keyEncryptionKeySqlMi'; Destination = 'Software' } # SQLManagedInstances
+ ) | ForEach-Object {
+ $null = Add-AzKeyVaultKey -VaultName $keyVaultName -Name $_.name -Destination $_.Destination
+ Write-Verbose ('Added key [{0}] to key vault [{1}]' -f $_.name, $keyVaultName) -Verbose
+ }
+ azurePowerShellVersion: 'LatestVersion'
+ pwsh: true
+
+ - stage: deploy_avdag
+ displayName: Deploy AVD application group
+ dependsOn:
+ - deploy_avdhp
+ variables:
+ resourceType: 'Microsoft.DesktopVirtualization/applicationgroups'
+ templateFilePath: $(modulesPath)/$(resourceType)/deploy.bicep
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ deploymentBlocks:
+ - path: $(dependencyPath)/$(resourceType)/parameters/parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: Default Application Group
+
+ - stage: deploy_rolea
+ displayName: Deploy role assignments
+ dependsOn:
+ - deploy_msi
+ variables:
+ resourceType: 'Microsoft.Authorization/roleAssignments'
+ templateFilePath: $(modulesPath)/$(resourceType)/subscription/deploy.bicep
+ msiPrincipalId: $[ stageDependencies.deploy_msi.job_set_msi_id.outputs['print_msi_prinId.msiPrincipalId'] ]
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ deploymentBlocks:
+ - path: $(dependencyPath)/$(resourceType)/parameters/parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: MSI Role Assignment
+ customParameterFileTokens: '{"msiPrincipalId":"$(msiPrincipalId)"}'
+
+ - stage: deploy_vnet
+ displayName: Deploy virtual networks
+ dependsOn:
+ - deploy_nsg
+ - ${{ if eq( parameters.deploySqlMiDependencies, true) }}:
+ - deploy_udr
+ variables:
+ resourceType: 'Microsoft.Network/virtualNetworks'
+ templateFilePath: $(modulesPath)/$(resourceType)/deploy.bicep
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ deploymentBlocks:
+ - path: $(dependencyPath)/$(resourceType)/parameters/parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: Default Virtual Network
+ - path: $(dependencyPath)/$(resourceType)/parameters/1.bastion.parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: Bastion Virtual Network
+ - path: $(dependencyPath)/$(resourceType)/parameters/2.vnetpeer01.parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: VNET PEering 1 Virtual Network
+ - path: $(dependencyPath)/$(resourceType)/parameters/3.vnetpeer02.parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: VNET Peering 2 Virtual Network
+ - path: $(dependencyPath)/$(resourceType)/parameters/4.azfw.parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: Azure Firewall Virtual Network
+ - path: $(dependencyPath)/$(resourceType)/parameters/5.aks.parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: AKS Virtual Network
+ - path: $(dependencyPath)/$(resourceType)/parameters/7.virtualHubConnection.parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: Virtual Hub Connection Virtual Network
+ - ${{ if eq( parameters.deploySqlMiDependencies, true) }}:
+ - path: $(dependencyPath)/$(resourceType)/parameters/6.sqlmi.parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: SQL MI Virtual Network
+
+ - stage: deploy_dnszone
+ displayName: Deploy private DNS zones
+ dependsOn:
+ - deploy_vnet
+ variables:
+ resourceType: 'Microsoft.Network/privateDnsZones'
+ templateFilePath: $(modulesPath)/$(resourceType)/deploy.bicep
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ deploymentBlocks:
+ - path: $(dependencyPath)/$(resourceType)/parameters/parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: Default Private DNS Zones
+
+ - stage: deploy_vm
+ displayName: Deploy virtual machines
+ dependsOn:
+ - deploy_vnet
+ - deploy_rsv
+ - deploy_kv
+ variables:
+ resourceType: 'Microsoft.Compute/virtualMachines'
+ templateFilePath: $(modulesPath)/$(resourceType)/deploy.bicep
+ jobs:
+ - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml
+ parameters:
+ deploymentBlocks:
+ - path: $(dependencyPath)/$(resourceType)/parameters/parameters.json
+ templateFilePath: $(templateFilePath)
+ displayName: Default Virtual Machine
diff --git a/.azuredevops/platformPipelines/platform.updateReadMe.yml b/.azuredevops/platformPipelines/platform.updateReadMe.yml
new file mode 100644
index 000000000..defe6e0d8
--- /dev/null
+++ b/.azuredevops/platformPipelines/platform.updateReadMe.yml
@@ -0,0 +1,88 @@
+name: '.Platform - Update ReadMe Module Tables'
+
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - 'arm/**/deploy.bicep'
+ - 'arm/**/deploy.json'
+
+variables:
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - name: pipelinePrincipalGitUserName
+ value: 'CARMLPipelinePrincipal'
+ - name: pipelinePrincipalGitUserEmail
+ value: 'CARML@noreply.github.com'
+
+jobs:
+ - job: Update_module_tables
+ pool:
+ ${{ if ne(variables.vmImage, '') }}:
+ vmImage: ${{ variables.vmImage }}
+ ${{ if ne(variables.poolName, '') }}:
+ name: ${{ variables.poolName }}
+ steps:
+ - checkout: self
+ persistCredentials: true
+ - task: PowerShell@2
+ displayName: 'Update general ReadMe'
+ inputs:
+ targetType: inline
+ pwsh: true
+ script: |
+ # Load used functions
+ . (Join-Path '$(System.DefaultWorkingDirectory)' 'utilities' 'tools' 'Set-ReadMeModuleTable.ps1')
+
+ $functionInput = @{
+ ModulesPath = Join-Path '$(System.DefaultWorkingDirectory)' 'arm'
+ FilePath = Join-Path '$(System.DefaultWorkingDirectory)' 'README.md'
+ Organization = '$(System.CollectionUri)'.Split('/')[3]
+ RepositoryName = '$(Build.Repository.Name)'
+ ColumnsInOrder = @('Name', 'Status')
+ SortByColumn = 'Name'
+ Environment = 'ADO'
+ ProjectName = '$(System.TeamProject)'
+ }
+
+ Write-Verbose "Invoke task with" -Verbose
+ Write-Verbose ($functionInput | ConvertTo-Json | Out-String) -Verbose
+
+ Set-ReadMeModuleTable @functionInput -Verbose
+ - task: PowerShell@2
+ displayName: 'Update module folder ReadMe'
+ inputs:
+ targetType: inline
+ pwsh: true
+ script: |
+ # Load used functions
+ . (Join-Path '$(System.DefaultWorkingDirectory)' 'utilities' 'tools' 'Set-ReadMeModuleTable.ps1')
+
+ $functionInput = @{
+ ModulesPath = Join-Path '$(System.DefaultWorkingDirectory)' 'arm'
+ FilePath = Join-Path '$(System.DefaultWorkingDirectory)' 'arm/README.md'
+ Organization = '$(System.CollectionUri)'.Split('/')[3]
+ RepositoryName = '$(Build.Repository.Name)'
+ ColumnsInOrder = @('Name', 'ProviderNamespace','ResourceType')
+ Environment = 'ADO'
+ ProjectName = '$(System.TeamProject)'
+ }
+
+ Write-Verbose "Invoke task with" -Verbose
+ Write-Verbose ($functionInput | ConvertTo-Json | Out-String) -Verbose
+
+ Set-ReadMeModuleTable @functionInput -Verbose
+ - task: PowerShell@2
+ displayName: 'Push changes'
+ inputs:
+ targetType: inline
+ pwsh: true
+ script: |
+ git config --global user.email '$(pipelinePrincipalGitUserEmail)'
+ git config --global user.name '$(pipelinePrincipalGitUserName)'
+ Write-Verbose '$(Build.SourceBranch)' -Verbose
+ git add .
+ git commit -m "Push updated Readme file(s)"
+ git push $(Build.Repository.Uri) HEAD:$(Build.SourceBranch)
diff --git a/.azuredevops/platformPipelines/platform.wiki-sync.yml b/.azuredevops/platformPipelines/platform.wiki-sync.yml
new file mode 100644
index 000000000..67802a3ee
--- /dev/null
+++ b/.azuredevops/platformPipelines/platform.wiki-sync.yml
@@ -0,0 +1,58 @@
+# NOTE:
+# This pipeline requires a secret 'PLATFORM_REPO_UPDATE_PAT' set up in a library named 'PLATFORM_VARIABLES'.
+# The secret's value should be a PAT token with the permissions to push to the repository's main branch.
+
+name: '.Platform - Sync Docs/Wiki'
+
+trigger:
+ branches:
+ include:
+ - main
+ paths:
+ include:
+ - 'docs/wiki/**'
+
+variables:
+ - group: 'PLATFORM_VARIABLES'
+ - template: '/.azuredevops/pipelineVariables/global.variables.yml'
+ - name: pipelinePrincipalGitUserName
+ value: 'CARMLPipelinePrincipal'
+ - name: pipelinePrincipalGitUserEmail
+ value: 'CARML@noreply.github.com'
+
+jobs:
+ - job: Update_module_tables
+ pool:
+ ${{ if ne('$(vmImage)', '') }}:
+ vmImage: '$(vmImage)'
+ ${{ if ne('$(poolName)', '') }}:
+ name: '$(poolName)'
+ steps:
+ - checkout: self
+ displayName: Checkout Source Repo
+ persistCredentials: true
+ # Create a variable
+ - task: PowerShell@2
+ displayName: 'Checkout Wiki Repo'
+ inputs:
+ targetType: inline
+ pwsh: true
+ script: |
+ git config --global user.email '$(pipelinePrincipalGitUserEmail)'
+ git config --global user.name '$(pipelinePrincipalGitUserName)'
+ $repositoryEndpoint= 'https://' + '$(PLATFORM_REPO_UPDATE_PAT)' + '@github.com/' + '$(Build.Repository.Name)' + '.wiki'
+ git clone $repositoryEndpoint
+ - task: PowerShell@2
+ displayName: 'Sync docs/wiki Into Wiki Repo'
+ inputs:
+ targetType: inline
+ pwsh: true
+ script: |
+ $docsPath = Join-Path '$(System.DefaultWorkingDirectory)' 'docs' 'wiki'
+ $wikiPath = ('$(Build.Repository.Name)').split('/')[1] + '.wiki'
+ $wikiRepository = Join-Path '$(System.DefaultWorkingDirectory)' $wikiPath
+ rsync -avzr --delete --exclude='.git/' $docsPath $wikiRepository
+ cd $wikiRepository
+ git add .
+ git commit -m "Push updated Wiki"
+ git push
diff --git a/.github/workflows/compile-bicep-arm.yml b/.github/workflows/compile-bicep-arm.yml
new file mode 100644
index 000000000..9e7b9d96d
--- /dev/null
+++ b/.github/workflows/compile-bicep-arm.yml
@@ -0,0 +1,71 @@
+# This is a basic workflow to help you get started with Actions
+
+name: CI
+
+# Controls when the workflow will run
+on:
+ # Triggers the workflow on push or pull request events but only for the main branch
+ push:
+ branches: [ main ]
+ pull_request:
+ branches: [ main ]
+
+ # Allows you to run this workflow manually from the Actions tab
+ workflow_dispatch:
+
+# A workflow run is made up of one or more jobs that can run sequentially or in parallel
+jobs:
+ # This workflow contains a single job called "build"
+ build:
+ # The type of runner that the job will run on
+ runs-on: ubuntu-latest
+
+ # Steps represent a sequence of tasks that will be executed as part of the job
+ steps:
+ # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
+ - uses: actions/checkout@v3
+
+ # Runs ARM build from the bicep. Used for portal UI. Compile AVD baseline.
+ - name: bicep-build-output
+ uses: Azure/bicep-build-action@v1.0.0
+ with:
+ bicepFilePath: ./workload/deploy-baseline.bicep
+ outputFilePath: ./workload/arm/deploy-baseline.json
+
+ - name: Validate the AVD baseline output
+ shell: bash
+ run: |
+ FILE="./workload/arm/deploy-baseline.json"
+ if test -f "$FILE"; then
+ echo "$FILE created successfully"
+ else
+ echo "$FILE not found."
+ exit 1
+ fi
+
+ # Runs ARM build from the bicep. Used for portal UI. Compile AVD Custom image.
+ - name: bicep-build-output
+ uses: Azure/bicep-build-action@v1.0.0
+ with:
+ bicepFilePath: ./workload/deploy-customImage.bicep
+ outputFilePath: ./workload/arm/deploy-customImage.json
+
+ - name: Validate the AVD custom image output
+ shell: bash
+ run: |
+ FILE="./workload/arm/deploy-customImage.json"
+ if test -f "$FILE"; then
+ echo "$FILE created successfully"
+ else
+ echo "$FILE not found."
+ exit 1
+ fi
+
+ # Publish the compiled ARM templates to Github
+ - name: publish
+ uses: stefanzweifel/git-auto-commit-action@v4
+ with:
+ commit_message: Automated update for ARM templates
+
+
+
diff --git a/.lycheeignore copy b/.lycheeignore copy
new file mode 100644
index 000000000..cb8f72b8e
--- /dev/null
+++ b/.lycheeignore copy
@@ -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/CARML README copy.md b/CARML README copy.md
new file mode 100644
index 000000000..48d68ee2b
--- /dev/null
+++ b/CARML README copy.md
@@ -0,0 +1,178 @@
+# ![AzureIcon] Common Azure Resource Modules Library
+
+## Description
+
+This repository includes a CI platform for and collection of mature and curated [Bicep][Bicep] modules.
+The platform supports both ARM and Bicep and can be leveraged using GitHub actions as well as Azure DevOps pipelines.
+
+## Status
+
+
+
+
+
+
+
+
+
+
+
+## Get started
+
+* For introduction guidance visit the [Wiki](https://github.com/azure/ResourceModules/wiki)
+* For reference documentation visit [Enterprise-Scale](https://github.com/azure/enterprise-scale)
+* For information on contributing, see [Contribution]()
+* File an issue via [GitHub Issues](https://github.com/azure/ResourceModules/issues/new/choose)
+
+## Available Resource Modules
+
+| Name | Status |
+| - | - |
+| [Action Groups](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Insights/actionGroups) | [!['Insights: ActionGroups'](https://github.com/Azure/ResourceModules/actions/workflows/ms.insights.actiongroups.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.insights.actiongroups.yml) |
+| [Activity Log Alerts](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Insights/activityLogAlerts) | [!['Insights: ActivityLogAlerts'](https://github.com/Azure/ResourceModules/actions/workflows/ms.insights.activitylogalerts.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.insights.activitylogalerts.yml) |
+| [Activity Logs](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Insights/diagnosticSettings) | [!['Insights: DiagnosticSettings'](https://github.com/Azure/ResourceModules/actions/workflows/ms.insights.diagnosticsettings.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.insights.diagnosticsettings.yml) |
+| [Analysis Services Server](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.AnalysisServices/servers) | [!['AnalysisServices: Servers'](https://github.com/Azure/ResourceModules/actions/workflows/ms.analysisservices.servers.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.analysisservices.servers.yml) |
+| [API Connections](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Web/connections) | [!['Web: Connections'](https://github.com/Azure/ResourceModules/actions/workflows/ms.web.connections.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.web.connections.yml) |
+| [API Management Services](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.ApiManagement/service) | [!['ApiManagement: Service'](https://github.com/Azure/ResourceModules/actions/workflows/ms.apimanagement.service.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.apimanagement.service.yml) |
+| [App Service Environments](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Web/hostingEnvironments) | [!['Web: HostingEnvironments'](https://github.com/Azure/ResourceModules/actions/workflows/ms.web.hostingenvironments.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.web.hostingenvironments.yml) |
+| [App Service Plans](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Web/serverfarms) | [!['Web: Serverfarms'](https://github.com/Azure/ResourceModules/actions/workflows/ms.web.serverfarms.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.web.serverfarms.yml) |
+| [Application Insights](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Insights/components) | [!['Insights: Components'](https://github.com/Azure/ResourceModules/actions/workflows/ms.insights.components.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.insights.components.yml) |
+| [Application Security Groups](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/applicationSecurityGroups) | [!['Network: ApplicationSecurityGroups'](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.applicationsecuritygroups.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.applicationsecuritygroups.yml) |
+| [Automation Accounts](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Automation/automationAccounts) | [!['Automation: AutomationAccounts'](https://github.com/Azure/ResourceModules/actions/workflows/ms.automation.automationaccounts.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.automation.automationaccounts.yml) |
+| [Availability Sets](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Compute/availabilitySets) | [!['Compute: AvailabilitySets'](https://github.com/Azure/ResourceModules/actions/workflows/ms.compute.availabilitysets.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.compute.availabilitysets.yml) |
+| [AVD Application Groups](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.DesktopVirtualization/applicationgroups) | [!['DesktopVirtualization: ApplicationGroups'](https://github.com/Azure/ResourceModules/actions/workflows/ms.desktopvirtualization.applicationgroups.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.desktopvirtualization.applicationgroups.yml) |
+| [AVD Host Pools](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.DesktopVirtualization/hostpools) | [!['DesktopVirtualization: HostPools'](https://github.com/Azure/ResourceModules/actions/workflows/ms.desktopvirtualization.hostpools.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.desktopvirtualization.hostpools.yml) |
+| [AVD Workspaces](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.DesktopVirtualization/workspaces) | [!['DesktopVirtualization: Workspaces'](https://github.com/Azure/ResourceModules/actions/workflows/ms.desktopvirtualization.workspaces.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.desktopvirtualization.workspaces.yml) |
+| [Azure Compute Galleries](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Compute/galleries) | [!['Compute: Galleries'](https://github.com/Azure/ResourceModules/actions/workflows/ms.compute.galleries.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.compute.galleries.yml) |
+| [Azure Databricks](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Databricks/workspaces) | [!['Databricks: Workspaces'](https://github.com/Azure/ResourceModules/actions/workflows/ms.databricks.workspaces.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.databricks.workspaces.yml) |
+| [Azure Firewalls](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/azureFirewalls) | [!['Network: AzureFirewalls'](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.azurefirewalls.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.azurefirewalls.yml) |
+| [Azure Health Bots](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.HealthBot/healthBots) | [!['HealthBot: HealthBots'](https://github.com/Azure/ResourceModules/actions/workflows/ms.healthbot.healthbots.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.healthbot.healthbots.yml) |
+| [Azure Kubernetes Services](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.ContainerService/managedClusters) | [!['ContainerService: ManagedClusters'](https://github.com/Azure/ResourceModules/actions/workflows/ms.containerservice.managedclusters.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.containerservice.managedclusters.yml) |
+| [Azure Monitor Private Link Scopes](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Insights/privateLinkScopes) | [!['Insights: PrivateLinkScopes'](https://github.com/Azure/ResourceModules/actions/workflows/ms.insights.privatelinkscopes.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.insights.privatelinkscopes.yml) |
+| [Azure NetApp Files](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.NetApp/netAppAccounts) | [!['NetApp: NetAppAccounts'](https://github.com/Azure/ResourceModules/actions/workflows/ms.netapp.netappaccounts.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.netapp.netappaccounts.yml) |
+| [Azure Security Center](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Security/azureSecurityCenter) | [!['Security: AzureSecurityCenter'](https://github.com/Azure/ResourceModules/actions/workflows/ms.security.azuresecuritycenter.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.security.azuresecuritycenter.yml) |
+| [Bastion Hosts](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/bastionHosts) | [!['Network: BastionHosts'](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.bastionhosts.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.bastionhosts.yml) |
+| [Batch Accounts](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Batch/batchAccounts) | [!['Batch: BatchAccounts'](https://github.com/Azure/ResourceModules/actions/workflows/ms.batch.batchaccounts.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.batch.batchaccounts.yml) |
+| [Budgets](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Consumption/budgets) | [!['Consumption: Budgets'](https://github.com/Azure/ResourceModules/actions/workflows/ms.consumption.budgets.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.consumption.budgets.yml) |
+| [Cognitive Services](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.CognitiveServices/accounts) | [!['CognitiveServices: Accounts'](https://github.com/Azure/ResourceModules/actions/workflows/ms.cognitiveservices.accounts.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.cognitiveservices.accounts.yml) |
+| [Compute Disks](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Compute/disks) | [!['Compute: Disks'](https://github.com/Azure/ResourceModules/actions/workflows/ms.compute.disks.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.compute.disks.yml) |
+| [Container Instances](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.ContainerInstance/containerGroups) | [!['ContainerInstance: ContainerGroups'](https://github.com/Azure/ResourceModules/actions/workflows/ms.containerinstance.containergroups.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.containerinstance.containergroups.yml) |
+| [Container Registries](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.ContainerRegistry/registries) | [!['ContainerRegistry: Registries'](https://github.com/Azure/ResourceModules/actions/workflows/ms.containerregistry.registries.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.containerregistry.registries.yml) |
+| [Data Factories](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.DataFactory/factories) | [!['DataFactory: Factories'](https://github.com/Azure/ResourceModules/actions/workflows/ms.datafactory.factories.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.datafactory.factories.yml) |
+| [DDoS Protection Plans](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/ddosProtectionPlans) | [!['Network: DdosProtectionPlans'](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.ddosprotectionplans.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.ddosprotectionplans.yml) |
+| [Deployment Scripts](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Resources/deploymentScripts) | [!['Resources: DeploymentScripts'](https://github.com/Azure/ResourceModules/actions/workflows/ms.resources.deploymentscripts.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.resources.deploymentscripts.yml) |
+| [Disk Encryption Sets](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Compute/diskEncryptionSets) | [!['Compute: DiskEncryptionSets'](https://github.com/Azure/ResourceModules/actions/workflows/ms.compute.diskencryptionsets.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.compute.diskencryptionsets.yml) |
+| [DocumentDB Database Accounts](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.DocumentDB/databaseAccounts) | [!['DocumentDB: DatabaseAccounts'](https://github.com/Azure/ResourceModules/actions/workflows/ms.documentdb.databaseaccounts.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.documentdb.databaseaccounts.yml) |
+| [Event Grid Topics](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.EventGrid/systemTopics) | [!['EventGrid: System Topics'](https://github.com/Azure/ResourceModules/actions/workflows/ms.eventgrid.systemtopics.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.eventgrid.systemtopics.yml) |
+| [Event Grid Topics](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.EventGrid/topics) | [!['EventGrid: Topics'](https://github.com/Azure/ResourceModules/actions/workflows/ms.eventgrid.topics.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.eventgrid.topics.yml) |
+| [Event Hub Namespaces](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.EventHub/namespaces) | [!['EventHub: Namespaces'](https://github.com/Azure/ResourceModules/actions/workflows/ms.eventhub.namespaces.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.eventhub.namespaces.yml) |
+| [ExpressRoute Circuits](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/expressRouteCircuits) | [!['Network: ExpressRouteCircuits'](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.expressroutecircuits.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.expressroutecircuits.yml) |
+| [Image Templates](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.VirtualMachineImages/imageTemplates) | [!['VirtualMachineImages: ImageTemplates'](https://github.com/Azure/ResourceModules/actions/workflows/ms.virtualmachineimages.imagetemplates.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.virtualmachineimages.imagetemplates.yml) |
+| [Images](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Compute/images) | [!['Compute: Images'](https://github.com/Azure/ResourceModules/actions/workflows/ms.compute.images.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.compute.images.yml) |
+| [IP Groups](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/ipGroups) | [!['Network: IpGroups'](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.ipgroups.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.ipgroups.yml) |
+| [Key Vaults](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.KeyVault/vaults) | [!['KeyVault: Vaults'](https://github.com/Azure/ResourceModules/actions/workflows/ms.keyvault.vaults.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.keyvault.vaults.yml) |
+| [Load Balancers](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/loadBalancers) | [!['Network: LoadBalancers'](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.loadbalancers.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.loadbalancers.yml) |
+| [Local Network Gateways](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/localNetworkGateways) | [!['Network: LocalNetworkGateways'](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.localnetworkgateways.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.localnetworkgateways.yml) |
+| [Log Analytics Workspaces](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.OperationalInsights/workspaces) | [!['OperationalInsights: Workspaces'](https://github.com/Azure/ResourceModules/actions/workflows/ms.operationalinsights.workspaces.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.operationalinsights.workspaces.yml) |
+| [Logic Apps](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Logic/workflows) | [!['Logic: Workflows'](https://github.com/Azure/ResourceModules/actions/workflows/ms.logic.workflows.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.logic.workflows.yml) |
+| [Machine Learning Workspaces](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.MachineLearningServices/workspaces) | [!['MachineLearningServices: Workspaces'](https://github.com/Azure/ResourceModules/actions/workflows/ms.machinelearningservices.workspaces.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.machinelearningservices.workspaces.yml) |
+| [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 Application Gateways](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/applicationGateways) | [!['Network: ApplicationGateways'](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.applicationgateways.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.applicationgateways.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) |
+| [Policy Definitions](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Authorization/policyDefinitions) | [!['Authorization: PolicyDefinitions'](https://github.com/Azure/ResourceModules/actions/workflows/ms.authorization.policydefinitions.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.authorization.policydefinitions.yml) |
+| [Policy Exemptions](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Authorization/policyExemptions) | [!['Authorization: PolicyExemptions'](https://github.com/Azure/ResourceModules/actions/workflows/ms.authorization.policyexemptions.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.authorization.policyexemptions.yml) |
+| [Policy Set Definitions](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Authorization/policySetDefinitions) | [!['Authorization: PolicySetDefinitions'](https://github.com/Azure/ResourceModules/actions/workflows/ms.authorization.policysetdefinitions.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.authorization.policysetdefinitions.yml) |
+| [Private DNS Zones](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/privateDnsZones) | [!['Network: PrivateDnsZones'](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.privatednszones.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.privatednszones.yml) |
+| [Private Endpoints](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/privateEndpoints) | [!['Network: PrivateEndpoints'](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.privateendpoints.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.privateendpoints.yml) |
+| [Proximity Placement Groups](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Compute/proximityPlacementGroups) | [!['Compute: ProximityPlacementGroups'](https://github.com/Azure/ResourceModules/actions/workflows/ms.compute.proximityplacementgroups.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.compute.proximityplacementgroups.yml) |
+| [Public IP Addresses](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/publicIPAddresses) | [!['Network: PublicIpAddresses'](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.publicipaddresses.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.publicipaddresses.yml) |
+| [Public IP Prefixes](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/publicIPPrefixes) | [!['Network: PublicIpPrefixes'](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.publicipprefixes.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.publicipprefixes.yml) |
+| [Recovery Services Vaults](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.RecoveryServices/vaults) | [!['RecoveryServices: Vaults'](https://github.com/Azure/ResourceModules/actions/workflows/ms.recoveryservices.vaults.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.recoveryservices.vaults.yml) |
+| [Registration Definitions](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.ManagedServices/registrationDefinitions) | [!['ManagedServices: RegistrationDefinitions'](https://github.com/Azure/ResourceModules/actions/workflows/ms.managedservices.registrationdefinitions.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.managedservices.registrationdefinitions.yml) |
+| [Resource Groups](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Resources/resourceGroups) | [!['Resources: ResourceGroups'](https://github.com/Azure/ResourceModules/actions/workflows/ms.resources.resourcegroups.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.resources.resourcegroups.yml) |
+| [Resources Tags](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Resources/tags) | [!['Resources: Tags'](https://github.com/Azure/ResourceModules/actions/workflows/ms.resources.tags.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.resources.tags.yml) |
+| [Role Assignments](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Authorization/roleAssignments) | [!['Authorization: RoleAssignments'](https://github.com/Azure/ResourceModules/actions/workflows/ms.authorization.roleassignments.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.authorization.roleassignments.yml) |
+| [Role Definitions](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Authorization/roleDefinitions) | [!['Authorization: RoleDefinitions'](https://github.com/Azure/ResourceModules/actions/workflows/ms.authorization.roledefinitions.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.authorization.roledefinitions.yml) |
+| [Route Tables](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/routeTables) | [!['Network: RouteTables'](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.routetables.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.routetables.yml) |
+| [Scheduled Query Rules](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Insights/scheduledQueryRules) | [!['Insights: ScheduledQueryRules'](https://github.com/Azure/ResourceModules/actions/workflows/ms.insights.scheduledqueryrules.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.insights.scheduledqueryrules.yml) |
+| [Service Bus Namespaces](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.ServiceBus/namespaces) | [!['ServiceBus: Namespaces'](https://github.com/Azure/ResourceModules/actions/workflows/ms.servicebus.namespaces.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.servicebus.namespaces.yml) |
+| [ServiceFabric Cluster](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.ServiceFabric/clusters) | [!['Service Fabric: Clusters'](https://github.com/Azure/ResourceModules/actions/workflows/ms.servicefabric.clusters.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.servicefabric.clusters.yml) |
+| [SQL Managed Instances](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Sql/managedInstances) | [!['Sql: ManagedInstances'](https://github.com/Azure/ResourceModules/actions/workflows/ms.sql.managedinstances.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.sql.managedinstances.yml) |
+| [SQL Servers](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Sql/servers) | [!['Sql: Servers'](https://github.com/Azure/ResourceModules/actions/workflows/ms.sql.servers.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.sql.servers.yml) |
+| [Storage Accounts](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Storage/storageAccounts) | [!['Storage: StorageAccounts'](https://github.com/Azure/ResourceModules/actions/workflows/ms.storage.storageaccounts.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.storage.storageaccounts.yml) |
+| [Synapse PrivateLinkHubs](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Synapse/privateLinkHubs) | [!['Synapse: PrivateLinkHubs'](https://github.com/Azure/ResourceModules/actions/workflows/ms.synapse.privatelinkhubs.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.synapse.privatelinkhubs.yml) |
+| [Traffic Manager Profiles](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/trafficmanagerprofiles) | [!['Network: TrafficManagerProfiles'](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.trafficmanagerprofiles.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.trafficmanagerprofiles.yml) |
+| [User Assigned Identities](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.ManagedIdentity/userAssignedIdentities) | [!['ManagedIdentity: UserAssignedIdentities'](https://github.com/Azure/ResourceModules/actions/workflows/ms.managedidentity.userassignedidentities.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.managedidentity.userassignedidentities.yml) |
+| [Virtual Hub](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/virtualHubs) | [!['Network: Virtual Hubs'](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.virtualhubs.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.virtualhubs.yml) |
+| [Virtual Machine Scale Sets](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Compute/virtualMachineScaleSets) | [!['Compute: VirtualMachineScaleSets'](https://github.com/Azure/ResourceModules/actions/workflows/ms.compute.virtualmachinescalesets.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.compute.virtualmachinescalesets.yml) |
+| [Virtual Machines](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Compute/virtualMachines) | [!['Compute: VirtualMachines'](https://github.com/Azure/ResourceModules/actions/workflows/ms.compute.virtualmachines.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.compute.virtualmachines.yml) |
+| [Virtual Network Gateway Connections](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/connections) | [!['Network: Connections'](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.connections.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.connections.yml) |
+| [Virtual Network Gateways](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/virtualNetworkGateways) | [!['Network: VirtualNetworkGateways'](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.virtualnetworkgateways.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.virtualnetworkgateways.yml) |
+| [Virtual Networks](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/virtualNetworks) | [!['Network: VirtualNetworks'](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.virtualnetworks.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.virtualnetworks.yml) |
+| [Virtual WANs](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Network/virtualWans) | [!['Network: VirtualWans'](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.virtualwans.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.network.virtualwans.yml) |
+| [Web/Function Apps](https://github.com/Azure/ResourceModules/tree/main/arm/Microsoft.Web/sites) | [!['Web: Sites'](https://github.com/Azure/ResourceModules/actions/workflows/ms.web.sites.yml/badge.svg)](https://github.com/Azure/ResourceModules/actions/workflows/ms.web.sites.yml) |
+
+## Tooling
+
+| Name | Status | Docs |
+| - | - | - |
+| [ConvertTo-ARMTemplate](https://github.com/Azure/ResourceModules/blob/main/utilities/tools/ConvertTo-ARMTemplate.ps1) | [![.Platform: Test - ConvertTo-ARMTemplate.ps1](https://github.com/Azure/ResourceModules/actions/workflows/platform.convertToArmTemplate.tests.yml/badge.svg?branch=main)](https://github.com/Azure/ResourceModules/actions/workflows/platform.convertToArmTemplate.tests.yml) | [link](https://github.com/Azure/ResourceModules/wiki/UtilitiesConvertToARMTemplate) |
+
+## Contributing
+
+This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit .
+
+When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.
+
+This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
+For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
+
+## Trademarks
+
+This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow
+[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general).
+Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship.
+Any use of third-party trademarks or logos are subject to those third-party's policies.
+
+## Learn More
+
+* [PowerShell Documentation][PowerShellDocs]
+* [Microsoft Azure Documentation][MicrosoftAzureDocs]
+* [GitHubDocs][GitHubDocs]
+* [Azure Resource Manager][AzureResourceManager]
+* [Bicep][Bicep]
+
+
+
+
+[Wiki]:
+[ProjectSetup]:
+[GitHubDocs]:
+[AzureDevOpsDocs]:
+[GitHubIssues]:
+[Contributing]: CONTRIBUTING.md
+[AzureIcon]: docs/media/MicrosoftAzure-32px.png
+[PowershellIcon]: docs/media/MicrosoftPowerShellCore-32px.png
+[BashIcon]: docs/media/Bash_Logo_black_and_white_icon_only-32px.svg.png
+
+
+[Bicep]:
+[Az]:
+[AzGallery]:
+[PowerShellCore]:
+[InstallAzPs]:
+[AzureResourceManager]:
+[TemplateSpecs]:
+
+[ESLZ]:
+[AzureSecurityBenchmark]:
+[ESLZWorkloadTemplatesLibrary]:
+
+
+[MicrosoftAzureDocs]:
+[PowerShellDocs]:
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 000000000..f9ba8cf65
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,9 @@
+# Microsoft Open Source Code of Conduct
+
+This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
+
+Resources:
+
+- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
+- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
+- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 000000000..9a18be1d1
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,11 @@
+This project welcomes contributions and suggestions. Most contributions require you to agree to a
+Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
+the rights to use your contribution. For details, visit .
+
+When you submit a pull request, a CLA bot will automatically determine whether you need to provide
+a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
+provided by the bot. You will only need to do this once across all repos using our CLA.
+
+This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
+For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
+contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 000000000..9e841e7a2
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+ MIT License
+
+ Copyright (c) Microsoft Corporation.
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE
diff --git a/README.md b/README.md
new file mode 100644
index 000000000..731c7be5d
--- /dev/null
+++ b/README.md
@@ -0,0 +1,68 @@
+# Welcome to the Azure Virtual Desktop (AVD) Landing Zone Accelerator
+
+## Optional: Custom Image Build
+
+Deploy a custom image based on the latest version of the Azure marketplace image to an Azure Compute Gallery. The following images are offered:
+ - Windows 10 21H2
+ - Windows 11 21H2
+ - Windows 10 21H2 with O365
+ - Windows 11 21H2 with O365
+
+ Custom image is optimized using [Virtual Desktop Optimization Tool (VDOT)](https://github.com/The-Virtual-Desktop-Team/Virtual-Desktop-Optimization-Tool) and patched with the latest Windows updates.
+
+[![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2Favdaccelerator%2Fmain%2Fworkload%2Farm%2Fdeploy-customImage.json/uiFormDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2Favdaccelerator%2Fmain%2Fworkload%2Fportal-ui%2Fportal-ui-customImage.json)
+
+## AVD Accelerator Baseline
+
+Deploy Azure Virtual Desktop (AVD) resources and dependent services for establishing the baseline
+- AVD resources: workplace, two(2) application groups and host pool
+- [Optional]: new virtual network (VNet) with baseline NSG and route table
+- Azure Files Premium share. Integration with Active Directory
+- Session Hosts
+
+
+[![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2Favdaccelerator%2Fmain%2Fworkload%2Farm%2Fdeploy-baseline.json/uiFormDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2Favdaccelerator%2Fmain%2Fworkload%2Fportal-ui%2Fportal-ui-baseline.json)
+
+## Overview
+
+Enterprise-scale is an architectural approach and a reference implementation that enables effective construction and operation of landing zones on Azure, at scale. This approach aligns with the Azure roadmap and the Cloud Adoption Framework for Azure.
+
+AVD Landing Zone Accelerator represents the strategic design path and target technical state for AVD deployment. This solution provides an architectural approach and reference implementation to prepare landing zone subscriptions for a scalable AVD deployment. For the architectural guidance, check out [Enterprise-scale for AVD in Microsoft Docs](https://docs.microsoft.com/azure/cloud-adoption-framework/scenarios/wvd/enterprise-scale-landing-zone).
+
+The AVD Landing Zone Accelerator only addresses what gets deployed in the specific AVD landing zone subscriptions, highlighted by the red boxes in the picture above. It is assumed that an appropriate platform foundation is already setup which may or may not be the official [ALZ platform foundation](https://docs.microsoft.com/azure/cloud-adoption-framework/ready/enterprise-scale/implementation#reference-implementation). This means that policies and governance should already be in place or should be set up after this implementation and are not a part of the scope this program. The policies applied to management groups in the hierarchy above the subscription will trickle down to the Enterprise-scale for AVD landing zone subscriptions.
+
+## This Repository
+
+This repository will contain various customer scenarios that can help accelerate the development and deployment of AVD that conforms with [Enterprise-Scale for AVD best practices and guidelines](https://docs.microsoft.com/azure/cloud-adoption-framework/scenarios/wvd/ready). Each scenario aims to represent common customer experiences with the goal of accelerating the process of developing and deploying conforming AVD using IaaC. Each scenario will eventually have an ARM, Bicep, PowerShell and CLI version to choose from.
+As of today, we have a first reference implementation scenario that is one of the most common ones used by Enterprise customers and partners and it can be used to deploy an AVD workload. We will continue to add new scenarios in future updates.
+
+## Next Steps
+
+Head over to [Getting Started Wiki](https://github.com/Azure/avdaccelerator/wiki/Getting-Started#Getting-Started) to review prerequisites and deployment options.
+
+## Baseline Architectural Diagram
+
+![AVD accelerator diagram](./workload/docs/diagrams/avd-accelerator-baseline.png)
+
+_Download a [Visio file](./workload/docs/diagrams/avd-accelerator-baseline-architecture.vsdx) of this architecture._
+## Contributing
+
+This project welcomes contributions and suggestions. Most contributions require you to agree to a
+Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
+the rights to use your contribution. For details, visit [https://cla.opensource.microsoft.com](https://cla.opensource.microsoft.com).
+
+When you submit a pull request, a CLA bot will automatically determine whether you need to provide
+a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
+provided by the bot. You will only need to do this once across all repos using our CLA.
+
+This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
+For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
+contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
+
+## Trademarks
+
+This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft
+trademarks or logos is subject to and must follow
+[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/legal/intellectualproperty/trademarks).
+Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship.
+Any use of third-party trademarks or logos are subject to those third-party's policies.
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 000000000..4fa5946a8
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,41 @@
+
+
+## Security
+
+Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
+
+If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)), please report it to us as described below.
+
+## Reporting Security Issues
+
+**Please do not report security vulnerabilities through public GitHub issues.**
+
+Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report).
+
+If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc).
+
+You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc).
+
+Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
+
+* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
+* Full paths of source file(s) related to the manifestation of the issue
+* The location of the affected source code (tag/branch/commit or direct URL)
+* Any special configuration required to reproduce the issue
+* Step-by-step instructions to reproduce the issue
+* Proof-of-concept or exploit code (if possible)
+* Impact of the issue, including how an attacker might exploit the issue
+
+This information will help us triage your report more quickly.
+
+If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs.
+
+## Preferred Languages
+
+We prefer all communications to be in English.
+
+## Policy
+
+Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd).
+
+
diff --git a/SUPPORT.md b/SUPPORT.md
new file mode 100644
index 000000000..544b011a4
--- /dev/null
+++ b/SUPPORT.md
@@ -0,0 +1,36 @@
+# Support
+
+## Microsoft Support Policy
+
+If issues are encountered when deploying these Bicep modules users will be able to engage Microsoft support via their usual channels. Please provide corelation IDs where possible when contacting support to be able to investigate the issue effectively and in a timely fashion. For instructions on how to get deployments and correlation ID, please follow this link [here](https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/deployment-history?tabs=azure-portal#get-deployments-and-correlation-id).
+
+Following list of issues are within the scope of Microsoft support:
+
+- Underlying Resource or Resource Provider issues when deploying modules (e.g. Management Groups, Policies, Log Analytics Workspace, Virtual WAN, Virtual Network) for any deployment failure
+- Module specific issues (e.g. template errors, internal server errors, etc.)
+- Template specific issues (e.g. template publishing, resource removal, etc.)
+
+Any issues that are deemed outside of the above list by Microsoft support and/or requires bugfix in the module or code in the repo, Microsoft support will redirect user to file the issue on GitHub.
+
+Project maintainers and community aim to get issues resolved in timely fashion as per community support policy of this repo.
+
+## Community Support Policy
+
+Project maintainers will aim to respond to new issues on a best effort basis.
+
+## How to file issues and get help
+
+This project uses GitHub Issues to track bugs and feature requests. Please search the existing issues before filing new issues to avoid duplicates. For new issues, file your bug or feature request as a new Issue.
+
+For help and questions about using this project, please submit a Github issue with corresponding [Issue Labels found here](https://github.com/Azure/ResourceModules/labels).
+
+
+
+[ProjectSetup]:
+[GitHubDocs]:
+[AzureDevOpsDocs]:
+[GitHubIssues]:
+[Contributing]: CONTRIBUTING.md
+[AzureIcon]: docs/media/MicrosoftAzure-32px.png
+[PowershellIcon]: docs/media/MicrosoftPowerShellCore-32px.png
+[BashIcon]: docs/media/Bash_Logo_black_and_white_icon_only-32px.svg.png
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
new file mode 100644
index 000000000..f53e97b6b
--- /dev/null
+++ b/azure-pipelines.yml
@@ -0,0 +1,19 @@
+# Starter pipeline
+# Start with a minimal pipeline that you can customize to build and deploy your code.
+# Add steps that build, run tests, deploy, and more:
+# https://aka.ms/yaml
+
+trigger:
+- main
+
+pool:
+ vmImage: ubuntu-latest
+
+steps:
+- script: echo Hello, world!
+ displayName: 'Run a one-line script'
+
+- script: |
+ echo Add other tasks to build, test, and deploy your project.
+ echo See https://aka.ms/yaml
+ displayName: 'Run a multi-line script'
diff --git a/carml/1.0.0/Microsoft.AnalysisServices/servers/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.AnalysisServices/servers/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.AnalysisServices/servers/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.AnalysisServices/servers/.bicep/nested_rbac.bicep b/carml/1.0.0/Microsoft.AnalysisServices/servers/.bicep/nested_rbac.bicep
new file mode 100644
index 000000000..5187be04b
--- /dev/null
+++ b/carml/1.0.0/Microsoft.AnalysisServices/servers/.bicep/nested_rbac.bicep
@@ -0,0 +1,32 @@
+param principalIds array
+param roleDefinitionIdOrName string
+param resourceId string
+
+var builtInRoleNames = {
+ 'Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')
+ 'Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')
+ 'Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')
+ 'Log Analytics Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')
+ 'Log Analytics Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')
+ 'Managed Application Contributor Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')
+ 'Managed Application Operator Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')
+ 'Managed Applications Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')
+ 'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')
+ 'Monitoring Metrics Publisher': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')
+ 'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')
+ 'Resource Policy Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')
+ 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')
+}
+
+resource server 'Microsoft.AnalysisServices/servers@2017-08-01' existing = {
+ name: last(split(resourceId, '/'))
+}
+
+resource roleAssignment 'Microsoft.Authorization/roleAssignments@2021-04-01-preview' = [for principalId in principalIds: {
+ name: guid(server.name, principalId, roleDefinitionIdOrName)
+ properties: {
+ roleDefinitionId: contains(builtInRoleNames, roleDefinitionIdOrName) ? builtInRoleNames[roleDefinitionIdOrName] : roleDefinitionIdOrName
+ principalId: principalId
+ }
+ scope: server
+}]
diff --git a/carml/1.0.0/Microsoft.AnalysisServices/servers/.parameters/min.parameters.json b/carml/1.0.0/Microsoft.AnalysisServices/servers/.parameters/min.parameters.json
new file mode 100644
index 000000000..33c06055d
--- /dev/null
+++ b/carml/1.0.0/Microsoft.AnalysisServices/servers/.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": "<>azasweumin001"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.AnalysisServices/servers/.parameters/parameters.json b/carml/1.0.0/Microsoft.AnalysisServices/servers/.parameters/parameters.json
new file mode 100644
index 000000000..29ad01f8a
--- /dev/null
+++ b/carml/1.0.0/Microsoft.AnalysisServices/servers/.parameters/parameters.json
@@ -0,0 +1,37 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>azasweux001"
+ },
+ "skuName": {
+ "value": "D1"
+ },
+ "roleAssignments": {
+ "value": [
+ {
+ "roleDefinitionIdOrName": "Reader",
+ "principalIds": [
+ "<>"
+ ]
+ }
+ ]
+ },
+ "diagnosticLogsRetentionInDays": {
+ "value": 7
+ },
+ "diagnosticStorageAccountId": {
+ "value": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Storage/storageAccounts/adp<>azsax001"
+ },
+ "diagnosticWorkspaceId": {
+ "value": "/subscriptions/<>/resourcegroups/validation-rg/providers/microsoft.operationalinsights/workspaces/adp-<>-az-law-x-001"
+ },
+ "diagnosticEventHubAuthorizationRuleId": {
+ "value": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.EventHub/namespaces/adp-<>-az-evhns-x-001/AuthorizationRules/RootManageSharedAccessKey"
+ },
+ "diagnosticEventHubName": {
+ "value": "adp-<>-az-evh-x-001"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.AnalysisServices/servers/deploy.bicep b/carml/1.0.0/Microsoft.AnalysisServices/servers/deploy.bicep
new file mode 100644
index 000000000..a49d21a2f
--- /dev/null
+++ b/carml/1.0.0/Microsoft.AnalysisServices/servers/deploy.bicep
@@ -0,0 +1,152 @@
+@description('Required. The name of the Azure Analysis Services server to create.')
+param name string
+
+@description('Optional. The sku name of the Azure Analysis Services server to create.')
+param skuName string = 'S0'
+
+@description('Optional. The total number of query replica scale-out instances.')
+param skuCapacity int = 1
+
+@description('Optional. The inbound firewall rules to define on the server. If not specified, firewall is disabled.')
+param firewallSettings object = {
+ firewallRules: [
+ {
+ firewallRuleName: 'AllowFromAll'
+ rangeStart: '0.0.0.0'
+ rangeEnd: '255.255.255.255'
+ }
+ ]
+ enablePowerBIService: true
+}
+
+@description('Optional. Location for all Resources.')
+param location string = resourceGroup().location
+
+@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 the diagnostic log analytics workspace.')
+param diagnosticWorkspaceId string = ''
+
+@description('Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to.')
+param diagnosticEventHubAuthorizationRuleId string = ''
+
+@description('Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category.')
+param diagnosticEventHubName string = ''
+
+@allowed([
+ 'CanNotDelete'
+ 'NotSpecified'
+ 'ReadOnly'
+])
+@description('Optional. Specify the type of lock.')
+param lock string = 'NotSpecified'
+
+@description('Optional. Array of role assignment objects that contain the \'roleDefinitionIdOrName\' and \'principalId\' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'')
+param roleAssignments array = []
+
+@description('Optional. Tags of the resource.')
+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([
+ 'Engine'
+ 'Service'
+])
+param logsToEnable array = [
+ 'Engine'
+ 'Service'
+]
+
+@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
+ }
+}]
+
+module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) {
+ name: 'pid-${cuaId}'
+ params: {}
+}
+
+resource server 'Microsoft.AnalysisServices/servers@2017-08-01' = {
+ name: name
+ location: location
+ tags: tags
+ sku: {
+ name: skuName
+ capacity: skuCapacity
+ }
+ properties: {
+ ipV4FirewallSettings: firewallSettings
+ }
+}
+
+resource server_lock 'Microsoft.Authorization/locks@2017-04-01' = if (lock != 'NotSpecified') {
+ name: '${server.name}-${lock}-lock'
+ properties: {
+ level: lock
+ notes: (lock == 'CanNotDelete') ? 'Cannot delete resource or child resources.' : 'Cannot modify the resource or child resources.'
+ }
+ scope: server
+}
+
+resource server_diagnosticSettings 'Microsoft.Insights/diagnosticsettings@2021-05-01-preview' = if ((!empty(diagnosticStorageAccountId)) || (!empty(diagnosticWorkspaceId)) || (!empty(diagnosticEventHubAuthorizationRuleId)) || (!empty(diagnosticEventHubName))) {
+ name: '${server.name}-diagnosticSettings'
+ properties: {
+ storageAccountId: !empty(diagnosticStorageAccountId) ? diagnosticStorageAccountId : null
+ workspaceId: !empty(diagnosticWorkspaceId) ? diagnosticWorkspaceId : null
+ eventHubAuthorizationRuleId: !empty(diagnosticEventHubAuthorizationRuleId) ? diagnosticEventHubAuthorizationRuleId : null
+ eventHubName: !empty(diagnosticEventHubName) ? diagnosticEventHubName : null
+ metrics: diagnosticsMetrics
+ logs: diagnosticsLogs
+ }
+ scope: server
+}
+
+module server_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: {
+ name: '${uniqueString(deployment().name, location)}-AnServicesServer-Rbac-${index}'
+ params: {
+ principalIds: roleAssignment.principalIds
+ roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName
+ resourceId: server.id
+ }
+}]
+
+@description('The name of the analysis service')
+output name string = server.name
+
+@description('The resource ID of the analysis service')
+output resourceId string = server.id
+
+@description('The resource group the analysis service was deployed into')
+output resourceGroupName string = resourceGroup().name
diff --git a/carml/1.0.0/Microsoft.AnalysisServices/servers/readme.md b/carml/1.0.0/Microsoft.AnalysisServices/servers/readme.md
new file mode 100644
index 000000000..524d12f5d
--- /dev/null
+++ b/carml/1.0.0/Microsoft.AnalysisServices/servers/readme.md
@@ -0,0 +1,93 @@
+# Analysis Services Server `[Microsoft.AnalysisServices/servers]`
+
+This module deploys an analysis service server.
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.AnalysisServices/servers` | 2017-08-01 |
+| `Microsoft.Authorization/locks` | 2017-04-01 |
+| `Microsoft.Authorization/roleAssignments` | 2021-04-01-preview |
+| `Microsoft.Insights/diagnosticSettings` | 2021-05-01-preview |
+
+### Resource dependency
+
+The following resources are required to be able to deploy this resource.
+
+- `Microsoft.Network/VirtualNetwork`
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered |
+| `diagnosticEventHubAuthorizationRuleId` | string | | | Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. |
+| `diagnosticEventHubName` | string | | | Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. |
+| `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. |
+| `diagnosticWorkspaceId` | string | | | Optional. Resource ID of the diagnostic log analytics workspace. |
+| `firewallSettings` | object | `{object}` | | Optional. The inbound firewall rules to define on the server. If not specified, firewall is disabled. |
+| `location` | string | `[resourceGroup().location]` | | Optional. Location for all Resources. |
+| `lock` | string | `NotSpecified` | `[CanNotDelete, NotSpecified, ReadOnly]` | Optional. Specify the type of lock. |
+| `logsToEnable` | array | `[Engine, Service]` | `[Engine, Service]` | 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 name of the Azure Analysis Services server to create. |
+| `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' |
+| `skuCapacity` | int | `1` | | Optional. The total number of query replica scale-out instances. |
+| `skuName` | string | `S0` | | Optional. The sku name of the Azure Analysis Services server to create. |
+| `tags` | object | `{object}` | | Optional. Tags of the resource. |
+
+### 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: `roleAssignments`
+
+```json
+"roleAssignments": {
+ "value": [
+ {
+ "roleDefinitionIdOrName": "Reader",
+ "principalIds": [
+ "12345678-1234-1234-1234-123456789012", // object 1
+ "78945612-1234-1234-1234-123456789012" // object 2
+ ]
+ },
+ {
+ "roleDefinitionIdOrName": "/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11",
+ "principalIds": [
+ "12345678-1234-1234-1234-123456789012" // object 1
+ ]
+ }
+ ]
+}
+```
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The name of the analysis service |
+| `resourceGroupName` | string | The resource group the analysis service was deployed into |
+| `resourceId` | string | The resource ID of the analysis service |
+
+## 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/2017-04-01/locks)
+- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/roleAssignments)
+- [Servers](https://docs.microsoft.com/en-us/azure/templates/Microsoft.AnalysisServices/2017-08-01/servers)
diff --git a/carml/1.0.0/Microsoft.AnalysisServices/servers/version.json b/carml/1.0.0/Microsoft.AnalysisServices/servers/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.AnalysisServices/servers/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/.bicep/nested_authorizationServers.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/.bicep/nested_authorizationServers.bicep
new file mode 100644
index 000000000..f8766ec1f
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/.bicep/nested_authorizationServers.bicep
@@ -0,0 +1,109 @@
+@description('Required. Identifier of the authorization server.')
+param name string
+
+@description('Required. The name of the of the API Management service.')
+param apiManagementServiceName string
+
+@description('Required. OAuth authorization endpoint. See .')
+param authorizationEndpoint string
+
+@description('Optional. HTTP verbs supported by the authorization endpoint. GET must be always present. POST is optional. - HEAD, OPTIONS, TRACE, GET, POST, PUT, PATCH, DELETE')
+param authorizationMethods array = [
+ 'GET'
+]
+
+@description('Optional. Specifies the mechanism by which access token is passed to the API. - authorizationHeader or query')
+param bearerTokenSendingMethods array = [
+ 'authorizationHeader'
+]
+
+@description('Optional. Method of authentication supported by the token endpoint of this authorization server. Possible values are Basic and/or Body. When Body is specified, client credentials and other parameters are passed within the request body in the application/x-www-form-urlencoded format. - Basic or Body')
+param clientAuthenticationMethod array = [
+ 'Basic'
+]
+
+@description('Optional. Optional reference to a page where client or app registration for this authorization server is performed. Contains absolute URL to entity being referenced.')
+param clientRegistrationEndpoint string = ''
+
+@description('Required. Name of the key vault that stores clientId and clientSecret for this authorization server.')
+param clientCredentialsKeyVaultId string
+
+@description('Required. Name of the secret that stores the Client or app ID registered with this authorization server.')
+param clientIdSecretName string
+
+@description('Required. Name of the secret that stores the Client or app secret registered with this authorization server. This property will not be filled on \'GET\' operations! Use \'/listSecrets\' POST request to get the value.')
+param clientSecretSecretName string
+
+@description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered')
+param cuaId string = ''
+
+@description('Optional. Access token scope that is going to be requested by default. Can be overridden at the API level. Should be provided in the form of a string containing space-delimited values.')
+param defaultScope string = ''
+
+@description('Optional. Description of the authorization server. Can contain HTML formatting tags.')
+param serverDescription string = ''
+
+@description('Required. Form of an authorization grant, which the client uses to request the access token. - authorizationCode, implicit, resourceOwnerPassword, clientCredentials')
+param grantTypes array
+
+@description('Optional. Can be optionally specified when resource owner password grant type is supported by this authorization server. Default resource owner password.')
+param resourceOwnerPassword string = ''
+
+@description('Optional. Can be optionally specified when resource owner password grant type is supported by this authorization server. Default resource owner username.')
+param resourceOwnerUsername string = ''
+
+@description('Optional. If true, authorization server will include state parameter from the authorization request to its response. Client may use state parameter to raise protocol security.')
+param supportState bool = false
+
+@description('Optional. Additional parameters required by the token endpoint of this authorization server represented as an array of JSON objects with name and value string properties, i.e. {"name" : "name value", "value": "a value"}. - TokenBodyParameterContract object')
+param tokenBodyParameters array = []
+
+@description('Optional. OAuth token endpoint. Contains absolute URI to entity being referenced.')
+param tokenEndpoint string = ''
+
+var defaultAuthorizationMethods = [
+ 'GET'
+]
+var setAuthorizationMethods = union(authorizationMethods, defaultAuthorizationMethods)
+
+module pid_cuaId '../authorizationServers/.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) {
+ name: 'pid-${cuaId}'
+ params: {}
+}
+
+resource keyVault 'Microsoft.KeyVault/vaults@2019-09-01' existing = {
+ name: last(split(clientCredentialsKeyVaultId, '/'))
+ scope: resourceGroup(split(clientCredentialsKeyVaultId, '/')[2], split(clientCredentialsKeyVaultId, '/')[4])
+}
+
+module authorizationServer '../authorizationServers/deploy.bicep' = {
+ name: '${deployment().name}-AuthorizationServer'
+ params: {
+ apiManagementServiceName: apiManagementServiceName
+ serverDescription: serverDescription
+ authorizationMethods: setAuthorizationMethods
+ clientAuthenticationMethod: clientAuthenticationMethod
+ tokenBodyParameters: tokenBodyParameters
+ tokenEndpoint: tokenEndpoint
+ supportState: supportState
+ defaultScope: defaultScope
+ bearerTokenSendingMethods: bearerTokenSendingMethods
+ resourceOwnerUsername: resourceOwnerUsername
+ resourceOwnerPassword: resourceOwnerPassword
+ name: name
+ clientRegistrationEndpoint: clientRegistrationEndpoint
+ authorizationEndpoint: authorizationEndpoint
+ grantTypes: grantTypes
+ clientId: keyVault.getSecret(clientIdSecretName)
+ clientSecret: keyVault.getSecret(clientSecretSecretName)
+ }
+}
+
+@description('The name of the API management service authorization server')
+output name string = authorizationServer.outputs.name
+
+@description('The resource ID of the API management service authorization server')
+output resourceId string = authorizationServer.outputs.resourceId
+
+@description('The resource group the API management service authorization server was deployed into')
+output resourceGroupName string = authorizationServer.outputs.resourceGroupName
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/.bicep/nested_rbac.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/.bicep/nested_rbac.bicep
new file mode 100644
index 000000000..2d8ca81f3
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/.bicep/nested_rbac.bicep
@@ -0,0 +1,35 @@
+param principalIds array
+param roleDefinitionIdOrName string
+param resourceId string
+
+var builtInRoleNames = {
+ 'Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')
+ 'Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')
+ 'Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')
+ 'API Management Service Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '312a565d-c81f-4fd8-895a-4e21e48d571c')
+ 'API Management Service Operator Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e022efe7-f5ba-4159-bbe4-b44f577e9b61')
+ 'API Management Service Reader Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '71522526-b88f-4d52-b57f-d31fc3546d0d')
+ 'Log Analytics Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')
+ 'Log Analytics Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')
+ 'Managed Application Contributor Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')
+ 'Managed Application Operator Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')
+ 'Managed Applications Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')
+ 'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')
+ 'Monitoring Metrics Publisher': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')
+ 'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')
+ 'Resource Policy Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')
+ 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')
+}
+
+resource service 'Microsoft.ApiManagement/service@2020-12-01' existing = {
+ name: last(split(resourceId, '/'))
+}
+
+resource roleAssignment 'Microsoft.Authorization/roleAssignments@2021-04-01-preview' = [for principalId in principalIds: {
+ name: guid(service.name, principalId, roleDefinitionIdOrName)
+ properties: {
+ roleDefinitionId: contains(builtInRoleNames, roleDefinitionIdOrName) ? builtInRoleNames[roleDefinitionIdOrName] : roleDefinitionIdOrName
+ principalId: principalId
+ }
+ scope: service
+}]
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/.parameters/max.parameters.json b/carml/1.0.0/Microsoft.ApiManagement/service/.parameters/max.parameters.json
new file mode 100644
index 000000000..127fda340
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/.parameters/max.parameters.json
@@ -0,0 +1,177 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-az-apim-max-001"
+ },
+ "publisherEmail": {
+ "value": "apimgmt-noreply@mail.windowsazure.com"
+ },
+ "publisherName": {
+ "value": "<>-az-amorg-x-001"
+ },
+ "cuaId": {
+ "value": "00000-0-000000"
+ },
+ "apis": {
+ "value": [
+ {
+ "name": "echo-api",
+ "displayName": "Echo API",
+ "path": "echo",
+ "serviceUrl": "http://echoapi.cloudapp.net/api",
+ "apiVersionSet": {
+ "name": "echo-version-set",
+ "properties": {
+ "description": "echo-version-set",
+ "displayName": "echo-version-set",
+ "versioningScheme": "Segment"
+ }
+ }
+ }
+ ]
+ },
+ "authorizationServers": {
+ "value": [
+ {
+ "name": "AuthServer1",
+ "authorizationEndpoint": "https://login.microsoftonline.com/651b43ce-ccb8-4301-b551-b04dd872d401/oauth2/v2.0/authorize",
+ "grantTypes": [
+ "authorizationCode"
+ ],
+ "clientCredentialsKeyVaultId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.KeyVault/vaults/adp-<>-az-kv-x-001",
+ "clientIdSecretName": "apimclientid",
+ "clientSecretSecretName": "apimclientsecret",
+ "clientRegistrationEndpoint": "http://localhost",
+ "tokenEndpoint": "https://login.microsoftonline.com/651b43ce-ccb8-4301-b551-b04dd872d401/oauth2/v2.0/token"
+ }
+ ]
+ },
+ "backends": {
+ "value": [
+ {
+ "name": "backend",
+ "url": "http://echoapi.cloudapp.net/api",
+ "tls": {
+ "validateCertificateChain": false,
+ "validateCertificateName": false
+ }
+ }
+ ]
+ },
+ "caches": {
+ "value": [
+ {
+ "name": "westeurope",
+ "connectionString": "connectionstringtest",
+ "useFromLocation": "westeurope"
+ }
+ ]
+ },
+ "identityProviders": {
+ "value": [
+ {
+ "name": "aadProvider"
+ }
+ ]
+ },
+ "namedValues": {
+ "value": [
+ {
+ "name": "apimkey",
+ "displayName": "apimkey",
+ "secret": true
+ }
+ ]
+ },
+ "policies": {
+ "value": [
+ {
+ "value": " ",
+ "format": "xml"
+ }
+ ]
+ },
+ "portalSettings": {
+ "value": [
+ {
+ "name": "signin",
+ "properties": {
+ "enabled": false
+ }
+ },
+ {
+ "name": "signup",
+ "properties": {
+ "enabled": false,
+ "termsOfService": {
+ "enabled": false,
+ "consentRequired": false
+ }
+ }
+ }
+ ]
+ },
+ "products": {
+ "value": [
+ {
+ "name": "Starter",
+ "subscriptionRequired": false,
+ "approvalRequired": false,
+ "apis": [
+ {
+ "name": "echo-api"
+ }
+ ],
+ "groups": [
+ {
+ "name": "developers"
+ }
+ ]
+ }
+ ]
+ },
+ "subscriptions": {
+ "value": [
+ {
+ "scope": "/apis",
+ "name": "testArmSubscriptionAllApis"
+ }
+ ]
+ },
+ "systemAssignedIdentity": {
+ "value": true
+ },
+ "userAssignedIdentities": {
+ "value": {
+ "/subscriptions/<>/resourcegroups/validation-rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/adp-<>-az-msi-x-001": {}
+ }
+ },
+ "roleAssignments": {
+ "value": [
+ {
+ "roleDefinitionIdOrName": "Reader",
+ "principalIds": [
+ "<>"
+ ]
+ }
+ ]
+ },
+ "diagnosticLogsRetentionInDays": {
+ "value": 7
+ },
+ "diagnosticStorageAccountId": {
+ "value": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Storage/storageAccounts/adp<>azsax001"
+ },
+ "diagnosticWorkspaceId": {
+ "value": "/subscriptions/<>/resourcegroups/validation-rg/providers/microsoft.operationalinsights/workspaces/adp-<>-az-law-x-001"
+ },
+ "diagnosticEventHubAuthorizationRuleId": {
+ "value": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.EventHub/namespaces/adp-<>-az-evhns-x-001/AuthorizationRules/RootManageSharedAccessKey"
+ },
+ "diagnosticEventHubName": {
+ "value": "adp-<>-az-evh-x-001"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/.parameters/parameters.json b/carml/1.0.0/Microsoft.ApiManagement/service/.parameters/parameters.json
new file mode 100644
index 000000000..a7ae0692b
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/.parameters/parameters.json
@@ -0,0 +1,56 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-az-apim-x-001"
+ },
+ "publisherEmail": {
+ "value": "apimgmt-noreply@mail.windowsazure.com"
+ },
+ "publisherName": {
+ "value": "<>-az-amorg-x-001"
+ },
+ "cuaId": {
+ "value": "00000-0-000000"
+ },
+ "portalSettings": {
+ "value": [
+ {
+ "name": "signin",
+ "properties": {
+ "enabled": false
+ }
+ },
+ {
+ "name": "signup",
+ "properties": {
+ "enabled": false,
+ "termsOfService": {
+ "enabled": false,
+ "consentRequired": false
+ }
+ }
+ }
+ ]
+ },
+ "policies": {
+ "value": [
+ {
+ "value": " ",
+ "format": "xml"
+ }
+ ]
+ },
+ "roleAssignments": {
+ "value": [
+ {
+ "roleDefinitionIdOrName": "Reader",
+ "principalIds": [
+ "<>"
+ ]
+ }
+ ]
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/apiVersionSets/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/apiVersionSets/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/apiVersionSets/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/apiVersionSets/deploy.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/apiVersionSets/deploy.bicep
new file mode 100644
index 000000000..b2cc5b3bb
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/apiVersionSets/deploy.bicep
@@ -0,0 +1,35 @@
+@description('Required. The name of the of the API Management service.')
+param apiManagementServiceName string
+
+@description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered')
+param cuaId string = ''
+
+@description('Optional. API Version set name')
+param name string = 'default'
+
+@description('Optional. API Version set properties')
+param properties object = {}
+
+module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) {
+ name: 'pid-${cuaId}'
+ params: {}
+}
+
+resource service 'Microsoft.ApiManagement/service@2021-08-01' existing = {
+ name: apiManagementServiceName
+}
+
+resource apiVersionSet 'Microsoft.ApiManagement/service/apiVersionSets@2021-08-01' = {
+ name: name
+ parent: service
+ properties: properties
+}
+
+@description('The resource ID of the API Version set')
+output resourceId string = apiVersionSet.id
+
+@description('The name of the API Version set')
+output name string = apiVersionSet.name
+
+@description('The resource group the API Version set was deployed into')
+output resourceGroupName string = resourceGroup().name
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/apiVersionSets/readme.md b/carml/1.0.0/Microsoft.ApiManagement/service/apiVersionSets/readme.md
new file mode 100644
index 000000000..9d2cb15f2
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/apiVersionSets/readme.md
@@ -0,0 +1,30 @@
+# API Management Service API Version Sets `[Microsoft.ApiManagement/service/apiVersionSets]`
+
+This module deploys API Management Service APIs Version Set.
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.ApiManagement/service/apiVersionSets` | 2021-08-01 |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `apiManagementServiceName` | string | | | Required. The name of the of the API Management service. |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered |
+| `name` | string | `default` | | Optional. API Version set name |
+| `properties` | object | `{object}` | | Optional. API Version set properties |
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The name of the API Version set |
+| `resourceGroupName` | string | The resource group the API Version set was deployed into |
+| `resourceId` | string | The resource ID of the API Version set |
+
+## Template references
+
+- [Service/Apiversionsets](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2021-08-01/service/apiVersionSets)
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/apiVersionSets/version.json b/carml/1.0.0/Microsoft.ApiManagement/service/apiVersionSets/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/apiVersionSets/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/apis/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/apis/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/apis/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/apis/deploy.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/apis/deploy.bicep
new file mode 100644
index 000000000..49dad325d
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/apis/deploy.bicep
@@ -0,0 +1,150 @@
+@description('Required. API revision identifier. Must be unique in the current API Management service instance. Non-current revision has ;rev=n as a suffix where n is the revision number.')
+param name string
+
+@description('Optional. Array of Policies to apply to the Service API.')
+param policies array = []
+
+@description('Required. The name of the of the API Management service.')
+param apiManagementServiceName string
+
+@description('Optional. Describes the Revision of the API. If no value is provided, default revision 1 is created')
+param apiRevision string = ''
+
+@description('Optional. Description of the API Revision.')
+param apiRevisionDescription string = ''
+
+@description('Optional. Type of API to create. * http creates a SOAP to REST API * soap creates a SOAP pass-through API.')
+@allowed([
+ 'http'
+ 'soap'
+])
+param apiType string = 'http'
+
+@description('Optional. Indicates the Version identifier of the API if the API is versioned')
+param apiVersion string = ''
+
+@description('Optional. Indicates the Version identifier of the API version set')
+param apiVersionSetId string = ''
+
+@description('Optional. Description of the API Version.')
+param apiVersionDescription string = ''
+
+@description('Optional. Collection of authentication settings included into this API.')
+param authenticationSettings object = {}
+
+@description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered')
+param cuaId string = ''
+
+@description('Optional. Description of the API. May include HTML formatting tags.')
+param apiDescription string = ''
+
+@description('Required. API name. Must be 1 to 300 characters long.')
+@maxLength(300)
+param displayName string
+
+@description('Optional. Format of the Content in which the API is getting imported.')
+@allowed([
+ 'wadl-xml'
+ 'wadl-link-json'
+ 'swagger-json'
+ 'swagger-link-json'
+ 'wsdl'
+ 'wsdl-link'
+ 'openapi'
+ 'openapi+json'
+ 'openapi-link'
+ 'openapi+json-link'
+])
+param format string = 'openapi'
+
+@description('Optional. Indicates if API revision is current API revision.')
+param isCurrent bool = true
+
+@description('Required. Relative URL uniquely identifying this API and all of its resource paths within the API Management service instance. It is appended to the API endpoint base URL specified during the service instance creation to form a public URL for this API.')
+param path string
+
+@description('Optional. Describes on which protocols the operations in this API can be invoked. - HTTP or HTTPS')
+param protocols array = [
+ 'https'
+]
+
+@description('Optional. Absolute URL of the backend service implementing this API. Cannot be more than 2000 characters long.')
+@maxLength(2000)
+param serviceUrl string = ''
+
+@description('Optional. API identifier of the source API.')
+param sourceApiId string = ''
+
+@description('Optional. Protocols over which API is made available.')
+param subscriptionKeyParameterNames object = {}
+
+@description('Optional. Specifies whether an API or Product subscription is required for accessing the API.')
+param subscriptionRequired bool = false
+
+@description('Optional. Type of API.')
+@allowed([
+ 'http'
+ 'soap'
+])
+param type string = 'http'
+
+@description('Optional. Content value when Importing an API.')
+param value string = ''
+
+@description('Optional. Criteria to limit import of WSDL to a subset of the document.')
+param wsdlSelector object = {}
+
+module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) {
+ name: 'pid-${cuaId}'
+ params: {}
+}
+
+resource service 'Microsoft.ApiManagement/service@2021-08-01' existing = {
+ name: apiManagementServiceName
+}
+
+resource api 'Microsoft.ApiManagement/service/apis@2021-08-01' = {
+ name: name
+ parent: service
+ properties: {
+ apiRevision: !empty(apiRevision) ? apiRevision : null
+ apiRevisionDescription: !empty(apiRevisionDescription) ? apiRevisionDescription : null
+ apiType: !empty(apiType) ? apiType : null
+ apiVersion: !empty(apiVersion) ? apiVersion : null
+ apiVersionDescription: !empty(apiVersionDescription) ? apiVersionDescription : null
+ apiVersionSetId: !empty(apiVersionSetId) ? apiVersionSetId : null
+ authenticationSettings: authenticationSettings
+ description: apiDescription
+ displayName: displayName
+ format: !empty(value) ? format : null
+ isCurrent: isCurrent
+ path: path
+ protocols: protocols
+ serviceUrl: !empty(serviceUrl) ? serviceUrl : null
+ sourceApiId: !empty(sourceApiId) ? sourceApiId : null
+ subscriptionKeyParameterNames: !empty(subscriptionKeyParameterNames) ? subscriptionKeyParameterNames : null
+ subscriptionRequired: subscriptionRequired
+ type: type
+ value: !empty(value) ? value : null
+ wsdlSelector: wsdlSelector
+ }
+}
+
+module policy 'policies/deploy.bicep' = [for (policy, index) in policies: {
+ name: '${deployment().name}-Policy-${index}'
+ params: {
+ apiManagementServiceName: apiManagementServiceName
+ apiName: api.name
+ format: contains(policy, 'format') ? policy.format : 'xml'
+ value: policy.value
+ }
+}]
+
+@description('The name of the API management service API')
+output name string = api.name
+
+@description('The resource ID of the API management service API')
+output resourceId string = api.id
+
+@description('The resource group the API management service API was deployed to')
+output resourceGroupName string = resourceGroup().name
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/apis/policies/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/apis/policies/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/apis/policies/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/apis/policies/deploy.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/apis/policies/deploy.bicep
new file mode 100644
index 000000000..a232bba14
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/apis/policies/deploy.bicep
@@ -0,0 +1,54 @@
+@description('Required. The name of the of the API Management service.')
+param apiManagementServiceName string
+
+@description('Required. The name of the of the API.')
+param apiName string
+
+@description('Optional. The name of the policy')
+param name string = 'policy'
+
+@description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered')
+param cuaId string = ''
+
+@description('Optional. Format of the policyContent.')
+@allowed([
+ 'rawxml'
+ 'rawxml-link'
+ 'xml'
+ 'xml-link'
+])
+param format string = 'xml'
+
+@description('Required. Contents of the Policy as defined by the format.')
+param value string
+
+module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) {
+ name: 'pid-${cuaId}'
+ params: {}
+}
+
+resource service 'Microsoft.ApiManagement/service@2021-08-01' existing = {
+ name: apiManagementServiceName
+
+ resource api 'apis@2021-08-01' existing = {
+ name: apiName
+ }
+}
+
+resource policy 'Microsoft.ApiManagement/service/apis/policies@2021-08-01' = {
+ name: name
+ parent: service::api
+ properties: {
+ format: format
+ value: value
+ }
+}
+
+@description('The resource ID of the API policy')
+output resourceId string = policy.id
+
+@description('The name of the API policy')
+output name string = policy.name
+
+@description('The resource group the API policy was deployed into')
+output resourceGroupName string = resourceGroup().name
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/apis/policies/readme.md b/carml/1.0.0/Microsoft.ApiManagement/service/apis/policies/readme.md
new file mode 100644
index 000000000..d78e1f54d
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/apis/policies/readme.md
@@ -0,0 +1,32 @@
+# API Management Service APIs Policies `[Microsoft.ApiManagement/service/apis/policies]`
+
+This module deploys API Management Service APIs policies.
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.ApiManagement/service/apis/policies` | 2021-08-01 |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `apiManagementServiceName` | string | | | Required. The name of the of the API Management service. |
+| `apiName` | string | | | Required. The name of the of the API. |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered |
+| `format` | string | `xml` | `[rawxml, rawxml-link, xml, xml-link]` | Optional. Format of the policyContent. |
+| `name` | string | `policy` | | Optional. The name of the policy |
+| `value` | string | | | Required. Contents of the Policy as defined by the format. |
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The name of the API policy |
+| `resourceGroupName` | string | The resource group the API policy was deployed into |
+| `resourceId` | string | The resource ID of the API policy |
+
+## Template references
+
+- [Service/Apis/Policies](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2021-08-01/service/apis/policies)
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/apis/policies/version.json b/carml/1.0.0/Microsoft.ApiManagement/service/apis/policies/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/apis/policies/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/apis/readme.md b/carml/1.0.0/Microsoft.ApiManagement/service/apis/readme.md
new file mode 100644
index 000000000..b57b0cc3c
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/apis/readme.md
@@ -0,0 +1,75 @@
+# API Management Service APIs `[Microsoft.ApiManagement/service/apis]`
+
+This module deploys API Management Service APIs.
+
+## Resource types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.ApiManagement/service/apis` | 2021-08-01 |
+| `Microsoft.ApiManagement/service/apis/policies` | 2021-08-01 |
+
+### Resource dependency
+
+The following resources are required to be able to deploy this resource.
+
+- `Microsoft.ApiManagement/service`
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `apiDescription` | string | | | Optional. Description of the API. May include HTML formatting tags. |
+| `apiManagementServiceName` | string | | | Required. The name of the of the API Management service. |
+| `apiRevision` | string | | | Optional. Describes the Revision of the API. If no value is provided, default revision 1 is created |
+| `apiRevisionDescription` | string | | | Optional. Description of the API Revision. |
+| `apiType` | string | `http` | `[http, soap]` | Optional. Type of API to create. * http creates a SOAP to REST API * soap creates a SOAP pass-through API. |
+| `apiVersion` | string | | | Optional. Indicates the Version identifier of the API if the API is versioned |
+| `apiVersionDescription` | string | | | Optional. Description of the API Version. |
+| `apiVersionSetId` | string | | | Optional. Indicates the Version identifier of the API version set |
+| `authenticationSettings` | object | `{object}` | | Optional. Collection of authentication settings included into this API. |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered |
+| `displayName` | string | | | Required. API name. Must be 1 to 300 characters long. |
+| `format` | string | `openapi` | `[wadl-xml, wadl-link-json, swagger-json, swagger-link-json, wsdl, wsdl-link, openapi, openapi+json, openapi-link, openapi+json-link]` | Optional. Format of the Content in which the API is getting imported. |
+| `isCurrent` | bool | `True` | | Optional. Indicates if API revision is current API revision. |
+| `name` | string | | | Required. API revision identifier. Must be unique in the current API Management service instance. Non-current revision has ;rev=n as a suffix where n is the revision number. |
+| `path` | string | | | Required. Relative URL uniquely identifying this API and all of its resource paths within the API Management service instance. It is appended to the API endpoint base URL specified during the service instance creation to form a public URL for this API. |
+| `policies` | _[policies](policies/readme.md)_ array | `[]` | | Optional. Array of Policies to apply to the Service API. |
+| `protocols` | array | `[https]` | | Optional. Describes on which protocols the operations in this API can be invoked. - HTTP or HTTPS |
+| `serviceUrl` | string | | | Optional. Absolute URL of the backend service implementing this API. Cannot be more than 2000 characters long. |
+| `sourceApiId` | string | | | Optional. API identifier of the source API. |
+| `subscriptionKeyParameterNames` | object | `{object}` | | Optional. Protocols over which API is made available. |
+| `subscriptionRequired` | bool | | | Optional. Specifies whether an API or Product subscription is required for accessing the API. |
+| `type` | string | `http` | `[http, soap]` | Optional. Type of API. |
+| `value` | string | | | Optional. Content value when Importing an API. |
+| `wsdlSelector` | object | `{object}` | | Optional. Criteria to limit import of WSDL to a subset of the document. |
+
+### Parameter Usage: `apiVersionSet`
+
+```json
+"apiVersionSet":{
+ "value":{
+ "name":"", //Required. API Version Set identifier. Must be unique in the current API Management service instance.
+ "properties":{
+ "description": "string", //Description of API Version Set.
+ "versionQueryName": "string", //Optional. Name of query parameter that indicates the API Version if versioningScheme is set to query.
+ "versionHeaderName": "string", //Optional. Name of HTTP header parameter that indicates the API Version if versioningScheme is set to header.
+ "displayName": "string", //Required. Name of API Version Set
+ "versioningScheme": "string" //Required. An value that determines where the API Version identifer will be located in a HTTP request. - Segment, Query, Header
+ }
+ }
+}
+```
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The name of the API management service API |
+| `resourceGroupName` | string | The resource group the API management service API was deployed to |
+| `resourceId` | string | The resource ID of the API management service API |
+
+## Template references
+
+- [Service/Apis](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2021-08-01/service/apis)
+- [Service/Apis/Policies](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2021-08-01/service/apis/policies)
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/apis/version.json b/carml/1.0.0/Microsoft.ApiManagement/service/apis/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/apis/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/authorizationServers/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/authorizationServers/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/authorizationServers/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/authorizationServers/deploy.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/authorizationServers/deploy.bicep
new file mode 100644
index 000000000..4296f8108
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/authorizationServers/deploy.bicep
@@ -0,0 +1,107 @@
+@description('Required. Identifier of the authorization server.')
+param name string
+
+@description('Required. The name of the of the API Management service.')
+param apiManagementServiceName string
+
+@description('Required. OAuth authorization endpoint. See .')
+param authorizationEndpoint string
+
+@description('Optional. HTTP verbs supported by the authorization endpoint. GET must be always present. POST is optional. - HEAD, OPTIONS, TRACE, GET, POST, PUT, PATCH, DELETE')
+param authorizationMethods array = [
+ 'GET'
+]
+
+@description('Optional. Specifies the mechanism by which access token is passed to the API. - authorizationHeader or query')
+param bearerTokenSendingMethods array = [
+ 'authorizationHeader'
+]
+
+@description('Optional. Method of authentication supported by the token endpoint of this authorization server. Possible values are Basic and/or Body. When Body is specified, client credentials and other parameters are passed within the request body in the application/x-www-form-urlencoded format. - Basic or Body')
+param clientAuthenticationMethod array = [
+ 'Basic'
+]
+
+@description('Required. Client or app ID registered with this authorization server.')
+@secure()
+param clientId string
+
+@description('Optional. Optional reference to a page where client or app registration for this authorization server is performed. Contains absolute URL to entity being referenced.')
+param clientRegistrationEndpoint string = ''
+
+@description('Required. Client or app secret registered with this authorization server. This property will not be filled on \'GET\' operations! Use \'/listSecrets\' POST request to get the value.')
+@secure()
+param clientSecret string
+
+@description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered')
+param cuaId string = ''
+
+@description('Optional. Access token scope that is going to be requested by default. Can be overridden at the API level. Should be provided in the form of a string containing space-delimited values.')
+param defaultScope string = ''
+
+@description('Optional. Description of the authorization server. Can contain HTML formatting tags.')
+param serverDescription string = ''
+
+@description('Required. Form of an authorization grant, which the client uses to request the access token. - authorizationCode, implicit, resourceOwnerPassword, clientCredentials')
+param grantTypes array
+
+@description('Optional. Can be optionally specified when resource owner password grant type is supported by this authorization server. Default resource owner password.')
+param resourceOwnerPassword string = ''
+
+@description('Optional. Can be optionally specified when resource owner password grant type is supported by this authorization server. Default resource owner username.')
+param resourceOwnerUsername string = ''
+
+@description('Optional. If true, authorization server will include state parameter from the authorization request to its response. Client may use state parameter to raise protocol security.')
+param supportState bool = false
+
+@description('Optional. Additional parameters required by the token endpoint of this authorization server represented as an array of JSON objects with name and value string properties, i.e. {"name" : "name value", "value": "a value"}. - TokenBodyParameterContract object')
+param tokenBodyParameters array = []
+
+@description('Optional. OAuth token endpoint. Contains absolute URI to entity being referenced.')
+param tokenEndpoint string = ''
+
+var defaultAuthorizationMethods = [
+ 'GET'
+]
+var setAuthorizationMethods = union(authorizationMethods, defaultAuthorizationMethods)
+
+module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) {
+ name: 'pid-${cuaId}'
+ params: {}
+}
+
+resource service 'Microsoft.ApiManagement/service@2021-08-01' existing = {
+ name: apiManagementServiceName
+}
+
+resource authorizationServer 'Microsoft.ApiManagement/service/authorizationServers@2021-08-01' = {
+ name: name
+ parent: service
+ properties: {
+ description: serverDescription
+ authorizationMethods: setAuthorizationMethods
+ clientAuthenticationMethod: clientAuthenticationMethod
+ tokenBodyParameters: tokenBodyParameters
+ tokenEndpoint: tokenEndpoint
+ supportState: supportState
+ defaultScope: defaultScope
+ bearerTokenSendingMethods: bearerTokenSendingMethods
+ resourceOwnerUsername: resourceOwnerUsername
+ resourceOwnerPassword: resourceOwnerPassword
+ displayName: name
+ clientRegistrationEndpoint: clientRegistrationEndpoint
+ authorizationEndpoint: authorizationEndpoint
+ grantTypes: grantTypes
+ clientId: clientId
+ clientSecret: clientSecret
+ }
+}
+
+@description('The name of the API management service authorization server')
+output name string = authorizationServer.name
+
+@description('The resource ID of the API management service authorization server')
+output resourceId string = authorizationServer.id
+
+@description('The resource group the API management service authorization server was deployed into')
+output resourceGroupName string = resourceGroup().name
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/authorizationServers/readme.md b/carml/1.0.0/Microsoft.ApiManagement/service/authorizationServers/readme.md
new file mode 100644
index 000000000..17429c386
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/authorizationServers/readme.md
@@ -0,0 +1,50 @@
+# API Management Service Authorization Servers `[Microsoft.ApiManagement/service/authorizationServers]`
+
+This module deploys API Management Service Authorization Servers.
+
+## Resource types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.ApiManagement/service/authorizationServers` | 2021-08-01 |
+
+### Resource dependency
+
+The following resources are required to be able to deploy this resource.
+
+- `Microsoft.ApiManagement/service`
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `apiManagementServiceName` | string | | | Required. The name of the of the API Management service. |
+| `authorizationEndpoint` | string | | | Required. OAuth authorization endpoint. See . |
+| `authorizationMethods` | array | `[GET]` | | Optional. HTTP verbs supported by the authorization endpoint. GET must be always present. POST is optional. - HEAD, OPTIONS, TRACE, GET, POST, PUT, PATCH, DELETE |
+| `bearerTokenSendingMethods` | array | `[authorizationHeader]` | | Optional. Specifies the mechanism by which access token is passed to the API. - authorizationHeader or query |
+| `clientAuthenticationMethod` | array | `[Basic]` | | Optional. Method of authentication supported by the token endpoint of this authorization server. Possible values are Basic and/or Body. When Body is specified, client credentials and other parameters are passed within the request body in the application/x-www-form-urlencoded format. - Basic or Body |
+| `clientId` | secureString | | | Required. Client or app ID registered with this authorization server. |
+| `clientRegistrationEndpoint` | string | | | Optional. Optional reference to a page where client or app registration for this authorization server is performed. Contains absolute URL to entity being referenced. |
+| `clientSecret` | secureString | | | Required. Client or app secret registered with this authorization server. This property will not be filled on 'GET' operations! Use '/listSecrets' POST request to get the value. |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered |
+| `defaultScope` | string | | | Optional. Access token scope that is going to be requested by default. Can be overridden at the API level. Should be provided in the form of a string containing space-delimited values. |
+| `grantTypes` | array | | | Required. Form of an authorization grant, which the client uses to request the access token. - authorizationCode, implicit, resourceOwnerPassword, clientCredentials |
+| `name` | string | | | Required. Identifier of the authorization server. |
+| `resourceOwnerPassword` | string | | | Optional. Can be optionally specified when resource owner password grant type is supported by this authorization server. Default resource owner password. |
+| `resourceOwnerUsername` | string | | | Optional. Can be optionally specified when resource owner password grant type is supported by this authorization server. Default resource owner username. |
+| `serverDescription` | string | | | Optional. Description of the authorization server. Can contain HTML formatting tags. |
+| `supportState` | bool | | | Optional. If true, authorization server will include state parameter from the authorization request to its response. Client may use state parameter to raise protocol security. |
+| `tokenBodyParameters` | array | `[]` | | Optional. Additional parameters required by the token endpoint of this authorization server represented as an array of JSON objects with name and value string properties, i.e. {"name" : "name value", "value": "a value"}. - TokenBodyParameterContract object |
+| `tokenEndpoint` | string | | | Optional. OAuth token endpoint. Contains absolute URI to entity being referenced. |
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The name of the API management service authorization server |
+| `resourceGroupName` | string | The resource group the API management service authorization server was deployed into |
+| `resourceId` | string | The resource ID of the API management service authorization server |
+
+## Template references
+
+- [Service/Authorizationservers](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2021-08-01/service/authorizationServers)
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/authorizationServers/version.json b/carml/1.0.0/Microsoft.ApiManagement/service/authorizationServers/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/authorizationServers/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/backends/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/backends/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/backends/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/backends/deploy.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/backends/deploy.bicep
new file mode 100644
index 000000000..f588942ad
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/backends/deploy.bicep
@@ -0,0 +1,74 @@
+@description('Required. The name of the of the API Management service.')
+param apiManagementServiceName string
+
+@description('Required. Backend Name.')
+param name string
+
+@description('Optional. Backend Credentials Contract Properties.')
+param credentials object = {}
+
+@description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered')
+param cuaId string = ''
+
+@description('Optional. Backend Description.')
+param backendDescription string = ''
+
+@description('Optional. Backend communication protocol. - http or soap')
+param protocol string = 'http'
+
+@description('Optional. Backend Proxy Contract Properties')
+param proxy object = {}
+
+@description('Optional. Management Uri of the Resource in External System. This URL can be the Arm Resource ID of Logic Apps, Function Apps or API Apps.')
+param resourceId string = ''
+
+@description('Optional. Backend Service Fabric Cluster Properties.')
+param serviceFabricCluster object = {}
+
+@description('Optional. Backend Title.')
+param title string = ''
+
+@description('Optional. Backend TLS Properties')
+param tls object = {
+ validateCertificateChain: false
+ validateCertificateName: false
+}
+
+@description('Required. Runtime URL of the Backend.')
+param url string
+
+module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) {
+ name: 'pid-${cuaId}'
+ params: {}
+}
+
+resource service 'Microsoft.ApiManagement/service@2021-08-01' existing = {
+ name: apiManagementServiceName
+}
+
+resource backend 'Microsoft.ApiManagement/service/backends@2021-08-01' = {
+ name: name
+ parent: service
+ properties: {
+ title: !empty(title) ? title : null
+ description: !empty(backendDescription) ? backendDescription : null
+ resourceId: !empty(resourceId) ? resourceId : null
+ properties: {
+ serviceFabricCluster: !empty(serviceFabricCluster) ? serviceFabricCluster : null
+ }
+ credentials: !empty(credentials) ? credentials : null
+ proxy: !empty(proxy) ? proxy : null
+ tls: !empty(tls) ? tls : null
+ url: url
+ protocol: protocol
+ }
+}
+
+@description('The resource ID of the API management service backend')
+output resourceId string = backend.id
+
+@description('The name of the API management service backend')
+output name string = backend.name
+
+@description('The resource group the API management service backend was deployed into')
+output resourceGroupName string = resourceGroup().name
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/backends/readme.md b/carml/1.0.0/Microsoft.ApiManagement/service/backends/readme.md
new file mode 100644
index 000000000..fcb1eb25d
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/backends/readme.md
@@ -0,0 +1,131 @@
+# API Management Service Backends `[Microsoft.ApiManagement/service/backends]`
+
+This module deploys API Management Service Backends.
+
+## Resource types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.ApiManagement/service/backends` | 2021-08-01 |
+
+### Resource dependency
+
+The following resources are required to be able to deploy this resource.
+
+- `Microsoft.ApiManagement/service`
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `apiManagementServiceName` | string | | | Required. The name of the of the API Management service. |
+| `backendDescription` | string | | | Optional. Backend Description. |
+| `credentials` | object | `{object}` | | Optional. Backend Credentials Contract Properties. |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered |
+| `name` | string | | | Required. Backend Name. |
+| `protocol` | string | `http` | | Optional. Backend communication protocol. - http or soap |
+| `proxy` | object | `{object}` | | Optional. Backend Proxy Contract Properties |
+| `resourceId` | string | | | Optional. Management Uri of the Resource in External System. This URL can be the Arm Resource ID of Logic Apps, Function Apps or API Apps. |
+| `serviceFabricCluster` | object | `{object}` | | Optional. Backend Service Fabric Cluster Properties. |
+| `title` | string | | | Optional. Backend Title. |
+| `tls` | object | `{object}` | | Optional. Backend TLS Properties |
+| `url` | string | | | Required. Runtime URL of the Backend. |
+
+### Parameters - credentials
+
+| Parameter Name| Type | Default Value | Possible values | Description |
+| :-- | :-- | :--- | :-- | :- |
+| `certificate` | array | | | Optional. List of Client Certificate Thumbprint. - string |
+| `query` | object | | | Optional. Query Parameter description. |
+| `header` | object | | | Optional. Header Parameter description. |
+| `authorization` | object | | | Optional. Authorization header authentication |
+
+### Parameter Usage: `credentials`
+
+```json
+"credentials": {
+ "value":{
+ "certificate": [
+ "string"
+ ],
+ "query": {},
+ "header": {},
+ "authorization": {
+ "scheme": "Authentication Scheme name.-string",
+ "parameter": "Authentication Parameter value. - string"
+ }
+ }
+}
+```
+
+### Parameter Usage: `proxy`
+
+| Parameter Name | Type | Default Value | Possible values | Description |
+| :- | :- | :- | :- | :- |
+| `url` | string | | | WebProxy Server AbsoluteUri property which includes the entire URI stored in the URI instance, including all fragments and query strings.|
+| `username` | string | | | Username to connect to the WebProxy server|
+| `password`| string | | | Password to connect to the WebProxy Server|
+
+```json
+"proxy": {
+ "value":{
+ "url": "string",
+ "username": "string",
+ "password": "string"
+ }
+}
+```
+
+### Parameter Usage: `serviceFabricCluster`
+
+| Parameter Name | Type | Default Value | Possible values | Description |
+| :-- | :-- | :--- | :-- | :- |
+| `clientCertificatethumbprint` | string | | | Required (if this object is used).The client certificate thumbprint for the management endpoint.|
+| `maxPartitionResolutionRetries` | integer | | | Optional. Maximum number of retries while attempting resolve the partition. |
+| `managementEndpoints` | array | | | Required (if this object is used). The cluster management endpoint. - string|
+| `serverCertificateThumbprints`| array | | | Optional. Thumbprints of certificates cluster management service uses for TLS communication - string|
+| `serverX509Names` | array | | | Optional. Server X509 Certificate Names Collection|
+
+```json
+"serviceFabricCluster": {
+ "value":{
+ "clientCertificatethumbprint": "string",
+ "maxPartitionResolutionRetries": "integer",
+ "managementEndpoints": [
+ "string"
+ ],
+ "serverCertificateThumbprints": [
+ "string"
+ ],
+ "serverX509Names": [
+ {
+ "name": "Common Name of the Certificate.- string",
+ "issuerCertificateThumbprint": "Thumbprint for the Issuer of the Certificate. - string"
+ }
+ ]
+ }
+}
+```
+
+### Parameter Usage: `tls`
+
+```json
+"tls": {
+ "value":{
+ "validateCertificateChain": "Flag indicating whether SSL certificate chain validation should be done when using self-signed certificates for this backend host. - boolean",
+ "validateCertificateName": "Flag indicating whether SSL certificate name validation should be done when using self-signed certificates for this backend host. - boolean"
+ }
+}
+```
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The name of the API management service backend |
+| `resourceGroupName` | string | The resource group the API management service backend was deployed into |
+| `resourceId` | string | The resource ID of the API management service backend |
+
+## Template references
+
+- [Service/Backends](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2021-08-01/service/backends)
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/backends/version.json b/carml/1.0.0/Microsoft.ApiManagement/service/backends/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/backends/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/caches/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/caches/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/caches/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/caches/deploy.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/caches/deploy.bicep
new file mode 100644
index 000000000..d3cd88147
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/caches/deploy.bicep
@@ -0,0 +1,49 @@
+@description('Required. The name of the of the API Management service.')
+param apiManagementServiceName string
+
+@description('Required. Identifier of the Cache entity. Cache identifier (should be either \'default\' or valid Azure region identifier).')
+param name string
+
+@description('Required. Runtime connection string to cache. Can be referenced by a named value like so, {{}}')
+param connectionString string
+
+@description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered')
+param cuaId string = ''
+
+@description('Optional. Cache description')
+param cacheDescription string = ''
+
+@description('Optional. Original uri of entity in external system cache points to.')
+param resourceId string = ''
+
+@description('Required. Location identifier to use cache from (should be either \'default\' or valid Azure region identifier)')
+param useFromLocation string
+
+module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) {
+ name: 'pid-${cuaId}'
+ params: {}
+}
+
+resource service 'Microsoft.ApiManagement/service@2021-08-01' existing = {
+ name: apiManagementServiceName
+}
+
+resource cache 'Microsoft.ApiManagement/service/caches@2021-08-01' = {
+ name: name
+ parent: service
+ properties: {
+ description: !empty(cacheDescription) ? cacheDescription : null
+ connectionString: connectionString
+ useFromLocation: useFromLocation
+ resourceId: !empty(resourceId) ? resourceId : null
+ }
+}
+
+@description('The resource ID of the API management service cache')
+output resourceId string = cache.id
+
+@description('The name of the API management service cache')
+output name string = cache.name
+
+@description('The resource group the API management service cache was deployed into')
+output resourceGroupName string = resourceGroup().name
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/caches/readme.md b/carml/1.0.0/Microsoft.ApiManagement/service/caches/readme.md
new file mode 100644
index 000000000..78f948c8f
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/caches/readme.md
@@ -0,0 +1,39 @@
+# API Management Service Cache `[Microsoft.ApiManagement/service/caches]`
+
+This module deploys an API Management Service Cache.
+
+## Resource types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.ApiManagement/service/caches` | 2021-08-01 |
+
+### Resource dependency
+
+The following resources are required to be able to deploy this resource.
+
+- `Microsoft.ApiManagement/service`
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `apiManagementServiceName` | string | | | Required. The name of the of the API Management service. |
+| `cacheDescription` | string | | | Optional. Cache description |
+| `connectionString` | string | | | Required. Runtime connection string to cache. Can be referenced by a named value like so, {{}} |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered |
+| `name` | string | | | Required. Identifier of the Cache entity. Cache identifier (should be either 'default' or valid Azure region identifier). |
+| `resourceId` | string | | | Optional. Original uri of entity in external system cache points to. |
+| `useFromLocation` | string | | | Required. Location identifier to use cache from (should be either 'default' or valid Azure region identifier) |
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The name of the API management service cache |
+| `resourceGroupName` | string | The resource group the API management service cache was deployed into |
+| `resourceId` | string | The resource ID of the API management service cache |
+
+## Template references
+
+- [Service/Caches](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2021-08-01/service/caches)
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/caches/version.json b/carml/1.0.0/Microsoft.ApiManagement/service/caches/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/caches/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/deploy.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/deploy.bicep
new file mode 100644
index 000000000..347272115
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/deploy.bicep
@@ -0,0 +1,440 @@
+@description('Optional. Additional datacenter locations of the API Management service.')
+param additionalLocations array = []
+
+@description('Required. The name of the of the API Management service.')
+param name string
+
+@description('Optional. List of Certificates that need to be installed in the API Management service. Max supported certificates that can be installed is 10.')
+@maxLength(10)
+param certificates array = []
+
+@description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered')
+param cuaId string = ''
+
+@description('Optional. Custom properties of the API Management service.')
+param customProperties object = {}
+
+@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. Property only valid for an API Management service deployed in multiple locations. This can be used to disable the gateway in master region.')
+param disableGateway bool = false
+
+@description('Optional. Property only meant to be used for Consumption SKU Service. This enforces a client certificate to be presented on each request to the gateway. This also enables the ability to authenticate the certificate in the policy on the gateway.')
+param enableClientCertificate bool = false
+
+@description('Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to.')
+param diagnosticEventHubAuthorizationRuleId string = ''
+
+@description('Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category.')
+param diagnosticEventHubName string = ''
+
+@description('Optional. Custom hostname configuration of the API Management service.')
+param hostnameConfigurations array = []
+
+@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. Location for all Resources.')
+param location string = resourceGroup().location
+
+@allowed([
+ 'CanNotDelete'
+ 'NotSpecified'
+ 'ReadOnly'
+])
+@description('Optional. Specify the type of lock.')
+param lock string = 'NotSpecified'
+
+@description('Optional. Limit control plane API calls to API Management service with version equal to or newer than this value.')
+param minApiVersion string = ''
+
+@description('Optional. The notification sender email address for the service.')
+param notificationSenderEmail string = 'apimgmt-noreply@mail.windowsazure.com'
+
+@description('Required. The email address of the owner of the service.')
+param publisherEmail string
+
+@description('Required. The name of the owner of the service.')
+param publisherName string
+
+@description('Optional. Undelete API Management Service if it was previously soft-deleted. If this flag is specified and set to True all other properties will be ignored.')
+param restore bool = false
+
+@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. The pricing tier of this API Management service.')
+@allowed([
+ 'Consumption'
+ 'Developer'
+ 'Basic'
+ 'Standard'
+ 'Premium'
+])
+param sku string = 'Developer'
+
+@description('Optional. The instance size of this API Management service.')
+@allowed([
+ 1
+ 2
+])
+param skuCount int = 1
+
+@description('Optional. The full resource ID of a subnet in a virtual network to deploy the API Management service in.')
+param subnetResourceId string = ''
+
+@description('Optional. Tags of the resource.')
+param tags object = {}
+
+@description('Optional. The type of VPN in which API Management service needs to be configured in. None (Default Value) means the API Management service is not part of any Virtual Network, External means the API Management deployment is set up inside a Virtual Network having an internet Facing Endpoint, and Internal means that API Management deployment is setup inside a Virtual Network having an Intranet Facing Endpoint only.')
+@allowed([
+ 'None'
+ 'External'
+ 'Internal'
+])
+param virtualNetworkType string = 'None'
+
+@description('Optional. Resource ID of the diagnostic log analytics workspace.')
+param diagnosticWorkspaceId string = ''
+
+@description('Optional. A list of availability zones denoting where the resource needs to come from.')
+param zones array = []
+
+@description('Optional. The name of logs that will be streamed.')
+@allowed([
+ 'GatewayLogs'
+])
+param logsToEnable array = [
+ 'GatewayLogs'
+]
+
+@description('Optional. The name of metrics that will be streamed.')
+@allowed([
+ 'AllMetrics'
+])
+param metricsToEnable array = [
+ 'AllMetrics'
+]
+@description('Optional. Necessary to create a new GUID.')
+param newGuidValue string = newGuid()
+
+@description('Optional. APIs.')
+param apis array = []
+@description('Optional. API Version Sets.')
+param apiVersionSets array = []
+@description('Optional. Authorization servers.')
+param authorizationServers array = []
+@description('Optional. Backends.')
+param backends array = []
+@description('Optional. Caches.')
+param caches array = []
+@description('Optional. Identity providers.')
+param identityProviders array = []
+@description('Optional. Named values.')
+param namedValues array = []
+@description('Optional. Policies.')
+param policies array = []
+@description('Optional. Portal settings.')
+param portalSettings array = []
+@description('Optional. Products.')
+param products array = []
+@description('Optional. Subscriptions.')
+param subscriptions array = []
+
+var diagnosticsLogs = [for log in logsToEnable: {
+ category: log
+ enabled: true
+ retentionPolicy: {
+ enabled: true
+ days: diagnosticLogsRetentionInDays
+ }
+}]
+
+var diagnosticsMetrics = [for metric in metricsToEnable: {
+ category: metric
+ timeGrain: null
+ enabled: true
+ retentionPolicy: {
+ enabled: true
+ days: diagnosticLogsRetentionInDays
+ }
+}]
+
+var 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 apiManagementService 'Microsoft.ApiManagement/service@2021-08-01' = {
+ name: name
+ location: location
+ tags: tags
+ sku: {
+ name: sku
+ capacity: skuCount
+ }
+ zones: zones
+ identity: identity
+ properties: {
+ publisherEmail: publisherEmail
+ publisherName: publisherName
+ notificationSenderEmail: notificationSenderEmail
+ hostnameConfigurations: hostnameConfigurations
+ additionalLocations: additionalLocations
+ customProperties: customProperties
+ certificates: certificates
+ enableClientCertificate: enableClientCertificate ? true : null
+ disableGateway: disableGateway
+ virtualNetworkType: virtualNetworkType
+ virtualNetworkConfiguration: !empty(subnetResourceId) ? json('{"subnetResourceId": "${subnetResourceId}"}') : null
+ apiVersionConstraint: !empty(minApiVersion) ? json('{"minApiVersion": "${minApiVersion}"}') : null
+ restore: restore
+ }
+}
+
+module apis_resource 'apis/deploy.bicep' = [for (api, index) in apis: {
+ name: '${uniqueString(deployment().name, location)}-Apim-Api-${index}'
+ params: {
+ apiManagementServiceName: apiManagementService.name
+ displayName: api.displayName
+ name: api.name
+ path: api.path
+ apiDescription: contains(api, 'apiDescription') ? api.apiDescription : ''
+ apiRevision: contains(api, 'apiRevision') ? api.apiRevision : ''
+ apiRevisionDescription: contains(api, 'apiRevisionDescription') ? api.apiRevisionDescription : ''
+ apiType: contains(api, 'apiType') ? api.apiType : 'http'
+ apiVersion: contains(api, 'apiVersion') ? api.apiVersion : ''
+ apiVersionDescription: contains(api, 'apiVersionDescription') ? api.apiVersionDescription : ''
+ apiVersionSetId: contains(api, 'apiVersionSetId') ? api.apiVersionSetId : ''
+ authenticationSettings: contains(api, 'authenticationSettings') ? api.authenticationSettings : {}
+ format: contains(api, 'format') ? api.format : 'openapi'
+ isCurrent: contains(api, 'isCurrent') ? api.isCurrent : true
+ protocols: contains(api, 'protocols') ? api.protocols : [
+ 'https'
+ ]
+ policies: contains(api, 'policies') ? api.policies : []
+ serviceUrl: contains(api, 'serviceUrl') ? api.serviceUrl : ''
+ sourceApiId: contains(api, 'sourceApiId') ? api.sourceApiId : ''
+ subscriptionKeyParameterNames: contains(api, 'subscriptionKeyParameterNames') ? api.subscriptionKeyParameterNames : {}
+ subscriptionRequired: contains(api, 'subscriptionRequired') ? api.subscriptionRequired : false
+ type: contains(api, 'type') ? api.type : 'http'
+ value: contains(api, 'value') ? api.value : ''
+ wsdlSelector: contains(api, 'wsdlSelector') ? api.wsdlSelector : {}
+ }
+ dependsOn: [
+ apiVersionSet_resource
+ ]
+}]
+
+module apiVersionSet_resource 'apiVersionSets/deploy.bicep' = [for (apiVersionSet, index) in apiVersionSets: {
+ name: '${uniqueString(deployment().name, location)}-Apim-ApiVersionSet-${index}'
+ params: {
+ apiManagementServiceName: apiManagementService.name
+ name: apiVersionSet.name
+ properties: contains(apiVersionSet, 'properties') ? apiVersionSet.properties : {}
+ }
+}]
+
+module authorizationServers_resource '.bicep/nested_authorizationServers.bicep' = [for (authorizationServer, index) in authorizationServers: {
+ name: '${uniqueString(deployment().name, location)}-Apim-AuthorizationServer-${index}'
+ params: {
+ apiManagementServiceName: apiManagementService.name
+ name: authorizationServer.name
+ authorizationEndpoint: authorizationServer.authorizationEndpoint
+ authorizationMethods: contains(authorizationServer, 'authorizationMethods') ? authorizationServer.authorizationMethods : [
+ 'GET'
+ ]
+ bearerTokenSendingMethods: contains(authorizationServer, 'bearerTokenSendingMethods') ? authorizationServer.bearerTokenSendingMethods : [
+ 'authorizationHeader'
+ ]
+ clientAuthenticationMethod: contains(authorizationServer, 'clientAuthenticationMethod') ? authorizationServer.clientAuthenticationMethod : [
+ 'Basic'
+ ]
+ clientCredentialsKeyVaultId: authorizationServer.clientCredentialsKeyVaultId
+ clientIdSecretName: authorizationServer.clientIdSecretName
+ clientSecretSecretName: authorizationServer.clientSecretSecretName
+ clientRegistrationEndpoint: contains(authorizationServer, 'clientRegistrationEndpoint') ? authorizationServer.clientRegistrationEndpoint : ''
+ defaultScope: contains(authorizationServer, 'defaultScope') ? authorizationServer.defaultScope : ''
+ grantTypes: authorizationServer.grantTypes
+ resourceOwnerPassword: contains(authorizationServer, 'resourceOwnerPassword') ? authorizationServer.resourceOwnerPassword : ''
+ resourceOwnerUsername: contains(authorizationServer, 'resourceOwnerUsername') ? authorizationServer.resourceOwnerUsername : ''
+ serverDescription: contains(authorizationServer, 'serverDescription') ? authorizationServer.serverDescription : ''
+ supportState: contains(authorizationServer, 'supportState') ? authorizationServer.supportState : false
+ tokenBodyParameters: contains(authorizationServer, 'tokenBodyParameters') ? authorizationServer.tokenBodyParameters : []
+ tokenEndpoint: contains(authorizationServer, 'tokenEndpoint') ? authorizationServer.tokenEndpoint : ''
+ }
+}]
+
+module backends_resource 'backends/deploy.bicep' = [for (backend, index) in backends: {
+ name: '${uniqueString(deployment().name, location)}-Apim-Backend-${index}'
+ params: {
+ apiManagementServiceName: apiManagementService.name
+ url: contains(backend, 'url') ? backend.url : ''
+ backendDescription: contains(backend, 'backendDescription') ? backend.backendDescription : ''
+ credentials: contains(backend, 'credentials') ? backend.credentials : {}
+ name: backend.name
+ protocol: contains(backend, 'protocol') ? backend.protocol : 'http'
+ proxy: contains(backend, 'proxy') ? backend.proxy : {}
+ resourceId: contains(backend, 'resourceId') ? backend.resourceId : ''
+ serviceFabricCluster: contains(backend, 'serviceFabricCluster') ? backend.serviceFabricCluster : {}
+ title: contains(backend, 'title') ? backend.title : ''
+ tls: contains(backend, 'tls') ? backend.tls : {
+ validateCertificateChain: false
+ validateCertificateName: false
+ }
+ }
+}]
+
+module caches_resource 'caches/deploy.bicep' = [for (cache, index) in caches: {
+ name: '${uniqueString(deployment().name, location)}-Apim-Cache-${index}'
+ params: {
+ apiManagementServiceName: apiManagementService.name
+ cacheDescription: contains(cache, 'cacheDescription') ? cache.cacheDescription : ''
+ connectionString: cache.connectionString
+ name: cache.name
+ resourceId: contains(cache, 'resourceId') ? cache.resourceId : ''
+ useFromLocation: cache.useFromLocation
+ }
+}]
+
+module identityProvider_resource 'identityProviders/deploy.bicep' = [for (identityProvider, index) in identityProviders: {
+ name: '${uniqueString(deployment().name, location)}-Apim-IdentityProvider-${index}'
+ params: {
+ apiManagementServiceName: apiManagementService.name
+ name: identityProvider.name
+ enableIdentityProviders: contains(identityProvider, 'enableIdentityProviders') ? identityProvider.enableIdentityProviders : false
+ identityProviderAllowedTenants: contains(identityProvider, 'identityProviderAllowedTenants') ? identityProvider.identityProviderAllowedTenants : []
+ identityProviderAuthority: contains(identityProvider, 'identityProviderAuthority') ? identityProvider.identityProviderAuthority : ''
+ identityProviderClientId: contains(identityProvider, 'identityProviderClientId') ? identityProvider.identityProviderClientId : ''
+ identityProviderClientSecret: contains(identityProvider, 'identityProviderClientSecret') ? identityProvider.identityProviderClientSecret : ''
+ identityProviderPasswordResetPolicyName: contains(identityProvider, 'identityProviderPasswordResetPolicyName') ? identityProvider.identityProviderPasswordResetPolicyName : ''
+ identityProviderProfileEditingPolicyName: contains(identityProvider, 'identityProviderProfileEditingPolicyName') ? identityProvider.identityProviderProfileEditingPolicyName : ''
+ identityProviderSignInPolicyName: contains(identityProvider, 'identityProviderSignInPolicyName') ? identityProvider.identityProviderSignInPolicyName : ''
+ identityProviderSignInTenant: contains(identityProvider, 'identityProviderSignInTenant') ? identityProvider.identityProviderSignInTenant : ''
+ identityProviderSignUpPolicyName: contains(identityProvider, 'identityProviderSignUpPolicyName') ? identityProvider.identityProviderSignUpPolicyName : ''
+ identityProviderType: contains(identityProvider, 'identityProviderType') ? identityProvider.identityProviderType : 'aad'
+ }
+}]
+
+module namedValues_resource 'namedValues/deploy.bicep' = [for (namedValue, index) in namedValues: {
+ name: '${uniqueString(deployment().name, location)}-Apim-NamedValue-${index}'
+ params: {
+ apiManagementServiceName: apiManagementService.name
+ displayName: namedValue.displayName
+ keyVault: contains(namedValue, 'keyVault') ? namedValue.keyVault : {}
+ name: namedValue.name
+ namedValueTags: contains(namedValue, 'namedValueTags') ? namedValue.namedValueTags : []
+ secret: contains(namedValue, 'secret') ? namedValue.secret : false
+ value: contains(namedValue, 'value') ? namedValue.value : newGuidValue
+ }
+}]
+
+module portalSettings_resource 'portalsettings/deploy.bicep' = [for (portalSetting, index) in portalSettings: {
+ name: '${uniqueString(deployment().name, location)}-Apim-PortalSetting-${index}'
+ params: {
+ apiManagementServiceName: apiManagementService.name
+ name: portalSetting.name
+ properties: contains(portalSetting, 'properties') ? portalSetting.properties : {}
+ }
+}]
+
+module policy_resource 'policies/deploy.bicep' = [for (policy, index) in policies: {
+ name: '${uniqueString(deployment().name, location)}-Apim-Policy-${index}'
+ params: {
+ apiManagementServiceName: apiManagementService.name
+ value: policy.value
+ format: contains(policy, 'format') ? policy.format : 'xml'
+ }
+}]
+
+module products_resource 'products/deploy.bicep' = [for (product, index) in products: {
+ name: '${uniqueString(deployment().name, location)}-Apim-Product-${index}'
+ params: {
+ apiManagementServiceName: apiManagementService.name
+ apis: contains(product, 'apis') ? product.apis : []
+ approvalRequired: contains(product, 'approvalRequired') ? product.approvalRequired : false
+ groups: contains(product, 'groups') ? product.groups : []
+ name: product.name
+ productDescription: contains(product, 'productDescription') ? product.productDescription : ''
+ state: contains(product, 'state') ? product.state : 'published'
+ subscriptionRequired: contains(product, 'subscriptionRequired') ? product.subscriptionRequired : false
+ subscriptionsLimit: contains(product, 'subscriptionsLimit') ? product.subscriptionsLimit : 1
+ terms: contains(product, 'terms') ? product.terms : ''
+ }
+ dependsOn: [
+ apis_resource
+ ]
+}]
+
+module subscriptions_resource 'subscriptions/deploy.bicep' = [for (subscription, index) in subscriptions: {
+ name: '${uniqueString(deployment().name, location)}-Apim-Subscription-${index}'
+ params: {
+ apiManagementServiceName: apiManagementService.name
+ name: contains(subscription, 'name') ? subscription.name : ''
+ allowTracing: contains(subscription, 'allowTracing') ? subscription.allowTracing : false
+ ownerId: contains(subscription, 'ownerId') ? subscription.ownerId : ''
+ primaryKey: contains(subscription, 'primaryKey') ? subscription.primaryKey : ''
+ scope: contains(subscription, 'scope') ? subscription.scope : '/apis'
+ secondaryKey: contains(subscription, 'secondaryKey') ? subscription.secondaryKey : ''
+ state: contains(subscription, 'state') ? subscription.state : ''
+ }
+}]
+
+resource apiManagementService_lock 'Microsoft.Authorization/locks@2017-04-01' = if (lock != 'NotSpecified') {
+ name: '${apiManagementService.name}-${lock}-lock'
+ properties: {
+ level: lock
+ notes: lock == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot modify the resource or child resources.'
+ }
+ scope: apiManagementService
+}
+
+resource apiManagementService_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if (!empty(diagnosticStorageAccountId) || !empty(diagnosticWorkspaceId) || !empty(diagnosticEventHubAuthorizationRuleId) || !empty(diagnosticEventHubName)) {
+ name: '${apiManagementService.name}-diagnosticSettings'
+ properties: {
+ storageAccountId: !empty(diagnosticStorageAccountId) ? diagnosticStorageAccountId : null
+ workspaceId: !empty(diagnosticWorkspaceId) ? diagnosticWorkspaceId : null
+ eventHubAuthorizationRuleId: !empty(diagnosticEventHubAuthorizationRuleId) ? diagnosticEventHubAuthorizationRuleId : null
+ eventHubName: !empty(diagnosticEventHubName) ? diagnosticEventHubName : null
+ metrics: diagnosticsMetrics
+ logs: diagnosticsLogs
+ }
+ scope: apiManagementService
+}
+
+module apiManagementService_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: {
+ name: '${uniqueString(deployment().name, location)}-Apim-Rbac-${index}'
+ params: {
+ principalIds: roleAssignment.principalIds
+ roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName
+ resourceId: apiManagementService.id
+ }
+}]
+
+@description('The name of the API management service')
+output name string = apiManagementService.name
+
+@description('The resource ID of the API management service')
+output resourceId string = apiManagementService.id
+
+@description('The resource group the API management service was deployed into')
+output resourceGroupName string = resourceGroup().name
+
+@description('The principal ID of the system assigned identity.')
+output systemAssignedPrincipalId string = systemAssignedIdentity && contains(apiManagementService.identity, 'principalId') ? apiManagementService.identity.principalId : ''
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/identityProviders/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/identityProviders/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/identityProviders/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/identityProviders/deploy.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/identityProviders/deploy.bicep
new file mode 100644
index 000000000..d872e9ac0
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/identityProviders/deploy.bicep
@@ -0,0 +1,87 @@
+@description('Required. The name of the of the API Management service.')
+param apiManagementServiceName string
+
+@description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered')
+param cuaId string = ''
+
+@description('Optional. Used to enable the deployment of the identityProviders child resource.')
+param enableIdentityProviders bool = false
+
+@description('Optional. List of Allowed Tenants when configuring Azure Active Directory login. - string')
+param identityProviderAllowedTenants array = []
+
+@description('Optional. OpenID Connect discovery endpoint hostname for AAD or AAD B2C.')
+param identityProviderAuthority string = ''
+
+@description('Optional. Client ID of the Application in the external Identity Provider. Required if identity provider is used.')
+param identityProviderClientId string = ''
+
+@description('Optional. Client secret of the Application in external Identity Provider, used to authenticate login request. Required if identity provider is used.')
+@secure()
+param identityProviderClientSecret string = ''
+
+@description('Optional. Password Reset Policy Name. Only applies to AAD B2C Identity Provider.')
+param identityProviderPasswordResetPolicyName string = ''
+
+@description('Optional. Profile Editing Policy Name. Only applies to AAD B2C Identity Provider.')
+param identityProviderProfileEditingPolicyName string = ''
+
+@description('Optional. Signin Policy Name. Only applies to AAD B2C Identity Provider.')
+param identityProviderSignInPolicyName string = ''
+
+@description('Optional. The TenantId to use instead of Common when logging into Active Directory')
+param identityProviderSignInTenant string = ''
+
+@description('Optional. Signup Policy Name. Only applies to AAD B2C Identity Provider.')
+param identityProviderSignUpPolicyName string = ''
+
+@description('Optional. Identity Provider Type identifier.')
+@allowed([
+ 'aad'
+ 'aadB2C'
+ 'facebook'
+ 'google'
+ 'microsoft'
+ 'twitter'
+])
+param identityProviderType string = 'aad'
+
+@description('Required. Identity provider name')
+param name string
+
+var isAadB2C = (identityProviderType == 'aadB2C')
+
+module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) {
+ name: 'pid-${cuaId}'
+ params: {}
+}
+
+resource service 'Microsoft.ApiManagement/service@2021-08-01' existing = {
+ name: apiManagementServiceName
+}
+
+resource identityProvider 'Microsoft.ApiManagement/service/identityProviders@2021-08-01' = if (enableIdentityProviders) {
+ name: name
+ parent: service
+ properties: {
+ type: identityProviderType
+ signinTenant: identityProviderSignInTenant
+ allowedTenants: identityProviderAllowedTenants
+ authority: identityProviderAuthority
+ signupPolicyName: isAadB2C ? identityProviderSignUpPolicyName : null
+ signinPolicyName: isAadB2C ? identityProviderSignInPolicyName : null
+ profileEditingPolicyName: isAadB2C ? identityProviderProfileEditingPolicyName : null
+ passwordResetPolicyName: isAadB2C ? identityProviderPasswordResetPolicyName : null
+ clientId: identityProviderClientId
+ clientSecret: identityProviderClientSecret
+ }
+}
+
+@description('The resource ID of the API management service identity provider')
+output resourceId string = identityProvider.id
+
+@description('The name of the API management service identity provider')
+output name string = identityProvider.name
+
+@description('The resource group the API management service identity provider was deployed into')
+output resourceGroupName string = resourceGroup().name
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/identityProviders/readme.md b/carml/1.0.0/Microsoft.ApiManagement/service/identityProviders/readme.md
new file mode 100644
index 000000000..3f24fd36d
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/identityProviders/readme.md
@@ -0,0 +1,40 @@
+# API Management Service Identity Providers `[Microsoft.ApiManagement/service/identityProviders]`
+
+This module deploys API Management Service Identity Provider.
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.ApiManagement/service/identityProviders` | 2021-08-01 |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `apiManagementServiceName` | string | | | Required. The name of the of the API Management service. |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered |
+| `enableIdentityProviders` | bool | | | Optional. Used to enable the deployment of the identityProviders child resource. |
+| `identityProviderAllowedTenants` | array | `[]` | | Optional. List of Allowed Tenants when configuring Azure Active Directory login. - string |
+| `identityProviderAuthority` | string | | | Optional. OpenID Connect discovery endpoint hostname for AAD or AAD B2C. |
+| `identityProviderClientId` | string | | | Optional. Client ID of the Application in the external Identity Provider. Required if identity provider is used. |
+| `identityProviderClientSecret` | secureString | | | Optional. Client secret of the Application in external Identity Provider, used to authenticate login request. Required if identity provider is used. |
+| `identityProviderPasswordResetPolicyName` | string | | | Optional. Password Reset Policy Name. Only applies to AAD B2C Identity Provider. |
+| `identityProviderProfileEditingPolicyName` | string | | | Optional. Profile Editing Policy Name. Only applies to AAD B2C Identity Provider. |
+| `identityProviderSignInPolicyName` | string | | | Optional. Signin Policy Name. Only applies to AAD B2C Identity Provider. |
+| `identityProviderSignInTenant` | string | | | Optional. The TenantId to use instead of Common when logging into Active Directory |
+| `identityProviderSignUpPolicyName` | string | | | Optional. Signup Policy Name. Only applies to AAD B2C Identity Provider. |
+| `identityProviderType` | string | `aad` | `[aad, aadB2C, facebook, google, microsoft, twitter]` | Optional. Identity Provider Type identifier. |
+| `name` | string | | | Required. Identity provider name |
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The name of the API management service identity provider |
+| `resourceGroupName` | string | The resource group the API management service identity provider was deployed into |
+| `resourceId` | string | The resource ID of the API management service identity provider |
+
+## Template references
+
+- [Service/Identityproviders](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2021-08-01/service/identityProviders)
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/identityProviders/version.json b/carml/1.0.0/Microsoft.ApiManagement/service/identityProviders/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/identityProviders/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/namedValues/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/namedValues/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/namedValues/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/policies/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/policies/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/policies/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/policies/deploy.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/policies/deploy.bicep
new file mode 100644
index 000000000..727aa22ed
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/policies/deploy.bicep
@@ -0,0 +1,47 @@
+@description('Required. The name of the of the API Management service.')
+param apiManagementServiceName string
+
+@description('Optional. The name of the policy')
+param name string = 'policy'
+
+@description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered')
+param cuaId string = ''
+
+@description('Optional. Format of the policyContent.')
+@allowed([
+ 'rawxml'
+ 'rawxml-link'
+ 'xml'
+ 'xml-link'
+])
+param format string = 'xml'
+
+@description('Required. Contents of the Policy as defined by the format.')
+param value string
+
+module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) {
+ name: 'pid-${cuaId}'
+ params: {}
+}
+
+resource service 'Microsoft.ApiManagement/service@2021-08-01' existing = {
+ name: apiManagementServiceName
+}
+
+resource policy 'Microsoft.ApiManagement/service/policies@2021-08-01' = {
+ name: name
+ parent: service
+ properties: {
+ format: format
+ value: value
+ }
+}
+
+@description('The resource ID of the API management service policy')
+output resourceId string = policy.id
+
+@description('The name of the API management service policy')
+output name string = policy.name
+
+@description('The resource group the API management service policy was deployed into')
+output resourceGroupName string = resourceGroup().name
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/policies/readme.md b/carml/1.0.0/Microsoft.ApiManagement/service/policies/readme.md
new file mode 100644
index 000000000..b6cefab6c
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/policies/readme.md
@@ -0,0 +1,31 @@
+# API Management Service Policies `[Microsoft.ApiManagement/service/policies]`
+
+This module deploys API Management Service Policy.
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.ApiManagement/service/policies` | 2021-08-01 |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `apiManagementServiceName` | string | | | Required. The name of the of the API Management service. |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered |
+| `format` | string | `xml` | `[rawxml, rawxml-link, xml, xml-link]` | Optional. Format of the policyContent. |
+| `name` | string | `policy` | | Optional. The name of the policy |
+| `value` | string | | | Required. Contents of the Policy as defined by the format. |
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The name of the API management service policy |
+| `resourceGroupName` | string | The resource group the API management service policy was deployed into |
+| `resourceId` | string | The resource ID of the API management service policy |
+
+## Template references
+
+- [Service/Policies](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2021-08-01/service/policies)
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/policies/version.json b/carml/1.0.0/Microsoft.ApiManagement/service/policies/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/policies/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/portalsettings/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/portalsettings/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/portalsettings/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/portalsettings/deploy.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/portalsettings/deploy.bicep
new file mode 100644
index 000000000..63b3f8255
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/portalsettings/deploy.bicep
@@ -0,0 +1,40 @@
+@description('Required. The name of the of the API Management service.')
+param apiManagementServiceName string
+
+@description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered')
+param cuaId string = ''
+
+@description('Required. Portal setting name')
+@allowed([
+ 'delegation'
+ 'signin'
+ 'signup'
+])
+param name string
+
+@description('Optional. Portal setting properties.')
+param properties object = {}
+
+module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) {
+ name: 'pid-${cuaId}'
+ params: {}
+}
+
+resource service 'Microsoft.ApiManagement/service@2021-08-01' existing = {
+ name: apiManagementServiceName
+}
+
+resource portalSetting 'Microsoft.ApiManagement/service/portalsettings@2021-08-01' = if (!empty(properties)) {
+ name: any(name)
+ parent: service
+ properties: properties
+}
+
+@description('The resource ID of the API management service portal setting')
+output resourceId string = portalSetting.id
+
+@description('The name of the API management service portal setting')
+output name string = portalSetting.name
+
+@description('The resource group the API management service portal setting was deployed into')
+output resourceGroupName string = resourceGroup().name
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/portalsettings/readme.md b/carml/1.0.0/Microsoft.ApiManagement/service/portalsettings/readme.md
new file mode 100644
index 000000000..912d8918b
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/portalsettings/readme.md
@@ -0,0 +1,30 @@
+# API Management Service Portal Settings `[Microsoft.ApiManagement/service/portalsettings]`
+
+This module deploys API Management Service Portal Setting.
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.ApiManagement/service/portalsettings` | 2021-08-01 |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `apiManagementServiceName` | string | | | Required. The name of the of the API Management service. |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered |
+| `name` | string | | `[delegation, signin, signup]` | Required. Portal setting name |
+| `properties` | object | `{object}` | | Optional. Portal setting properties. |
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The name of the API management service portal setting |
+| `resourceGroupName` | string | The resource group the API management service portal setting was deployed into |
+| `resourceId` | string | The resource ID of the API management service portal setting |
+
+## Template references
+
+- ['service/portalsettings' Parent Documentation](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/service)
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/portalsettings/version.json b/carml/1.0.0/Microsoft.ApiManagement/service/portalsettings/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/portalsettings/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/products/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/products/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/products/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/products/apis/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/products/apis/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/products/apis/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/products/apis/deploy.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/products/apis/deploy.bicep
new file mode 100644
index 000000000..416285c15
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/products/apis/deploy.bicep
@@ -0,0 +1,38 @@
+@description('Required. The name of the of the API Management service.')
+param apiManagementServiceName string
+
+@description('Required. The name of the of the Product.')
+param productName string
+
+@description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered')
+param cuaId string = ''
+
+@description('Required. Name of the product API.')
+param name string
+
+module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) {
+ name: 'pid-${cuaId}'
+ params: {}
+}
+
+resource service 'Microsoft.ApiManagement/service@2021-08-01' existing = {
+ name: apiManagementServiceName
+
+ resource product 'products@2021-04-01-preview' existing = {
+ name: productName
+ }
+}
+
+resource api 'Microsoft.ApiManagement/service/products/apis@2021-08-01' = {
+ name: name
+ parent: service::product
+}
+
+@description('The resource ID of the product API')
+output resourceId string = api.id
+
+@description('The name of the product API')
+output name string = api.name
+
+@description('The resource group the product API was deployed into')
+output resourceGroupName string = resourceGroup().name
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/products/apis/readme.md b/carml/1.0.0/Microsoft.ApiManagement/service/products/apis/readme.md
new file mode 100644
index 000000000..ff50366e0
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/products/apis/readme.md
@@ -0,0 +1,30 @@
+# API Management Service Products APIs `[Microsoft.ApiManagement/service/products/apis]`
+
+This module deploys API Management Service Product APIs.
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.ApiManagement/service/products/apis` | 2021-08-01 |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `apiManagementServiceName` | string | | | Required. The name of the of the API Management service. |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered |
+| `name` | string | | | Required. Name of the product API. |
+| `productName` | string | | | Required. The name of the of the Product. |
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The name of the product API |
+| `resourceGroupName` | string | The resource group the product API was deployed into |
+| `resourceId` | string | The resource ID of the product API |
+
+## Template references
+
+- [Service/Products/Apis](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2021-08-01/service/products/apis)
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/products/apis/version.json b/carml/1.0.0/Microsoft.ApiManagement/service/products/apis/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/products/apis/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/products/deploy.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/products/deploy.bicep
new file mode 100644
index 000000000..6c5fd141a
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/products/deploy.bicep
@@ -0,0 +1,88 @@
+@description('Required. The name of the of the API Management service.')
+param apiManagementServiceName string
+
+@description('Optional. Whether subscription approval is required. If false, new subscriptions will be approved automatically enabling developers to call the products APIs immediately after subscribing. If true, administrators must manually approve the subscription before the developer can any of the products APIs. Can be present only if subscriptionRequired property is present and has a value of false.')
+param approvalRequired bool = false
+
+@description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered')
+param cuaId string = ''
+
+@description('Optional. Product description. May include HTML formatting tags.')
+param productDescription string = ''
+
+@description('Optional. Array of Product APIs.')
+param apis array = []
+
+@description('Optional. Array of Product Groups.')
+param groups array = []
+
+@description('Required. Product Name.')
+param name string
+
+@description('Optional. whether product is published or not. Published products are discoverable by users of developer portal. Non published products are visible only to administrators. Default state of Product is notPublished. - notPublished or published')
+param state string = 'published'
+
+@description('Optional. Whether a product subscription is required for accessing APIs included in this product. If true, the product is referred to as "protected" and a valid subscription key is required for a request to an API included in the product to succeed. If false, the product is referred to as "open" and requests to an API included in the product can be made without a subscription key. If property is omitted when creating a new product it\'s value is assumed to be true.')
+param subscriptionRequired bool = false
+
+@description('Optional. Whether the number of subscriptions a user can have to this product at the same time. Set to null or omit to allow unlimited per user subscriptions. Can be present only if subscriptionRequired property is present and has a value of false.')
+param subscriptionsLimit int = 1
+
+@description('Optional. Product terms of use. Developers trying to subscribe to the product will be presented and required to accept these terms before they can complete the subscription process.')
+param terms string = ''
+
+module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) {
+ name: 'pid-${cuaId}'
+ params: {}
+}
+
+resource service 'Microsoft.ApiManagement/service@2021-08-01' existing = {
+ name: apiManagementServiceName
+}
+
+resource product 'Microsoft.ApiManagement/service/products@2021-08-01' = {
+ name: name
+ parent: service
+ properties: {
+ description: productDescription
+ displayName: name
+ terms: terms
+ subscriptionRequired: subscriptionRequired
+ approvalRequired: subscriptionRequired ? approvalRequired : null
+ subscriptionsLimit: subscriptionRequired ? subscriptionsLimit : null
+ state: state
+ }
+}
+
+module product_apis 'apis/deploy.bicep' = [for (api, index) in apis: {
+ name: '${deployment().name}-Api-${index}'
+ params: {
+ apiManagementServiceName: apiManagementServiceName
+ name: api.name
+ productName: name
+ }
+}]
+
+module product_groups 'groups/deploy.bicep' = [for (group, index) in groups: {
+ name: '${deployment().name}-Group-${index}'
+ params: {
+ apiManagementServiceName: apiManagementServiceName
+ name: group.name
+ productName: name
+ }
+}]
+
+@description('The resource ID of the API management service product')
+output resourceId string = product.id
+
+@description('The name of the API management service product')
+output name string = product.name
+
+@description('The resource group the API management service product was deployed into')
+output resourceGroupName string = resourceGroup().name
+
+@description('The Resources IDs of the API management service product APIs')
+output apiResourceIds array = [for index in range(0, length(apis)): product_apis[index].outputs.resourceId]
+
+@description('The Resources IDs of the API management service product groups')
+output groupResourceIds array = [for index in range(0, length(groups)): product_groups[index].outputs.resourceId]
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/products/groups/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/products/groups/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/products/groups/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/products/groups/deploy.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/products/groups/deploy.bicep
new file mode 100644
index 000000000..e65409637
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/products/groups/deploy.bicep
@@ -0,0 +1,38 @@
+@description('Required. The name of the of the API Management service.')
+param apiManagementServiceName string
+
+@description('Required. The name of the of the Product.')
+param productName string
+
+@description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered')
+param cuaId string = ''
+
+@description('Required. Name of the product group.')
+param name string
+
+module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) {
+ name: 'pid-${cuaId}'
+ params: {}
+}
+
+resource service 'Microsoft.ApiManagement/service@2021-08-01' existing = {
+ name: apiManagementServiceName
+
+ resource product 'products@2021-04-01-preview' existing = {
+ name: productName
+ }
+}
+
+resource group 'Microsoft.ApiManagement/service/products/groups@2021-08-01' = {
+ name: name
+ parent: service::product
+}
+
+@description('The resource ID of the product group')
+output resourceId string = group.id
+
+@description('The name of the product group')
+output name string = group.name
+
+@description('The resource group the product group was deployed into')
+output resourceGroupName string = resourceGroup().name
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/products/groups/readme.md b/carml/1.0.0/Microsoft.ApiManagement/service/products/groups/readme.md
new file mode 100644
index 000000000..63ea7a723
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/products/groups/readme.md
@@ -0,0 +1,30 @@
+# API Management Service Products Groups `[Microsoft.ApiManagement/service/products/groups]`
+
+This module deploys API Management Service Product Groups.
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.ApiManagement/service/products/groups` | 2021-08-01 |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `apiManagementServiceName` | string | | | Required. The name of the of the API Management service. |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered |
+| `name` | string | | | Required. Name of the product group. |
+| `productName` | string | | | Required. The name of the of the Product. |
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The name of the product group |
+| `resourceGroupName` | string | The resource group the product group was deployed into |
+| `resourceId` | string | The resource ID of the product group |
+
+## Template references
+
+- [Service/Products/Groups](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2021-08-01/service/products/groups)
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/products/groups/version.json b/carml/1.0.0/Microsoft.ApiManagement/service/products/groups/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/products/groups/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/products/readme.md b/carml/1.0.0/Microsoft.ApiManagement/service/products/readme.md
new file mode 100644
index 000000000..9026f639f
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/products/readme.md
@@ -0,0 +1,49 @@
+# API Management Service Products `[Microsoft.ApiManagement/service/products]`
+
+This module deploys API Management Service Products.
+
+## Resource types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.ApiManagement/service/products` | 2021-08-01 |
+| `Microsoft.ApiManagement/service/products/apis` | 2021-08-01 |
+| `Microsoft.ApiManagement/service/products/groups` | 2021-08-01 |
+
+### Resource dependency
+
+The following resources are required to be able to deploy this resource.
+
+- `Microsoft.ApiManagement/service`
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `apiManagementServiceName` | string | | | Required. The name of the of the API Management service. |
+| `apis` | _[apis](apis/readme.md)_ array | `[]` | | Optional. Array of Product APIs. |
+| `approvalRequired` | bool | | | Optional. Whether subscription approval is required. If false, new subscriptions will be approved automatically enabling developers to call the products APIs immediately after subscribing. If true, administrators must manually approve the subscription before the developer can any of the products APIs. Can be present only if subscriptionRequired property is present and has a value of false. |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered |
+| `groups` | _[groups](groups/readme.md)_ array | `[]` | | Optional. Array of Product Groups. |
+| `name` | string | | | Required. Product Name. |
+| `productDescription` | string | | | Optional. Product description. May include HTML formatting tags. |
+| `state` | string | `published` | | Optional. whether product is published or not. Published products are discoverable by users of developer portal. Non published products are visible only to administrators. Default state of Product is notPublished. - notPublished or published |
+| `subscriptionRequired` | bool | | | Optional. Whether a product subscription is required for accessing APIs included in this product. If true, the product is referred to as "protected" and a valid subscription key is required for a request to an API included in the product to succeed. If false, the product is referred to as "open" and requests to an API included in the product can be made without a subscription key. If property is omitted when creating a new product it's value is assumed to be true. |
+| `subscriptionsLimit` | int | `1` | | Optional. Whether the number of subscriptions a user can have to this product at the same time. Set to null or omit to allow unlimited per user subscriptions. Can be present only if subscriptionRequired property is present and has a value of false. |
+| `terms` | string | | | Optional. Product terms of use. Developers trying to subscribe to the product will be presented and required to accept these terms before they can complete the subscription process. |
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `apiResourceIds` | array | The Resources IDs of the API management service product APIs |
+| `groupResourceIds` | array | The Resources IDs of the API management service product groups |
+| `name` | string | The name of the API management service product |
+| `resourceGroupName` | string | The resource group the API management service product was deployed into |
+| `resourceId` | string | The resource ID of the API management service product |
+
+## Template references
+
+- [Service/Products](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2021-08-01/service/products)
+- [Service/Products/Apis](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2021-08-01/service/products/apis)
+- [Service/Products/Groups](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2021-08-01/service/products/groups)
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/products/version.json b/carml/1.0.0/Microsoft.ApiManagement/service/products/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/products/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/readme.md b/carml/1.0.0/Microsoft.ApiManagement/service/readme.md
new file mode 100644
index 000000000..59b0616fa
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/readme.md
@@ -0,0 +1,171 @@
+# API Management Services `[Microsoft.ApiManagement/service]`
+
+This module deploys an API management service.
+
+## Resource types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.ApiManagement/service` | 2021-08-01 |
+| `Microsoft.ApiManagement/service/apis` | 2021-08-01 |
+| `Microsoft.ApiManagement/service/apis/policies` | 2021-08-01 |
+| `Microsoft.ApiManagement/service/apiVersionSets` | 2021-08-01 |
+| `Microsoft.ApiManagement/service/authorizationServers` | 2021-08-01 |
+| `Microsoft.ApiManagement/service/backends` | 2021-08-01 |
+| `Microsoft.ApiManagement/service/caches` | 2021-08-01 |
+| `Microsoft.ApiManagement/service/identityProviders` | 2021-08-01 |
+| `Microsoft.ApiManagement/service/namedValues` | 2021-08-01 |
+| `Microsoft.ApiManagement/service/policies` | 2021-08-01 |
+| `Microsoft.ApiManagement/service/portalsettings` | 2021-08-01 |
+| `Microsoft.ApiManagement/service/products` | 2021-08-01 |
+| `Microsoft.ApiManagement/service/products/apis` | 2021-08-01 |
+| `Microsoft.ApiManagement/service/products/groups` | 2021-08-01 |
+| `Microsoft.ApiManagement/service/subscriptions` | 2021-08-01 |
+| `Microsoft.Authorization/locks` | 2017-04-01 |
+| `Microsoft.Authorization/roleAssignments` | 2021-04-01-preview |
+| `Microsoft.Insights/diagnosticSettings` | 2021-05-01-preview |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `additionalLocations` | array | `[]` | | Optional. Additional datacenter locations of the API Management service. |
+| `apis` | _[apis](apis/readme.md)_ array | `[]` | | Optional. APIs. |
+| `apiVersionSets` | _[apiVersionSets](apiVersionSets/readme.md)_ array | `[]` | | Optional. API Version Sets. |
+| `authorizationServers` | _[authorizationServers](authorizationServers/readme.md)_ array | `[]` | | Optional. Authorization servers. |
+| `backends` | _[backends](backends/readme.md)_ array | `[]` | | Optional. Backends. |
+| `caches` | _[caches](caches/readme.md)_ array | `[]` | | Optional. Caches. |
+| `certificates` | array | `[]` | | Optional. List of Certificates that need to be installed in the API Management service. Max supported certificates that can be installed is 10. |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered |
+| `customProperties` | object | `{object}` | | Optional. Custom properties of the API Management service. |
+| `diagnosticEventHubAuthorizationRuleId` | string | | | Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. |
+| `diagnosticEventHubName` | string | | | Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. |
+| `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. |
+| `diagnosticWorkspaceId` | string | | | Optional. Resource ID of the diagnostic log analytics workspace. |
+| `disableGateway` | bool | | | Optional. Property only valid for an API Management service deployed in multiple locations. This can be used to disable the gateway in master region. |
+| `enableClientCertificate` | bool | | | Optional. Property only meant to be used for Consumption SKU Service. This enforces a client certificate to be presented on each request to the gateway. This also enables the ability to authenticate the certificate in the policy on the gateway. |
+| `hostnameConfigurations` | array | `[]` | | Optional. Custom hostname configuration of the API Management service. |
+| `identityProviders` | _[identityProviders](identityProviders/readme.md)_ array | `[]` | | Optional. Identity providers. |
+| `location` | string | `[resourceGroup().location]` | | Optional. Location for all Resources. |
+| `lock` | string | `NotSpecified` | `[CanNotDelete, NotSpecified, ReadOnly]` | Optional. Specify the type of lock. |
+| `logsToEnable` | array | `[GatewayLogs]` | `[GatewayLogs]` | Optional. The name of logs that will be streamed. |
+| `metricsToEnable` | array | `[AllMetrics]` | `[AllMetrics]` | Optional. The name of metrics that will be streamed. |
+| `minApiVersion` | string | | | Optional. Limit control plane API calls to API Management service with version equal to or newer than this value. |
+| `name` | string | | | Required. The name of the of the API Management service. |
+| `namedValues` | _[namedValues](namedValues/readme.md)_ array | `[]` | | Optional. Named values. |
+| `newGuidValue` | string | `[newGuid()]` | | Optional. Necessary to create a new GUID. |
+| `notificationSenderEmail` | string | `apimgmt-noreply@mail.windowsazure.com` | | Optional. The notification sender email address for the service. |
+| `policies` | _[policies](policies/readme.md)_ array | `[]` | | Optional. Policies. |
+| `portalSettings` | _[portalSettings](portalSettings/readme.md)_ array | `[]` | | Optional. Portal settings. |
+| `products` | _[products](products/readme.md)_ array | `[]` | | Optional. Products. |
+| `publisherEmail` | string | | | Required. The email address of the owner of the service. |
+| `publisherName` | string | | | Required. The name of the owner of the service. |
+| `restore` | bool | | | Optional. Undelete API Management Service if it was previously soft-deleted. If this flag is specified and set to True all other properties will be ignored. |
+| `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' |
+| `sku` | string | `Developer` | `[Consumption, Developer, Basic, Standard, Premium]` | Optional. The pricing tier of this API Management service. |
+| `skuCount` | int | `1` | `[1, 2]` | Optional. The instance size of this API Management service. |
+| `subnetResourceId` | string | | | Optional. The full resource ID of a subnet in a virtual network to deploy the API Management service in. |
+| `subscriptions` | _[subscriptions](subscriptions/readme.md)_ array | `[]` | | Optional. Subscriptions. |
+| `systemAssignedIdentity` | bool | | | Optional. Enables system assigned managed identity on the resource. |
+| `tags` | object | `{object}` | | Optional. Tags of the resource. |
+| `userAssignedIdentities` | object | `{object}` | | Optional. The ID(s) to assign to the resource. |
+| `virtualNetworkType` | string | `None` | `[None, External, Internal]` | Optional. The type of VPN in which API Management service needs to be configured in. None (Default Value) means the API Management service is not part of any Virtual Network, External means the API Management deployment is set up inside a Virtual Network having an internet Facing Endpoint, and Internal means that API Management deployment is setup inside a Virtual Network having an Intranet Facing Endpoint only. |
+| `zones` | array | `[]` | | Optional. A list of availability zones denoting where the resource needs to come from. |
+
+### Parameter Usage: `roleAssignments`
+
+```json
+"roleAssignments": {
+ "value": [
+ {
+ "roleDefinitionIdOrName": "Reader",
+ "principalIds": [
+ "12345678-1234-1234-1234-123456789012", // object 1
+ "78945612-1234-1234-1234-123456789012" // object 2
+ ]
+ },
+ {
+ "roleDefinitionIdOrName": "/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11",
+ "principalIds": [
+ "12345678-1234-1234-1234-123456789012" // object 1
+ ]
+ }
+ ]
+}
+```
+
+### 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: `apiManagementServicePolicy`
+
+```Json
+"apiManagementServicePolicy": {
+ "value": {
+ "value":" ",
+ "format":"xml"
+ }
+}
+```
+
+### 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 |
+| :-- | :-- | :-- |
+| `name` | string | The name of the API management service |
+| `resourceGroupName` | string | The resource group the API management service was deployed into |
+| `resourceId` | string | The resource ID of the API management service |
+| `systemAssignedPrincipalId` | string | The principal ID of the system assigned identity. |
+
+## Considerations
+
+- *None*
+
+## 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/2017-04-01/locks)
+- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/roleAssignments)
+- [Service](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2021-08-01/service)
+- [Service/Apis](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2021-08-01/service/apis)
+- [Service/Apis/Policies](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2021-08-01/service/apis/policies)
+- [Service/Apiversionsets](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2021-08-01/service/apiVersionSets)
+- [Service/Authorizationservers](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2021-08-01/service/authorizationServers)
+- [Service/Backends](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2021-08-01/service/backends)
+- [Service/Caches](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2021-08-01/service/caches)
+- [Service/Identityproviders](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2021-08-01/service/identityProviders)
+- [Service/Namedvalues](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2021-08-01/service/namedValues)
+- [Service/Policies](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2021-08-01/service/policies)
+- [Service/Products](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2021-08-01/service/products)
+- [Service/Products/Apis](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2021-08-01/service/products/apis)
+- [Service/Products/Groups](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2021-08-01/service/products/groups)
+- [Service/Subscriptions](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2021-08-01/service/subscriptions)
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/subscriptions/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/subscriptions/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/subscriptions/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/subscriptions/deploy.bicep b/carml/1.0.0/Microsoft.ApiManagement/service/subscriptions/deploy.bicep
new file mode 100644
index 000000000..0c7d4cc81
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/subscriptions/deploy.bicep
@@ -0,0 +1,58 @@
+@description('Optional. Determines whether tracing can be enabled.')
+param allowTracing bool = true
+
+@description('Required. The name of the of the API Management service.')
+param apiManagementServiceName string
+
+@description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered')
+param cuaId string = ''
+
+@description('Optional. User (user ID path) for whom subscription is being created in form /users/{userId}')
+param ownerId string = ''
+
+@description('Optional. Primary subscription key. If not specified during request key will be generated automatically.')
+param primaryKey string = ''
+
+@description('Optional. Scope type to choose between a product, "allAPIs" or a specific API. Scope like "/products/{productId}" or "/apis" or "/apis/{apiId}".')
+param scope string = '/apis'
+
+@description('Optional. Secondary subscription key. If not specified during request key will be generated automatically.')
+param secondaryKey string = ''
+
+@description('Optional. Initial subscription state. If no value is specified, subscription is created with Submitted state. Possible states are "*" active "?" the subscription is active, "*" suspended "?" the subscription is blocked, and the subscriber cannot call any APIs of the product, * submitted ? the subscription request has been made by the developer, but has not yet been approved or rejected, * rejected ? the subscription request has been denied by an administrator, * cancelled ? the subscription has been cancelled by the developer or administrator, * expired ? the subscription reached its expiration date and was deactivated. - suspended, active, expired, submitted, rejected, cancelled')
+param state string = ''
+
+@description('Required. Subscription name.')
+param name string
+
+module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) {
+ name: 'pid-${cuaId}'
+ params: {}
+}
+
+resource service 'Microsoft.ApiManagement/service@2021-08-01' existing = {
+ name: apiManagementServiceName
+}
+
+resource subscription 'Microsoft.ApiManagement/service/subscriptions@2021-08-01' = {
+ name: name
+ parent: service
+ properties: {
+ scope: scope
+ displayName: name
+ ownerId: !empty(ownerId) ? ownerId : null
+ primaryKey: !empty(primaryKey) ? primaryKey : null
+ secondaryKey: !empty(secondaryKey) ? secondaryKey : null
+ state: !empty(state) ? state : null
+ allowTracing: allowTracing
+ }
+}
+
+@description('The resource ID of the API management service subscription')
+output resourceId string = subscription.id
+
+@description('The name of the API management service subscription')
+output name string = subscription.name
+
+@description('The resource group the API management service subscription was deployed into')
+output resourceGroupName string = resourceGroup().name
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/subscriptions/readme.md b/carml/1.0.0/Microsoft.ApiManagement/service/subscriptions/readme.md
new file mode 100644
index 000000000..9b3bd6414
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/subscriptions/readme.md
@@ -0,0 +1,41 @@
+# API Management Subscriptions `[Microsoft.ApiManagement/service/subscriptions]`
+
+This module deploys API Management Subscriptions.
+
+## Resource types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.ApiManagement/service/subscriptions` | 2021-08-01 |
+
+### Resource dependency
+
+The following resources are required to be able to deploy this resource.
+
+- `Microsoft.ApiManagement/service`
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `allowTracing` | bool | `True` | | Optional. Determines whether tracing can be enabled. |
+| `apiManagementServiceName` | string | | | Required. The name of the of the API Management service. |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered |
+| `name` | string | | | Required. Subscription name. |
+| `ownerId` | string | | | Optional. User (user ID path) for whom subscription is being created in form /users/{userId} |
+| `primaryKey` | string | | | Optional. Primary subscription key. If not specified during request key will be generated automatically. |
+| `scope` | string | `/apis` | | Optional. Scope type to choose between a product, "allAPIs" or a specific API. Scope like "/products/{productId}" or "/apis" or "/apis/{apiId}". |
+| `secondaryKey` | string | | | Optional. Secondary subscription key. If not specified during request key will be generated automatically. |
+| `state` | string | | | Optional. Initial subscription state. If no value is specified, subscription is created with Submitted state. Possible states are "*" active "?" the subscription is active, "*" suspended "?" the subscription is blocked, and the subscriber cannot call any APIs of the product, * submitted ? the subscription request has been made by the developer, but has not yet been approved or rejected, * rejected ? the subscription request has been denied by an administrator, * cancelled ? the subscription has been cancelled by the developer or administrator, * expired ? the subscription reached its expiration date and was deactivated. - suspended, active, expired, submitted, rejected, cancelled |
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The name of the API management service subscription |
+| `resourceGroupName` | string | The resource group the API management service subscription was deployed into |
+| `resourceId` | string | The resource ID of the API management service subscription |
+
+## Template references
+
+- [Service/Subscriptions](https://docs.microsoft.com/en-us/azure/templates/Microsoft.ApiManagement/2021-08-01/service/subscriptions)
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/subscriptions/version.json b/carml/1.0.0/Microsoft.ApiManagement/service/subscriptions/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/subscriptions/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.ApiManagement/service/version.json b/carml/1.0.0/Microsoft.ApiManagement/service/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.ApiManagement/service/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policyAssignments/.parameters/mg.min.parameters.json b/carml/1.0.0/Microsoft.Authorization/policyAssignments/.parameters/mg.min.parameters.json
new file mode 100644
index 000000000..7271e1d83
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyAssignments/.parameters/mg.min.parameters.json
@@ -0,0 +1,12 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-min-mg-polAss"
+ },
+ "policyDefinitionID": {
+ "value": "/providers/Microsoft.Authorization/policyDefinitions/06a78e20-9358-41c9-923c-fb736d382a4d"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policyAssignments/.parameters/mg.parameters.json b/carml/1.0.0/Microsoft.Authorization/policyAssignments/.parameters/mg.parameters.json
new file mode 100644
index 000000000..f140b8c7e
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyAssignments/.parameters/mg.parameters.json
@@ -0,0 +1,59 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-mg-polAss"
+ },
+ "displayName": {
+ "value": "[Display Name] Policy Assignment at the management group scope"
+ },
+ "description": {
+ "value": "[Description] Policy Assignment at the management group scope"
+ },
+ "policyDefinitionId": {
+ "value": "/providers/Microsoft.Authorization/policyDefinitions/4f9dc7db-30c1-420c-b61a-e1d640128d26"
+ },
+ "parameters": {
+ "value": {
+ "tagName": {
+ "value": "env"
+ },
+ "tagValue": {
+ "value": "prod"
+ }
+ }
+ },
+ "nonComplianceMessage": {
+ "value": "Violated Policy Assignment - This is a Non Compliance Message"
+ },
+ "enforcementMode": {
+ "value": "DoNotEnforce"
+ },
+ "metadata": {
+ "value": {
+ "category": "Security",
+ "version": "1.0"
+ }
+ },
+ "location": {
+ "value": "australiaeast"
+ },
+ "notScopes": {
+ "value": [
+ "/subscriptions/<>/resourceGroups/validation-rg"
+ ]
+ },
+ "identity": {
+ "value": "SystemAssigned"
+ },
+ "roleDefinitionIds": {
+ "value": [
+ "/providers/microsoft.authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c"
+ ]
+ },
+ "managementGroupId": {
+ "value": "<>"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policyAssignments/.parameters/rg.min.parameters.json b/carml/1.0.0/Microsoft.Authorization/policyAssignments/.parameters/rg.min.parameters.json
new file mode 100644
index 000000000..de4e5052a
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyAssignments/.parameters/rg.min.parameters.json
@@ -0,0 +1,18 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-min-rg-polAss"
+ },
+ "policyDefinitionID": {
+ "value": "/providers/Microsoft.Authorization/policyDefinitions/06a78e20-9358-41c9-923c-fb736d382a4d"
+ },
+ "subscriptionId": {
+ "value": "<>"
+ },
+ "resourceGroupName": {
+ "value": "<>"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policyAssignments/.parameters/rg.parameters.json b/carml/1.0.0/Microsoft.Authorization/policyAssignments/.parameters/rg.parameters.json
new file mode 100644
index 000000000..e28b39cfd
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyAssignments/.parameters/rg.parameters.json
@@ -0,0 +1,62 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-rg-polAss"
+ },
+ "displayName": {
+ "value": "[Display Name] Policy Assignment at the resource group scope"
+ },
+ "description": {
+ "value": "[Description] Policy Assignment at the resource group scope"
+ },
+ "policyDefinitionId": {
+ "value": "/providers/Microsoft.Authorization/policyDefinitions/4f9dc7db-30c1-420c-b61a-e1d640128d26"
+ },
+ "parameters": {
+ "value": {
+ "tagName": {
+ "value": "env"
+ },
+ "tagValue": {
+ "value": "prod"
+ }
+ }
+ },
+ "nonComplianceMessage": {
+ "value": "Violated Policy Assignment - This is a Non Compliance Message"
+ },
+ "enforcementMode": {
+ "value": "DoNotEnforce"
+ },
+ "metadata": {
+ "value": {
+ "category": "Security",
+ "version": "1.0"
+ }
+ },
+ "location": {
+ "value": "australiaeast"
+ },
+ "notScopes": {
+ "value": [
+ "/subscriptions/<>/resourceGroups/<>/providers/Microsoft.KeyVault/vaults/adp-<>-az-kv-x-001"
+ ]
+ },
+ "identity": {
+ "value": "SystemAssigned"
+ },
+ "roleDefinitionIds": {
+ "value": [
+ "/providers/microsoft.authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c"
+ ]
+ },
+ "subscriptionId": {
+ "value": "<>"
+ },
+ "resourceGroupName": {
+ "value": "<>"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policyAssignments/.parameters/sub.min.parameters.json b/carml/1.0.0/Microsoft.Authorization/policyAssignments/.parameters/sub.min.parameters.json
new file mode 100644
index 000000000..ebadf2e43
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyAssignments/.parameters/sub.min.parameters.json
@@ -0,0 +1,15 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-min-sub-polAss"
+ },
+ "policyDefinitionID": {
+ "value": "/providers/Microsoft.Authorization/policyDefinitions/06a78e20-9358-41c9-923c-fb736d382a4d"
+ },
+ "subscriptionId": {
+ "value": "<>"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policyAssignments/.parameters/sub.parameters.json b/carml/1.0.0/Microsoft.Authorization/policyAssignments/.parameters/sub.parameters.json
new file mode 100644
index 000000000..cc671f092
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyAssignments/.parameters/sub.parameters.json
@@ -0,0 +1,59 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-sub-polAss"
+ },
+ "displayName": {
+ "value": "[Display Name] Policy Assignment at the subscription scope"
+ },
+ "description": {
+ "value": "[Description] Policy Assignment at the subscription scope"
+ },
+ "policyDefinitionId": {
+ "value": "/providers/Microsoft.Authorization/policyDefinitions/4f9dc7db-30c1-420c-b61a-e1d640128d26"
+ },
+ "parameters": {
+ "value": {
+ "tagName": {
+ "value": "env"
+ },
+ "tagValue": {
+ "value": "prod"
+ }
+ }
+ },
+ "nonComplianceMessage": {
+ "value": "Violated Policy Assignment - This is a Non Compliance Message"
+ },
+ "enforcementMode": {
+ "value": "DoNotEnforce"
+ },
+ "metadata": {
+ "value": {
+ "category": "Security",
+ "version": "1.0"
+ }
+ },
+ "location": {
+ "value": "australiaeast"
+ },
+ "notScopes": {
+ "value": [
+ "/subscriptions/<>/resourceGroups/validation-rg"
+ ]
+ },
+ "identity": {
+ "value": "SystemAssigned"
+ },
+ "roleDefinitionIds": {
+ "value": [
+ "/providers/microsoft.authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c"
+ ]
+ },
+ "subscriptionId": {
+ "value": "<>"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policyAssignments/deploy.bicep b/carml/1.0.0/Microsoft.Authorization/policyAssignments/deploy.bicep
new file mode 100644
index 000000000..7e5c1b1e8
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyAssignments/deploy.bicep
@@ -0,0 +1,124 @@
+targetScope = 'managementGroup'
+
+@sys.description('Required. Specifies the name of the policy assignment. Maximum length is 24 characters for management group scope, 64 characters for subscription and resource group scopes.')
+param name string
+
+@sys.description('Optional. This message will be part of response in case of policy violation.')
+param description string = ''
+
+@sys.description('Optional. The display name of the policy assignment. Maximum length is 128 characters.')
+@maxLength(128)
+param displayName string = ''
+
+@sys.description('Required. Specifies the ID of the policy definition or policy set definition being assigned.')
+param policyDefinitionId string
+
+@sys.description('Optional. Parameters for the policy assignment if needed.')
+param parameters object = {}
+
+@sys.description('Optional. The managed identity associated with the policy assignment. Policy assignments must include a resource identity when assigning \'Modify\' policy definitions.')
+@allowed([
+ 'SystemAssigned'
+ 'None'
+])
+param identity string = 'SystemAssigned'
+
+@sys.description('Required. The IDs Of the Azure Role Definition list that is used to assign permissions to the identity. You need to provide either the fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.. See https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles for the list IDs for built-in Roles. They must match on what is on the policy definition')
+param roleDefinitionIds array = []
+
+@sys.description('Optional. The policy assignment metadata. Metadata is an open ended object and is typically a collection of key-value pairs.')
+param metadata object = {}
+
+@sys.description('Optional. The messages that describe why a resource is non-compliant with the policy.')
+param nonComplianceMessage string = ''
+
+@sys.description('Optional. The policy assignment enforcement mode. Possible values are Default and DoNotEnforce. - Default or DoNotEnforce')
+@allowed([
+ 'Default'
+ 'DoNotEnforce'
+])
+param enforcementMode string = 'Default'
+
+@sys.description('Optional. The Target Scope for the Policy. The name of the management group for the policy assignment. If not provided, will use the current scope for deployment.')
+param managementGroupId string = managementGroup().name
+
+@sys.description('Optional. The Target Scope for the Policy. The subscription ID of the subscription for the policy assignment')
+param subscriptionId string = ''
+
+@sys.description('Optional. The Target Scope for the Policy. The name of the resource group for the policy assignment')
+param resourceGroupName string = ''
+
+@sys.description('Optional. The policy excluded scopes')
+param notScopes array = []
+
+@sys.description('Optional. Location for all resources.')
+param location string = deployment().location
+
+module policyAssignment_mg 'managementGroup/deploy.bicep' = if (empty(subscriptionId) && empty(resourceGroupName)) {
+ name: '${uniqueString(deployment().name, location)}-PolicyAssignment-MG-Module'
+ scope: managementGroup(managementGroupId)
+ params: {
+ name: name
+ policyDefinitionId: policyDefinitionId
+ displayName: !empty(displayName) ? displayName : ''
+ description: !empty(description) ? description : ''
+ parameters: !empty(parameters) ? parameters : {}
+ identity: identity
+ roleDefinitionIds: !empty(roleDefinitionIds) ? roleDefinitionIds : []
+ metadata: !empty(metadata) ? metadata : {}
+ nonComplianceMessage: !empty(nonComplianceMessage) ? nonComplianceMessage : ''
+ enforcementMode: enforcementMode
+ notScopes: !empty(notScopes) ? notScopes : []
+ managementGroupId: managementGroupId
+ location: location
+ }
+}
+
+module policyAssignment_sub 'subscription/deploy.bicep' = if (!empty(subscriptionId) && empty(resourceGroupName)) {
+ name: '${uniqueString(deployment().name, location)}-PolicyAssignment-Sub-Module'
+ scope: subscription(subscriptionId)
+ params: {
+ name: name
+ policyDefinitionId: policyDefinitionId
+ displayName: !empty(displayName) ? displayName : ''
+ description: !empty(description) ? description : ''
+ parameters: !empty(parameters) ? parameters : {}
+ identity: identity
+ roleDefinitionIds: !empty(roleDefinitionIds) ? roleDefinitionIds : []
+ metadata: !empty(metadata) ? metadata : {}
+ nonComplianceMessage: !empty(nonComplianceMessage) ? nonComplianceMessage : ''
+ enforcementMode: enforcementMode
+ notScopes: !empty(notScopes) ? notScopes : []
+ subscriptionId: subscriptionId
+ location: location
+ }
+}
+
+module policyAssignment_rg 'resourceGroup/deploy.bicep' = if (!empty(resourceGroupName) && !empty(subscriptionId)) {
+ name: '${uniqueString(deployment().name, location)}-PolicyAssignment-RG-Module'
+ scope: resourceGroup(subscriptionId, resourceGroupName)
+ params: {
+ name: name
+ policyDefinitionId: policyDefinitionId
+ displayName: !empty(displayName) ? displayName : ''
+ description: !empty(description) ? description : ''
+ parameters: !empty(parameters) ? parameters : {}
+ identity: identity
+ roleDefinitionIds: !empty(roleDefinitionIds) ? roleDefinitionIds : []
+ metadata: !empty(metadata) ? metadata : {}
+ nonComplianceMessage: !empty(nonComplianceMessage) ? nonComplianceMessage : ''
+ enforcementMode: enforcementMode
+ notScopes: !empty(notScopes) ? notScopes : []
+ subscriptionId: subscriptionId
+ location: location
+ }
+}
+
+@sys.description('Policy Assignment Name')
+output name string = empty(subscriptionId) && empty(resourceGroupName) ? policyAssignment_mg.outputs.name : (!empty(subscriptionId) && empty(resourceGroupName) ? policyAssignment_sub.outputs.name : policyAssignment_rg.outputs.name)
+
+@sys.description('Policy Assignment principal ID')
+output principalId string = empty(subscriptionId) && empty(resourceGroupName) ? policyAssignment_mg.outputs.principalId : (!empty(subscriptionId) && empty(resourceGroupName) ? policyAssignment_sub.outputs.principalId : policyAssignment_rg.outputs.principalId)
+
+@sys.description('Policy Assignment resource ID')
+output resourceId string = empty(subscriptionId) && empty(resourceGroupName) ? policyAssignment_mg.outputs.resourceId : (!empty(subscriptionId) && empty(resourceGroupName) ? policyAssignment_sub.outputs.resourceId : policyAssignment_rg.outputs.resourceId)
diff --git a/carml/1.0.0/Microsoft.Authorization/policyAssignments/managementGroup/deploy.bicep b/carml/1.0.0/Microsoft.Authorization/policyAssignments/managementGroup/deploy.bicep
new file mode 100644
index 000000000..7cfbb7889
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyAssignments/managementGroup/deploy.bicep
@@ -0,0 +1,92 @@
+targetScope = 'managementGroup'
+
+@sys.description('Required. Specifies the name of the policy assignment. Maximum length is 24 characters for management group scope.')
+@maxLength(24)
+param name string
+
+@sys.description('Optional. This message will be part of response in case of policy violation.')
+param description string = ''
+
+@sys.description('Optional. The display name of the policy assignment. Maximum length is 128 characters.')
+@maxLength(128)
+param displayName string = ''
+
+@sys.description('Required. Specifies the ID of the policy definition or policy set definition being assigned.')
+param policyDefinitionId string
+
+@sys.description('Optional. Parameters for the policy assignment if needed.')
+param parameters object = {}
+
+@sys.description('Optional. The managed identity associated with the policy assignment. Policy assignments must include a resource identity when assigning \'Modify\' policy definitions.')
+@allowed([
+ 'SystemAssigned'
+ 'None'
+])
+param identity string = 'SystemAssigned'
+
+@sys.description('Required. The IDs Of the Azure Role Definition list that is used to assign permissions to the identity. You need to provide either the fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.. See https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles for the list IDs for built-in Roles. They must match on what is on the policy definition')
+param roleDefinitionIds array = []
+
+@sys.description('Optional. The policy assignment metadata. Metadata is an open ended object and is typically a collection of key-value pairs.')
+param metadata object = {}
+
+@sys.description('Optional. The messages that describe why a resource is non-compliant with the policy.')
+param nonComplianceMessage string = ''
+
+@sys.description('Optional. The policy assignment enforcement mode. Possible values are Default and DoNotEnforce. - Default or DoNotEnforce')
+@allowed([
+ 'Default'
+ 'DoNotEnforce'
+])
+param enforcementMode string = 'Default'
+
+@sys.description('Optional. The Target Scope for the Policy. The name of the management group for the policy assignment. If not provided, will use the current scope for deployment.')
+param managementGroupId string = managementGroup().name
+
+@sys.description('Optional. The policy excluded scopes')
+param notScopes array = []
+
+@sys.description('Optional. Location for all resources.')
+param location string = deployment().location
+
+var nonComplianceMessage_var = {
+ message: !empty(nonComplianceMessage) ? nonComplianceMessage : null
+}
+
+var identity_var = identity == 'SystemAssigned' ? {
+ type: identity
+} : null
+
+resource policyAssignment 'Microsoft.Authorization/policyAssignments@2021-06-01' = {
+ name: name
+ location: location
+ properties: {
+ displayName: !empty(displayName) ? displayName : null
+ metadata: !empty(metadata) ? metadata : null
+ description: !empty(description) ? description : null
+ policyDefinitionId: policyDefinitionId
+ parameters: parameters
+ nonComplianceMessages: !empty(nonComplianceMessage) ? array(nonComplianceMessage_var) : []
+ enforcementMode: enforcementMode
+ notScopes: !empty(notScopes) ? notScopes : []
+ }
+ identity: identity_var
+}
+
+resource roleAssignment 'Microsoft.Authorization/roleAssignments@2021-04-01-preview' = [for roleDefinitionId in roleDefinitionIds: if (!empty(roleDefinitionIds) && identity != 'None') {
+ name: guid(managementGroupId, roleDefinitionId, location, name)
+ properties: {
+ roleDefinitionId: roleDefinitionId
+ principalId: policyAssignment.identity.principalId
+ principalType: 'ServicePrincipal'
+ }
+}]
+
+@sys.description('Policy Assignment Name')
+output name string = policyAssignment.name
+
+@sys.description('Policy Assignment principal ID')
+output principalId string = identity == 'SystemAssigned' ? policyAssignment.identity.principalId : ''
+
+@sys.description('Policy Assignment resource ID')
+output resourceId string = extensionResourceId(tenantResourceId('Microsoft.Management/managementGroups', managementGroupId), 'Microsoft.Authorization/policyAssignments', policyAssignment.name)
diff --git a/carml/1.0.0/Microsoft.Authorization/policyAssignments/managementGroup/readme.md b/carml/1.0.0/Microsoft.Authorization/policyAssignments/managementGroup/readme.md
new file mode 100644
index 000000000..1f527ccc1
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyAssignments/managementGroup/readme.md
@@ -0,0 +1,41 @@
+# Policy Assignment on Management Group level `[Microsoft.Authorization/policyAssignments/managementGroup]`
+
+With this module you can perform policy assignments on a management group level.
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/policyAssignments` | 2021-06-01 |
+| `Microsoft.Authorization/roleAssignments` | 2021-04-01-preview |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `description` | string | | | Optional. This message will be part of response in case of policy violation. |
+| `displayName` | string | | | Optional. The display name of the policy assignment. Maximum length is 128 characters. |
+| `enforcementMode` | string | `Default` | `[Default, DoNotEnforce]` | Optional. The policy assignment enforcement mode. Possible values are Default and DoNotEnforce. - Default or DoNotEnforce |
+| `identity` | string | `SystemAssigned` | `[SystemAssigned, None]` | Optional. The managed identity associated with the policy assignment. Policy assignments must include a resource identity when assigning 'Modify' policy definitions. |
+| `location` | string | `[deployment().location]` | | Optional. Location for all resources. |
+| `managementGroupId` | string | `[managementGroup().name]` | | Optional. The Target Scope for the Policy. The name of the management group for the policy assignment. If not provided, will use the current scope for deployment. |
+| `metadata` | object | `{object}` | | Optional. The policy assignment metadata. Metadata is an open ended object and is typically a collection of key-value pairs. |
+| `name` | string | | | Required. Specifies the name of the policy assignment. Maximum length is 24 characters for management group scope. |
+| `nonComplianceMessage` | string | | | Optional. The messages that describe why a resource is non-compliant with the policy. |
+| `notScopes` | array | `[]` | | Optional. The policy excluded scopes |
+| `parameters` | object | `{object}` | | Optional. Parameters for the policy assignment if needed. |
+| `policyDefinitionId` | string | | | Required. Specifies the ID of the policy definition or policy set definition being assigned. |
+| `roleDefinitionIds` | array | `[]` | | Required. The IDs Of the Azure Role Definition list that is used to assign permissions to the identity. You need to provide either the fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'.. See https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles for the list IDs for built-in Roles. They must match on what is on the policy definition |
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | Policy Assignment Name |
+| `principalId` | string | Policy Assignment principal ID |
+| `resourceId` | string | Policy Assignment resource ID |
+
+## Template references
+
+- [Policyassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2021-06-01/policyAssignments)
+- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/roleAssignments)
diff --git a/carml/1.0.0/Microsoft.Authorization/policyAssignments/managementGroup/version.json b/carml/1.0.0/Microsoft.Authorization/policyAssignments/managementGroup/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyAssignments/managementGroup/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policyAssignments/readme.md b/carml/1.0.0/Microsoft.Authorization/policyAssignments/readme.md
new file mode 100644
index 000000000..b7cc49035
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyAssignments/readme.md
@@ -0,0 +1,101 @@
+# Policy Assignments `[Microsoft.Authorization/policyAssignments]`
+
+With this module you can perform policy assignments across the management group, subscription or resource group scope.
+
+## Resource types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/policyAssignments` | 2021-06-01 |
+| `Microsoft.Authorization/roleAssignments` | 2021-04-01-preview |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `description` | string | | | Optional. This message will be part of response in case of policy violation. |
+| `displayName` | string | | | Optional. The display name of the policy assignment. Maximum length is 128 characters. |
+| `enforcementMode` | string | `Default` | `[Default, DoNotEnforce]` | Optional. The policy assignment enforcement mode. Possible values are Default and DoNotEnforce. - Default or DoNotEnforce |
+| `identity` | string | `SystemAssigned` | `[SystemAssigned, None]` | Optional. The managed identity associated with the policy assignment. Policy assignments must include a resource identity when assigning 'Modify' policy definitions. |
+| `location` | string | `[deployment().location]` | | Optional. Location for all resources. |
+| `managementGroupId` | string | `[managementGroup().name]` | | Optional. The Target Scope for the Policy. The name of the management group for the policy assignment. If not provided, will use the current scope for deployment. |
+| `metadata` | object | `{object}` | | Optional. The policy assignment metadata. Metadata is an open ended object and is typically a collection of key-value pairs. |
+| `name` | string | | | Required. Specifies the name of the policy assignment. Maximum length is 24 characters for management group scope, 64 characters for subscription and resource group scopes. |
+| `nonComplianceMessage` | string | | | Optional. The messages that describe why a resource is non-compliant with the policy. |
+| `notScopes` | array | `[]` | | Optional. The policy excluded scopes |
+| `parameters` | object | `{object}` | | Optional. Parameters for the policy assignment if needed. |
+| `policyDefinitionId` | string | | | Required. Specifies the ID of the policy definition or policy set definition being assigned. |
+| `resourceGroupName` | string | | | Optional. The Target Scope for the Policy. The name of the resource group for the policy assignment |
+| `roleDefinitionIds` | array | `[]` | | Required. The IDs Of the Azure Role Definition list that is used to assign permissions to the identity. You need to provide either the fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'.. See https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles for the list IDs for built-in Roles. They must match on what is on the policy definition |
+| `subscriptionId` | string | | | Optional. The Target Scope for the Policy. The subscription ID of the subscription for the policy assignment |
+
+### Parameter Usage: `managementGroupId`
+
+To deploy resource to a Management Group, provide the `managementGroupId` as an input parameter to the module.
+
+```json
+"managementGroupId": {
+ "value": "contoso-group"
+}
+```
+
+> `managementGroupId` is an optional parameter. If not provided, the deployment will use the management group defined in the current deployment scope (i.e. `managementGroup().name`).
+
+### Parameter Usage: `subscriptionId`
+
+To deploy resource to an Azure Subscription, provide the `subscriptionId` as an input parameter to the module. **Example**:
+
+```json
+"subscriptionId": {
+ "value": "12345678-b049-471c-95af-123456789012"
+}
+```
+
+### Parameter Usage: `resourceGroupName`
+
+To deploy resource to a Resource Group, provide the `subscriptionId` and `resourceGroupName` as an input parameter to the module. **Example**:
+
+```json
+"subscriptionId": {
+ "value": "12345678-b049-471c-95af-123456789012"
+},
+"resourceGroupName": {
+ "value": "target-resourceGroup"
+}
+```
+
+> The `subscriptionId` is used to enable deployment to a Resource Group Scope, allowing the use of the `resourceGroup()` function from a Management Group Scope. [Additional Details](https://github.com/Azure/bicep/pull/1420).
+
+## Module Usage Guidance
+
+In general, most of the resources under the `Microsoft.Authorization` namespace allows deploying resources at multiple scopes (management groups, subscriptions, resource groups). The `deploy.bicep` root module is simply an orchestrator module that targets sub-modules for different scopes as seen in the parameter usage section. All sub-modules for this namespace have folders that represent the target scope. For example, if the orchestrator module in the [root](deploy.bicep) needs to target 'subscription' level scopes. It will look at the relative path ['/subscription/deploy.bicep'](./subscription/deploy.bicep) and use this sub-module for the actual deployment, while still passing the same parameters from the root module.
+
+The above method is useful when you want to use a single point to interact with the module but rely on parameter combinations to achieve the target scope. But what if you want to incorporate this module in other modules with lower scopes? This would force you to deploy the module in scope `managementGroup` regardless and further require you to provide its ID with it. If you do not set the scope to management group, this would be the error that you can expect to face:
+
+```bicep
+Error BCP134: Scope "subscription" is not valid for this module. Permitted scopes: "managementGroup"
+```
+
+The solution is to have the option of directly targeting the sub-module that achieves the required scope. For example, if you have your own Bicep file wanting to create resources at the subscription level, and also use some of the modules from the `Microsoft.Authorization` namespace, then you can directly use the sub-module ['/subscription/deploy.bicep'](./subscription/deploy.bicep) as a path within your repository, or reference that same published module from the bicep registry. CARML also published the sub-modules so you would be able to reference it like the following:
+
+**Bicep Registry Reference**
+```bicep
+module policyassignment 'br:bicepregistry.azurecr.io/bicep/modules/microsoft.authorization.policyassignments.subscription:version' = {}
+```
+**Local Path Reference**
+```bicep
+module policyassignment 'yourpath/arm/Microsoft.Authorization.policyAssignments/subscription/deploy.bicep' = {}
+```
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | Policy Assignment Name |
+| `principalId` | string | Policy Assignment principal ID |
+| `resourceId` | string | Policy Assignment resource ID |
+
+## Template references
+
+- [Policyassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2021-06-01/policyAssignments)
+- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/roleAssignments)
diff --git a/carml/1.0.0/Microsoft.Authorization/policyAssignments/resourceGroup/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.Authorization/policyAssignments/resourceGroup/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyAssignments/resourceGroup/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.Authorization/policyAssignments/resourceGroup/deploy.bicep b/carml/1.0.0/Microsoft.Authorization/policyAssignments/resourceGroup/deploy.bicep
new file mode 100644
index 000000000..c6e25feff
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyAssignments/resourceGroup/deploy.bicep
@@ -0,0 +1,106 @@
+targetScope = 'resourceGroup'
+
+@sys.description('Required. Specifies the name of the policy assignment. Maximum length is 64 characters for resource group scope.')
+@maxLength(64)
+param name string
+
+@sys.description('Optional. This message will be part of response in case of policy violation.')
+param description string = ''
+
+@sys.description('Optional. The display name of the policy assignment. Maximum length is 128 characters.')
+@maxLength(128)
+param displayName string = ''
+
+@sys.description('Required. Specifies the ID of the policy definition or policy set definition being assigned.')
+param policyDefinitionId string
+
+@sys.description('Optional. Parameters for the policy assignment if needed.')
+param parameters object = {}
+
+@sys.description('Optional. The managed identity associated with the policy assignment. Policy assignments must include a resource identity when assigning \'Modify\' policy definitions.')
+@allowed([
+ 'SystemAssigned'
+ 'None'
+])
+param identity string = 'SystemAssigned'
+
+@sys.description('Required. The IDs Of the Azure Role Definition list that is used to assign permissions to the identity. You need to provide either the fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.. See https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles for the list IDs for built-in Roles. They must match on what is on the policy definition')
+param roleDefinitionIds array = []
+
+@sys.description('Optional. The policy assignment metadata. Metadata is an open ended object and is typically a collection of key-value pairs.')
+param metadata object = {}
+
+@sys.description('Optional. The messages that describe why a resource is non-compliant with the policy.')
+param nonComplianceMessage string = ''
+
+@sys.description('Optional. The policy assignment enforcement mode. Possible values are Default and DoNotEnforce. - Default or DoNotEnforce')
+@allowed([
+ 'Default'
+ 'DoNotEnforce'
+])
+param enforcementMode string = 'Default'
+
+@sys.description('Optional. The policy excluded scopes')
+param notScopes array = []
+
+@sys.description('Optional. Location for all resources.')
+param location string = resourceGroup().location
+
+var nonComplianceMessage_var = {
+ message: !empty(nonComplianceMessage) ? nonComplianceMessage : null
+}
+
+@sys.description('Optional. The Target Scope for the Policy. The subscription ID of the subscription for the policy assignment. If not provided, will use the current scope for deployment.')
+param subscriptionId string = subscription().subscriptionId
+
+@sys.description('Optional. The Target Scope for the Policy. The name of the resource group for the policy assignment. If not provided, will use the current scope for deployment.')
+param resourceGroupName string = resourceGroup().name
+
+@sys.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: {}
+}
+
+var identity_var = identity == 'SystemAssigned' ? {
+ type: identity
+} : null
+
+resource policyAssignment 'Microsoft.Authorization/policyAssignments@2021-06-01' = {
+ name: name
+ location: location
+ properties: {
+ displayName: !empty(displayName) ? displayName : null
+ metadata: !empty(metadata) ? metadata : null
+ description: !empty(description) ? description : null
+ policyDefinitionId: policyDefinitionId
+ parameters: parameters
+ nonComplianceMessages: !empty(nonComplianceMessage) ? array(nonComplianceMessage_var) : []
+ enforcementMode: enforcementMode
+ notScopes: !empty(notScopes) ? notScopes : []
+ }
+ identity: identity_var
+}
+
+resource roleAssignment 'Microsoft.Authorization/roleAssignments@2021-04-01-preview' = [for roleDefinitionId in roleDefinitionIds: if (!empty(roleDefinitionIds) && identity != 'None') {
+ name: guid(subscriptionId, resourceGroupName, roleDefinitionId, location, name)
+ properties: {
+ roleDefinitionId: roleDefinitionId
+ principalId: policyAssignment.identity.principalId
+ principalType: 'ServicePrincipal'
+ }
+}]
+
+@sys.description('Policy Assignment Name')
+output name string = policyAssignment.name
+
+@sys.description('Policy Assignment principal ID')
+output principalId string = identity == 'SystemAssigned' ? policyAssignment.identity.principalId : ''
+
+@sys.description('Policy Assignment resource ID')
+output resourceId string = az.resourceId(subscriptionId, resourceGroupName, 'Microsoft.Authorization/policyAssignments', policyAssignment.name)
+
+@sys.description('The name of the resource group the policy was assigned to')
+output resourceGroupName string = resourceGroup().name
diff --git a/carml/1.0.0/Microsoft.Authorization/policyAssignments/resourceGroup/readme.md b/carml/1.0.0/Microsoft.Authorization/policyAssignments/resourceGroup/readme.md
new file mode 100644
index 000000000..57000e661
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyAssignments/resourceGroup/readme.md
@@ -0,0 +1,44 @@
+# Policy Assignment on Resource Group level `[Microsoft.Authorization/policyAssignments/resourceGroup]`
+
+With this module you can perform policy assignments on a resource group level
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/policyAssignments` | 2021-06-01 |
+| `Microsoft.Authorization/roleAssignments` | 2021-04-01-preview |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered. |
+| `description` | string | | | Optional. This message will be part of response in case of policy violation. |
+| `displayName` | string | | | Optional. The display name of the policy assignment. Maximum length is 128 characters. |
+| `enforcementMode` | string | `Default` | `[Default, DoNotEnforce]` | Optional. The policy assignment enforcement mode. Possible values are Default and DoNotEnforce. - Default or DoNotEnforce |
+| `identity` | string | `SystemAssigned` | `[SystemAssigned, None]` | Optional. The managed identity associated with the policy assignment. Policy assignments must include a resource identity when assigning 'Modify' policy definitions. |
+| `location` | string | `[resourceGroup().location]` | | Optional. Location for all resources. |
+| `metadata` | object | `{object}` | | Optional. The policy assignment metadata. Metadata is an open ended object and is typically a collection of key-value pairs. |
+| `name` | string | | | Required. Specifies the name of the policy assignment. Maximum length is 64 characters for resource group scope. |
+| `nonComplianceMessage` | string | | | Optional. The messages that describe why a resource is non-compliant with the policy. |
+| `notScopes` | array | `[]` | | Optional. The policy excluded scopes |
+| `parameters` | object | `{object}` | | Optional. Parameters for the policy assignment if needed. |
+| `policyDefinitionId` | string | | | Required. Specifies the ID of the policy definition or policy set definition being assigned. |
+| `resourceGroupName` | string | `[resourceGroup().name]` | | Optional. The Target Scope for the Policy. The name of the resource group for the policy assignment. If not provided, will use the current scope for deployment. |
+| `roleDefinitionIds` | array | `[]` | | Required. The IDs Of the Azure Role Definition list that is used to assign permissions to the identity. You need to provide either the fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'.. See https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles for the list IDs for built-in Roles. They must match on what is on the policy definition |
+| `subscriptionId` | string | `[subscription().subscriptionId]` | | Optional. The Target Scope for the Policy. The subscription ID of the subscription for the policy assignment. If not provided, will use the current scope for deployment. |
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | Policy Assignment Name |
+| `principalId` | string | Policy Assignment principal ID |
+| `resourceGroupName` | string | The name of the resource group the policy was assigned to |
+| `resourceId` | string | Policy Assignment resource ID |
+
+## Template references
+
+- [Policyassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2021-06-01/policyAssignments)
+- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/roleAssignments)
diff --git a/carml/1.0.0/Microsoft.Authorization/policyAssignments/resourceGroup/version.json b/carml/1.0.0/Microsoft.Authorization/policyAssignments/resourceGroup/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyAssignments/resourceGroup/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policyAssignments/subscription/deploy.bicep b/carml/1.0.0/Microsoft.Authorization/policyAssignments/subscription/deploy.bicep
new file mode 100644
index 000000000..d13fbf2e8
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyAssignments/subscription/deploy.bicep
@@ -0,0 +1,92 @@
+targetScope = 'subscription'
+
+@sys.description('Required. Specifies the name of the policy assignment. Maximum length is 64 characters for subscription scope.')
+@maxLength(64)
+param name string
+
+@sys.description('Optional. This message will be part of response in case of policy violation.')
+param description string = ''
+
+@sys.description('Optional. The display name of the policy assignment. Maximum length is 128 characters.')
+@maxLength(128)
+param displayName string = ''
+
+@sys.description('Required. Specifies the ID of the policy definition or policy set definition being assigned.')
+param policyDefinitionId string
+
+@sys.description('Optional. Parameters for the policy assignment if needed.')
+param parameters object = {}
+
+@sys.description('Optional. The managed identity associated with the policy assignment. Policy assignments must include a resource identity when assigning \'Modify\' policy definitions.')
+@allowed([
+ 'SystemAssigned'
+ 'None'
+])
+param identity string = 'SystemAssigned'
+
+@sys.description('Required. The IDs Of the Azure Role Definition list that is used to assign permissions to the identity. You need to provide either the fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.. See https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles for the list IDs for built-in Roles. They must match on what is on the policy definition')
+param roleDefinitionIds array = []
+
+@sys.description('Optional. The policy assignment metadata. Metadata is an open ended object and is typically a collection of key-value pairs.')
+param metadata object = {}
+
+@sys.description('Optional. The messages that describe why a resource is non-compliant with the policy.')
+param nonComplianceMessage string = ''
+
+@sys.description('Optional. The policy assignment enforcement mode. Possible values are Default and DoNotEnforce. - Default or DoNotEnforce')
+@allowed([
+ 'Default'
+ 'DoNotEnforce'
+])
+param enforcementMode string = 'Default'
+
+@sys.description('Optional. The policy excluded scopes')
+param notScopes array = []
+
+@sys.description('Optional. Location for all resources.')
+param location string = deployment().location
+
+var nonComplianceMessage_var = {
+ message: !empty(nonComplianceMessage) ? nonComplianceMessage : null
+}
+
+@sys.description('Optional. The Target Scope for the Policy. The subscription ID of the subscription for the policy assignment. If not provided, will use the current scope for deployment.')
+param subscriptionId string = subscription().subscriptionId
+
+var identity_var = identity == 'SystemAssigned' ? {
+ type: identity
+} : null
+
+resource policyAssignment 'Microsoft.Authorization/policyAssignments@2021-06-01' = {
+ name: name
+ location: location
+ properties: {
+ displayName: !empty(displayName) ? displayName : null
+ metadata: !empty(metadata) ? metadata : null
+ description: !empty(description) ? description : null
+ policyDefinitionId: policyDefinitionId
+ parameters: parameters
+ nonComplianceMessages: !empty(nonComplianceMessage) ? array(nonComplianceMessage_var) : []
+ enforcementMode: enforcementMode
+ notScopes: !empty(notScopes) ? notScopes : []
+ }
+ identity: identity_var
+}
+
+resource roleAssignment 'Microsoft.Authorization/roleAssignments@2021-04-01-preview' = [for roleDefinitionId in roleDefinitionIds: if (!empty(roleDefinitionIds) && identity != 'None') {
+ name: guid(subscriptionId, roleDefinitionId, location, name)
+ properties: {
+ roleDefinitionId: roleDefinitionId
+ principalId: policyAssignment.identity.principalId
+ principalType: 'ServicePrincipal'
+ }
+}]
+
+@sys.description('Policy Assignment Name')
+output name string = policyAssignment.name
+
+@sys.description('Policy Assignment principal ID')
+output principalId string = identity == 'SystemAssigned' ? policyAssignment.identity.principalId : ''
+
+@sys.description('Policy Assignment resource ID')
+output resourceId string = subscriptionResourceId(subscriptionId, 'Microsoft.Authorization/policyAssignments', policyAssignment.name)
diff --git a/carml/1.0.0/Microsoft.Authorization/policyAssignments/subscription/readme.md b/carml/1.0.0/Microsoft.Authorization/policyAssignments/subscription/readme.md
new file mode 100644
index 000000000..0214edc0c
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyAssignments/subscription/readme.md
@@ -0,0 +1,41 @@
+# Policy Assignment on Subscription level `[Microsoft.Authorization/policyAssignments/subscription]`
+
+With this module you can perform policy assignments on a subscription level.
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/policyAssignments` | 2021-06-01 |
+| `Microsoft.Authorization/roleAssignments` | 2021-04-01-preview |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `description` | string | | | Optional. This message will be part of response in case of policy violation. |
+| `displayName` | string | | | Optional. The display name of the policy assignment. Maximum length is 128 characters. |
+| `enforcementMode` | string | `Default` | `[Default, DoNotEnforce]` | Optional. The policy assignment enforcement mode. Possible values are Default and DoNotEnforce. - Default or DoNotEnforce |
+| `identity` | string | `SystemAssigned` | `[SystemAssigned, None]` | Optional. The managed identity associated with the policy assignment. Policy assignments must include a resource identity when assigning 'Modify' policy definitions. |
+| `location` | string | `[deployment().location]` | | Optional. Location for all resources. |
+| `metadata` | object | `{object}` | | Optional. The policy assignment metadata. Metadata is an open ended object and is typically a collection of key-value pairs. |
+| `name` | string | | | Required. Specifies the name of the policy assignment. Maximum length is 64 characters for subscription scope. |
+| `nonComplianceMessage` | string | | | Optional. The messages that describe why a resource is non-compliant with the policy. |
+| `notScopes` | array | `[]` | | Optional. The policy excluded scopes |
+| `parameters` | object | `{object}` | | Optional. Parameters for the policy assignment if needed. |
+| `policyDefinitionId` | string | | | Required. Specifies the ID of the policy definition or policy set definition being assigned. |
+| `roleDefinitionIds` | array | `[]` | | Required. The IDs Of the Azure Role Definition list that is used to assign permissions to the identity. You need to provide either the fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'.. See https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles for the list IDs for built-in Roles. They must match on what is on the policy definition |
+| `subscriptionId` | string | `[subscription().subscriptionId]` | | Optional. The Target Scope for the Policy. The subscription ID of the subscription for the policy assignment. If not provided, will use the current scope for deployment. |
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | Policy Assignment Name |
+| `principalId` | string | Policy Assignment principal ID |
+| `resourceId` | string | Policy Assignment resource ID |
+
+## Template references
+
+- [Policyassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2021-06-01/policyAssignments)
+- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/roleAssignments)
diff --git a/carml/1.0.0/Microsoft.Authorization/policyAssignments/subscription/version.json b/carml/1.0.0/Microsoft.Authorization/policyAssignments/subscription/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyAssignments/subscription/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policyAssignments/version.json b/carml/1.0.0/Microsoft.Authorization/policyAssignments/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyAssignments/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policyDefinitions/.parameters/mg.min.parameters.json b/carml/1.0.0/Microsoft.Authorization/policyDefinitions/.parameters/mg.min.parameters.json
new file mode 100644
index 000000000..431a0f6f5
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyDefinitions/.parameters/mg.min.parameters.json
@@ -0,0 +1,35 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-mg-min-policyDef"
+ },
+ "policyRule": {
+ "value": {
+ "if": {
+ "allOf": [
+ {
+ "equals": "Microsoft.KeyVault/vaults",
+ "field": "type"
+ }
+ ]
+ },
+ "then": {
+ "effect": "[parameters('effect')]"
+ }
+ }
+ },
+ "parameters": {
+ "value": {
+ "effect": {
+ "allowedValues": [
+ "Audit"
+ ],
+ "defaultValue": "Audit",
+ "type": "String"
+ }
+ }
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policyDefinitions/.parameters/mg.parameters.json b/carml/1.0.0/Microsoft.Authorization/policyDefinitions/.parameters/mg.parameters.json
new file mode 100644
index 000000000..7196de615
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyDefinitions/.parameters/mg.parameters.json
@@ -0,0 +1,72 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-mg-policyDef"
+ },
+ "displayName": {
+ "value": "[DisplayName] This policy definition is deployed at the management group scope"
+ },
+ "description": {
+ "value": "[Description] This policy definition is deployed at the management group scope"
+ },
+ "policyRule": {
+ "value": {
+ "if": {
+ "allOf": [
+ {
+ "field": "type",
+ "equals": "Microsoft.Resources/subscriptions"
+ },
+ {
+ "field": "[concat('tags[', parameters('tagName'), ']')]",
+ "exists": "false"
+ }
+ ]
+ },
+ "then": {
+ "effect": "modify",
+ "details": {
+ "roleDefinitionIds": [
+ "/providers/microsoft.authorization/roleDefinitions/4a9ae827-6dc8-4573-8ac7-8239d42aa03f"
+ ],
+ "operations": [
+ {
+ "operation": "add",
+ "field": "[concat('tags[', parameters('tagName'), ']')]",
+ "value": "[parameters('tagValue')]"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "parameters": {
+ "value": {
+ "tagName": {
+ "type": "String",
+ "metadata": {
+ "displayName": "Tag Name",
+ "description": "Name of the tag, such as 'environment'"
+ }
+ },
+ "tagValue": {
+ "type": "String",
+ "metadata": {
+ "displayName": "Tag Value",
+ "description": "Value of the tag, such as 'production'"
+ }
+ }
+ }
+ },
+ "metadata": {
+ "value": {
+ "category": "Security"
+ }
+ },
+ "managementGroupId": {
+ "value": "<>"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policyDefinitions/.parameters/sub.min.parameters.json b/carml/1.0.0/Microsoft.Authorization/policyDefinitions/.parameters/sub.min.parameters.json
new file mode 100644
index 000000000..f2cd03cfb
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyDefinitions/.parameters/sub.min.parameters.json
@@ -0,0 +1,38 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-sub-min-policyDef"
+ },
+ "policyRule": {
+ "value": {
+ "if": {
+ "allOf": [
+ {
+ "equals": "Microsoft.KeyVault/vaults",
+ "field": "type"
+ }
+ ]
+ },
+ "then": {
+ "effect": "[parameters('effect')]"
+ }
+ }
+ },
+ "parameters": {
+ "value": {
+ "effect": {
+ "allowedValues": [
+ "Audit"
+ ],
+ "defaultValue": "Audit",
+ "type": "String"
+ }
+ }
+ },
+ "subscriptionId": {
+ "value": "<>"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policyDefinitions/.parameters/sub.parameters.json b/carml/1.0.0/Microsoft.Authorization/policyDefinitions/.parameters/sub.parameters.json
new file mode 100644
index 000000000..e44512751
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyDefinitions/.parameters/sub.parameters.json
@@ -0,0 +1,72 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-sub-policyDef"
+ },
+ "displayName": {
+ "value": "[DisplayName] This policy definition is deployed at subscription scope"
+ },
+ "description": {
+ "value": "[Description] This policy definition is deployed at subscription scope"
+ },
+ "policyRule": {
+ "value": {
+ "if": {
+ "allOf": [
+ {
+ "field": "type",
+ "equals": "Microsoft.Resources/subscriptions"
+ },
+ {
+ "field": "[concat('tags[', parameters('tagName'), ']')]",
+ "exists": "false"
+ }
+ ]
+ },
+ "then": {
+ "effect": "modify",
+ "details": {
+ "roleDefinitionIds": [
+ "/providers/microsoft.authorization/roleDefinitions/4a9ae827-6dc8-4573-8ac7-8239d42aa03f"
+ ],
+ "operations": [
+ {
+ "operation": "add",
+ "field": "[concat('tags[', parameters('tagName'), ']')]",
+ "value": "[parameters('tagValue')]"
+ }
+ ]
+ }
+ }
+ }
+ },
+ "parameters": {
+ "value": {
+ "tagName": {
+ "type": "String",
+ "metadata": {
+ "displayName": "Tag Name",
+ "description": "Name of the tag, such as 'environment'"
+ }
+ },
+ "tagValue": {
+ "type": "String",
+ "metadata": {
+ "displayName": "Tag Value",
+ "description": "Value of the tag, such as 'production'"
+ }
+ }
+ }
+ },
+ "metadata": {
+ "value": {
+ "category": "Security"
+ }
+ },
+ "subscriptionId": {
+ "value": "<>"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policyDefinitions/deploy.bicep b/carml/1.0.0/Microsoft.Authorization/policyDefinitions/deploy.bicep
new file mode 100644
index 000000000..198a9be60
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyDefinitions/deploy.bicep
@@ -0,0 +1,79 @@
+targetScope = 'managementGroup'
+
+@sys.description('Required. Specifies the name of the policy definition. Maximum length is 64 characters for management group scope and subscription scope.')
+@maxLength(64)
+param name string
+
+@sys.description('Optional. The display name of the policy definition. Maximum length is 128 characters.')
+@maxLength(128)
+param displayName string = ''
+
+@sys.description('Optional. The policy definition description.')
+param description string = ''
+
+@sys.description('Optional. The policy definition mode. Default is All, Some examples are All, Indexed, Microsoft.KeyVault.Data.')
+@allowed([
+ 'All'
+ 'Indexed'
+ 'Microsoft.KeyVault.Data'
+ 'Microsoft.ContainerService.Data'
+ 'Microsoft.Kubernetes.Data'
+])
+param mode string = 'All'
+
+@sys.description('Optional. The policy Definition metadata. Metadata is an open ended object and is typically a collection of key-value pairs.')
+param metadata object = {}
+
+@sys.description('Optional. The policy definition parameters that can be used in policy definition references.')
+param parameters object = {}
+
+@sys.description('Required. The Policy Rule details for the Policy Definition')
+param policyRule object
+
+@sys.description('Optional. The group ID of the Management Group (Scope). If not provided, will use the current scope for deployment.')
+param managementGroupId string = managementGroup().name
+
+@sys.description('Optional. The subscription ID of the subscription (Scope). Cannot be used with managementGroupId')
+param subscriptionId string = ''
+
+@sys.description('Optional. Location for all resources.')
+param location string = deployment().location
+
+module policyDefinition_mg 'managementGroup/deploy.bicep' = if (empty(subscriptionId)) {
+ name: '${uniqueString(deployment().name, location)}-PolicyDefinition-MG-Module'
+ scope: managementGroup(managementGroupId)
+ params: {
+ name: name
+ managementGroupId: managementGroupId
+ mode: mode
+ displayName: !empty(displayName) ? displayName : ''
+ description: !empty(description) ? description : ''
+ metadata: !empty(metadata) ? metadata : {}
+ parameters: !empty(parameters) ? parameters : {}
+ policyRule: policyRule
+ }
+}
+
+module policyDefinition_sub 'subscription/deploy.bicep' = if (!empty(subscriptionId)) {
+ name: '${uniqueString(deployment().name, location)}-PolicyDefinition-Sub-Module'
+ scope: subscription(subscriptionId)
+ params: {
+ name: name
+ subscriptionId: subscriptionId
+ mode: mode
+ displayName: !empty(displayName) ? displayName : ''
+ description: !empty(description) ? description : ''
+ metadata: !empty(metadata) ? metadata : {}
+ parameters: !empty(parameters) ? parameters : {}
+ policyRule: policyRule
+ }
+}
+
+@sys.description('Policy Definition Name')
+output name string = empty(subscriptionId) ? policyDefinition_mg.outputs.name : policyDefinition_sub.outputs.name
+
+@sys.description('Policy Definition resource ID')
+output resourceId string = empty(subscriptionId) ? policyDefinition_mg.outputs.resourceId : policyDefinition_sub.outputs.resourceId
+
+@sys.description('Policy Definition Role Definition IDs')
+output roleDefinitionIds array = empty(subscriptionId) ? policyDefinition_mg.outputs.roleDefinitionIds : policyDefinition_sub.outputs.roleDefinitionIds
diff --git a/carml/1.0.0/Microsoft.Authorization/policyDefinitions/managementGroup/deploy.bicep b/carml/1.0.0/Microsoft.Authorization/policyDefinitions/managementGroup/deploy.bicep
new file mode 100644
index 000000000..2e0046ff2
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyDefinitions/managementGroup/deploy.bicep
@@ -0,0 +1,56 @@
+targetScope = 'managementGroup'
+
+@sys.description('Required. Specifies the name of the policy definition. Maximum length is 64 characters.')
+@maxLength(64)
+param name string
+
+@sys.description('Optional. The display name of the policy definition. Maximum length is 128 characters.')
+@maxLength(128)
+param displayName string = ''
+
+@sys.description('Optional. The policy definition description.')
+param description string = ''
+
+@sys.description('Optional. The policy definition mode. Default is All, Some examples are All, Indexed, Microsoft.KeyVault.Data.')
+@allowed([
+ 'All'
+ 'Indexed'
+ 'Microsoft.KeyVault.Data'
+ 'Microsoft.ContainerService.Data'
+ 'Microsoft.Kubernetes.Data'
+])
+param mode string = 'All'
+
+@sys.description('Optional. The policy Definition metadata. Metadata is an open ended object and is typically a collection of key-value pairs.')
+param metadata object = {}
+
+@sys.description('Optional. The policy definition parameters that can be used in policy definition references.')
+param parameters object = {}
+
+@sys.description('Required. The Policy Rule details for the Policy Definition')
+param policyRule object
+
+@sys.description('Optional. The group ID of the Management Group. If not provided, will use the current scope for deployment.')
+param managementGroupId string = managementGroup().name
+
+resource policyDefinition 'Microsoft.Authorization/policyDefinitions@2021-06-01' = {
+ name: name
+ properties: {
+ policyType: 'Custom'
+ mode: mode
+ displayName: !empty(displayName) ? displayName : null
+ description: !empty(description) ? description : null
+ metadata: !empty(metadata) ? metadata : null
+ parameters: !empty(parameters) ? parameters : null
+ policyRule: policyRule
+ }
+}
+
+@sys.description('Policy Definition Name')
+output name string = policyDefinition.name
+
+@sys.description('Policy Definition resource ID')
+output resourceId string = extensionResourceId(tenantResourceId('Microsoft.Management/managementGroups', managementGroupId), 'Microsoft.Authorization/policyDefinitions', policyDefinition.name)
+
+@sys.description('Policy Definition Role Definition IDs')
+output roleDefinitionIds array = (contains(policyDefinition.properties.policyRule.then, 'details') ? ((contains(policyDefinition.properties.policyRule.then.details, 'roleDefinitionIds') ? policyDefinition.properties.policyRule.then.details.roleDefinitionIds : [])) : [])
diff --git a/carml/1.0.0/Microsoft.Authorization/policyDefinitions/managementGroup/readme.md b/carml/1.0.0/Microsoft.Authorization/policyDefinitions/managementGroup/readme.md
new file mode 100644
index 000000000..ba5d7fe80
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyDefinitions/managementGroup/readme.md
@@ -0,0 +1,34 @@
+# Policy Definitions on Management Group level `[Microsoft.Authorization/policyDefinitions/managementGroup]`
+
+With this module you can create policy definitions on a management group level.
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/policyDefinitions` | 2021-06-01 |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `description` | string | | | Optional. The policy definition description. |
+| `displayName` | string | | | Optional. The display name of the policy definition. Maximum length is 128 characters. |
+| `managementGroupId` | string | `[managementGroup().name]` | | Optional. The group ID of the Management Group. If not provided, will use the current scope for deployment. |
+| `metadata` | object | `{object}` | | Optional. The policy Definition metadata. Metadata is an open ended object and is typically a collection of key-value pairs. |
+| `mode` | string | `All` | `[All, Indexed, Microsoft.KeyVault.Data, Microsoft.ContainerService.Data, Microsoft.Kubernetes.Data]` | Optional. The policy definition mode. Default is All, Some examples are All, Indexed, Microsoft.KeyVault.Data. |
+| `name` | string | | | Required. Specifies the name of the policy definition. Maximum length is 64 characters. |
+| `parameters` | object | `{object}` | | Optional. The policy definition parameters that can be used in policy definition references. |
+| `policyRule` | object | | | Required. The Policy Rule details for the Policy Definition |
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | Policy Definition Name |
+| `resourceId` | string | Policy Definition resource ID |
+| `roleDefinitionIds` | array | Policy Definition Role Definition IDs |
+
+## Template references
+
+- [Policydefinitions](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2021-06-01/policyDefinitions)
diff --git a/carml/1.0.0/Microsoft.Authorization/policyDefinitions/managementGroup/version.json b/carml/1.0.0/Microsoft.Authorization/policyDefinitions/managementGroup/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyDefinitions/managementGroup/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policyDefinitions/readme.md b/carml/1.0.0/Microsoft.Authorization/policyDefinitions/readme.md
new file mode 100644
index 000000000..5190891a5
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyDefinitions/readme.md
@@ -0,0 +1,79 @@
+# Policy Definitions `[Microsoft.Authorization/policyDefinitions]`
+
+With this module you can create policy definitions across the management group or subscription scope.
+
+## Resource types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/policyDefinitions` | 2021-06-01 |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `description` | string | | | Optional. The policy definition description. |
+| `displayName` | string | | | Optional. The display name of the policy definition. Maximum length is 128 characters. |
+| `location` | string | `[deployment().location]` | | Optional. Location for all resources. |
+| `managementGroupId` | string | `[managementGroup().name]` | | Optional. The group ID of the Management Group (Scope). If not provided, will use the current scope for deployment. |
+| `metadata` | object | `{object}` | | Optional. The policy Definition metadata. Metadata is an open ended object and is typically a collection of key-value pairs. |
+| `mode` | string | `All` | `[All, Indexed, Microsoft.KeyVault.Data, Microsoft.ContainerService.Data, Microsoft.Kubernetes.Data]` | Optional. The policy definition mode. Default is All, Some examples are All, Indexed, Microsoft.KeyVault.Data. |
+| `name` | string | | | Required. Specifies the name of the policy definition. Maximum length is 64 characters for management group scope and subscription scope. |
+| `parameters` | object | `{object}` | | Optional. The policy definition parameters that can be used in policy definition references. |
+| `policyRule` | object | | | Required. The Policy Rule details for the Policy Definition |
+| `subscriptionId` | string | | | Optional. The subscription ID of the subscription (Scope). Cannot be used with managementGroupId |
+
+### Parameter Usage: `managementGroupId`
+
+To deploy resource to a Management Group, provide the `managementGroupId` as an input parameter to the module.
+
+```json
+"managementGroupId": {
+ "value": "contoso-group"
+}
+```
+
+> `managementGroupId` is an optional parameter. If not provided, the deployment will use the management group defined in the current deployment scope (i.e. `managementGroup().name`).
+
+### Parameter Usage: `subscriptionId`
+
+To deploy resource to an Azure Subscription, provide the `subscriptionId` as an input parameter to the module. **Example**:
+
+```json
+"subscriptionId": {
+ "value": "12345678-b049-471c-95af-123456789012"
+}
+```
+
+## Module Usage Guidance
+
+In general, most of the resources under the `Microsoft.Authorization` namespace allows deploying resources at multiple scopes (management groups, subscriptions, resource groups). The `deploy.bicep` root module is simply an orchestrator module that targets sub-modules for different scopes as seen in the parameter usage section. All sub-modules for this namespace have folders that represent the target scope. For example, if the orchestrator module in the [root](deploy.bicep) needs to target 'subscription' level scopes. It will look at the relative path ['/subscription/deploy.bicep'](./subscription/deploy.bicep) and use this sub-module for the actual deployment, while still passing the same parameters from the root module.
+
+The above method is useful when you want to use a single point to interact with the module but rely on parameter combinations to achieve the target scope. But what if you want to incorporate this module in other modules with lower scopes? This would force you to deploy the module in scope `managementGroup` regardless and further require you to provide its ID with it. If you do not set the scope to management group, this would be the error that you can expect to face:
+
+```bicep
+Error BCP134: Scope "subscription" is not valid for this module. Permitted scopes: "managementGroup"
+```
+
+The solution is to have the option of directly targeting the sub-module that achieves the required scope. For example, if you have your own Bicep file wanting to create resources at the subscription level, and also use some of the modules from the `Microsoft.Authorization` namespace, then you can directly use the sub-module ['/subscription/deploy.bicep'](./subscription/deploy.bicep) as a path within your repository, or reference that same published module from the bicep registry. CARML also published the sub-modules so you would be able to reference it like the following:
+
+**Bicep Registry Reference**
+```bicep
+module policydefinition 'br:bicepregistry.azurecr.io/bicep/modules/microsoft.authorization.policydefinitions.subscription:version' = {}
+```
+**Local Path Reference**
+```bicep
+module policydefinition 'yourpath/arm/Microsoft.Authorization.policyDefinitions/subscription/deploy.bicep' = {}
+```
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | Policy Definition Name |
+| `resourceId` | string | Policy Definition resource ID |
+| `roleDefinitionIds` | array | Policy Definition Role Definition IDs |
+
+## Template references
+
+- [Policydefinitions](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2021-06-01/policyDefinitions)
diff --git a/carml/1.0.0/Microsoft.Authorization/policyDefinitions/subscription/deploy.bicep b/carml/1.0.0/Microsoft.Authorization/policyDefinitions/subscription/deploy.bicep
new file mode 100644
index 000000000..b99c23225
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyDefinitions/subscription/deploy.bicep
@@ -0,0 +1,56 @@
+targetScope = 'subscription'
+
+@sys.description('Required. Specifies the name of the policy definition. Maximum length is 64 characters.')
+@maxLength(64)
+param name string
+
+@sys.description('Optional. The display name of the policy definition. Maximum length is 128 characters.')
+@maxLength(128)
+param displayName string = ''
+
+@sys.description('Optional. The policy definition description.')
+param description string = ''
+
+@sys.description('Optional. The policy definition mode. Default is All, Some examples are All, Indexed, Microsoft.KeyVault.Data.')
+@allowed([
+ 'All'
+ 'Indexed'
+ 'Microsoft.KeyVault.Data'
+ 'Microsoft.ContainerService.Data'
+ 'Microsoft.Kubernetes.Data'
+])
+param mode string = 'All'
+
+@sys.description('Optional. The policy Definition metadata. Metadata is an open ended object and is typically a collection of key-value pairs.')
+param metadata object = {}
+
+@sys.description('Optional. The policy definition parameters that can be used in policy definition references.')
+param parameters object = {}
+
+@sys.description('Required. The Policy Rule details for the Policy Definition')
+param policyRule object
+
+@sys.description('Optional. The subscription ID of the subscription')
+param subscriptionId string = subscription().subscriptionId
+
+resource policyDefinition 'Microsoft.Authorization/policyDefinitions@2021-06-01' = {
+ name: name
+ properties: {
+ policyType: 'Custom'
+ mode: mode
+ displayName: !empty(displayName) ? displayName : null
+ description: !empty(description) ? description : null
+ metadata: !empty(metadata) ? metadata : null
+ parameters: !empty(parameters) ? parameters : null
+ policyRule: policyRule
+ }
+}
+
+@sys.description('Policy Definition Name')
+output name string = policyDefinition.name
+
+@sys.description('Policy Definition resource ID')
+output resourceId string = subscriptionResourceId(subscriptionId, 'Microsoft.Authorization/policyDefinitions', policyDefinition.name)
+
+@sys.description('Policy Definition Role Definition IDs')
+output roleDefinitionIds array = (contains(policyDefinition.properties.policyRule.then, 'details') ? ((contains(policyDefinition.properties.policyRule.then.details, 'roleDefinitionIds') ? policyDefinition.properties.policyRule.then.details.roleDefinitionIds : [])) : [])
diff --git a/carml/1.0.0/Microsoft.Authorization/policyDefinitions/subscription/readme.md b/carml/1.0.0/Microsoft.Authorization/policyDefinitions/subscription/readme.md
new file mode 100644
index 000000000..4f47add45
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyDefinitions/subscription/readme.md
@@ -0,0 +1,34 @@
+# Policy Definitions on Subscription level `[Microsoft.Authorization/policyDefinitions/subscription]`
+
+With this module you can create policy definitions on a subscription level.
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/policyDefinitions` | 2021-06-01 |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `description` | string | | | Optional. The policy definition description. |
+| `displayName` | string | | | Optional. The display name of the policy definition. Maximum length is 128 characters. |
+| `metadata` | object | `{object}` | | Optional. The policy Definition metadata. Metadata is an open ended object and is typically a collection of key-value pairs. |
+| `mode` | string | `All` | `[All, Indexed, Microsoft.KeyVault.Data, Microsoft.ContainerService.Data, Microsoft.Kubernetes.Data]` | Optional. The policy definition mode. Default is All, Some examples are All, Indexed, Microsoft.KeyVault.Data. |
+| `name` | string | | | Required. Specifies the name of the policy definition. Maximum length is 64 characters. |
+| `parameters` | object | `{object}` | | Optional. The policy definition parameters that can be used in policy definition references. |
+| `policyRule` | object | | | Required. The Policy Rule details for the Policy Definition |
+| `subscriptionId` | string | `[subscription().subscriptionId]` | | Optional. The subscription ID of the subscription |
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | Policy Definition Name |
+| `resourceId` | string | Policy Definition resource ID |
+| `roleDefinitionIds` | array | Policy Definition Role Definition IDs |
+
+## Template references
+
+- [Policydefinitions](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2021-06-01/policyDefinitions)
diff --git a/carml/1.0.0/Microsoft.Authorization/policyDefinitions/subscription/version.json b/carml/1.0.0/Microsoft.Authorization/policyDefinitions/subscription/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyDefinitions/subscription/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policyDefinitions/version.json b/carml/1.0.0/Microsoft.Authorization/policyDefinitions/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyDefinitions/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policyExemptions/.parameters/mg.min.parameters.json b/carml/1.0.0/Microsoft.Authorization/policyExemptions/.parameters/mg.min.parameters.json
new file mode 100644
index 000000000..f5816fcd6
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyExemptions/.parameters/mg.min.parameters.json
@@ -0,0 +1,12 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-min-mg-polexem"
+ },
+ "policyAssignmentId": {
+ "value": "/providers/Microsoft.Management/managementGroups/<>/providers/Microsoft.Authorization/policyAssignments/adp-<>-mg-pass-loc-rg"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policyExemptions/.parameters/mg.parameters.json b/carml/1.0.0/Microsoft.Authorization/policyExemptions/.parameters/mg.parameters.json
new file mode 100644
index 000000000..2c76ecb64
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyExemptions/.parameters/mg.parameters.json
@@ -0,0 +1,29 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-mg-polexem"
+ },
+ "displayName": {
+ "value": "[Display Name] policy exempt (management group scope)"
+ },
+ "policyAssignmentId": {
+ "value": "/providers/Microsoft.Management/managementGroups/<>/providers/Microsoft.Authorization/policyAssignments/adp-<>-mg-pass-loc-rg"
+ },
+ "exemptionCategory": {
+ "value": "Waiver"
+ },
+ "metadata": {
+ "value": {
+ "category": "Security"
+ }
+ },
+ "expiresOn": {
+ "value": "2025-10-02T03:57:00.000Z"
+ },
+ "managementGroupId": {
+ "value": "<>"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policyExemptions/.parameters/rg.min.parameters.json b/carml/1.0.0/Microsoft.Authorization/policyExemptions/.parameters/rg.min.parameters.json
new file mode 100644
index 000000000..2573b17fe
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyExemptions/.parameters/rg.min.parameters.json
@@ -0,0 +1,18 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-min-rg-polexem"
+ },
+ "policyAssignmentId": {
+ "value": "/subscriptions/<>/providers/Microsoft.Authorization/policyAssignments/adp-<>-sb-pass-loc-rg"
+ },
+ "subscriptionId": {
+ "value": "<>"
+ },
+ "resourceGroupName": {
+ "value": "<>"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policyExemptions/.parameters/rg.parameters.json b/carml/1.0.0/Microsoft.Authorization/policyExemptions/.parameters/rg.parameters.json
new file mode 100644
index 000000000..68fda77de
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyExemptions/.parameters/rg.parameters.json
@@ -0,0 +1,32 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-rg-polexem"
+ },
+ "displayName": {
+ "value": "[Display Name] policy exempt (resource group scope)"
+ },
+ "policyAssignmentId": {
+ "value": "/subscriptions/<>/providers/Microsoft.Authorization/policyAssignments/adp-<>-sb-pass-loc-rg"
+ },
+ "exemptionCategory": {
+ "value": "Waiver"
+ },
+ "metadata": {
+ "value": {
+ "category": "Security"
+ }
+ },
+ "expiresOn": {
+ "value": "2025-10-02T03:57:00.000Z"
+ },
+ "subscriptionId": {
+ "value": "<>"
+ },
+ "resourceGroupName": {
+ "value": "<>"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policyExemptions/.parameters/sub.min.parameters.json b/carml/1.0.0/Microsoft.Authorization/policyExemptions/.parameters/sub.min.parameters.json
new file mode 100644
index 000000000..920e7d2ad
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyExemptions/.parameters/sub.min.parameters.json
@@ -0,0 +1,15 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-min-sub-polexem"
+ },
+ "policyAssignmentId": {
+ "value": "/subscriptions/<>/providers/Microsoft.Authorization/policyAssignments/adp-<>-sb-pass-loc-rg"
+ },
+ "subscriptionId": {
+ "value": "<>"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policyExemptions/.parameters/sub.parameters.json b/carml/1.0.0/Microsoft.Authorization/policyExemptions/.parameters/sub.parameters.json
new file mode 100644
index 000000000..02b3e9037
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyExemptions/.parameters/sub.parameters.json
@@ -0,0 +1,29 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-sub-polexem"
+ },
+ "displayName": {
+ "value": "[Display Name] policy exempt (subscription scope)"
+ },
+ "policyAssignmentId": {
+ "value": "/subscriptions/<>/providers/Microsoft.Authorization/policyAssignments/adp-<>-sb-pass-loc-rg"
+ },
+ "exemptionCategory": {
+ "value": "Waiver"
+ },
+ "metadata": {
+ "value": {
+ "category": "Security"
+ }
+ },
+ "expiresOn": {
+ "value": "2025-10-02T03:57:00.000Z"
+ },
+ "subscriptionId": {
+ "value": "<>"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policyExemptions/deploy.bicep b/carml/1.0.0/Microsoft.Authorization/policyExemptions/deploy.bicep
new file mode 100644
index 000000000..5f89ad16f
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyExemptions/deploy.bicep
@@ -0,0 +1,101 @@
+targetScope = 'managementGroup'
+
+@sys.description('Required. Specifies the name of the policy exemption. Maximum length is 64 characters for management group, subscription and resource group scopes.')
+@maxLength(64)
+param name string
+
+@sys.description('Optional. The display name of the policy exemption. Maximum length is 128 characters.')
+@maxLength(128)
+param displayName string = ''
+
+@sys.description('Optional. The description of the policy exemption.')
+param description string = ''
+
+@sys.description('Optional. The policy exemption metadata. Metadata is an open ended object and is typically a collection of key-value pairs.')
+param metadata object = {}
+
+@sys.description('Optional. The policy exemption category. Possible values are Waiver and Mitigated. Default is Mitigated')
+@allowed([
+ 'Mitigated'
+ 'Waiver'
+])
+param exemptionCategory string = 'Mitigated'
+
+@sys.description('Required. The resource ID of the policy assignment that is being exempted.')
+param policyAssignmentId string
+
+@sys.description('Optional. The policy definition reference ID list when the associated policy assignment is an assignment of a policy set definition.')
+param policyDefinitionReferenceIds array = []
+
+@sys.description('Optional. The expiration date and time (in UTC ISO 8601 format yyyy-MM-ddTHH:mm:ssZ) of the policy exemption. e.g. 2021-10-02T03:57:00.000Z ')
+param expiresOn string = ''
+
+@sys.description('Optional. The group ID of the management group to be exempted from the policy assignment. If not provided, will use the current scope for deployment.')
+param managementGroupId string = managementGroup().name
+
+@sys.description('Optional. The subscription ID of the subscription to be exempted from the policy assignment. Cannot use with management group ID parameter.')
+param subscriptionId string = ''
+
+@sys.description('Optional. The name of the resource group to be exempted from the policy assignment. Must also use the subscription ID parameter.')
+param resourceGroupName string = ''
+
+@sys.description('Optional. Location for all resources.')
+param location string = deployment().location
+
+module policyExemption_mg 'managementGroup/deploy.bicep' = if (empty(subscriptionId) && empty(resourceGroupName)) {
+ name: '${uniqueString(deployment().name, location)}-PolicyExemption-MG-Module'
+ scope: managementGroup(managementGroupId)
+ params: {
+ name: name
+ displayName: !empty(displayName) ? displayName : ''
+ description: !empty(description) ? description : ''
+ metadata: !empty(metadata) ? metadata : {}
+ exemptionCategory: exemptionCategory
+ policyAssignmentId: policyAssignmentId
+ policyDefinitionReferenceIds: !empty(policyDefinitionReferenceIds) ? policyDefinitionReferenceIds : []
+ expiresOn: !empty(expiresOn) ? expiresOn : ''
+ managementGroupId: managementGroupId
+ }
+}
+
+module policyExemption_sub 'subscription/deploy.bicep' = if (!empty(subscriptionId) && empty(resourceGroupName)) {
+ name: '${uniqueString(deployment().name, location)}-PolicyExemption-Sub-Module'
+ scope: subscription(subscriptionId)
+ params: {
+ name: name
+ displayName: !empty(displayName) ? displayName : ''
+ description: !empty(description) ? description : ''
+ metadata: !empty(metadata) ? metadata : {}
+ exemptionCategory: exemptionCategory
+ policyAssignmentId: policyAssignmentId
+ policyDefinitionReferenceIds: !empty(policyDefinitionReferenceIds) ? policyDefinitionReferenceIds : []
+ expiresOn: !empty(expiresOn) ? expiresOn : ''
+ subscriptionId: subscriptionId
+ }
+}
+
+module policyExemption_rg 'resourceGroup/deploy.bicep' = if (!empty(resourceGroupName) && !empty(subscriptionId)) {
+ name: '${uniqueString(deployment().name, location)}-PolicyExemption-RG-Module'
+ scope: resourceGroup(subscriptionId, resourceGroupName)
+ params: {
+ name: name
+ displayName: !empty(displayName) ? displayName : ''
+ description: !empty(description) ? description : ''
+ metadata: !empty(metadata) ? metadata : {}
+ exemptionCategory: exemptionCategory
+ policyAssignmentId: policyAssignmentId
+ policyDefinitionReferenceIds: !empty(policyDefinitionReferenceIds) ? policyDefinitionReferenceIds : []
+ expiresOn: !empty(expiresOn) ? expiresOn : ''
+ subscriptionId: subscriptionId
+ resourceGroupName: resourceGroupName
+ }
+}
+
+@sys.description('Policy Exemption Name')
+output name string = empty(subscriptionId) && empty(resourceGroupName) ? policyExemption_mg.outputs.name : (!empty(subscriptionId) && empty(resourceGroupName) ? policyExemption_sub.outputs.name : policyExemption_rg.outputs.name)
+
+@sys.description('Policy Exemption resource ID')
+output resourceId string = empty(subscriptionId) && empty(resourceGroupName) ? policyExemption_mg.outputs.resourceId : (!empty(subscriptionId) && empty(resourceGroupName) ? policyExemption_sub.outputs.resourceId : policyExemption_rg.outputs.resourceId)
+
+@sys.description('Policy Exemption Scope')
+output scope string = empty(subscriptionId) && empty(resourceGroupName) ? policyExemption_mg.outputs.scope : (!empty(subscriptionId) && empty(resourceGroupName) ? policyExemption_sub.outputs.scope : policyExemption_rg.outputs.scope)
diff --git a/carml/1.0.0/Microsoft.Authorization/policyExemptions/managementGroup/deploy.bicep b/carml/1.0.0/Microsoft.Authorization/policyExemptions/managementGroup/deploy.bicep
new file mode 100644
index 000000000..c1f1169e9
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyExemptions/managementGroup/deploy.bicep
@@ -0,0 +1,56 @@
+targetScope = 'managementGroup'
+
+@sys.description('Required. Specifies the name of the policy exemption. Maximum length is 64 characters for management group scope.')
+@maxLength(64)
+param name string
+
+@sys.description('Optional. The display name of the policy assignment. Maximum length is 128 characters.')
+@maxLength(128)
+param displayName string = ''
+
+@sys.description('Optional. The description of the policy exemption.')
+param description string = ''
+
+@sys.description('Optional. The policy exemption metadata. Metadata is an open ended object and is typically a collection of key-value pairs.')
+param metadata object = {}
+
+@sys.description('Optional. The policy exemption category. Possible values are Waiver and Mitigated. Default is Mitigated')
+@allowed([
+ 'Mitigated'
+ 'Waiver'
+])
+param exemptionCategory string = 'Mitigated'
+
+@sys.description('Required. The resource ID of the policy assignment that is being exempted.')
+param policyAssignmentId string
+
+@sys.description('Optional. The policy definition reference ID list when the associated policy assignment is an assignment of a policy set definition.')
+param policyDefinitionReferenceIds array = []
+
+@sys.description('Optional. The expiration date and time (in UTC ISO 8601 format yyyy-MM-ddTHH:mm:ssZ) of the policy exemption. e.g. 2021-10-02T03:57:00.000Z ')
+param expiresOn string = ''
+
+@sys.description('Optional. The group ID of the management group to be exempted from the policy assignment. If not provided, will use the current scope for deployment.')
+param managementGroupId string = managementGroup().name
+
+resource policyExemption 'Microsoft.Authorization/policyExemptions@2020-07-01-preview' = {
+ name: name
+ properties: {
+ displayName: !empty(displayName) ? displayName : null
+ description: !empty(description) ? description : null
+ metadata: !empty(metadata) ? metadata : null
+ exemptionCategory: exemptionCategory
+ policyAssignmentId: policyAssignmentId
+ policyDefinitionReferenceIds: !empty(policyDefinitionReferenceIds) ? policyDefinitionReferenceIds : []
+ expiresOn: !empty(expiresOn) ? expiresOn : null
+ }
+}
+
+@sys.description('Policy Exemption Name')
+output name string = policyExemption.name
+
+@sys.description('Policy Exemption resource ID')
+output resourceId string = extensionResourceId(tenantResourceId('Microsoft.Management/managementGroups', managementGroupId), 'Microsoft.Authorization/policyExemptions', policyExemption.name)
+
+@sys.description('Policy Exemption Scope')
+output scope string = tenantResourceId('Microsoft.Management/managementGroups', managementGroupId)
diff --git a/carml/1.0.0/Microsoft.Authorization/policyExemptions/managementGroup/readme.md b/carml/1.0.0/Microsoft.Authorization/policyExemptions/managementGroup/readme.md
new file mode 100644
index 000000000..3ac457016
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyExemptions/managementGroup/readme.md
@@ -0,0 +1,35 @@
+# Policy Exemptions on Management Group level `[Microsoft.Authorization/policyExemptions/managementGroup]`
+
+With this module you can create policy exemptions on a management group level.
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/policyExemptions` | 2020-07-01-preview |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `description` | string | | | Optional. The description of the policy exemption. |
+| `displayName` | string | | | Optional. The display name of the policy assignment. Maximum length is 128 characters. |
+| `exemptionCategory` | string | `Mitigated` | `[Mitigated, Waiver]` | Optional. The policy exemption category. Possible values are Waiver and Mitigated. Default is Mitigated |
+| `expiresOn` | string | | | Optional. The expiration date and time (in UTC ISO 8601 format yyyy-MM-ddTHH:mm:ssZ) of the policy exemption. e.g. 2021-10-02T03:57:00.000Z |
+| `managementGroupId` | string | `[managementGroup().name]` | | Optional. The group ID of the management group to be exempted from the policy assignment. If not provided, will use the current scope for deployment. |
+| `metadata` | object | `{object}` | | Optional. The policy exemption metadata. Metadata is an open ended object and is typically a collection of key-value pairs. |
+| `name` | string | | | Required. Specifies the name of the policy exemption. Maximum length is 64 characters for management group scope. |
+| `policyAssignmentId` | string | | | Required. The resource ID of the policy assignment that is being exempted. |
+| `policyDefinitionReferenceIds` | array | `[]` | | Optional. The policy definition reference ID list when the associated policy assignment is an assignment of a policy set definition. |
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | Policy Exemption Name |
+| `resourceId` | string | Policy Exemption resource ID |
+| `scope` | string | Policy Exemption Scope |
+
+## Template references
+
+- [Policyexemptions](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-07-01-preview/policyExemptions)
diff --git a/carml/1.0.0/Microsoft.Authorization/policyExemptions/managementGroup/version.json b/carml/1.0.0/Microsoft.Authorization/policyExemptions/managementGroup/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyExemptions/managementGroup/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policyExemptions/readme.md b/carml/1.0.0/Microsoft.Authorization/policyExemptions/readme.md
new file mode 100644
index 000000000..6936706c5
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyExemptions/readme.md
@@ -0,0 +1,100 @@
+# Policy Exemptions `[Microsoft.Authorization/policyExemptions]`
+
+With this module you can create policy exemptions across the management group, subscription or resource group scope.
+
+## Resource types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/policyExemptions` | 2020-07-01-preview |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `description` | string | | | Optional. The description of the policy exemption. |
+| `displayName` | string | | | Optional. The display name of the policy exemption. Maximum length is 128 characters. |
+| `exemptionCategory` | string | `Mitigated` | `[Mitigated, Waiver]` | Optional. The policy exemption category. Possible values are Waiver and Mitigated. Default is Mitigated |
+| `expiresOn` | string | | | Optional. The expiration date and time (in UTC ISO 8601 format yyyy-MM-ddTHH:mm:ssZ) of the policy exemption. e.g. 2021-10-02T03:57:00.000Z |
+| `location` | string | `[deployment().location]` | | Optional. Location for all resources. |
+| `managementGroupId` | string | `[managementGroup().name]` | | Optional. The group ID of the management group to be exempted from the policy assignment. If not provided, will use the current scope for deployment. |
+| `metadata` | object | `{object}` | | Optional. The policy exemption metadata. Metadata is an open ended object and is typically a collection of key-value pairs. |
+| `name` | string | | | Required. Specifies the name of the policy exemption. Maximum length is 64 characters for management group, subscription and resource group scopes. |
+| `policyAssignmentId` | string | | | Required. The resource ID of the policy assignment that is being exempted. |
+| `policyDefinitionReferenceIds` | array | `[]` | | Optional. The policy definition reference ID list when the associated policy assignment is an assignment of a policy set definition. |
+| `resourceGroupName` | string | | | Optional. The name of the resource group to be exempted from the policy assignment. Must also use the subscription ID parameter. |
+| `subscriptionId` | string | | | Optional. The subscription ID of the subscription to be exempted from the policy assignment. Cannot use with management group ID parameter. |
+
+### Parameter Usage: `managementGroupId`
+
+To deploy resource to a Management Group, provide the `managementGroupId` as an input parameter to the module.
+
+```json
+"managementGroupId": {
+ "value": "contoso-group"
+}
+```
+
+> `managementGroupId` is an optional parameter. If not provided, the deployment will use the management group defined in the current deployment scope (i.e. `managementGroup().name`).
+
+### Parameter Usage: `subscriptionId`
+
+To deploy resource to an Azure Subscription, provide the `subscriptionId` as an input parameter to the module. **Example**:
+
+```json
+"subscriptionId": {
+ "value": "12345678-b049-471c-95af-123456789012"
+}
+```
+
+### Parameter Usage: `resourceGroupName`
+
+To deploy resource to a Resource Group, provide the `subscriptionId` and `resourceGroupName` as an input parameter to the module. **Example**:
+
+```json
+"subscriptionId": {
+ "value": "12345678-b049-471c-95af-123456789012"
+},
+"resourceGroupName": {
+ "value": "target-resourceGroup"
+}
+```
+
+> The `subscriptionId` is used to enable deployment to a Resource Group Scope, allowing the use of the `resourceGroup()` function from a Management Group Scope. [Additional Details](https://github.com/Azure/bicep/pull/1420).
+
+## Module Usage Guidance
+
+In general, most of the resources under the `Microsoft.Authorization` namespace allows deploying resources at multiple scopes (management groups, subscriptions, resource groups). The `deploy.bicep` root module is simply an orchestrator module that targets sub-modules for different scopes as seen in the parameter usage section. All sub-modules for this namespace have folders that represent the target scope. For example, if the orchestrator module in the [root](deploy.bicep) needs to target 'subscription' level scopes. It will look at the relative path ['/subscription/deploy.bicep'](./subscription/deploy.bicep) and use this sub-module for the actual deployment, while still passing the same parameters from the root module.
+
+The above method is useful when you want to use a single point to interact with the module but rely on parameter combinations to achieve the target scope. But what if you want to incorporate this module in other modules with lower scopes? This would force you to deploy the module in scope `managementGroup` regardless and further require you to provide its ID with it. If you do not set the scope to management group, this would be the error that you can expect to face:
+
+```bicep
+Error BCP134: Scope "subscription" is not valid for this module. Permitted scopes: "managementGroup"
+```
+
+The solution is to have the option of directly targeting the sub-module that achieves the required scope. For example, if you have your own Bicep file wanting to create resources at the subscription level, and also use some of the modules from the `Microsoft.Authorization` namespace, then you can directly use the sub-module ['/subscription/deploy.bicep'](./subscription/deploy.bicep) as a path within your repository, or reference that same published module from the bicep registry. CARML also published the sub-modules so you would be able to reference it like the following:
+
+**Bicep Registry Reference**
+```bicep
+module policyexemption 'br:bicepregistry.azurecr.io/bicep/modules/microsoft.authorization.policyexemptions.subscription:version' = {}
+```
+**Local Path Reference**
+```bicep
+module policyexemption 'yourpath/arm/Microsoft.Authorization.policyExemptions/subscription/deploy.bicep' = {}
+```
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | Policy Exemption Name |
+| `resourceId` | string | Policy Exemption resource ID |
+| `scope` | string | Policy Exemption Scope |
+
+## Considerations
+
+- Policy Exemptions have a dependency on Policy Assignments being applied before creating an exemption. You can use the Policy Assignment [Module](../policyAssignments/deploy.bicep) to deploy a Policy Assignment and then create the exemption for it on the required scope.
+
+## Template references
+
+- [Policyexemptions](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-07-01-preview/policyExemptions)
diff --git a/carml/1.0.0/Microsoft.Authorization/policyExemptions/resourceGroup/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.Authorization/policyExemptions/resourceGroup/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyExemptions/resourceGroup/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.Authorization/policyExemptions/resourceGroup/deploy.bicep b/carml/1.0.0/Microsoft.Authorization/policyExemptions/resourceGroup/deploy.bicep
new file mode 100644
index 000000000..22caa4f38
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyExemptions/resourceGroup/deploy.bicep
@@ -0,0 +1,70 @@
+targetScope = 'resourceGroup'
+
+@sys.description('Required. Specifies the name of the policy exemption. Maximum length is 64 characters for resource group scope.')
+@maxLength(64)
+param name string
+
+@sys.description('Optional. The display name of the policy exemption. Maximum length is 128 characters.')
+@maxLength(128)
+param displayName string = ''
+
+@sys.description('Optional. The description of the policy exemption.')
+param description string = ''
+
+@sys.description('Optional. The policy exemption metadata. Metadata is an open ended object and is typically a collection of key-value pairs.')
+param metadata object = {}
+
+@sys.description('Optional. The policy exemption category. Possible values are Waiver and Mitigated. Default is Mitigated')
+@allowed([
+ 'Mitigated'
+ 'Waiver'
+])
+param exemptionCategory string = 'Mitigated'
+
+@sys.description('Required. The resource ID of the policy assignment that is being exempted.')
+param policyAssignmentId string
+
+@sys.description('Optional. The policy definition reference ID list when the associated policy assignment is an assignment of a policy set definition.')
+param policyDefinitionReferenceIds array = []
+
+@sys.description('Optional. The expiration date and time (in UTC ISO 8601 format yyyy-MM-ddTHH:mm:ssZ) of the policy exemption. e.g. 2021-10-02T03:57:00.000Z ')
+param expiresOn string = ''
+
+@sys.description('Optional. The subscription ID of the subscription to be exempted from the policy assignment. If not provided, will use the current scope for deployment.')
+param subscriptionId string = subscription().subscriptionId
+
+@sys.description('Optional. The name of the resource group to be exempted from the policy assignment. If not provided, will use the current scope for deployment.')
+param resourceGroupName string = resourceGroup().name
+
+@sys.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 policyExemption 'Microsoft.Authorization/policyExemptions@2020-07-01-preview' = {
+ name: name
+ properties: {
+ displayName: !empty(displayName) ? displayName : null
+ description: !empty(description) ? description : null
+ metadata: !empty(metadata) ? metadata : null
+ exemptionCategory: exemptionCategory
+ policyAssignmentId: policyAssignmentId
+ policyDefinitionReferenceIds: !empty(policyDefinitionReferenceIds) ? policyDefinitionReferenceIds : []
+ expiresOn: !empty(expiresOn) ? expiresOn : null
+ }
+}
+
+@sys.description('Policy Exemption Name')
+output name string = policyExemption.name
+
+@sys.description('Policy Exemption resource ID')
+output resourceId string = az.resourceId(subscriptionId, resourceGroupName, 'Microsoft.Authorization/policyExemptions', policyExemption.name)
+
+@sys.description('Policy Exemption Scope')
+output scope string = resourceGroup().id
+
+@sys.description('The name of the resource group the policy exemption was applied at')
+output resourceGroupName string = resourceGroup().name
diff --git a/carml/1.0.0/Microsoft.Authorization/policyExemptions/resourceGroup/readme.md b/carml/1.0.0/Microsoft.Authorization/policyExemptions/resourceGroup/readme.md
new file mode 100644
index 000000000..57fedef4e
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyExemptions/resourceGroup/readme.md
@@ -0,0 +1,38 @@
+# Policy Exemptions on Resource Group level `[Microsoft.Authorization/policyExemptions/resourceGroup]`
+
+With this module you can create policy exemptions on a resource group level.
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/policyExemptions` | 2020-07-01-preview |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered. |
+| `description` | string | | | Optional. The description of the policy exemption. |
+| `displayName` | string | | | Optional. The display name of the policy exemption. Maximum length is 128 characters. |
+| `exemptionCategory` | string | `Mitigated` | `[Mitigated, Waiver]` | Optional. The policy exemption category. Possible values are Waiver and Mitigated. Default is Mitigated |
+| `expiresOn` | string | | | Optional. The expiration date and time (in UTC ISO 8601 format yyyy-MM-ddTHH:mm:ssZ) of the policy exemption. e.g. 2021-10-02T03:57:00.000Z |
+| `metadata` | object | `{object}` | | Optional. The policy exemption metadata. Metadata is an open ended object and is typically a collection of key-value pairs. |
+| `name` | string | | | Required. Specifies the name of the policy exemption. Maximum length is 64 characters for resource group scope. |
+| `policyAssignmentId` | string | | | Required. The resource ID of the policy assignment that is being exempted. |
+| `policyDefinitionReferenceIds` | array | `[]` | | Optional. The policy definition reference ID list when the associated policy assignment is an assignment of a policy set definition. |
+| `resourceGroupName` | string | `[resourceGroup().name]` | | Optional. The name of the resource group to be exempted from the policy assignment. If not provided, will use the current scope for deployment. |
+| `subscriptionId` | string | `[subscription().subscriptionId]` | | Optional. The subscription ID of the subscription to be exempted from the policy assignment. If not provided, will use the current scope for deployment. |
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | Policy Exemption Name |
+| `resourceGroupName` | string | The name of the resource group the policy exemption was applied at |
+| `resourceId` | string | Policy Exemption resource ID |
+| `scope` | string | Policy Exemption Scope |
+
+## Template references
+
+- [Policyexemptions](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-07-01-preview/policyExemptions)
diff --git a/carml/1.0.0/Microsoft.Authorization/policyExemptions/resourceGroup/version.json b/carml/1.0.0/Microsoft.Authorization/policyExemptions/resourceGroup/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyExemptions/resourceGroup/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policyExemptions/subscription/deploy.bicep b/carml/1.0.0/Microsoft.Authorization/policyExemptions/subscription/deploy.bicep
new file mode 100644
index 000000000..9d8678ebb
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyExemptions/subscription/deploy.bicep
@@ -0,0 +1,56 @@
+targetScope = 'subscription'
+
+@sys.description('Required. Specifies the name of the policy exemption. Maximum length is 64 characters for subscription scope.')
+@maxLength(64)
+param name string
+
+@sys.description('Optional. The display name of the policy exemption. Maximum length is 128 characters.')
+@maxLength(128)
+param displayName string = ''
+
+@sys.description('Optional. The description of the policy exemption.')
+param description string = ''
+
+@sys.description('Optional. The policy exemption metadata. Metadata is an open ended object and is typically a collection of key-value pairs.')
+param metadata object = {}
+
+@sys.description('Optional. The policy exemption category. Possible values are Waiver and Mitigated. Default is Mitigated')
+@allowed([
+ 'Mitigated'
+ 'Waiver'
+])
+param exemptionCategory string = 'Mitigated'
+
+@sys.description('Required. The resource ID of the policy assignment that is being exempted.')
+param policyAssignmentId string
+
+@sys.description('Optional. The policy definition reference ID list when the associated policy assignment is an assignment of a policy set definition.')
+param policyDefinitionReferenceIds array = []
+
+@sys.description('Optional. The expiration date and time (in UTC ISO 8601 format yyyy-MM-ddTHH:mm:ssZ) of the policy exemption. e.g. 2021-10-02T03:57:00.000Z ')
+param expiresOn string = ''
+
+@sys.description('Optional. The subscription ID of the subscription to be exempted from the policy assignment. If not provided, will use the current scope for deployment.')
+param subscriptionId string = subscription().subscriptionId
+
+resource policyExemption 'Microsoft.Authorization/policyExemptions@2020-07-01-preview' = {
+ name: name
+ properties: {
+ displayName: !empty(displayName) ? displayName : null
+ description: !empty(description) ? description : null
+ metadata: !empty(metadata) ? metadata : null
+ exemptionCategory: exemptionCategory
+ policyAssignmentId: policyAssignmentId
+ policyDefinitionReferenceIds: !empty(policyDefinitionReferenceIds) ? policyDefinitionReferenceIds : []
+ expiresOn: !empty(expiresOn) ? expiresOn : null
+ }
+}
+
+@sys.description('Policy Exemption Name')
+output name string = policyExemption.name
+
+@sys.description('Policy Exemption resource ID')
+output resourceId string = subscriptionResourceId(subscriptionId, 'Microsoft.Authorization/policyExemptions', policyExemption.name)
+
+@sys.description('Policy Exemption Scope')
+output scope string = subscription().id
diff --git a/carml/1.0.0/Microsoft.Authorization/policyExemptions/subscription/readme.md b/carml/1.0.0/Microsoft.Authorization/policyExemptions/subscription/readme.md
new file mode 100644
index 000000000..111d44783
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyExemptions/subscription/readme.md
@@ -0,0 +1,35 @@
+# Policy Exemptions on Subscription level `[Microsoft.Authorization/policyExemptions/subscription]`
+
+With this module you can create policy exemptions on a subscription level.
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/policyExemptions` | 2020-07-01-preview |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `description` | string | | | Optional. The description of the policy exemption. |
+| `displayName` | string | | | Optional. The display name of the policy exemption. Maximum length is 128 characters. |
+| `exemptionCategory` | string | `Mitigated` | `[Mitigated, Waiver]` | Optional. The policy exemption category. Possible values are Waiver and Mitigated. Default is Mitigated |
+| `expiresOn` | string | | | Optional. The expiration date and time (in UTC ISO 8601 format yyyy-MM-ddTHH:mm:ssZ) of the policy exemption. e.g. 2021-10-02T03:57:00.000Z |
+| `metadata` | object | `{object}` | | Optional. The policy exemption metadata. Metadata is an open ended object and is typically a collection of key-value pairs. |
+| `name` | string | | | Required. Specifies the name of the policy exemption. Maximum length is 64 characters for subscription scope. |
+| `policyAssignmentId` | string | | | Required. The resource ID of the policy assignment that is being exempted. |
+| `policyDefinitionReferenceIds` | array | `[]` | | Optional. The policy definition reference ID list when the associated policy assignment is an assignment of a policy set definition. |
+| `subscriptionId` | string | `[subscription().subscriptionId]` | | Optional. The subscription ID of the subscription to be exempted from the policy assignment. If not provided, will use the current scope for deployment. |
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | Policy Exemption Name |
+| `resourceId` | string | Policy Exemption resource ID |
+| `scope` | string | Policy Exemption Scope |
+
+## Template references
+
+- [Policyexemptions](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-07-01-preview/policyExemptions)
diff --git a/carml/1.0.0/Microsoft.Authorization/policyExemptions/subscription/version.json b/carml/1.0.0/Microsoft.Authorization/policyExemptions/subscription/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyExemptions/subscription/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policyExemptions/version.json b/carml/1.0.0/Microsoft.Authorization/policyExemptions/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policyExemptions/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/.parameters/mg.min.parameters.json b/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/.parameters/mg.min.parameters.json
new file mode 100644
index 000000000..92f9d4ac2
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/.parameters/mg.min.parameters.json
@@ -0,0 +1,23 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-mg-min-policySet"
+ },
+ "policyDefinitions": {
+ "value": [
+ {
+ "parameters": {
+ "listOfAllowedLocations": {
+ "value": [
+ "australiaeast"
+ ]
+ }
+ },
+ "policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/e56962a6-4747-49cd-b67b-bf8b01975c4c"
+ }
+ ]
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/.parameters/mg.parameters.json b/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/.parameters/mg.parameters.json
new file mode 100644
index 000000000..029e2d47c
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/.parameters/mg.parameters.json
@@ -0,0 +1,66 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-mg-policySet"
+ },
+ "displayName": {
+ "value": "[DisplayName] This policy set definition is deployed at management group scope"
+ },
+ "description": {
+ "value": "[Description] This policy set definition is deployed at management group scope"
+ },
+ "policyDefinitionGroups": {
+ "value": [
+ {
+ "name": "Network"
+ },
+ {
+ "name": "ARM"
+ }
+ ]
+ },
+ "policyDefinitions": {
+ "value": [
+ {
+ "groupNames": [
+ "ARM"
+ ],
+ "parameters": {
+ "listOfAllowedLocations": {
+ "value": [
+ "australiaeast"
+ ]
+ }
+ },
+ "policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/e56962a6-4747-49cd-b67b-bf8b01975c4c",
+ "policyDefinitionReferenceId": "Allowed locations_1"
+ },
+ {
+ "groupNames": [
+ "ARM"
+ ],
+ "parameters": {
+ "listOfAllowedLocations": {
+ "value": [
+ "australiaeast"
+ ]
+ }
+ },
+ "policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/e765b5de-1225-4ba3-bd56-1ac6695af988",
+ "policyDefinitionReferenceId": "Allowed locations for resource groups_1"
+ }
+ ]
+ },
+ "metadata": {
+ "value": {
+ "category": "Security",
+ "version": "1"
+ }
+ },
+ "managementGroupId": {
+ "value": "<>"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/.parameters/sub.min.parameters.json b/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/.parameters/sub.min.parameters.json
new file mode 100644
index 000000000..f6a7e68f6
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/.parameters/sub.min.parameters.json
@@ -0,0 +1,26 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-sub-min-policySet"
+ },
+ "policyDefinitions": {
+ "value": [
+ {
+ "parameters": {
+ "listOfAllowedLocations": {
+ "value": [
+ "australiaeast"
+ ]
+ }
+ },
+ "policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/e56962a6-4747-49cd-b67b-bf8b01975c4c"
+ }
+ ]
+ },
+ "subscriptionId": {
+ "value": "<>"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/.parameters/sub.parameters.json b/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/.parameters/sub.parameters.json
new file mode 100644
index 000000000..16a92428b
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/.parameters/sub.parameters.json
@@ -0,0 +1,66 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-sub-policySet"
+ },
+ "displayName": {
+ "value": "[DisplayName] This policy set definition is deployed at subscription scope"
+ },
+ "description": {
+ "value": "[Description] This policy set definition is deployed at subscription scope"
+ },
+ "policyDefinitionGroups": {
+ "value": [
+ {
+ "name": "Network"
+ },
+ {
+ "name": "ARM"
+ }
+ ]
+ },
+ "policyDefinitions": {
+ "value": [
+ {
+ "groupNames": [
+ "ARM"
+ ],
+ "parameters": {
+ "listOfAllowedLocations": {
+ "value": [
+ "australiaeast"
+ ]
+ }
+ },
+ "policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/e56962a6-4747-49cd-b67b-bf8b01975c4c",
+ "policyDefinitionReferenceId": "Allowed locations_1"
+ },
+ {
+ "groupNames": [
+ "ARM"
+ ],
+ "parameters": {
+ "listOfAllowedLocations": {
+ "value": [
+ "australiaeast"
+ ]
+ }
+ },
+ "policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/e765b5de-1225-4ba3-bd56-1ac6695af988",
+ "policyDefinitionReferenceId": "Allowed locations for resource groups_1"
+ }
+ ]
+ },
+ "metadata": {
+ "value": {
+ "category": "Security",
+ "version": "1"
+ }
+ },
+ "subscriptionId": {
+ "value": "<>"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/deploy.bicep b/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/deploy.bicep
new file mode 100644
index 000000000..7aef6f525
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/deploy.bicep
@@ -0,0 +1,69 @@
+targetScope = 'managementGroup'
+
+@sys.description('Required. Specifies the name of the policy Set Definition (Initiative). Maximum length is 24 characters for management group scope and 64 characters for subscription scope.')
+@maxLength(64)
+param name string
+
+@sys.description('Optional. The display name of the Set Definition (Initiative). Maximum length is 128 characters.')
+@maxLength(128)
+param displayName string = ''
+
+@sys.description('Optional. The description name of the Set Definition (Initiative)')
+param description string = ''
+
+@sys.description('Optional. The group ID of the Management Group (Scope). If not provided, will use the current scope for deployment.')
+param managementGroupId string = managementGroup().name
+
+@sys.description('Optional. The subscription ID of the subscription (Scope). Cannot be used with managementGroupId')
+param subscriptionId string = ''
+
+@sys.description('Optional. The Set Definition (Initiative) metadata. Metadata is an open ended object and is typically a collection of key-value pairs.')
+param metadata object = {}
+
+@sys.description('Required. The array of Policy definitions object to include for this policy set. Each object must include the Policy definition ID, and optionally other properties like parameters')
+param policyDefinitions array
+
+@sys.description('Optional. The metadata describing groups of policy definition references within the Policy Set Definition (Initiative).')
+param policyDefinitionGroups array = []
+
+@sys.description('Optional. The Set Definition (Initiative) parameters that can be used in policy definition references.')
+param parameters object = {}
+
+@sys.description('Optional. Location for all resources.')
+param location string = deployment().location
+
+module policySetDefinition_mg 'managementGroup/deploy.bicep' = if (empty(subscriptionId)) {
+ name: '${uniqueString(deployment().name, location)}-PolicySetDefinition-MG-Module'
+ scope: managementGroup(managementGroupId)
+ params: {
+ name: name
+ displayName: !empty(displayName) ? displayName : ''
+ description: !empty(description) ? description : ''
+ metadata: !empty(metadata) ? metadata : {}
+ parameters: !empty(parameters) ? parameters : {}
+ policyDefinitions: policyDefinitions
+ policyDefinitionGroups: !empty(policyDefinitionGroups) ? policyDefinitionGroups : []
+ managementGroupId: managementGroupId
+ }
+}
+
+module policySetDefinition_sub 'subscription/deploy.bicep' = if (!empty(subscriptionId)) {
+ name: '${uniqueString(deployment().name, location)}-PolicySetDefinition-Sub-Module'
+ scope: subscription(subscriptionId)
+ params: {
+ name: name
+ displayName: !empty(displayName) ? displayName : ''
+ description: !empty(description) ? description : ''
+ metadata: !empty(metadata) ? metadata : {}
+ parameters: !empty(parameters) ? parameters : {}
+ policyDefinitions: policyDefinitions
+ policyDefinitionGroups: !empty(policyDefinitionGroups) ? policyDefinitionGroups : []
+ subscriptionId: subscriptionId
+ }
+}
+
+@sys.description('Policy Set Definition Name')
+output name string = empty(subscriptionId) ? policySetDefinition_mg.outputs.name : policySetDefinition_sub.outputs.name
+
+@sys.description('Policy Set Definition resource ID')
+output resourceId string = empty(subscriptionId) ? policySetDefinition_mg.outputs.resourceId : policySetDefinition_sub.outputs.resourceId
diff --git a/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/managementGroup/deploy.bicep b/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/managementGroup/deploy.bicep
new file mode 100644
index 000000000..192012e44
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/managementGroup/deploy.bicep
@@ -0,0 +1,46 @@
+targetScope = 'managementGroup'
+
+@sys.description('Required. Specifies the name of the policy Set Definition (Initiative). Maximum length is 24 characters for management group scope.')
+@maxLength(24)
+param name string
+
+@sys.description('Optional. The display name of the Set Definition (Initiative). Maximum length is 128 characters.')
+@maxLength(128)
+param displayName string = ''
+
+@sys.description('Optional. The description name of the Set Definition (Initiative)')
+param description string = ''
+
+@sys.description('Optional. The group ID of the Management Group. If not provided, will use the current scope for deployment.')
+param managementGroupId string = managementGroup().name
+
+@sys.description('Optional. The Set Definition (Initiative) metadata. Metadata is an open ended object and is typically a collection of key-value pairs.')
+param metadata object = {}
+
+@sys.description('Required. The array of Policy definitions object to include for this policy set. Each object must include the Policy definition ID, and optionally other properties like parameters')
+param policyDefinitions array
+
+@sys.description('Optional. The metadata describing groups of policy definition references within the Policy Set Definition (Initiative).')
+param policyDefinitionGroups array = []
+
+@sys.description('Optional. The Set Definition (Initiative) parameters that can be used in policy definition references.')
+param parameters object = {}
+
+resource policySetDefinition 'Microsoft.Authorization/policySetDefinitions@2021-06-01' = {
+ name: name
+ properties: {
+ policyType: 'Custom'
+ displayName: !empty(displayName) ? displayName : null
+ description: !empty(description) ? description : null
+ metadata: !empty(metadata) ? metadata : null
+ parameters: !empty(parameters) ? parameters : null
+ policyDefinitions: policyDefinitions
+ policyDefinitionGroups: !empty(policyDefinitionGroups) ? policyDefinitionGroups : []
+ }
+}
+
+@sys.description('Policy Set Definition Name')
+output name string = policySetDefinition.name
+
+@sys.description('Policy Set Definition resource ID')
+output resourceId string = extensionResourceId(tenantResourceId('Microsoft.Management/managementGroups', managementGroupId), 'Microsoft.Authorization/policySetDefinitions', policySetDefinition.name)
diff --git a/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/managementGroup/readme.md b/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/managementGroup/readme.md
new file mode 100644
index 000000000..17ed1856b
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/managementGroup/readme.md
@@ -0,0 +1,33 @@
+# Policy Set Definitions on Management Group level `[Microsoft.Authorization/policySetDefinitions/managementGroup]`
+
+With this module you can create policy set definitions on a management group level.
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/policySetDefinitions` | 2021-06-01 |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `description` | string | | | Optional. The description name of the Set Definition (Initiative) |
+| `displayName` | string | | | Optional. The display name of the Set Definition (Initiative). Maximum length is 128 characters. |
+| `managementGroupId` | string | `[managementGroup().name]` | | Optional. The group ID of the Management Group. If not provided, will use the current scope for deployment. |
+| `metadata` | object | `{object}` | | Optional. The Set Definition (Initiative) metadata. Metadata is an open ended object and is typically a collection of key-value pairs. |
+| `name` | string | | | Required. Specifies the name of the policy Set Definition (Initiative). Maximum length is 24 characters for management group scope. |
+| `parameters` | object | `{object}` | | Optional. The Set Definition (Initiative) parameters that can be used in policy definition references. |
+| `policyDefinitionGroups` | array | `[]` | | Optional. The metadata describing groups of policy definition references within the Policy Set Definition (Initiative). |
+| `policyDefinitions` | array | | | Required. The array of Policy definitions object to include for this policy set. Each object must include the Policy definition ID, and optionally other properties like parameters |
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | Policy Set Definition Name |
+| `resourceId` | string | Policy Set Definition resource ID |
+
+## Template references
+
+- [Policysetdefinitions](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2021-06-01/policySetDefinitions)
diff --git a/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/managementGroup/version.json b/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/managementGroup/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/managementGroup/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/readme.md b/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/readme.md
new file mode 100644
index 000000000..f2f27209c
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/readme.md
@@ -0,0 +1,82 @@
+# Policy Set Definitions `[Microsoft.Authorization/policySetDefinitions]`
+
+With this module you can create policy set definitions across the management group or subscription scope.
+
+## Resource types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/policySetDefinitions` | 2021-06-01 |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `description` | string | | | Optional. The description name of the Set Definition (Initiative) |
+| `displayName` | string | | | Optional. The display name of the Set Definition (Initiative). Maximum length is 128 characters. |
+| `location` | string | `[deployment().location]` | | Optional. Location for all resources. |
+| `managementGroupId` | string | `[managementGroup().name]` | | Optional. The group ID of the Management Group (Scope). If not provided, will use the current scope for deployment. |
+| `metadata` | object | `{object}` | | Optional. The Set Definition (Initiative) metadata. Metadata is an open ended object and is typically a collection of key-value pairs. |
+| `name` | string | | | Required. Specifies the name of the policy Set Definition (Initiative). Maximum length is 24 characters for management group scope and 64 characters for subscription scope. |
+| `parameters` | object | `{object}` | | Optional. The Set Definition (Initiative) parameters that can be used in policy definition references. |
+| `policyDefinitionGroups` | array | `[]` | | Optional. The metadata describing groups of policy definition references within the Policy Set Definition (Initiative). |
+| `policyDefinitions` | array | | | Required. The array of Policy definitions object to include for this policy set. Each object must include the Policy definition ID, and optionally other properties like parameters |
+| `subscriptionId` | string | | | Optional. The subscription ID of the subscription (Scope). Cannot be used with managementGroupId |
+
+### Parameter Usage: `managementGroupId`
+
+To deploy resource to a Management Group, provide the `managementGroupId` as an input parameter to the module.
+
+```json
+"managementGroupId": {
+ "value": "contoso-group"
+}
+```
+
+> `managementGroupId` is an optional parameter. If not provided, the deployment will use the management group defined in the current deployment scope (i.e. `managementGroup().name`).
+
+### Parameter Usage: `subscriptionId`
+
+To deploy resource to an Azure Subscription, provide the `subscriptionId` as an input parameter to the module. **Example**:
+
+```json
+"subscriptionId": {
+ "value": "12345678-b049-471c-95af-123456789012"
+}
+```
+
+## Module Usage Guidance
+
+In general, most of the resources under the `Microsoft.Authorization` namespace allows deploying resources at multiple scopes (management groups, subscriptions, resource groups). The `deploy.bicep` root module is simply an orchestrator module that targets sub-modules for different scopes as seen in the parameter usage section. All sub-modules for this namespace have folders that represent the target scope. For example, if the orchestrator module in the [root](deploy.bicep) needs to target 'subscription' level scopes. It will look at the relative path ['/subscription/deploy.bicep'](./subscription/deploy.bicep) and use this sub-module for the actual deployment, while still passing the same parameters from the root module.
+
+The above method is useful when you want to use a single point to interact with the module but rely on parameter combinations to achieve the target scope. But what if you want to incorporate this module in other modules with lower scopes? This would force you to deploy the module in scope `managementGroup` regardless and further require you to provide its ID with it. If you do not set the scope to management group, this would be the error that you can expect to face:
+
+```bicep
+Error BCP134: Scope "subscription" is not valid for this module. Permitted scopes: "managementGroup"
+```
+
+The solution is to have the option of directly targeting the sub-module that achieves the required scope. For example, if you have your own Bicep file wanting to create resources at the subscription level, and also use some of the modules from the `Microsoft.Authorization` namespace, then you can directly use the sub-module ['/subscription/deploy.bicep'](./subscription/deploy.bicep) as a path within your repository, or reference that same published module from the bicep registry. CARML also published the sub-modules so you would be able to reference it like the following:
+
+**Bicep Registry Reference**
+```bicep
+module policysetdefinition 'br:bicepregistry.azurecr.io/bicep/modules/microsoft.authorization.policysetdefinitions.subscription:version' = {}
+```
+**Local Path Reference**
+```bicep
+module policysetdefinition 'yourpath/arm/Microsoft.Authorization.policySetDefinitions/subscription/deploy.bicep' = {}
+```
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | Policy Set Definition Name |
+| `resourceId` | string | Policy Set Definition resource ID |
+
+## Considerations
+
+- Policy Set Definitions (Initiatives) have a dependency on Policy Assignments being applied before creating an initiative. You can use the Policy Assignment [Module](../policyDefinitions/deploy.bicep) to deploy a Policy Definition and then create an initiative for it on the required scope.
+
+## Template references
+
+- [Policysetdefinitions](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2021-06-01/policySetDefinitions)
diff --git a/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/subscription/deploy.bicep b/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/subscription/deploy.bicep
new file mode 100644
index 000000000..236bc90c5
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/subscription/deploy.bicep
@@ -0,0 +1,46 @@
+targetScope = 'subscription'
+
+@sys.description('Required. Specifies the name of the policy Set Definition (Initiative). Maximum length is 64 characters for subscription scope.')
+@maxLength(64)
+param name string
+
+@sys.description('Optional. The display name of the Set Definition (Initiative). Maximum length is 128 characters.')
+@maxLength(128)
+param displayName string = ''
+
+@sys.description('Optional. The description name of the Set Definition (Initiative)')
+param description string = ''
+
+@sys.description('Optional. The subscription ID of the subscription')
+param subscriptionId string = subscription().subscriptionId
+
+@sys.description('Optional. The Set Definition (Initiative) metadata. Metadata is an open ended object and is typically a collection of key-value pairs.')
+param metadata object = {}
+
+@sys.description('Required. The array of Policy definitions object to include for this policy set. Each object must include the Policy definition ID, and optionally other properties like parameters')
+param policyDefinitions array
+
+@sys.description('Optional. The metadata describing groups of policy definition references within the Policy Set Definition (Initiative).')
+param policyDefinitionGroups array = []
+
+@sys.description('Optional. The Set Definition (Initiative) parameters that can be used in policy definition references.')
+param parameters object = {}
+
+resource policySetDefinition 'Microsoft.Authorization/policySetDefinitions@2021-06-01' = {
+ name: name
+ properties: {
+ policyType: 'Custom'
+ displayName: !empty(displayName) ? displayName : null
+ description: !empty(description) ? description : null
+ metadata: !empty(metadata) ? metadata : null
+ parameters: !empty(parameters) ? parameters : null
+ policyDefinitions: policyDefinitions
+ policyDefinitionGroups: !empty(policyDefinitionGroups) ? policyDefinitionGroups : []
+ }
+}
+
+@sys.description('Policy Set Definition Name')
+output name string = policySetDefinition.name
+
+@sys.description('Policy Set Definition resource ID')
+output resourceId string = subscriptionResourceId(subscriptionId, 'Microsoft.Authorization/policySetDefinitions', policySetDefinition.name)
diff --git a/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/subscription/readme.md b/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/subscription/readme.md
new file mode 100644
index 000000000..11a83a542
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/subscription/readme.md
@@ -0,0 +1,33 @@
+# Policy Set Definitions on Subscription level `[Microsoft.Authorization/policySetDefinitions/subscription]`
+
+With this module you can create policy set definitions on a subscription level.
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/policySetDefinitions` | 2021-06-01 |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `description` | string | | | Optional. The description name of the Set Definition (Initiative) |
+| `displayName` | string | | | Optional. The display name of the Set Definition (Initiative). Maximum length is 128 characters. |
+| `metadata` | object | `{object}` | | Optional. The Set Definition (Initiative) metadata. Metadata is an open ended object and is typically a collection of key-value pairs. |
+| `name` | string | | | Required. Specifies the name of the policy Set Definition (Initiative). Maximum length is 64 characters for subscription scope. |
+| `parameters` | object | `{object}` | | Optional. The Set Definition (Initiative) parameters that can be used in policy definition references. |
+| `policyDefinitionGroups` | array | `[]` | | Optional. The metadata describing groups of policy definition references within the Policy Set Definition (Initiative). |
+| `policyDefinitions` | array | | | Required. The array of Policy definitions object to include for this policy set. Each object must include the Policy definition ID, and optionally other properties like parameters |
+| `subscriptionId` | string | `[subscription().subscriptionId]` | | Optional. The subscription ID of the subscription |
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | Policy Set Definition Name |
+| `resourceId` | string | Policy Set Definition resource ID |
+
+## Template references
+
+- [Policysetdefinitions](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2021-06-01/policySetDefinitions)
diff --git a/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/subscription/version.json b/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/subscription/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/subscription/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/version.json b/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/policySetDefinitions/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/roleAssignments/.parameters/mg.min.parameters.json b/carml/1.0.0/Microsoft.Authorization/roleAssignments/.parameters/mg.min.parameters.json
new file mode 100644
index 000000000..02a409875
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleAssignments/.parameters/mg.min.parameters.json
@@ -0,0 +1,12 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "roleDefinitionIdOrName": {
+ "value": "Storage Queue Data Reader"
+ },
+ "principalId": {
+ "value": "<>"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/roleAssignments/.parameters/mg.parameters.json b/carml/1.0.0/Microsoft.Authorization/roleAssignments/.parameters/mg.parameters.json
new file mode 100644
index 000000000..e6362b62a
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleAssignments/.parameters/mg.parameters.json
@@ -0,0 +1,21 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "roleDefinitionIdOrName": {
+ "value": "Backup Reader"
+ },
+ "description": {
+ "value": "Role Assignment (management group scope)"
+ },
+ "principalId": {
+ "value": "<>"
+ },
+ "principalType": {
+ "value": "ServicePrincipal"
+ },
+ "managementGroupId": {
+ "value": "<>"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/roleAssignments/.parameters/rg.min.parameters.json b/carml/1.0.0/Microsoft.Authorization/roleAssignments/.parameters/rg.min.parameters.json
new file mode 100644
index 000000000..6011dc7e9
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleAssignments/.parameters/rg.min.parameters.json
@@ -0,0 +1,18 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "roleDefinitionIdOrName": {
+ "value": "Storage Queue Data Reader"
+ },
+ "principalId": {
+ "value": "<>"
+ },
+ "subscriptionId": {
+ "value": "<>"
+ },
+ "resourceGroupName": {
+ "value": "<>"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/roleAssignments/.parameters/rg.parameters.json b/carml/1.0.0/Microsoft.Authorization/roleAssignments/.parameters/rg.parameters.json
new file mode 100644
index 000000000..faf9fc3d9
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleAssignments/.parameters/rg.parameters.json
@@ -0,0 +1,24 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "roleDefinitionIdOrName": {
+ "value": "Backup Reader"
+ },
+ "description": {
+ "value": "Role Assignment (resource group scope)"
+ },
+ "principalId": {
+ "value": "<>"
+ },
+ "principalType": {
+ "value": "ServicePrincipal"
+ },
+ "subscriptionId": {
+ "value": "<>"
+ },
+ "resourceGroupName": {
+ "value": "<>"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/roleAssignments/.parameters/sub.min.parameters.json b/carml/1.0.0/Microsoft.Authorization/roleAssignments/.parameters/sub.min.parameters.json
new file mode 100644
index 000000000..2a90f97fb
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleAssignments/.parameters/sub.min.parameters.json
@@ -0,0 +1,15 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "roleDefinitionIdOrName": {
+ "value": "Storage Queue Data Reader"
+ },
+ "principalId": {
+ "value": "<>"
+ },
+ "subscriptionId": {
+ "value": "<>"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/roleAssignments/.parameters/sub.parameters.json b/carml/1.0.0/Microsoft.Authorization/roleAssignments/.parameters/sub.parameters.json
new file mode 100644
index 000000000..346ba64c0
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleAssignments/.parameters/sub.parameters.json
@@ -0,0 +1,21 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "roleDefinitionIdOrName": {
+ "value": "Backup Reader"
+ },
+ "description": {
+ "value": "Role Assignment (subscription scope)"
+ },
+ "principalId": {
+ "value": "<>"
+ },
+ "principalType": {
+ "value": "ServicePrincipal"
+ },
+ "subscriptionId": {
+ "value": "<>"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/roleAssignments/deploy.bicep b/carml/1.0.0/Microsoft.Authorization/roleAssignments/deploy.bicep
new file mode 100644
index 000000000..01a069ea8
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleAssignments/deploy.bicep
@@ -0,0 +1,100 @@
+targetScope = 'managementGroup'
+
+@sys.description('Required. 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 roleDefinitionIdOrName string
+
+@sys.description('Required. The Principal or Object ID of the Security Principal (User, Group, Service Principal, Managed Identity)')
+param principalId string
+
+@sys.description('Optional. Name of the Resource Group to assign the RBAC role to. If Resource Group name is provided, and Subscription ID is provided, the module deploys at resource group level, therefore assigns the provided RBAC role to the resource group.')
+param resourceGroupName string = ''
+
+@sys.description('Optional. Subscription ID of the subscription to assign the RBAC role to. If no Resource Group name is provided, the module deploys at subscription level, therefore assigns the provided RBAC role to the subscription.')
+param subscriptionId string = ''
+
+@sys.description('Optional. Group ID of the Management Group to assign the RBAC role to. If not provided, will use the current scope for deployment.')
+param managementGroupId string = managementGroup().name
+
+@sys.description('Optional. Location for all resources.')
+param location string = deployment().location
+
+@sys.description('Optional. Description of role assignment')
+param description string = ''
+
+@sys.description('Optional. ID of the delegated managed identity resource')
+param delegatedManagedIdentityResourceId string = ''
+
+@sys.description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to')
+param condition string = ''
+
+@sys.description('Optional. Version of the condition. Currently accepted value is "2.0"')
+@allowed([
+ '2.0'
+])
+param conditionVersion string = '2.0'
+
+@sys.description('Optional. The principal type of the assigned principal ID.')
+@allowed([
+ 'ServicePrincipal'
+ 'Group'
+ 'User'
+ 'ForeignGroup'
+ 'Device'
+ ''
+])
+param principalType string = ''
+
+module roleAssignment_mg 'managementGroup/deploy.bicep' = if (empty(subscriptionId) && empty(resourceGroupName)) {
+ name: '${uniqueString(deployment().name, location)}-RoleAssignment-MG-Module'
+ scope: managementGroup(managementGroupId)
+ params: {
+ roleDefinitionIdOrName: roleDefinitionIdOrName
+ principalId: principalId
+ managementGroupId: managementGroupId
+ description: !empty(description) ? description : ''
+ principalType: !empty(principalType) ? principalType : ''
+ delegatedManagedIdentityResourceId: !empty(delegatedManagedIdentityResourceId) ? delegatedManagedIdentityResourceId : ''
+ conditionVersion: conditionVersion
+ condition: !empty(condition) ? condition : ''
+ }
+}
+
+module roleAssignment_sub 'subscription/deploy.bicep' = if (!empty(subscriptionId) && empty(resourceGroupName)) {
+ name: '${uniqueString(deployment().name, location)}-RoleAssignment-Sub-Module'
+ scope: subscription(subscriptionId)
+ params: {
+ roleDefinitionIdOrName: roleDefinitionIdOrName
+ principalId: principalId
+ subscriptionId: subscriptionId
+ description: !empty(description) ? description : ''
+ principalType: !empty(principalType) ? principalType : ''
+ delegatedManagedIdentityResourceId: !empty(delegatedManagedIdentityResourceId) ? delegatedManagedIdentityResourceId : ''
+ conditionVersion: conditionVersion
+ condition: !empty(condition) ? condition : ''
+ }
+}
+
+module roleAssignment_rg 'resourceGroup/deploy.bicep' = if (!empty(resourceGroupName) && !empty(subscriptionId)) {
+ name: '${uniqueString(deployment().name, location)}-RoleAssignment-RG-Module'
+ scope: resourceGroup(subscriptionId, resourceGroupName)
+ params: {
+ roleDefinitionIdOrName: roleDefinitionIdOrName
+ principalId: principalId
+ subscriptionId: subscriptionId
+ resourceGroupName: resourceGroupName
+ description: !empty(description) ? description : ''
+ principalType: !empty(principalType) ? principalType : ''
+ delegatedManagedIdentityResourceId: !empty(delegatedManagedIdentityResourceId) ? delegatedManagedIdentityResourceId : ''
+ conditionVersion: conditionVersion
+ condition: !empty(condition) ? condition : ''
+ }
+}
+
+@sys.description('The GUID of the Role Assignment')
+output name string = empty(subscriptionId) && empty(resourceGroupName) ? roleAssignment_mg.outputs.name : (!empty(subscriptionId) && empty(resourceGroupName) ? roleAssignment_sub.outputs.name : roleAssignment_rg.outputs.name)
+
+@sys.description('The resource ID of the Role Assignment')
+output resourceId string = empty(subscriptionId) && empty(resourceGroupName) ? roleAssignment_mg.outputs.resourceId : (!empty(subscriptionId) && empty(resourceGroupName) ? roleAssignment_sub.outputs.resourceId : roleAssignment_rg.outputs.resourceId)
+
+@sys.description('The scope this Role Assignment applies to')
+output scope string = empty(subscriptionId) && empty(resourceGroupName) ? roleAssignment_mg.outputs.scope : (!empty(subscriptionId) && empty(resourceGroupName) ? roleAssignment_sub.outputs.scope : roleAssignment_rg.outputs.scope)
diff --git a/carml/1.0.0/Microsoft.Authorization/roleAssignments/managementGroup/deploy.bicep b/carml/1.0.0/Microsoft.Authorization/roleAssignments/managementGroup/deploy.bicep
new file mode 100644
index 000000000..1bc2e4ce8
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleAssignments/managementGroup/deploy.bicep
@@ -0,0 +1,344 @@
+targetScope = 'managementGroup'
+
+@sys.description('Required. 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 roleDefinitionIdOrName string
+
+@sys.description('Required. The Principal or Object ID of the Security Principal (User, Group, Service Principal, Managed Identity)')
+param principalId string
+
+@sys.description('Optional. Group ID of the Management Group to assign the RBAC role to. If not provided, will use the current scope for deployment.')
+param managementGroupId string = managementGroup().name
+
+@sys.description('Optional. Description of role assignment')
+param description string = ''
+
+@sys.description('Optional. ID of the delegated managed identity resource')
+param delegatedManagedIdentityResourceId string = ''
+
+@sys.description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to')
+param condition string = ''
+
+@sys.description('Optional. Version of the condition. Currently accepted value is "2.0"')
+@allowed([
+ '2.0'
+])
+param conditionVersion string = '2.0'
+
+@sys.description('Optional. The principal type of the assigned principal ID.')
+@allowed([
+ 'ServicePrincipal'
+ 'Group'
+ 'User'
+ 'ForeignGroup'
+ 'Device'
+ ''
+])
+param principalType string = ''
+
+var builtInRoleNames_var = {
+ 'AcrPush': '/providers/Microsoft.Authorization/roleDefinitions/8311e382-0749-4cb8-b61a-304f252e45ec'
+ 'API Management Service Contributor': '/providers/Microsoft.Authorization/roleDefinitions/312a565d-c81f-4fd8-895a-4e21e48d571c'
+ 'AcrPull': '/providers/Microsoft.Authorization/roleDefinitions/7f951dda-4ed3-4680-a7ca-43fe172d538d'
+ 'AcrImageSigner': '/providers/Microsoft.Authorization/roleDefinitions/6cef56e8-d556-48e5-a04f-b8e64114680f'
+ 'AcrDelete': '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'
+ 'AcrQuarantineReader': '/providers/Microsoft.Authorization/roleDefinitions/cdda3590-29a3-44f6-95f2-9f980659eb04'
+ 'AcrQuarantineWriter': '/providers/Microsoft.Authorization/roleDefinitions/c8d4ff99-41c3-41a8-9f60-21dfdad59608'
+ 'API Management Service Operator Role': '/providers/Microsoft.Authorization/roleDefinitions/e022efe7-f5ba-4159-bbe4-b44f577e9b61'
+ 'API Management Service Reader Role': '/providers/Microsoft.Authorization/roleDefinitions/71522526-b88f-4d52-b57f-d31fc3546d0d'
+ 'Application Insights Component Contributor': '/providers/Microsoft.Authorization/roleDefinitions/ae349356-3a1b-4a5e-921d-050484c6347e'
+ 'Application Insights Snapshot Debugger': '/providers/Microsoft.Authorization/roleDefinitions/08954f03-6346-4c2e-81c0-ec3a5cfae23b'
+ 'Attestation Reader': '/providers/Microsoft.Authorization/roleDefinitions/fd1bd22b-8476-40bc-a0bc-69b95687b9f3'
+ 'Automation Job Operator': '/providers/Microsoft.Authorization/roleDefinitions/4fe576fe-1146-4730-92eb-48519fa6bf9f'
+ 'Automation Runbook Operator': '/providers/Microsoft.Authorization/roleDefinitions/5fb5aef8-1081-4b8e-bb16-9d5d0385bab5'
+ 'Automation Operator': '/providers/Microsoft.Authorization/roleDefinitions/d3881f73-407a-4167-8283-e981cbba0404'
+ 'Avere Contributor': '/providers/Microsoft.Authorization/roleDefinitions/4f8fab4f-1852-4a58-a46a-8eaf358af14a'
+ 'Avere Operator': '/providers/Microsoft.Authorization/roleDefinitions/c025889f-8102-4ebf-b32c-fc0c6f0c6bd9'
+ 'Azure Kubernetes Service Cluster Admin Role': '/providers/Microsoft.Authorization/roleDefinitions/0ab0b1a8-8aac-4efd-b8c2-3ee1fb270be8'
+ 'Azure Kubernetes Service Cluster User Role': '/providers/Microsoft.Authorization/roleDefinitions/4abbcc35-e782-43d8-92c5-2d3f1bd2253f'
+ 'Azure Maps Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/423170ca-a8f6-4b0f-8487-9e4eb8f49bfa'
+ 'Azure Stack Registration Owner': '/providers/Microsoft.Authorization/roleDefinitions/6f12a6df-dd06-4f3e-bcb1-ce8be600526a'
+ 'Backup Contributor': '/providers/Microsoft.Authorization/roleDefinitions/5e467623-bb1f-42f4-a55d-6e525e11384b'
+ 'Billing Reader': '/providers/Microsoft.Authorization/roleDefinitions/fa23ad8b-c56e-40d8-ac0c-ce449e1d2c64'
+ 'Backup Operator': '/providers/Microsoft.Authorization/roleDefinitions/00c29273-979b-4161-815c-10b084fb9324'
+ 'Backup Reader': '/providers/Microsoft.Authorization/roleDefinitions/a795c7a0-d4a2-40c1-ae25-d81f01202912'
+ 'BizTalk Contributor': '/providers/Microsoft.Authorization/roleDefinitions/5e3c6656-6cfa-4708-81fe-0de47ac73342'
+ 'CDN Endpoint Contributor': '/providers/Microsoft.Authorization/roleDefinitions/426e0c7f-0c7e-4658-b36f-ff54d6c29b45'
+ 'CDN Endpoint Reader': '/providers/Microsoft.Authorization/roleDefinitions/871e35f6-b5c1-49cc-a043-bde969a0f2cd'
+ 'CDN Profile Contributor': '/providers/Microsoft.Authorization/roleDefinitions/ec156ff8-a8d1-4d15-830c-5b80698ca432'
+ 'CDN Profile Reader': '/providers/Microsoft.Authorization/roleDefinitions/8f96442b-4075-438f-813d-ad51ab4019af'
+ 'Classic Network Contributor': '/providers/Microsoft.Authorization/roleDefinitions/b34d265f-36f7-4a0d-a4d4-e158ca92e90f'
+ 'Classic Storage Account Contributor': '/providers/Microsoft.Authorization/roleDefinitions/86e8f5dc-a6e9-4c67-9d15-de283e8eac25'
+ 'Classic Storage Account Key Operator Service Role': '/providers/Microsoft.Authorization/roleDefinitions/985d6b00-f706-48f5-a6fe-d0ca12fb668d'
+ 'ClearDB MySQL DB Contributor': '/providers/Microsoft.Authorization/roleDefinitions/9106cda0-8a86-4e81-b686-29a22c54effe'
+ 'Classic Virtual Machine Contributor': '/providers/Microsoft.Authorization/roleDefinitions/d73bb868-a0df-4d4d-bd69-98a00b01fccb'
+ 'Cognitive Services User': '/providers/Microsoft.Authorization/roleDefinitions/a97b65f3-24c7-4388-baec-2e87135dc908'
+ 'Cognitive Services Contributor': '/providers/Microsoft.Authorization/roleDefinitions/25fbc0a9-bd7c-42a3-aa1a-3b75d497ee68'
+ 'CosmosBackupOperator': '/providers/Microsoft.Authorization/roleDefinitions/db7b14f2-5adf-42da-9f96-f2ee17bab5cb'
+ 'Contributor': '/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c'
+ 'Cosmos DB Account Reader Role': '/providers/Microsoft.Authorization/roleDefinitions/fbdf93bf-df7d-467e-a4d2-9458aa1360c8'
+ 'Cost Management Contributor': '/providers/Microsoft.Authorization/roleDefinitions/434105ed-43f6-45c7-a02f-909b2ba83430'
+ 'Cost Management Reader': '/providers/Microsoft.Authorization/roleDefinitions/72fafb9e-0641-4937-9268-a91bfd8191a3'
+ 'Data Box Contributor': '/providers/Microsoft.Authorization/roleDefinitions/add466c9-e687-43fc-8d98-dfcf8d720be5'
+ 'Data Box Reader': '/providers/Microsoft.Authorization/roleDefinitions/028f4ed7-e2a9-465e-a8f4-9c0ffdfdc027'
+ 'Data Factory Contributor': '/providers/Microsoft.Authorization/roleDefinitions/673868aa-7521-48a0-acc6-0f60742d39f5'
+ 'Data Purger': '/providers/Microsoft.Authorization/roleDefinitions/150f5e0c-0603-4f03-8c7f-cf70034c4e90'
+ 'Data Lake Analytics Developer': '/providers/Microsoft.Authorization/roleDefinitions/47b7735b-770e-4598-a7da-8b91488b4c88'
+ 'DevTest Labs User': '/providers/Microsoft.Authorization/roleDefinitions/76283e04-6283-4c54-8f91-bcf1374a3c64'
+ 'DocumentDB Account Contributor': '/providers/Microsoft.Authorization/roleDefinitions/5bd9cd88-fe45-4216-938b-f97437e15450'
+ 'DNS Zone Contributor': '/providers/Microsoft.Authorization/roleDefinitions/befefa01-2a29-4197-83a8-272ff33ce314'
+ 'EventGrid EventSubscription Contributor': '/providers/Microsoft.Authorization/roleDefinitions/428e0ff0-5e57-4d9c-a221-2c70d0e0a443'
+ 'EventGrid EventSubscription Reader': '/providers/Microsoft.Authorization/roleDefinitions/2414bbcf-6497-4faf-8c65-045460748405'
+ 'Graph Owner': '/providers/Microsoft.Authorization/roleDefinitions/b60367af-1334-4454-b71e-769d9a4f83d9'
+ 'HDInsight Domain Services Contributor': '/providers/Microsoft.Authorization/roleDefinitions/8d8d5a11-05d3-4bda-a417-a08778121c7c'
+ 'Intelligent Systems Account Contributor': '/providers/Microsoft.Authorization/roleDefinitions/03a6d094-3444-4b3d-88af-7477090a9e5e'
+ 'Key Vault Contributor': '/providers/Microsoft.Authorization/roleDefinitions/f25e0fa2-a7c8-4377-a976-54943a77a395'
+ 'Knowledge Consumer': '/providers/Microsoft.Authorization/roleDefinitions/ee361c5d-f7b5-4119-b4b6-892157c8f64c'
+ 'Lab Creator': '/providers/Microsoft.Authorization/roleDefinitions/b97fb8bc-a8b2-4522-a38b-dd33c7e65ead'
+ 'Log Analytics Reader': '/providers/Microsoft.Authorization/roleDefinitions/73c42c96-874c-492b-b04d-ab87d138a893'
+ 'Log Analytics Contributor': '/providers/Microsoft.Authorization/roleDefinitions/92aaf0da-9dab-42b6-94a3-d43ce8d16293'
+ 'Logic App Operator': '/providers/Microsoft.Authorization/roleDefinitions/515c2055-d9d4-4321-b1b9-bd0c9a0f79fe'
+ 'Logic App Contributor': '/providers/Microsoft.Authorization/roleDefinitions/87a39d53-fc1b-424a-814c-f7e04687dc9e'
+ 'Managed Application Operator Role': '/providers/Microsoft.Authorization/roleDefinitions/c7393b34-138c-406f-901b-d8cf2b17e6ae'
+ 'Managed Applications Reader': '/providers/Microsoft.Authorization/roleDefinitions/b9331d33-8a36-4f8c-b097-4f54124fdb44'
+ 'Managed Identity Operator': '/providers/Microsoft.Authorization/roleDefinitions/f1a07417-d97a-45cb-824c-7a7467783830'
+ 'Managed Identity Contributor': '/providers/Microsoft.Authorization/roleDefinitions/e40ec5ca-96e0-45a2-b4ff-59039f2c2b59'
+ 'Management Group Contributor': '/providers/Microsoft.Authorization/roleDefinitions/5d58bcaf-24a5-4b20-bdb6-eed9f69fbe4c'
+ 'Management Group Reader': '/providers/Microsoft.Authorization/roleDefinitions/ac63b705-f282-497d-ac71-919bf39d939d'
+ 'Monitoring Metrics Publisher': '/providers/Microsoft.Authorization/roleDefinitions/3913510d-42f4-4e42-8a64-420c390055eb'
+ 'Monitoring Reader': '/providers/Microsoft.Authorization/roleDefinitions/43d0d8ad-25c7-4714-9337-8ba259a9fe05'
+ 'Network Contributor': '/providers/Microsoft.Authorization/roleDefinitions/4d97b98b-1d4f-4787-a291-c67834d212e7'
+ 'Monitoring Contributor': '/providers/Microsoft.Authorization/roleDefinitions/749f88d5-cbae-40b8-bcfc-e573ddc772fa'
+ 'New Relic APM Account Contributor': '/providers/Microsoft.Authorization/roleDefinitions/5d28c62d-5b37-4476-8438-e587778df237'
+ 'Owner': '/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635'
+ 'Reader': '/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7'
+ 'Redis Cache Contributor': '/providers/Microsoft.Authorization/roleDefinitions/e0f68234-74aa-48ed-b826-c38b57376e17'
+ 'Reader and Data Access': '/providers/Microsoft.Authorization/roleDefinitions/c12c1c16-33a1-487b-954d-41c89c60f349'
+ 'Resource Policy Contributor': '/providers/Microsoft.Authorization/roleDefinitions/36243c78-bf99-498c-9df9-86d9f8d28608'
+ 'Scheduler Job Collections Contributor': '/providers/Microsoft.Authorization/roleDefinitions/188a0f2f-5c9e-469b-ae67-2aa5ce574b94'
+ 'Search Service Contributor': '/providers/Microsoft.Authorization/roleDefinitions/7ca78c08-252a-4471-8644-bb5ff32d4ba0'
+ 'Security Admin': '/providers/Microsoft.Authorization/roleDefinitions/fb1c8493-542b-48eb-b624-b4c8fea62acd'
+ 'Security Reader': '/providers/Microsoft.Authorization/roleDefinitions/39bc4728-0917-49c7-9d2c-d95423bc2eb4'
+ 'Spatial Anchors Account Contributor': '/providers/Microsoft.Authorization/roleDefinitions/8bbe83f1-e2a6-4df7-8cb4-4e04d4e5c827'
+ 'Site Recovery Contributor': '/providers/Microsoft.Authorization/roleDefinitions/6670b86e-a3f7-4917-ac9b-5d6ab1be4567'
+ 'Site Recovery Operator': '/providers/Microsoft.Authorization/roleDefinitions/494ae006-db33-4328-bf46-533a6560a3ca'
+ 'Spatial Anchors Account Reader': '/providers/Microsoft.Authorization/roleDefinitions/5d51204f-eb77-4b1c-b86a-2ec626c49413'
+ 'Site Recovery Reader': '/providers/Microsoft.Authorization/roleDefinitions/dbaa88c4-0c30-4179-9fb3-46319faa6149'
+ 'Spatial Anchors Account Owner': '/providers/Microsoft.Authorization/roleDefinitions/70bbe301-9835-447d-afdd-19eb3167307c'
+ 'SQL Managed Instance Contributor': '/providers/Microsoft.Authorization/roleDefinitions/4939a1f6-9ae0-4e48-a1e0-f2cbe897382d'
+ 'SQL DB Contributor': '/providers/Microsoft.Authorization/roleDefinitions/9b7fa17d-e63e-47b0-bb0a-15c516ac86ec'
+ 'SQL Security Manager': '/providers/Microsoft.Authorization/roleDefinitions/056cd41c-7e88-42e1-933e-88ba6a50c9c3'
+ 'Storage Account Contributor': '/providers/Microsoft.Authorization/roleDefinitions/17d1049b-9a84-46fb-8f53-869881c3d3ab'
+ 'SQL Server Contributor': '/providers/Microsoft.Authorization/roleDefinitions/6d8ee4ec-f05a-4a1d-8b00-a9b17e38b437'
+ 'Storage Account Key Operator Service Role': '/providers/Microsoft.Authorization/roleDefinitions/81a9662b-bebf-436f-a333-f67b29880f12'
+ 'Storage Blob Data Contributor': '/providers/Microsoft.Authorization/roleDefinitions/ba92f5b4-2d11-453d-a403-e96b0029c9fe'
+ 'Storage Blob Data Owner': '/providers/Microsoft.Authorization/roleDefinitions/b7e6dc6d-f1e8-4753-8033-0f276bb0955b'
+ 'Storage Blob Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/2a2b9908-6ea1-4ae2-8e65-a410df84e7d1'
+ 'Storage Queue Data Contributor': '/providers/Microsoft.Authorization/roleDefinitions/974c5e8b-45b9-4653-ba55-5f855dd0fb88'
+ 'Storage Queue Data Message Processor': '/providers/Microsoft.Authorization/roleDefinitions/8a0f0c08-91a1-4084-bc3d-661d67233fed'
+ 'Storage Queue Data Message Sender': '/providers/Microsoft.Authorization/roleDefinitions/c6a89b2d-59bc-44d0-9896-0f6e12d7b80a'
+ 'Storage Queue Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/19e7f393-937e-4f77-808e-94535e297925'
+ 'Support Request Contributor': '/providers/Microsoft.Authorization/roleDefinitions/cfd33db0-3dd1-45e3-aa9d-cdbdf3b6f24e'
+ 'Traffic Manager Contributor': '/providers/Microsoft.Authorization/roleDefinitions/a4b10055-b0c7-44c2-b00f-c7b5b3550cf7'
+ 'Virtual Machine Administrator Login': '/providers/Microsoft.Authorization/roleDefinitions/1c0163c0-47e6-4577-8991-ea5c82e286e4'
+ 'User Access Administrator': '/providers/Microsoft.Authorization/roleDefinitions/18d7d88d-d35e-4fb5-a5c3-7773c20a72d9'
+ 'Virtual Machine User Login': '/providers/Microsoft.Authorization/roleDefinitions/fb879df8-f326-4884-b1cf-06f3ad86be52'
+ 'Virtual Machine Contributor': '/providers/Microsoft.Authorization/roleDefinitions/9980e02c-c2be-4d73-94e8-173b1dc7cf3c'
+ 'Web Plan Contributor': '/providers/Microsoft.Authorization/roleDefinitions/2cc479cb-7b4d-49a8-b449-8c00fd0f0a4b'
+ 'Website Contributor': '/providers/Microsoft.Authorization/roleDefinitions/de139f84-1756-47ae-9be6-808fbbe84772'
+ 'Azure Service Bus Data Owner': '/providers/Microsoft.Authorization/roleDefinitions/090c5cfd-751d-490a-894a-3ce6f1109419'
+ 'Azure Event Hubs Data Owner': '/providers/Microsoft.Authorization/roleDefinitions/f526a384-b230-433a-b45c-95f59c4a2dec'
+ 'Attestation Contributor': '/providers/Microsoft.Authorization/roleDefinitions/bbf86eb8-f7b4-4cce-96e4-18cddf81d86e'
+ 'HDInsight Cluster Operator': '/providers/Microsoft.Authorization/roleDefinitions/61ed4efc-fab3-44fd-b111-e24485cc132a'
+ 'Cosmos DB Operator': '/providers/Microsoft.Authorization/roleDefinitions/230815da-be43-4aae-9cb4-875f7bd000aa'
+ 'Hybrid Server Resource Administrator': '/providers/Microsoft.Authorization/roleDefinitions/48b40c6e-82e0-4eb3-90d5-19e40f49b624'
+ 'Hybrid Server Onboarding': '/providers/Microsoft.Authorization/roleDefinitions/5d1e5ee4-7c68-4a71-ac8b-0739630a3dfb'
+ 'Azure Event Hubs Data Receiver': '/providers/Microsoft.Authorization/roleDefinitions/a638d3c7-ab3a-418d-83e6-5f17a39d4fde'
+ 'Azure Event Hubs Data Sender': '/providers/Microsoft.Authorization/roleDefinitions/2b629674-e913-4c01-ae53-ef4638d8f975'
+ 'Azure Service Bus Data Receiver': '/providers/Microsoft.Authorization/roleDefinitions/4f6d3b9b-027b-4f4c-9142-0e5a2a2247e0'
+ 'Azure Service Bus Data Sender': '/providers/Microsoft.Authorization/roleDefinitions/69a216fc-b8fb-44d8-bc22-1f3c2cd27a39'
+ 'Storage File Data SMB Share Reader': '/providers/Microsoft.Authorization/roleDefinitions/aba4ae5f-2193-4029-9191-0cb91df5e314'
+ 'Storage File Data SMB Share Contributor': '/providers/Microsoft.Authorization/roleDefinitions/0c867c2a-1d8c-454a-a3db-ab2ea1bdc8bb'
+ 'Private DNS Zone Contributor': '/providers/Microsoft.Authorization/roleDefinitions/b12aa53e-6015-4669-85d0-8515ebb3ae7f'
+ 'Storage Blob Delegator': '/providers/Microsoft.Authorization/roleDefinitions/db58b8e5-c6ad-4a2a-8342-4190687cbf4a'
+ 'Desktop Virtualization User': '/providers/Microsoft.Authorization/roleDefinitions/1d18fff3-a72a-46b5-b4a9-0b38a3cd7e63'
+ 'Storage File Data SMB Share Elevated Contributor': '/providers/Microsoft.Authorization/roleDefinitions/a7264617-510b-434b-a828-9731dc254ea7'
+ 'Blueprint Contributor': '/providers/Microsoft.Authorization/roleDefinitions/41077137-e803-4205-871c-5a86e6a753b4'
+ 'Blueprint Operator': '/providers/Microsoft.Authorization/roleDefinitions/437d2ced-4a38-4302-8479-ed2bcb43d090'
+ 'Azure Sentinel Contributor': '/providers/Microsoft.Authorization/roleDefinitions/ab8e14d6-4a74-4a29-9ba8-549422addade'
+ 'Azure Sentinel Responder': '/providers/Microsoft.Authorization/roleDefinitions/3e150937-b8fe-4cfb-8069-0eaf05ecd056'
+ 'Azure Sentinel Reader': '/providers/Microsoft.Authorization/roleDefinitions/8d289c81-5878-46d4-8554-54e1e3d8b5cb'
+ 'Workbook Reader': '/providers/Microsoft.Authorization/roleDefinitions/b279062a-9be3-42a0-92ae-8b3cf002ec4d'
+ 'Workbook Contributor': '/providers/Microsoft.Authorization/roleDefinitions/e8ddcd69-c73f-4f9f-9844-4100522f16ad'
+ 'SignalR AccessKey Reader': '/providers/Microsoft.Authorization/roleDefinitions/04165923-9d83-45d5-8227-78b77b0a687e'
+ 'SignalR/Web PubSub Contributor': '/providers/Microsoft.Authorization/roleDefinitions/8cf5e20a-e4b2-4e9d-b3a1-5ceb692c2761'
+ 'Azure Connected Machine Onboarding': '/providers/Microsoft.Authorization/roleDefinitions/b64e21ea-ac4e-4cdf-9dc9-5b892992bee7'
+ 'Azure Connected Machine Resource Administrator': '/providers/Microsoft.Authorization/roleDefinitions/cd570a14-e51a-42ad-bac8-bafd67325302'
+ 'Managed Services Registration assignment Delete Role': '/providers/Microsoft.Authorization/roleDefinitions/91c1777a-f3dc-4fae-b103-61d183457e46'
+ 'App Configuration Data Owner': '/providers/Microsoft.Authorization/roleDefinitions/5ae67dd6-50cb-40e7-96ff-dc2bfa4b606b'
+ 'App Configuration Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/516239f1-63e1-4d78-a4de-a74fb236a071'
+ 'Kubernetes Cluster - Azure Arc Onboarding': '/providers/Microsoft.Authorization/roleDefinitions/34e09817-6cbe-4d01-b1a2-e0eac5743d41'
+ 'Experimentation Contributor': '/providers/Microsoft.Authorization/roleDefinitions/7f646f1b-fa08-80eb-a22b-edd6ce5c915c'
+ 'Cognitive Services QnA Maker Reader': '/providers/Microsoft.Authorization/roleDefinitions/466ccd10-b268-4a11-b098-b4849f024126'
+ 'Cognitive Services QnA Maker Editor': '/providers/Microsoft.Authorization/roleDefinitions/f4cc2bf9-21be-47a1-bdf1-5c5804381025'
+ 'Experimentation Administrator': '/providers/Microsoft.Authorization/roleDefinitions/7f646f1b-fa08-80eb-a33b-edd6ce5c915c'
+ 'Remote Rendering Administrator': '/providers/Microsoft.Authorization/roleDefinitions/3df8b902-2a6f-47c7-8cc5-360e9b272a7e'
+ 'Remote Rendering Client': '/providers/Microsoft.Authorization/roleDefinitions/d39065c4-c120-43c9-ab0a-63eed9795f0a'
+ 'Managed Application Contributor Role': '/providers/Microsoft.Authorization/roleDefinitions/641177b8-a67a-45b9-a033-47bc880bb21e'
+ 'Security Assessment Contributor': '/providers/Microsoft.Authorization/roleDefinitions/612c2aa1-cb24-443b-ac28-3ab7272de6f5'
+ 'Tag Contributor': '/providers/Microsoft.Authorization/roleDefinitions/4a9ae827-6dc8-4573-8ac7-8239d42aa03f'
+ 'Integration Service Environment Developer': '/providers/Microsoft.Authorization/roleDefinitions/c7aa55d3-1abb-444a-a5ca-5e51e485d6ec'
+ 'Integration Service Environment Contributor': '/providers/Microsoft.Authorization/roleDefinitions/a41e2c5b-bd99-4a07-88f4-9bf657a760b8'
+ 'Azure Kubernetes Service Contributor Role': '/providers/Microsoft.Authorization/roleDefinitions/ed7f3fbd-7b88-4dd4-9017-9adb7ce333f8'
+ 'Azure Digital Twins Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/d57506d4-4c8d-48b1-8587-93c323f6a5a3'
+ 'Azure Digital Twins Data Owner': '/providers/Microsoft.Authorization/roleDefinitions/bcd981a7-7f74-457b-83e1-cceb9e632ffe'
+ 'Hierarchy Settings Administrator': '/providers/Microsoft.Authorization/roleDefinitions/350f8d15-c687-4448-8ae1-157740a3936d'
+ 'FHIR Data Contributor': '/providers/Microsoft.Authorization/roleDefinitions/5a1fc7df-4bf1-4951-a576-89034ee01acd'
+ 'FHIR Data Exporter': '/providers/Microsoft.Authorization/roleDefinitions/3db33094-8700-4567-8da5-1501d4e7e843'
+ 'FHIR Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/4c8d0bbc-75d3-4935-991f-5f3c56d81508'
+ 'FHIR Data Writer': '/providers/Microsoft.Authorization/roleDefinitions/3f88fce4-5892-4214-ae73-ba5294559913'
+ 'Experimentation Reader': '/providers/Microsoft.Authorization/roleDefinitions/49632ef5-d9ac-41f4-b8e7-bbe587fa74a1'
+ 'Object Understanding Account Owner': '/providers/Microsoft.Authorization/roleDefinitions/4dd61c23-6743-42fe-a388-d8bdd41cb745'
+ 'Azure Maps Data Contributor': '/providers/Microsoft.Authorization/roleDefinitions/8f5e0ce6-4f7b-4dcf-bddf-e6f48634a204'
+ 'Cognitive Services Custom Vision Contributor': '/providers/Microsoft.Authorization/roleDefinitions/c1ff6cc2-c111-46fe-8896-e0ef812ad9f3'
+ 'Cognitive Services Custom Vision Deployment': '/providers/Microsoft.Authorization/roleDefinitions/5c4089e1-6d96-4d2f-b296-c1bc7137275f'
+ 'Cognitive Services Custom Vision Labeler': '/providers/Microsoft.Authorization/roleDefinitions/88424f51-ebe7-446f-bc41-7fa16989e96c'
+ 'Cognitive Services Custom Vision Reader': '/providers/Microsoft.Authorization/roleDefinitions/93586559-c37d-4a6b-ba08-b9f0940c2d73'
+ 'Cognitive Services Custom Vision Trainer': '/providers/Microsoft.Authorization/roleDefinitions/0a5ae4ab-0d65-4eeb-be61-29fc9b54394b'
+ 'Key Vault Administrator': '/providers/Microsoft.Authorization/roleDefinitions/00482a5a-887f-4fb3-b363-3b7fe8e74483'
+ 'Key Vault Crypto Officer': '/providers/Microsoft.Authorization/roleDefinitions/14b46e9e-c2b7-41b4-b07b-48a6ebf60603'
+ 'Key Vault Crypto User': '/providers/Microsoft.Authorization/roleDefinitions/12338af0-0e69-4776-bea7-57ae8d297424'
+ 'Key Vault Secrets Officer': '/providers/Microsoft.Authorization/roleDefinitions/b86a8fe4-44ce-4948-aee5-eccb2c155cd7'
+ 'Key Vault Secrets User': '/providers/Microsoft.Authorization/roleDefinitions/4633458b-17de-408a-b874-0445c86b69e6'
+ 'Key Vault Certificates Officer': '/providers/Microsoft.Authorization/roleDefinitions/a4417e6f-fecd-4de8-b567-7b0420556985'
+ 'Key Vault Reader': '/providers/Microsoft.Authorization/roleDefinitions/21090545-7ca7-4776-b22c-e363652d74d2'
+ 'Key Vault Crypto Service Encryption User': '/providers/Microsoft.Authorization/roleDefinitions/e147488a-f6f5-4113-8e2d-b22465e65bf6'
+ 'Azure Arc Kubernetes Viewer': '/providers/Microsoft.Authorization/roleDefinitions/63f0a09d-1495-4db4-a681-037d84835eb4'
+ 'Azure Arc Kubernetes Writer': '/providers/Microsoft.Authorization/roleDefinitions/5b999177-9696-4545-85c7-50de3797e5a1'
+ 'Azure Arc Kubernetes Cluster Admin': '/providers/Microsoft.Authorization/roleDefinitions/8393591c-06b9-48a2-a542-1bd6b377f6a2'
+ 'Azure Arc Kubernetes Admin': '/providers/Microsoft.Authorization/roleDefinitions/dffb1e0c-446f-4dde-a09f-99eb5cc68b96'
+ 'Azure Kubernetes Service RBAC Cluster Admin': '/providers/Microsoft.Authorization/roleDefinitions/b1ff04bb-8a4e-4dc4-8eb5-8693973ce19b'
+ 'Azure Kubernetes Service RBAC Admin': '/providers/Microsoft.Authorization/roleDefinitions/3498e952-d568-435e-9b2c-8d77e338d7f7'
+ 'Azure Kubernetes Service RBAC Reader': '/providers/Microsoft.Authorization/roleDefinitions/7f6c6a51-bcf8-42ba-9220-52d62157d7db'
+ 'Azure Kubernetes Service RBAC Writer': '/providers/Microsoft.Authorization/roleDefinitions/a7ffa36f-339b-4b5c-8bdf-e2c188b2c0eb'
+ 'Services Hub Operator': '/providers/Microsoft.Authorization/roleDefinitions/82200a5b-e217-47a5-b665-6d8765ee745b'
+ 'Object Understanding Account Reader': '/providers/Microsoft.Authorization/roleDefinitions/d18777c0-1514-4662-8490-608db7d334b6'
+ 'Azure Arc Enabled Kubernetes Cluster User Role': '/providers/Microsoft.Authorization/roleDefinitions/00493d72-78f6-4148-b6c5-d3ce8e4799dd'
+ 'SignalR REST API Owner': '/providers/Microsoft.Authorization/roleDefinitions/fd53cd77-2268-407a-8f46-7e7863d0f521'
+ 'Collaborative Data Contributor': '/providers/Microsoft.Authorization/roleDefinitions/daa9e50b-21df-454c-94a6-a8050adab352'
+ 'Device Update Reader': '/providers/Microsoft.Authorization/roleDefinitions/e9dba6fb-3d52-4cf0-bce3-f06ce71b9e0f'
+ 'Device Update Administrator': '/providers/Microsoft.Authorization/roleDefinitions/02ca0879-e8e4-47a5-a61e-5c618b76e64a'
+ 'Device Update Content Administrator': '/providers/Microsoft.Authorization/roleDefinitions/0378884a-3af5-44ab-8323-f5b22f9f3c98'
+ 'Device Update Deployments Administrator': '/providers/Microsoft.Authorization/roleDefinitions/e4237640-0e3d-4a46-8fda-70bc94856432'
+ 'Device Update Deployments Reader': '/providers/Microsoft.Authorization/roleDefinitions/49e2f5d2-7741-4835-8efa-19e1fe35e47f'
+ 'Device Update Content Reader': '/providers/Microsoft.Authorization/roleDefinitions/d1ee9a80-8b14-47f0-bdc2-f4a351625a7b'
+ 'Cognitive Services Metrics Advisor Administrator': '/providers/Microsoft.Authorization/roleDefinitions/cb43c632-a144-4ec5-977c-e80c4affc34a'
+ 'Cognitive Services Metrics Advisor User': '/providers/Microsoft.Authorization/roleDefinitions/3b20f47b-3825-43cb-8114-4bd2201156a8'
+ 'AgFood Platform Service Reader': '/providers/Microsoft.Authorization/roleDefinitions/7ec7ccdc-f61e-41fe-9aaf-980df0a44eba'
+ 'AgFood Platform Service Contributor': '/providers/Microsoft.Authorization/roleDefinitions/8508508a-4469-4e45-963b-2518ee0bb728'
+ 'AgFood Platform Service Admin': '/providers/Microsoft.Authorization/roleDefinitions/f8da80de-1ff9-4747-ad80-a19b7f6079e3'
+ 'Managed HSM contributor': '/providers/Microsoft.Authorization/roleDefinitions/18500a29-7fe2-46b2-a342-b16a415e101d'
+ 'Security Detonation Chamber Submitter': '/providers/Microsoft.Authorization/roleDefinitions/0b555d9b-b4a7-4f43-b330-627f0e5be8f0'
+ 'SignalR REST API Reader': '/providers/Microsoft.Authorization/roleDefinitions/ddde6b66-c0df-4114-a159-3618637b3035'
+ 'SignalR Service Owner': '/providers/Microsoft.Authorization/roleDefinitions/7e4f1700-ea5a-4f59-8f37-079cfe29dce3'
+ 'Reservation Purchaser': '/providers/Microsoft.Authorization/roleDefinitions/f7b75c60-3036-4b75-91c3-6b41c27c1689'
+ 'Storage Account Backup Contributor Role': '/providers/Microsoft.Authorization/roleDefinitions/e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1'
+ 'Experimentation Metric Contributor': '/providers/Microsoft.Authorization/roleDefinitions/6188b7c9-7d01-4f99-a59f-c88b630326c0'
+ 'Project Babylon Data Curator': '/providers/Microsoft.Authorization/roleDefinitions/9ef4ef9c-a049-46b0-82ab-dd8ac094c889'
+ 'Project Babylon Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/c8d896ba-346d-4f50-bc1d-7d1c84130446'
+ 'Project Babylon Data Source Administrator': '/providers/Microsoft.Authorization/roleDefinitions/05b7651b-dc44-475e-b74d-df3db49fae0f'
+ 'Application Group Contributor': '/providers/Microsoft.Authorization/roleDefinitions/ca6382a4-1721-4bcf-a114-ff0c70227b6b'
+ 'Desktop Virtualization Reader': '/providers/Microsoft.Authorization/roleDefinitions/49a72310-ab8d-41df-bbb0-79b649203868'
+ 'Desktop Virtualization Contributor': '/providers/Microsoft.Authorization/roleDefinitions/082f0a83-3be5-4ba1-904c-961cca79b387'
+ 'Desktop Virtualization Workspace Contributor': '/providers/Microsoft.Authorization/roleDefinitions/21efdde3-836f-432b-bf3d-3e8e734d4b2b'
+ 'Desktop Virtualization User Session Operator': '/providers/Microsoft.Authorization/roleDefinitions/ea4bfff8-7fb4-485a-aadd-d4129a0ffaa6'
+ 'Desktop Virtualization Session Host Operator': '/providers/Microsoft.Authorization/roleDefinitions/2ad6aaab-ead9-4eaa-8ac5-da422f562408'
+ 'Desktop Virtualization Host Pool Reader': '/providers/Microsoft.Authorization/roleDefinitions/ceadfde2-b300-400a-ab7b-6143895aa822'
+ 'Desktop Virtualization Host Pool Contributor': '/providers/Microsoft.Authorization/roleDefinitions/e307426c-f9b6-4e81-87de-d99efb3c32bc'
+ 'Desktop Virtualization Application Group Reader': '/providers/Microsoft.Authorization/roleDefinitions/aebf23d0-b568-4e86-b8f9-fe83a2c6ab55'
+ 'Desktop Virtualization Application Group Contributor': '/providers/Microsoft.Authorization/roleDefinitions/86240b0e-9422-4c43-887b-b61143f32ba8'
+ 'Desktop Virtualization Workspace Reader': '/providers/Microsoft.Authorization/roleDefinitions/0fa44ee9-7a7d-466b-9bb2-2bf446b1204d'
+ 'Disk Backup Reader': '/providers/Microsoft.Authorization/roleDefinitions/3e5e47e6-65f7-47ef-90b5-e5dd4d455f24'
+ 'Disk Restore Operator': '/providers/Microsoft.Authorization/roleDefinitions/b50d9833-a0cb-478e-945f-707fcc997c13'
+ 'Disk Snapshot Contributor': '/providers/Microsoft.Authorization/roleDefinitions/7efff54f-a5b4-42b5-a1c5-5411624893ce'
+ 'Microsoft.Kubernetes connected cluster role': '/providers/Microsoft.Authorization/roleDefinitions/5548b2cf-c94c-4228-90ba-30851930a12f'
+ 'Security Detonation Chamber Submission Manager': '/providers/Microsoft.Authorization/roleDefinitions/a37b566d-3efa-4beb-a2f2-698963fa42ce'
+ 'Security Detonation Chamber Publisher': '/providers/Microsoft.Authorization/roleDefinitions/352470b3-6a9c-4686-b503-35deb827e500'
+ 'Collaborative Runtime Operator': '/providers/Microsoft.Authorization/roleDefinitions/7a6f0e70-c033-4fb1-828c-08514e5f4102'
+ 'CosmosRestoreOperator': '/providers/Microsoft.Authorization/roleDefinitions/5432c526-bc82-444a-b7ba-57c5b0b5b34f'
+ 'FHIR Data Converter': '/providers/Microsoft.Authorization/roleDefinitions/a1705bd2-3a8f-45a5-8683-466fcfd5cc24'
+ 'Azure Sentinel Automation Contributor': '/providers/Microsoft.Authorization/roleDefinitions/f4c81013-99ee-4d62-a7ee-b3f1f648599a'
+ 'Quota Request Operator': '/providers/Microsoft.Authorization/roleDefinitions/0e5f05e5-9ab9-446b-b98d-1e2157c94125'
+ 'EventGrid Contributor': '/providers/Microsoft.Authorization/roleDefinitions/1e241071-0855-49ea-94dc-649edcd759de'
+ 'Security Detonation Chamber Reader': '/providers/Microsoft.Authorization/roleDefinitions/28241645-39f8-410b-ad48-87863e2951d5'
+ 'Object Anchors Account Reader': '/providers/Microsoft.Authorization/roleDefinitions/4a167cdf-cb95-4554-9203-2347fe489bd9'
+ 'Object Anchors Account Owner': '/providers/Microsoft.Authorization/roleDefinitions/ca0835dd-bacc-42dd-8ed2-ed5e7230d15b'
+ 'WorkloadBuilder Migration Agent Role': '/providers/Microsoft.Authorization/roleDefinitions/d17ce0a2-0697-43bc-aac5-9113337ab61c'
+ 'Azure Spring Cloud Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/b5537268-8956-4941-a8f0-646150406f0c'
+ 'Cognitive Services Speech User': '/providers/Microsoft.Authorization/roleDefinitions/f2dc8367-1007-4938-bd23-fe263f013447'
+ 'Cognitive Services Speech Contributor': '/providers/Microsoft.Authorization/roleDefinitions/0e75ca1e-0464-4b4d-8b93-68208a576181'
+ 'Cognitive Services Face Recognizer': '/providers/Microsoft.Authorization/roleDefinitions/9894cab4-e18a-44aa-828b-cb588cd6f2d7'
+ 'Media Services Account Administrator': '/providers/Microsoft.Authorization/roleDefinitions/054126f8-9a2b-4f1c-a9ad-eca461f08466'
+ 'Media Services Live Events Administrator': '/providers/Microsoft.Authorization/roleDefinitions/532bc159-b25e-42c0-969e-a1d439f60d77'
+ 'Media Services Media Operator': '/providers/Microsoft.Authorization/roleDefinitions/e4395492-1534-4db2-bedf-88c14621589c'
+ 'Media Services Policy Administrator': '/providers/Microsoft.Authorization/roleDefinitions/c4bba371-dacd-4a26-b320-7250bca963ae'
+ 'Media Services Streaming Endpoints Administrator': '/providers/Microsoft.Authorization/roleDefinitions/99dba123-b5fe-44d5-874c-ced7199a5804'
+ 'Stream Analytics Query Tester': '/providers/Microsoft.Authorization/roleDefinitions/1ec5b3c1-b17e-4e25-8312-2acb3c3c5abf'
+ 'AnyBuild Builder': '/providers/Microsoft.Authorization/roleDefinitions/a2138dac-4907-4679-a376-736901ed8ad8'
+ 'IoT Hub Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/b447c946-2db7-41ec-983d-d8bf3b1c77e3'
+ 'IoT Hub Twin Contributor': '/providers/Microsoft.Authorization/roleDefinitions/494bdba2-168f-4f31-a0a1-191d2f7c028c'
+ 'IoT Hub Registry Contributor': '/providers/Microsoft.Authorization/roleDefinitions/4ea46cd5-c1b2-4a8e-910b-273211f9ce47'
+ 'IoT Hub Data Contributor': '/providers/Microsoft.Authorization/roleDefinitions/4fc6c259-987e-4a07-842e-c321cc9d413f'
+ 'Test Base Reader': '/providers/Microsoft.Authorization/roleDefinitions/15e0f5a1-3450-4248-8e25-e2afe88a9e85'
+ 'Search Index Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/1407120a-92aa-4202-b7e9-c0e197c71c8f'
+ 'Search Index Data Contributor': '/providers/Microsoft.Authorization/roleDefinitions/8ebe5a00-799e-43f5-93ac-243d3dce84a7'
+ 'Storage Table Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/76199698-9eea-4c19-bc75-cec21354c6b6'
+ 'Storage Table Data Contributor': '/providers/Microsoft.Authorization/roleDefinitions/0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3'
+ 'DICOM Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/e89c7a3c-2f64-4fa1-a847-3e4c9ba4283a'
+ 'DICOM Data Owner': '/providers/Microsoft.Authorization/roleDefinitions/58a3b984-7adf-4c20-983a-32417c86fbc8'
+ 'EventGrid Data Sender': '/providers/Microsoft.Authorization/roleDefinitions/d5a91429-5739-47e2-a06b-3470a27159e7'
+ 'Disk Pool Operator': '/providers/Microsoft.Authorization/roleDefinitions/60fc6e62-5479-42d4-8bf4-67625fcc2840'
+ 'AzureML Data Scientist': '/providers/Microsoft.Authorization/roleDefinitions/f6c7c914-8db3-469d-8ca1-694a8f32e121'
+ 'Grafana Admin': '/providers/Microsoft.Authorization/roleDefinitions/22926164-76b3-42b3-bc55-97df8dab3e41'
+ 'Azure Connected SQL Server Onboarding': '/providers/Microsoft.Authorization/roleDefinitions/e8113dce-c529-4d33-91fa-e9b972617508'
+ 'Azure Relay Sender': '/providers/Microsoft.Authorization/roleDefinitions/26baccc8-eea7-41f1-98f4-1762cc7f685d'
+ 'Azure Relay Owner': '/providers/Microsoft.Authorization/roleDefinitions/2787bf04-f1f5-4bfe-8383-c8a24483ee38'
+ 'Azure Relay Listener': '/providers/Microsoft.Authorization/roleDefinitions/26e0b698-aa6d-4085-9386-aadae190014d'
+ 'Grafana Viewer': '/providers/Microsoft.Authorization/roleDefinitions/60921a7e-fef1-4a43-9b16-a26c52ad4769'
+ 'Grafana Editor': '/providers/Microsoft.Authorization/roleDefinitions/a79a5197-3a5c-4973-a920-486035ffd60f'
+ 'Automation Contributor': '/providers/Microsoft.Authorization/roleDefinitions/f353d9bd-d4a6-484e-a77a-8050b599b867'
+ 'Kubernetes Extension Contributor': '/providers/Microsoft.Authorization/roleDefinitions/85cb6faf-e071-4c9b-8136-154b5a04f717'
+ 'Device Provisioning Service Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/10745317-c249-44a1-a5ce-3a4353c0bbd8'
+ 'Device Provisioning Service Data Contributor': '/providers/Microsoft.Authorization/roleDefinitions/dfce44e4-17b7-4bd1-a6d1-04996ec95633'
+ 'CodeSigning Certificate Profile Signer': '/providers/Microsoft.Authorization/roleDefinitions/2837e146-70d7-4cfd-ad55-7efa6464f958'
+ 'Azure Spring Cloud Service Registry Reader': '/providers/Microsoft.Authorization/roleDefinitions/cff1b556-2399-4e7e-856d-a8f754be7b65'
+ 'Azure Spring Cloud Service Registry Contributor': '/providers/Microsoft.Authorization/roleDefinitions/f5880b48-c26d-48be-b172-7927bfa1c8f1'
+ 'Azure Spring Cloud Config Server Reader': '/providers/Microsoft.Authorization/roleDefinitions/d04c6db6-4947-4782-9e91-30a88feb7be7'
+ 'Azure Spring Cloud Config Server Contributor': '/providers/Microsoft.Authorization/roleDefinitions/a06f5c24-21a7-4e1a-aa2b-f19eb6684f5b'
+ 'Azure VM Managed identities restore Contributor': '/providers/Microsoft.Authorization/roleDefinitions/6ae96244-5829-4925-a7d3-5975537d91dd'
+ 'Azure Maps Search and Render Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/6be48352-4f82-47c9-ad5e-0acacefdb005'
+ 'Azure Maps Contributor': '/providers/Microsoft.Authorization/roleDefinitions/dba33070-676a-4fb0-87fa-064dc56ff7fb'
+}
+
+var roleDefinitionId_var = (contains(builtInRoleNames_var, roleDefinitionIdOrName) ? builtInRoleNames_var[roleDefinitionIdOrName] : roleDefinitionIdOrName)
+
+resource roleAssignment 'Microsoft.Authorization/roleAssignments@2021-04-01-preview' = {
+ name: guid(managementGroupId, roleDefinitionId_var, principalId)
+ properties: {
+ roleDefinitionId: roleDefinitionId_var
+ principalId: principalId
+ description: !empty(description) ? description : null
+ principalType: !empty(principalType) ? any(principalType) : null
+ delegatedManagedIdentityResourceId: !empty(delegatedManagedIdentityResourceId) ? delegatedManagedIdentityResourceId : null
+ conditionVersion: !empty(conditionVersion) && !empty(condition) ? conditionVersion : null
+ condition: !empty(condition) ? condition : null
+ }
+}
+
+@sys.description('The GUID of the Role Assignment')
+output name string = roleAssignment.name
+
+@sys.description('The resource ID of the Role Assignment')
+output scope string = tenantResourceId('Microsoft.Management/managementGroups', managementGroupId)
+
+@sys.description('The scope this Role Assignment applies to')
+output resourceId string = extensionResourceId(tenantResourceId('Microsoft.Management/managementGroups', managementGroupId), 'Microsoft.Authorization/roleAssignments', roleAssignment.name)
diff --git a/carml/1.0.0/Microsoft.Authorization/roleAssignments/managementGroup/readme.md b/carml/1.0.0/Microsoft.Authorization/roleAssignments/managementGroup/readme.md
new file mode 100644
index 000000000..10e98eb01
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleAssignments/managementGroup/readme.md
@@ -0,0 +1,34 @@
+# Role Assignment on Management Group level `[Microsoft.Authorization/roleAssignments/managementGroup]`
+
+With this module you can perform role assignments on a management group level
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/roleAssignments` | 2021-04-01-preview |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `condition` | string | | | Optional. The conditions on the role assignment. This limits the resources it can be assigned to |
+| `conditionVersion` | string | `2.0` | `[2.0]` | Optional. Version of the condition. Currently accepted value is "2.0" |
+| `delegatedManagedIdentityResourceId` | string | | | Optional. ID of the delegated managed identity resource |
+| `description` | string | | | Optional. Description of role assignment |
+| `managementGroupId` | string | `[managementGroup().name]` | | Optional. Group ID of the Management Group to assign the RBAC role to. If not provided, will use the current scope for deployment. |
+| `principalId` | string | | | Required. The Principal or Object ID of the Security Principal (User, Group, Service Principal, Managed Identity) |
+| `principalType` | string | | `[ServicePrincipal, Group, User, ForeignGroup, Device, ]` | Optional. The principal type of the assigned principal ID. |
+| `roleDefinitionIdOrName` | string | | | Required. 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' |
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The GUID of the Role Assignment |
+| `resourceId` | string | The scope this Role Assignment applies to |
+| `scope` | string | The resource ID of the Role Assignment |
+
+## Template references
+
+- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/roleAssignments)
diff --git a/carml/1.0.0/Microsoft.Authorization/roleAssignments/managementGroup/version.json b/carml/1.0.0/Microsoft.Authorization/roleAssignments/managementGroup/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleAssignments/managementGroup/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/roleAssignments/readme.md b/carml/1.0.0/Microsoft.Authorization/roleAssignments/readme.md
new file mode 100644
index 000000000..bbfb50fcc
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleAssignments/readme.md
@@ -0,0 +1,99 @@
+# Role Assignments `[Microsoft.Authorization/roleAssignments]`
+
+This module deploys Role Assignments across the management group, subscription or resource group scope.
+
+## Resource types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/roleAssignments` | 2021-04-01-preview |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `condition` | string | | | Optional. The conditions on the role assignment. This limits the resources it can be assigned to |
+| `conditionVersion` | string | `2.0` | `[2.0]` | Optional. Version of the condition. Currently accepted value is "2.0" |
+| `delegatedManagedIdentityResourceId` | string | | | Optional. ID of the delegated managed identity resource |
+| `description` | string | | | Optional. Description of role assignment |
+| `location` | string | `[deployment().location]` | | Optional. Location for all resources. |
+| `managementGroupId` | string | `[managementGroup().name]` | | Optional. Group ID of the Management Group to assign the RBAC role to. If not provided, will use the current scope for deployment. |
+| `principalId` | string | | | Required. The Principal or Object ID of the Security Principal (User, Group, Service Principal, Managed Identity) |
+| `principalType` | string | | `[ServicePrincipal, Group, User, ForeignGroup, Device, ]` | Optional. The principal type of the assigned principal ID. |
+| `resourceGroupName` | string | | | Optional. Name of the Resource Group to assign the RBAC role to. If Resource Group name is provided, and Subscription ID is provided, the module deploys at resource group level, therefore assigns the provided RBAC role to the resource group. |
+| `roleDefinitionIdOrName` | string | | | Required. 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' |
+| `subscriptionId` | string | | | Optional. Subscription ID of the subscription to assign the RBAC role to. If no Resource Group name is provided, the module deploys at subscription level, therefore assigns the provided RBAC role to the subscription. |
+
+### Parameter Usage: `managementGroupId`
+
+To deploy resource to a Management Group, provide the `managementGroupId` as an input parameter to the module.
+
+```json
+"managementGroupId": {
+ "value": "contoso-group"
+}
+```
+
+> `managementGroupId` is an optional parameter. If not provided, the deployment will use the management group defined in the current deployment scope (i.e. `managementGroup().name`).
+
+### Parameter Usage: `subscriptionId`
+
+To deploy resource to an Azure Subscription, provide the `subscriptionId` as an input parameter to the module. **Example**:
+
+```json
+"subscriptionId": {
+ "value": "12345678-b049-471c-95af-123456789012"
+}
+```
+
+### Parameter Usage: `resourceGroupName`
+
+To deploy resource to a Resource Group, provide the `subscriptionId` and `resourceGroupName` as an input parameter to the module. **Example**:
+
+```json
+"subscriptionId": {
+ "value": "12345678-b049-471c-95af-123456789012"
+},
+"resourceGroupName": {
+ "value": "target-resourceGroup"
+}
+```
+
+> The `subscriptionId` is used to enable deployment to a Resource Group Scope, allowing the use of the `resourceGroup()` function from a Management Group Scope. [Additional Details](https://github.com/Azure/bicep/pull/1420).
+
+## Module Usage Guidance
+
+In general, most of the resources under the `Microsoft.Authorization` namespace allows deploying resources at multiple scopes (management groups, subscriptions, resource groups). The `deploy.bicep` root module is simply an orchestrator module that targets sub-modules for different scopes as seen in the parameter usage section. All sub-modules for this namespace have folders that represent the target scope. For example, if the orchestrator module in the [root](deploy.bicep) needs to target 'subscription' level scopes. It will look at the relative path ['/subscription/deploy.bicep'](./subscription/deploy.bicep) and use this sub-module for the actual deployment, while still passing the same parameters from the root module.
+
+The above method is useful when you want to use a single point to interact with the module but rely on parameter combinations to achieve the target scope. But what if you want to incorporate this module in other modules with lower scopes? This would force you to deploy the module in scope `managementGroup` regardless and further require you to provide its ID with it. If you do not set the scope to management group, this would be the error that you can expect to face:
+
+```bicep
+Error BCP134: Scope "subscription" is not valid for this module. Permitted scopes: "managementGroup"
+```
+
+The solution is to have the option of directly targeting the sub-module that achieves the required scope. For example, if you have your own Bicep file wanting to create resources at the subscription level, and also use some of the modules from the `Microsoft.Authorization` namespace, then you can directly use the sub-module ['/subscription/deploy.bicep'](./subscription/deploy.bicep) as a path within your repository, or reference that same published module from the bicep registry. CARML also published the sub-modules so you would be able to reference it like the following:
+
+**Bicep Registry Reference**
+```bicep
+module roleassignment 'br:bicepregistry.azurecr.io/bicep/modules/microsoft.authorization.roleassignments.subscription:version' = {}
+```
+**Local Path Reference**
+```bicep
+module roleassignment 'yourpath/arm/Microsoft.Authorization.roleAssignments/subscription/deploy.bicep' = {}
+```
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The GUID of the Role Assignment |
+| `resourceId` | string | The resource ID of the Role Assignment |
+| `scope` | string | The scope this Role Assignment applies to |
+
+## Considerations
+
+This module can be deployed at the management group, subscription or resource group level
+
+## Template references
+
+- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/roleAssignments)
diff --git a/carml/1.0.0/Microsoft.Authorization/roleAssignments/resourceGroup/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.Authorization/roleAssignments/resourceGroup/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleAssignments/resourceGroup/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.Authorization/roleAssignments/resourceGroup/deploy.bicep b/carml/1.0.0/Microsoft.Authorization/roleAssignments/resourceGroup/deploy.bicep
new file mode 100644
index 000000000..693661c13
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleAssignments/resourceGroup/deploy.bicep
@@ -0,0 +1,358 @@
+targetScope = 'resourceGroup'
+
+@sys.description('Required. 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 roleDefinitionIdOrName string
+
+@sys.description('Required. The Principal or Object ID of the Security Principal (User, Group, Service Principal, Managed Identity)')
+param principalId string
+
+@sys.description('Optional. Name of the Resource Group to assign the RBAC role to. If not provided, will use the current scope for deployment.')
+param resourceGroupName string = resourceGroup().name
+
+@sys.description('Optional. Subscription ID of the subscription to assign the RBAC role to. If not provided, will use the current scope for deployment.')
+param subscriptionId string = subscription().subscriptionId
+
+@sys.description('Optional. Description of role assignment')
+param description string = ''
+
+@sys.description('Optional. ID of the delegated managed identity resource')
+param delegatedManagedIdentityResourceId string = ''
+
+@sys.description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to')
+param condition string = ''
+
+@sys.description('Optional. Version of the condition. Currently accepted value is "2.0"')
+@allowed([
+ '2.0'
+])
+param conditionVersion string = '2.0'
+
+@sys.description('Optional. The principal type of the assigned principal ID.')
+@allowed([
+ 'ServicePrincipal'
+ 'Group'
+ 'User'
+ 'ForeignGroup'
+ 'Device'
+ ''
+])
+param principalType string = ''
+
+@sys.description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered.')
+param cuaId string = ''
+
+var builtInRoleNames_var = {
+ 'AcrPush': '/providers/Microsoft.Authorization/roleDefinitions/8311e382-0749-4cb8-b61a-304f252e45ec'
+ 'API Management Service Contributor': '/providers/Microsoft.Authorization/roleDefinitions/312a565d-c81f-4fd8-895a-4e21e48d571c'
+ 'AcrPull': '/providers/Microsoft.Authorization/roleDefinitions/7f951dda-4ed3-4680-a7ca-43fe172d538d'
+ 'AcrImageSigner': '/providers/Microsoft.Authorization/roleDefinitions/6cef56e8-d556-48e5-a04f-b8e64114680f'
+ 'AcrDelete': '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'
+ 'AcrQuarantineReader': '/providers/Microsoft.Authorization/roleDefinitions/cdda3590-29a3-44f6-95f2-9f980659eb04'
+ 'AcrQuarantineWriter': '/providers/Microsoft.Authorization/roleDefinitions/c8d4ff99-41c3-41a8-9f60-21dfdad59608'
+ 'API Management Service Operator Role': '/providers/Microsoft.Authorization/roleDefinitions/e022efe7-f5ba-4159-bbe4-b44f577e9b61'
+ 'API Management Service Reader Role': '/providers/Microsoft.Authorization/roleDefinitions/71522526-b88f-4d52-b57f-d31fc3546d0d'
+ 'Application Insights Component Contributor': '/providers/Microsoft.Authorization/roleDefinitions/ae349356-3a1b-4a5e-921d-050484c6347e'
+ 'Application Insights Snapshot Debugger': '/providers/Microsoft.Authorization/roleDefinitions/08954f03-6346-4c2e-81c0-ec3a5cfae23b'
+ 'Attestation Reader': '/providers/Microsoft.Authorization/roleDefinitions/fd1bd22b-8476-40bc-a0bc-69b95687b9f3'
+ 'Automation Job Operator': '/providers/Microsoft.Authorization/roleDefinitions/4fe576fe-1146-4730-92eb-48519fa6bf9f'
+ 'Automation Runbook Operator': '/providers/Microsoft.Authorization/roleDefinitions/5fb5aef8-1081-4b8e-bb16-9d5d0385bab5'
+ 'Automation Operator': '/providers/Microsoft.Authorization/roleDefinitions/d3881f73-407a-4167-8283-e981cbba0404'
+ 'Avere Contributor': '/providers/Microsoft.Authorization/roleDefinitions/4f8fab4f-1852-4a58-a46a-8eaf358af14a'
+ 'Avere Operator': '/providers/Microsoft.Authorization/roleDefinitions/c025889f-8102-4ebf-b32c-fc0c6f0c6bd9'
+ 'Azure Kubernetes Service Cluster Admin Role': '/providers/Microsoft.Authorization/roleDefinitions/0ab0b1a8-8aac-4efd-b8c2-3ee1fb270be8'
+ 'Azure Kubernetes Service Cluster User Role': '/providers/Microsoft.Authorization/roleDefinitions/4abbcc35-e782-43d8-92c5-2d3f1bd2253f'
+ 'Azure Maps Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/423170ca-a8f6-4b0f-8487-9e4eb8f49bfa'
+ 'Azure Stack Registration Owner': '/providers/Microsoft.Authorization/roleDefinitions/6f12a6df-dd06-4f3e-bcb1-ce8be600526a'
+ 'Backup Contributor': '/providers/Microsoft.Authorization/roleDefinitions/5e467623-bb1f-42f4-a55d-6e525e11384b'
+ 'Billing Reader': '/providers/Microsoft.Authorization/roleDefinitions/fa23ad8b-c56e-40d8-ac0c-ce449e1d2c64'
+ 'Backup Operator': '/providers/Microsoft.Authorization/roleDefinitions/00c29273-979b-4161-815c-10b084fb9324'
+ 'Backup Reader': '/providers/Microsoft.Authorization/roleDefinitions/a795c7a0-d4a2-40c1-ae25-d81f01202912'
+ 'BizTalk Contributor': '/providers/Microsoft.Authorization/roleDefinitions/5e3c6656-6cfa-4708-81fe-0de47ac73342'
+ 'CDN Endpoint Contributor': '/providers/Microsoft.Authorization/roleDefinitions/426e0c7f-0c7e-4658-b36f-ff54d6c29b45'
+ 'CDN Endpoint Reader': '/providers/Microsoft.Authorization/roleDefinitions/871e35f6-b5c1-49cc-a043-bde969a0f2cd'
+ 'CDN Profile Contributor': '/providers/Microsoft.Authorization/roleDefinitions/ec156ff8-a8d1-4d15-830c-5b80698ca432'
+ 'CDN Profile Reader': '/providers/Microsoft.Authorization/roleDefinitions/8f96442b-4075-438f-813d-ad51ab4019af'
+ 'Classic Network Contributor': '/providers/Microsoft.Authorization/roleDefinitions/b34d265f-36f7-4a0d-a4d4-e158ca92e90f'
+ 'Classic Storage Account Contributor': '/providers/Microsoft.Authorization/roleDefinitions/86e8f5dc-a6e9-4c67-9d15-de283e8eac25'
+ 'Classic Storage Account Key Operator Service Role': '/providers/Microsoft.Authorization/roleDefinitions/985d6b00-f706-48f5-a6fe-d0ca12fb668d'
+ 'ClearDB MySQL DB Contributor': '/providers/Microsoft.Authorization/roleDefinitions/9106cda0-8a86-4e81-b686-29a22c54effe'
+ 'Classic Virtual Machine Contributor': '/providers/Microsoft.Authorization/roleDefinitions/d73bb868-a0df-4d4d-bd69-98a00b01fccb'
+ 'Cognitive Services User': '/providers/Microsoft.Authorization/roleDefinitions/a97b65f3-24c7-4388-baec-2e87135dc908'
+ 'Cognitive Services Contributor': '/providers/Microsoft.Authorization/roleDefinitions/25fbc0a9-bd7c-42a3-aa1a-3b75d497ee68'
+ 'CosmosBackupOperator': '/providers/Microsoft.Authorization/roleDefinitions/db7b14f2-5adf-42da-9f96-f2ee17bab5cb'
+ 'Contributor': '/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c'
+ 'Cosmos DB Account Reader Role': '/providers/Microsoft.Authorization/roleDefinitions/fbdf93bf-df7d-467e-a4d2-9458aa1360c8'
+ 'Cost Management Contributor': '/providers/Microsoft.Authorization/roleDefinitions/434105ed-43f6-45c7-a02f-909b2ba83430'
+ 'Cost Management Reader': '/providers/Microsoft.Authorization/roleDefinitions/72fafb9e-0641-4937-9268-a91bfd8191a3'
+ 'Data Box Contributor': '/providers/Microsoft.Authorization/roleDefinitions/add466c9-e687-43fc-8d98-dfcf8d720be5'
+ 'Data Box Reader': '/providers/Microsoft.Authorization/roleDefinitions/028f4ed7-e2a9-465e-a8f4-9c0ffdfdc027'
+ 'Data Factory Contributor': '/providers/Microsoft.Authorization/roleDefinitions/673868aa-7521-48a0-acc6-0f60742d39f5'
+ 'Data Purger': '/providers/Microsoft.Authorization/roleDefinitions/150f5e0c-0603-4f03-8c7f-cf70034c4e90'
+ 'Data Lake Analytics Developer': '/providers/Microsoft.Authorization/roleDefinitions/47b7735b-770e-4598-a7da-8b91488b4c88'
+ 'DevTest Labs User': '/providers/Microsoft.Authorization/roleDefinitions/76283e04-6283-4c54-8f91-bcf1374a3c64'
+ 'DocumentDB Account Contributor': '/providers/Microsoft.Authorization/roleDefinitions/5bd9cd88-fe45-4216-938b-f97437e15450'
+ 'DNS Zone Contributor': '/providers/Microsoft.Authorization/roleDefinitions/befefa01-2a29-4197-83a8-272ff33ce314'
+ 'EventGrid EventSubscription Contributor': '/providers/Microsoft.Authorization/roleDefinitions/428e0ff0-5e57-4d9c-a221-2c70d0e0a443'
+ 'EventGrid EventSubscription Reader': '/providers/Microsoft.Authorization/roleDefinitions/2414bbcf-6497-4faf-8c65-045460748405'
+ 'Graph Owner': '/providers/Microsoft.Authorization/roleDefinitions/b60367af-1334-4454-b71e-769d9a4f83d9'
+ 'HDInsight Domain Services Contributor': '/providers/Microsoft.Authorization/roleDefinitions/8d8d5a11-05d3-4bda-a417-a08778121c7c'
+ 'Intelligent Systems Account Contributor': '/providers/Microsoft.Authorization/roleDefinitions/03a6d094-3444-4b3d-88af-7477090a9e5e'
+ 'Key Vault Contributor': '/providers/Microsoft.Authorization/roleDefinitions/f25e0fa2-a7c8-4377-a976-54943a77a395'
+ 'Knowledge Consumer': '/providers/Microsoft.Authorization/roleDefinitions/ee361c5d-f7b5-4119-b4b6-892157c8f64c'
+ 'Lab Creator': '/providers/Microsoft.Authorization/roleDefinitions/b97fb8bc-a8b2-4522-a38b-dd33c7e65ead'
+ 'Log Analytics Reader': '/providers/Microsoft.Authorization/roleDefinitions/73c42c96-874c-492b-b04d-ab87d138a893'
+ 'Log Analytics Contributor': '/providers/Microsoft.Authorization/roleDefinitions/92aaf0da-9dab-42b6-94a3-d43ce8d16293'
+ 'Logic App Operator': '/providers/Microsoft.Authorization/roleDefinitions/515c2055-d9d4-4321-b1b9-bd0c9a0f79fe'
+ 'Logic App Contributor': '/providers/Microsoft.Authorization/roleDefinitions/87a39d53-fc1b-424a-814c-f7e04687dc9e'
+ 'Managed Application Operator Role': '/providers/Microsoft.Authorization/roleDefinitions/c7393b34-138c-406f-901b-d8cf2b17e6ae'
+ 'Managed Applications Reader': '/providers/Microsoft.Authorization/roleDefinitions/b9331d33-8a36-4f8c-b097-4f54124fdb44'
+ 'Managed Identity Operator': '/providers/Microsoft.Authorization/roleDefinitions/f1a07417-d97a-45cb-824c-7a7467783830'
+ 'Managed Identity Contributor': '/providers/Microsoft.Authorization/roleDefinitions/e40ec5ca-96e0-45a2-b4ff-59039f2c2b59'
+ 'Management Group Contributor': '/providers/Microsoft.Authorization/roleDefinitions/5d58bcaf-24a5-4b20-bdb6-eed9f69fbe4c'
+ 'Management Group Reader': '/providers/Microsoft.Authorization/roleDefinitions/ac63b705-f282-497d-ac71-919bf39d939d'
+ 'Monitoring Metrics Publisher': '/providers/Microsoft.Authorization/roleDefinitions/3913510d-42f4-4e42-8a64-420c390055eb'
+ 'Monitoring Reader': '/providers/Microsoft.Authorization/roleDefinitions/43d0d8ad-25c7-4714-9337-8ba259a9fe05'
+ 'Network Contributor': '/providers/Microsoft.Authorization/roleDefinitions/4d97b98b-1d4f-4787-a291-c67834d212e7'
+ 'Monitoring Contributor': '/providers/Microsoft.Authorization/roleDefinitions/749f88d5-cbae-40b8-bcfc-e573ddc772fa'
+ 'New Relic APM Account Contributor': '/providers/Microsoft.Authorization/roleDefinitions/5d28c62d-5b37-4476-8438-e587778df237'
+ 'Owner': '/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635'
+ 'Reader': '/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7'
+ 'Redis Cache Contributor': '/providers/Microsoft.Authorization/roleDefinitions/e0f68234-74aa-48ed-b826-c38b57376e17'
+ 'Reader and Data Access': '/providers/Microsoft.Authorization/roleDefinitions/c12c1c16-33a1-487b-954d-41c89c60f349'
+ 'Resource Policy Contributor': '/providers/Microsoft.Authorization/roleDefinitions/36243c78-bf99-498c-9df9-86d9f8d28608'
+ 'Scheduler Job Collections Contributor': '/providers/Microsoft.Authorization/roleDefinitions/188a0f2f-5c9e-469b-ae67-2aa5ce574b94'
+ 'Search Service Contributor': '/providers/Microsoft.Authorization/roleDefinitions/7ca78c08-252a-4471-8644-bb5ff32d4ba0'
+ 'Security Admin': '/providers/Microsoft.Authorization/roleDefinitions/fb1c8493-542b-48eb-b624-b4c8fea62acd'
+ 'Security Reader': '/providers/Microsoft.Authorization/roleDefinitions/39bc4728-0917-49c7-9d2c-d95423bc2eb4'
+ 'Spatial Anchors Account Contributor': '/providers/Microsoft.Authorization/roleDefinitions/8bbe83f1-e2a6-4df7-8cb4-4e04d4e5c827'
+ 'Site Recovery Contributor': '/providers/Microsoft.Authorization/roleDefinitions/6670b86e-a3f7-4917-ac9b-5d6ab1be4567'
+ 'Site Recovery Operator': '/providers/Microsoft.Authorization/roleDefinitions/494ae006-db33-4328-bf46-533a6560a3ca'
+ 'Spatial Anchors Account Reader': '/providers/Microsoft.Authorization/roleDefinitions/5d51204f-eb77-4b1c-b86a-2ec626c49413'
+ 'Site Recovery Reader': '/providers/Microsoft.Authorization/roleDefinitions/dbaa88c4-0c30-4179-9fb3-46319faa6149'
+ 'Spatial Anchors Account Owner': '/providers/Microsoft.Authorization/roleDefinitions/70bbe301-9835-447d-afdd-19eb3167307c'
+ 'SQL Managed Instance Contributor': '/providers/Microsoft.Authorization/roleDefinitions/4939a1f6-9ae0-4e48-a1e0-f2cbe897382d'
+ 'SQL DB Contributor': '/providers/Microsoft.Authorization/roleDefinitions/9b7fa17d-e63e-47b0-bb0a-15c516ac86ec'
+ 'SQL Security Manager': '/providers/Microsoft.Authorization/roleDefinitions/056cd41c-7e88-42e1-933e-88ba6a50c9c3'
+ 'Storage Account Contributor': '/providers/Microsoft.Authorization/roleDefinitions/17d1049b-9a84-46fb-8f53-869881c3d3ab'
+ 'SQL Server Contributor': '/providers/Microsoft.Authorization/roleDefinitions/6d8ee4ec-f05a-4a1d-8b00-a9b17e38b437'
+ 'Storage Account Key Operator Service Role': '/providers/Microsoft.Authorization/roleDefinitions/81a9662b-bebf-436f-a333-f67b29880f12'
+ 'Storage Blob Data Contributor': '/providers/Microsoft.Authorization/roleDefinitions/ba92f5b4-2d11-453d-a403-e96b0029c9fe'
+ 'Storage Blob Data Owner': '/providers/Microsoft.Authorization/roleDefinitions/b7e6dc6d-f1e8-4753-8033-0f276bb0955b'
+ 'Storage Blob Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/2a2b9908-6ea1-4ae2-8e65-a410df84e7d1'
+ 'Storage Queue Data Contributor': '/providers/Microsoft.Authorization/roleDefinitions/974c5e8b-45b9-4653-ba55-5f855dd0fb88'
+ 'Storage Queue Data Message Processor': '/providers/Microsoft.Authorization/roleDefinitions/8a0f0c08-91a1-4084-bc3d-661d67233fed'
+ 'Storage Queue Data Message Sender': '/providers/Microsoft.Authorization/roleDefinitions/c6a89b2d-59bc-44d0-9896-0f6e12d7b80a'
+ 'Storage Queue Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/19e7f393-937e-4f77-808e-94535e297925'
+ 'Support Request Contributor': '/providers/Microsoft.Authorization/roleDefinitions/cfd33db0-3dd1-45e3-aa9d-cdbdf3b6f24e'
+ 'Traffic Manager Contributor': '/providers/Microsoft.Authorization/roleDefinitions/a4b10055-b0c7-44c2-b00f-c7b5b3550cf7'
+ 'Virtual Machine Administrator Login': '/providers/Microsoft.Authorization/roleDefinitions/1c0163c0-47e6-4577-8991-ea5c82e286e4'
+ 'User Access Administrator': '/providers/Microsoft.Authorization/roleDefinitions/18d7d88d-d35e-4fb5-a5c3-7773c20a72d9'
+ 'Virtual Machine User Login': '/providers/Microsoft.Authorization/roleDefinitions/fb879df8-f326-4884-b1cf-06f3ad86be52'
+ 'Virtual Machine Contributor': '/providers/Microsoft.Authorization/roleDefinitions/9980e02c-c2be-4d73-94e8-173b1dc7cf3c'
+ 'Web Plan Contributor': '/providers/Microsoft.Authorization/roleDefinitions/2cc479cb-7b4d-49a8-b449-8c00fd0f0a4b'
+ 'Website Contributor': '/providers/Microsoft.Authorization/roleDefinitions/de139f84-1756-47ae-9be6-808fbbe84772'
+ 'Azure Service Bus Data Owner': '/providers/Microsoft.Authorization/roleDefinitions/090c5cfd-751d-490a-894a-3ce6f1109419'
+ 'Azure Event Hubs Data Owner': '/providers/Microsoft.Authorization/roleDefinitions/f526a384-b230-433a-b45c-95f59c4a2dec'
+ 'Attestation Contributor': '/providers/Microsoft.Authorization/roleDefinitions/bbf86eb8-f7b4-4cce-96e4-18cddf81d86e'
+ 'HDInsight Cluster Operator': '/providers/Microsoft.Authorization/roleDefinitions/61ed4efc-fab3-44fd-b111-e24485cc132a'
+ 'Cosmos DB Operator': '/providers/Microsoft.Authorization/roleDefinitions/230815da-be43-4aae-9cb4-875f7bd000aa'
+ 'Hybrid Server Resource Administrator': '/providers/Microsoft.Authorization/roleDefinitions/48b40c6e-82e0-4eb3-90d5-19e40f49b624'
+ 'Hybrid Server Onboarding': '/providers/Microsoft.Authorization/roleDefinitions/5d1e5ee4-7c68-4a71-ac8b-0739630a3dfb'
+ 'Azure Event Hubs Data Receiver': '/providers/Microsoft.Authorization/roleDefinitions/a638d3c7-ab3a-418d-83e6-5f17a39d4fde'
+ 'Azure Event Hubs Data Sender': '/providers/Microsoft.Authorization/roleDefinitions/2b629674-e913-4c01-ae53-ef4638d8f975'
+ 'Azure Service Bus Data Receiver': '/providers/Microsoft.Authorization/roleDefinitions/4f6d3b9b-027b-4f4c-9142-0e5a2a2247e0'
+ 'Azure Service Bus Data Sender': '/providers/Microsoft.Authorization/roleDefinitions/69a216fc-b8fb-44d8-bc22-1f3c2cd27a39'
+ 'Storage File Data SMB Share Reader': '/providers/Microsoft.Authorization/roleDefinitions/aba4ae5f-2193-4029-9191-0cb91df5e314'
+ 'Storage File Data SMB Share Contributor': '/providers/Microsoft.Authorization/roleDefinitions/0c867c2a-1d8c-454a-a3db-ab2ea1bdc8bb'
+ 'Private DNS Zone Contributor': '/providers/Microsoft.Authorization/roleDefinitions/b12aa53e-6015-4669-85d0-8515ebb3ae7f'
+ 'Storage Blob Delegator': '/providers/Microsoft.Authorization/roleDefinitions/db58b8e5-c6ad-4a2a-8342-4190687cbf4a'
+ 'Desktop Virtualization User': '/providers/Microsoft.Authorization/roleDefinitions/1d18fff3-a72a-46b5-b4a9-0b38a3cd7e63'
+ 'Storage File Data SMB Share Elevated Contributor': '/providers/Microsoft.Authorization/roleDefinitions/a7264617-510b-434b-a828-9731dc254ea7'
+ 'Blueprint Contributor': '/providers/Microsoft.Authorization/roleDefinitions/41077137-e803-4205-871c-5a86e6a753b4'
+ 'Blueprint Operator': '/providers/Microsoft.Authorization/roleDefinitions/437d2ced-4a38-4302-8479-ed2bcb43d090'
+ 'Azure Sentinel Contributor': '/providers/Microsoft.Authorization/roleDefinitions/ab8e14d6-4a74-4a29-9ba8-549422addade'
+ 'Azure Sentinel Responder': '/providers/Microsoft.Authorization/roleDefinitions/3e150937-b8fe-4cfb-8069-0eaf05ecd056'
+ 'Azure Sentinel Reader': '/providers/Microsoft.Authorization/roleDefinitions/8d289c81-5878-46d4-8554-54e1e3d8b5cb'
+ 'Workbook Reader': '/providers/Microsoft.Authorization/roleDefinitions/b279062a-9be3-42a0-92ae-8b3cf002ec4d'
+ 'Workbook Contributor': '/providers/Microsoft.Authorization/roleDefinitions/e8ddcd69-c73f-4f9f-9844-4100522f16ad'
+ 'SignalR AccessKey Reader': '/providers/Microsoft.Authorization/roleDefinitions/04165923-9d83-45d5-8227-78b77b0a687e'
+ 'SignalR/Web PubSub Contributor': '/providers/Microsoft.Authorization/roleDefinitions/8cf5e20a-e4b2-4e9d-b3a1-5ceb692c2761'
+ 'Azure Connected Machine Onboarding': '/providers/Microsoft.Authorization/roleDefinitions/b64e21ea-ac4e-4cdf-9dc9-5b892992bee7'
+ 'Azure Connected Machine Resource Administrator': '/providers/Microsoft.Authorization/roleDefinitions/cd570a14-e51a-42ad-bac8-bafd67325302'
+ 'Managed Services Registration assignment Delete Role': '/providers/Microsoft.Authorization/roleDefinitions/91c1777a-f3dc-4fae-b103-61d183457e46'
+ 'App Configuration Data Owner': '/providers/Microsoft.Authorization/roleDefinitions/5ae67dd6-50cb-40e7-96ff-dc2bfa4b606b'
+ 'App Configuration Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/516239f1-63e1-4d78-a4de-a74fb236a071'
+ 'Kubernetes Cluster - Azure Arc Onboarding': '/providers/Microsoft.Authorization/roleDefinitions/34e09817-6cbe-4d01-b1a2-e0eac5743d41'
+ 'Experimentation Contributor': '/providers/Microsoft.Authorization/roleDefinitions/7f646f1b-fa08-80eb-a22b-edd6ce5c915c'
+ 'Cognitive Services QnA Maker Reader': '/providers/Microsoft.Authorization/roleDefinitions/466ccd10-b268-4a11-b098-b4849f024126'
+ 'Cognitive Services QnA Maker Editor': '/providers/Microsoft.Authorization/roleDefinitions/f4cc2bf9-21be-47a1-bdf1-5c5804381025'
+ 'Experimentation Administrator': '/providers/Microsoft.Authorization/roleDefinitions/7f646f1b-fa08-80eb-a33b-edd6ce5c915c'
+ 'Remote Rendering Administrator': '/providers/Microsoft.Authorization/roleDefinitions/3df8b902-2a6f-47c7-8cc5-360e9b272a7e'
+ 'Remote Rendering Client': '/providers/Microsoft.Authorization/roleDefinitions/d39065c4-c120-43c9-ab0a-63eed9795f0a'
+ 'Managed Application Contributor Role': '/providers/Microsoft.Authorization/roleDefinitions/641177b8-a67a-45b9-a033-47bc880bb21e'
+ 'Security Assessment Contributor': '/providers/Microsoft.Authorization/roleDefinitions/612c2aa1-cb24-443b-ac28-3ab7272de6f5'
+ 'Tag Contributor': '/providers/Microsoft.Authorization/roleDefinitions/4a9ae827-6dc8-4573-8ac7-8239d42aa03f'
+ 'Integration Service Environment Developer': '/providers/Microsoft.Authorization/roleDefinitions/c7aa55d3-1abb-444a-a5ca-5e51e485d6ec'
+ 'Integration Service Environment Contributor': '/providers/Microsoft.Authorization/roleDefinitions/a41e2c5b-bd99-4a07-88f4-9bf657a760b8'
+ 'Azure Kubernetes Service Contributor Role': '/providers/Microsoft.Authorization/roleDefinitions/ed7f3fbd-7b88-4dd4-9017-9adb7ce333f8'
+ 'Azure Digital Twins Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/d57506d4-4c8d-48b1-8587-93c323f6a5a3'
+ 'Azure Digital Twins Data Owner': '/providers/Microsoft.Authorization/roleDefinitions/bcd981a7-7f74-457b-83e1-cceb9e632ffe'
+ 'Hierarchy Settings Administrator': '/providers/Microsoft.Authorization/roleDefinitions/350f8d15-c687-4448-8ae1-157740a3936d'
+ 'FHIR Data Contributor': '/providers/Microsoft.Authorization/roleDefinitions/5a1fc7df-4bf1-4951-a576-89034ee01acd'
+ 'FHIR Data Exporter': '/providers/Microsoft.Authorization/roleDefinitions/3db33094-8700-4567-8da5-1501d4e7e843'
+ 'FHIR Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/4c8d0bbc-75d3-4935-991f-5f3c56d81508'
+ 'FHIR Data Writer': '/providers/Microsoft.Authorization/roleDefinitions/3f88fce4-5892-4214-ae73-ba5294559913'
+ 'Experimentation Reader': '/providers/Microsoft.Authorization/roleDefinitions/49632ef5-d9ac-41f4-b8e7-bbe587fa74a1'
+ 'Object Understanding Account Owner': '/providers/Microsoft.Authorization/roleDefinitions/4dd61c23-6743-42fe-a388-d8bdd41cb745'
+ 'Azure Maps Data Contributor': '/providers/Microsoft.Authorization/roleDefinitions/8f5e0ce6-4f7b-4dcf-bddf-e6f48634a204'
+ 'Cognitive Services Custom Vision Contributor': '/providers/Microsoft.Authorization/roleDefinitions/c1ff6cc2-c111-46fe-8896-e0ef812ad9f3'
+ 'Cognitive Services Custom Vision Deployment': '/providers/Microsoft.Authorization/roleDefinitions/5c4089e1-6d96-4d2f-b296-c1bc7137275f'
+ 'Cognitive Services Custom Vision Labeler': '/providers/Microsoft.Authorization/roleDefinitions/88424f51-ebe7-446f-bc41-7fa16989e96c'
+ 'Cognitive Services Custom Vision Reader': '/providers/Microsoft.Authorization/roleDefinitions/93586559-c37d-4a6b-ba08-b9f0940c2d73'
+ 'Cognitive Services Custom Vision Trainer': '/providers/Microsoft.Authorization/roleDefinitions/0a5ae4ab-0d65-4eeb-be61-29fc9b54394b'
+ 'Key Vault Administrator': '/providers/Microsoft.Authorization/roleDefinitions/00482a5a-887f-4fb3-b363-3b7fe8e74483'
+ 'Key Vault Crypto Officer': '/providers/Microsoft.Authorization/roleDefinitions/14b46e9e-c2b7-41b4-b07b-48a6ebf60603'
+ 'Key Vault Crypto User': '/providers/Microsoft.Authorization/roleDefinitions/12338af0-0e69-4776-bea7-57ae8d297424'
+ 'Key Vault Secrets Officer': '/providers/Microsoft.Authorization/roleDefinitions/b86a8fe4-44ce-4948-aee5-eccb2c155cd7'
+ 'Key Vault Secrets User': '/providers/Microsoft.Authorization/roleDefinitions/4633458b-17de-408a-b874-0445c86b69e6'
+ 'Key Vault Certificates Officer': '/providers/Microsoft.Authorization/roleDefinitions/a4417e6f-fecd-4de8-b567-7b0420556985'
+ 'Key Vault Reader': '/providers/Microsoft.Authorization/roleDefinitions/21090545-7ca7-4776-b22c-e363652d74d2'
+ 'Key Vault Crypto Service Encryption User': '/providers/Microsoft.Authorization/roleDefinitions/e147488a-f6f5-4113-8e2d-b22465e65bf6'
+ 'Azure Arc Kubernetes Viewer': '/providers/Microsoft.Authorization/roleDefinitions/63f0a09d-1495-4db4-a681-037d84835eb4'
+ 'Azure Arc Kubernetes Writer': '/providers/Microsoft.Authorization/roleDefinitions/5b999177-9696-4545-85c7-50de3797e5a1'
+ 'Azure Arc Kubernetes Cluster Admin': '/providers/Microsoft.Authorization/roleDefinitions/8393591c-06b9-48a2-a542-1bd6b377f6a2'
+ 'Azure Arc Kubernetes Admin': '/providers/Microsoft.Authorization/roleDefinitions/dffb1e0c-446f-4dde-a09f-99eb5cc68b96'
+ 'Azure Kubernetes Service RBAC Cluster Admin': '/providers/Microsoft.Authorization/roleDefinitions/b1ff04bb-8a4e-4dc4-8eb5-8693973ce19b'
+ 'Azure Kubernetes Service RBAC Admin': '/providers/Microsoft.Authorization/roleDefinitions/3498e952-d568-435e-9b2c-8d77e338d7f7'
+ 'Azure Kubernetes Service RBAC Reader': '/providers/Microsoft.Authorization/roleDefinitions/7f6c6a51-bcf8-42ba-9220-52d62157d7db'
+ 'Azure Kubernetes Service RBAC Writer': '/providers/Microsoft.Authorization/roleDefinitions/a7ffa36f-339b-4b5c-8bdf-e2c188b2c0eb'
+ 'Services Hub Operator': '/providers/Microsoft.Authorization/roleDefinitions/82200a5b-e217-47a5-b665-6d8765ee745b'
+ 'Object Understanding Account Reader': '/providers/Microsoft.Authorization/roleDefinitions/d18777c0-1514-4662-8490-608db7d334b6'
+ 'Azure Arc Enabled Kubernetes Cluster User Role': '/providers/Microsoft.Authorization/roleDefinitions/00493d72-78f6-4148-b6c5-d3ce8e4799dd'
+ 'SignalR REST API Owner': '/providers/Microsoft.Authorization/roleDefinitions/fd53cd77-2268-407a-8f46-7e7863d0f521'
+ 'Collaborative Data Contributor': '/providers/Microsoft.Authorization/roleDefinitions/daa9e50b-21df-454c-94a6-a8050adab352'
+ 'Device Update Reader': '/providers/Microsoft.Authorization/roleDefinitions/e9dba6fb-3d52-4cf0-bce3-f06ce71b9e0f'
+ 'Device Update Administrator': '/providers/Microsoft.Authorization/roleDefinitions/02ca0879-e8e4-47a5-a61e-5c618b76e64a'
+ 'Device Update Content Administrator': '/providers/Microsoft.Authorization/roleDefinitions/0378884a-3af5-44ab-8323-f5b22f9f3c98'
+ 'Device Update Deployments Administrator': '/providers/Microsoft.Authorization/roleDefinitions/e4237640-0e3d-4a46-8fda-70bc94856432'
+ 'Device Update Deployments Reader': '/providers/Microsoft.Authorization/roleDefinitions/49e2f5d2-7741-4835-8efa-19e1fe35e47f'
+ 'Device Update Content Reader': '/providers/Microsoft.Authorization/roleDefinitions/d1ee9a80-8b14-47f0-bdc2-f4a351625a7b'
+ 'Cognitive Services Metrics Advisor Administrator': '/providers/Microsoft.Authorization/roleDefinitions/cb43c632-a144-4ec5-977c-e80c4affc34a'
+ 'Cognitive Services Metrics Advisor User': '/providers/Microsoft.Authorization/roleDefinitions/3b20f47b-3825-43cb-8114-4bd2201156a8'
+ 'AgFood Platform Service Reader': '/providers/Microsoft.Authorization/roleDefinitions/7ec7ccdc-f61e-41fe-9aaf-980df0a44eba'
+ 'AgFood Platform Service Contributor': '/providers/Microsoft.Authorization/roleDefinitions/8508508a-4469-4e45-963b-2518ee0bb728'
+ 'AgFood Platform Service Admin': '/providers/Microsoft.Authorization/roleDefinitions/f8da80de-1ff9-4747-ad80-a19b7f6079e3'
+ 'Managed HSM contributor': '/providers/Microsoft.Authorization/roleDefinitions/18500a29-7fe2-46b2-a342-b16a415e101d'
+ 'Security Detonation Chamber Submitter': '/providers/Microsoft.Authorization/roleDefinitions/0b555d9b-b4a7-4f43-b330-627f0e5be8f0'
+ 'SignalR REST API Reader': '/providers/Microsoft.Authorization/roleDefinitions/ddde6b66-c0df-4114-a159-3618637b3035'
+ 'SignalR Service Owner': '/providers/Microsoft.Authorization/roleDefinitions/7e4f1700-ea5a-4f59-8f37-079cfe29dce3'
+ 'Reservation Purchaser': '/providers/Microsoft.Authorization/roleDefinitions/f7b75c60-3036-4b75-91c3-6b41c27c1689'
+ 'Storage Account Backup Contributor Role': '/providers/Microsoft.Authorization/roleDefinitions/e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1'
+ 'Experimentation Metric Contributor': '/providers/Microsoft.Authorization/roleDefinitions/6188b7c9-7d01-4f99-a59f-c88b630326c0'
+ 'Project Babylon Data Curator': '/providers/Microsoft.Authorization/roleDefinitions/9ef4ef9c-a049-46b0-82ab-dd8ac094c889'
+ 'Project Babylon Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/c8d896ba-346d-4f50-bc1d-7d1c84130446'
+ 'Project Babylon Data Source Administrator': '/providers/Microsoft.Authorization/roleDefinitions/05b7651b-dc44-475e-b74d-df3db49fae0f'
+ 'Application Group Contributor': '/providers/Microsoft.Authorization/roleDefinitions/ca6382a4-1721-4bcf-a114-ff0c70227b6b'
+ 'Desktop Virtualization Reader': '/providers/Microsoft.Authorization/roleDefinitions/49a72310-ab8d-41df-bbb0-79b649203868'
+ 'Desktop Virtualization Contributor': '/providers/Microsoft.Authorization/roleDefinitions/082f0a83-3be5-4ba1-904c-961cca79b387'
+ 'Desktop Virtualization Workspace Contributor': '/providers/Microsoft.Authorization/roleDefinitions/21efdde3-836f-432b-bf3d-3e8e734d4b2b'
+ 'Desktop Virtualization User Session Operator': '/providers/Microsoft.Authorization/roleDefinitions/ea4bfff8-7fb4-485a-aadd-d4129a0ffaa6'
+ 'Desktop Virtualization Session Host Operator': '/providers/Microsoft.Authorization/roleDefinitions/2ad6aaab-ead9-4eaa-8ac5-da422f562408'
+ 'Desktop Virtualization Host Pool Reader': '/providers/Microsoft.Authorization/roleDefinitions/ceadfde2-b300-400a-ab7b-6143895aa822'
+ 'Desktop Virtualization Host Pool Contributor': '/providers/Microsoft.Authorization/roleDefinitions/e307426c-f9b6-4e81-87de-d99efb3c32bc'
+ 'Desktop Virtualization Application Group Reader': '/providers/Microsoft.Authorization/roleDefinitions/aebf23d0-b568-4e86-b8f9-fe83a2c6ab55'
+ 'Desktop Virtualization Application Group Contributor': '/providers/Microsoft.Authorization/roleDefinitions/86240b0e-9422-4c43-887b-b61143f32ba8'
+ 'Desktop Virtualization Workspace Reader': '/providers/Microsoft.Authorization/roleDefinitions/0fa44ee9-7a7d-466b-9bb2-2bf446b1204d'
+ 'Disk Backup Reader': '/providers/Microsoft.Authorization/roleDefinitions/3e5e47e6-65f7-47ef-90b5-e5dd4d455f24'
+ 'Disk Restore Operator': '/providers/Microsoft.Authorization/roleDefinitions/b50d9833-a0cb-478e-945f-707fcc997c13'
+ 'Disk Snapshot Contributor': '/providers/Microsoft.Authorization/roleDefinitions/7efff54f-a5b4-42b5-a1c5-5411624893ce'
+ 'Microsoft.Kubernetes connected cluster role': '/providers/Microsoft.Authorization/roleDefinitions/5548b2cf-c94c-4228-90ba-30851930a12f'
+ 'Security Detonation Chamber Submission Manager': '/providers/Microsoft.Authorization/roleDefinitions/a37b566d-3efa-4beb-a2f2-698963fa42ce'
+ 'Security Detonation Chamber Publisher': '/providers/Microsoft.Authorization/roleDefinitions/352470b3-6a9c-4686-b503-35deb827e500'
+ 'Collaborative Runtime Operator': '/providers/Microsoft.Authorization/roleDefinitions/7a6f0e70-c033-4fb1-828c-08514e5f4102'
+ 'CosmosRestoreOperator': '/providers/Microsoft.Authorization/roleDefinitions/5432c526-bc82-444a-b7ba-57c5b0b5b34f'
+ 'FHIR Data Converter': '/providers/Microsoft.Authorization/roleDefinitions/a1705bd2-3a8f-45a5-8683-466fcfd5cc24'
+ 'Azure Sentinel Automation Contributor': '/providers/Microsoft.Authorization/roleDefinitions/f4c81013-99ee-4d62-a7ee-b3f1f648599a'
+ 'Quota Request Operator': '/providers/Microsoft.Authorization/roleDefinitions/0e5f05e5-9ab9-446b-b98d-1e2157c94125'
+ 'EventGrid Contributor': '/providers/Microsoft.Authorization/roleDefinitions/1e241071-0855-49ea-94dc-649edcd759de'
+ 'Security Detonation Chamber Reader': '/providers/Microsoft.Authorization/roleDefinitions/28241645-39f8-410b-ad48-87863e2951d5'
+ 'Object Anchors Account Reader': '/providers/Microsoft.Authorization/roleDefinitions/4a167cdf-cb95-4554-9203-2347fe489bd9'
+ 'Object Anchors Account Owner': '/providers/Microsoft.Authorization/roleDefinitions/ca0835dd-bacc-42dd-8ed2-ed5e7230d15b'
+ 'WorkloadBuilder Migration Agent Role': '/providers/Microsoft.Authorization/roleDefinitions/d17ce0a2-0697-43bc-aac5-9113337ab61c'
+ 'Azure Spring Cloud Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/b5537268-8956-4941-a8f0-646150406f0c'
+ 'Cognitive Services Speech User': '/providers/Microsoft.Authorization/roleDefinitions/f2dc8367-1007-4938-bd23-fe263f013447'
+ 'Cognitive Services Speech Contributor': '/providers/Microsoft.Authorization/roleDefinitions/0e75ca1e-0464-4b4d-8b93-68208a576181'
+ 'Cognitive Services Face Recognizer': '/providers/Microsoft.Authorization/roleDefinitions/9894cab4-e18a-44aa-828b-cb588cd6f2d7'
+ 'Media Services Account Administrator': '/providers/Microsoft.Authorization/roleDefinitions/054126f8-9a2b-4f1c-a9ad-eca461f08466'
+ 'Media Services Live Events Administrator': '/providers/Microsoft.Authorization/roleDefinitions/532bc159-b25e-42c0-969e-a1d439f60d77'
+ 'Media Services Media Operator': '/providers/Microsoft.Authorization/roleDefinitions/e4395492-1534-4db2-bedf-88c14621589c'
+ 'Media Services Policy Administrator': '/providers/Microsoft.Authorization/roleDefinitions/c4bba371-dacd-4a26-b320-7250bca963ae'
+ 'Media Services Streaming Endpoints Administrator': '/providers/Microsoft.Authorization/roleDefinitions/99dba123-b5fe-44d5-874c-ced7199a5804'
+ 'Stream Analytics Query Tester': '/providers/Microsoft.Authorization/roleDefinitions/1ec5b3c1-b17e-4e25-8312-2acb3c3c5abf'
+ 'AnyBuild Builder': '/providers/Microsoft.Authorization/roleDefinitions/a2138dac-4907-4679-a376-736901ed8ad8'
+ 'IoT Hub Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/b447c946-2db7-41ec-983d-d8bf3b1c77e3'
+ 'IoT Hub Twin Contributor': '/providers/Microsoft.Authorization/roleDefinitions/494bdba2-168f-4f31-a0a1-191d2f7c028c'
+ 'IoT Hub Registry Contributor': '/providers/Microsoft.Authorization/roleDefinitions/4ea46cd5-c1b2-4a8e-910b-273211f9ce47'
+ 'IoT Hub Data Contributor': '/providers/Microsoft.Authorization/roleDefinitions/4fc6c259-987e-4a07-842e-c321cc9d413f'
+ 'Test Base Reader': '/providers/Microsoft.Authorization/roleDefinitions/15e0f5a1-3450-4248-8e25-e2afe88a9e85'
+ 'Search Index Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/1407120a-92aa-4202-b7e9-c0e197c71c8f'
+ 'Search Index Data Contributor': '/providers/Microsoft.Authorization/roleDefinitions/8ebe5a00-799e-43f5-93ac-243d3dce84a7'
+ 'Storage Table Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/76199698-9eea-4c19-bc75-cec21354c6b6'
+ 'Storage Table Data Contributor': '/providers/Microsoft.Authorization/roleDefinitions/0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3'
+ 'DICOM Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/e89c7a3c-2f64-4fa1-a847-3e4c9ba4283a'
+ 'DICOM Data Owner': '/providers/Microsoft.Authorization/roleDefinitions/58a3b984-7adf-4c20-983a-32417c86fbc8'
+ 'EventGrid Data Sender': '/providers/Microsoft.Authorization/roleDefinitions/d5a91429-5739-47e2-a06b-3470a27159e7'
+ 'Disk Pool Operator': '/providers/Microsoft.Authorization/roleDefinitions/60fc6e62-5479-42d4-8bf4-67625fcc2840'
+ 'AzureML Data Scientist': '/providers/Microsoft.Authorization/roleDefinitions/f6c7c914-8db3-469d-8ca1-694a8f32e121'
+ 'Grafana Admin': '/providers/Microsoft.Authorization/roleDefinitions/22926164-76b3-42b3-bc55-97df8dab3e41'
+ 'Azure Connected SQL Server Onboarding': '/providers/Microsoft.Authorization/roleDefinitions/e8113dce-c529-4d33-91fa-e9b972617508'
+ 'Azure Relay Sender': '/providers/Microsoft.Authorization/roleDefinitions/26baccc8-eea7-41f1-98f4-1762cc7f685d'
+ 'Azure Relay Owner': '/providers/Microsoft.Authorization/roleDefinitions/2787bf04-f1f5-4bfe-8383-c8a24483ee38'
+ 'Azure Relay Listener': '/providers/Microsoft.Authorization/roleDefinitions/26e0b698-aa6d-4085-9386-aadae190014d'
+ 'Grafana Viewer': '/providers/Microsoft.Authorization/roleDefinitions/60921a7e-fef1-4a43-9b16-a26c52ad4769'
+ 'Grafana Editor': '/providers/Microsoft.Authorization/roleDefinitions/a79a5197-3a5c-4973-a920-486035ffd60f'
+ 'Automation Contributor': '/providers/Microsoft.Authorization/roleDefinitions/f353d9bd-d4a6-484e-a77a-8050b599b867'
+ 'Kubernetes Extension Contributor': '/providers/Microsoft.Authorization/roleDefinitions/85cb6faf-e071-4c9b-8136-154b5a04f717'
+ 'Device Provisioning Service Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/10745317-c249-44a1-a5ce-3a4353c0bbd8'
+ 'Device Provisioning Service Data Contributor': '/providers/Microsoft.Authorization/roleDefinitions/dfce44e4-17b7-4bd1-a6d1-04996ec95633'
+ 'CodeSigning Certificate Profile Signer': '/providers/Microsoft.Authorization/roleDefinitions/2837e146-70d7-4cfd-ad55-7efa6464f958'
+ 'Azure Spring Cloud Service Registry Reader': '/providers/Microsoft.Authorization/roleDefinitions/cff1b556-2399-4e7e-856d-a8f754be7b65'
+ 'Azure Spring Cloud Service Registry Contributor': '/providers/Microsoft.Authorization/roleDefinitions/f5880b48-c26d-48be-b172-7927bfa1c8f1'
+ 'Azure Spring Cloud Config Server Reader': '/providers/Microsoft.Authorization/roleDefinitions/d04c6db6-4947-4782-9e91-30a88feb7be7'
+ 'Azure Spring Cloud Config Server Contributor': '/providers/Microsoft.Authorization/roleDefinitions/a06f5c24-21a7-4e1a-aa2b-f19eb6684f5b'
+ 'Azure VM Managed identities restore Contributor': '/providers/Microsoft.Authorization/roleDefinitions/6ae96244-5829-4925-a7d3-5975537d91dd'
+ 'Azure Maps Search and Render Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/6be48352-4f82-47c9-ad5e-0acacefdb005'
+ 'Azure Maps Contributor': '/providers/Microsoft.Authorization/roleDefinitions/dba33070-676a-4fb0-87fa-064dc56ff7fb'
+}
+
+var roleDefinitionId_var = (contains(builtInRoleNames_var, roleDefinitionIdOrName) ? builtInRoleNames_var[roleDefinitionIdOrName] : roleDefinitionIdOrName)
+
+module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) {
+ name: 'pid-${cuaId}'
+ params: {}
+}
+
+resource roleAssignment 'Microsoft.Authorization/roleAssignments@2021-04-01-preview' = {
+ name: guid(subscriptionId, resourceGroupName, roleDefinitionId_var, principalId)
+ properties: {
+ roleDefinitionId: roleDefinitionId_var
+ principalId: principalId
+ description: !empty(description) ? description : null
+ principalType: !empty(principalType) ? any(principalType) : null
+ delegatedManagedIdentityResourceId: !empty(delegatedManagedIdentityResourceId) ? delegatedManagedIdentityResourceId : null
+ conditionVersion: !empty(conditionVersion) && !empty(condition) ? conditionVersion : null
+ condition: !empty(condition) ? condition : null
+ }
+}
+
+@sys.description('The GUID of the Role Assignment')
+output name string = roleAssignment.name
+
+@sys.description('The resource ID of the Role Assignment')
+output scope string = resourceGroup().id
+
+@sys.description('The scope this Role Assignment applies to')
+output resourceId string = az.resourceId(resourceGroupName, 'Microsoft.Authorization/roleAssignments', roleAssignment.name)
+
+@sys.description('The name of the resource group the role assignment was applied at')
+output resourceGroupName string = resourceGroup().name
diff --git a/carml/1.0.0/Microsoft.Authorization/roleAssignments/resourceGroup/readme.md b/carml/1.0.0/Microsoft.Authorization/roleAssignments/resourceGroup/readme.md
new file mode 100644
index 000000000..aca00e1a3
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleAssignments/resourceGroup/readme.md
@@ -0,0 +1,37 @@
+# Role Assignment on Resource Group level `[Microsoft.Authorization/roleAssignments/resourceGroup]`
+
+With this module you can perform role assignments on a resource group level
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/roleAssignments` | 2021-04-01-preview |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `condition` | string | | | Optional. The conditions on the role assignment. This limits the resources it can be assigned to |
+| `conditionVersion` | string | `2.0` | `[2.0]` | Optional. Version of the condition. Currently accepted value is "2.0" |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered. |
+| `delegatedManagedIdentityResourceId` | string | | | Optional. ID of the delegated managed identity resource |
+| `description` | string | | | Optional. Description of role assignment |
+| `principalId` | string | | | Required. The Principal or Object ID of the Security Principal (User, Group, Service Principal, Managed Identity) |
+| `principalType` | string | | `[ServicePrincipal, Group, User, ForeignGroup, Device, ]` | Optional. The principal type of the assigned principal ID. |
+| `resourceGroupName` | string | `[resourceGroup().name]` | | Optional. Name of the Resource Group to assign the RBAC role to. If not provided, will use the current scope for deployment. |
+| `roleDefinitionIdOrName` | string | | | Required. 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' |
+| `subscriptionId` | string | `[subscription().subscriptionId]` | | Optional. Subscription ID of the subscription to assign the RBAC role to. If not provided, will use the current scope for deployment. |
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The GUID of the Role Assignment |
+| `resourceGroupName` | string | The name of the resource group the role assignment was applied at |
+| `resourceId` | string | The scope this Role Assignment applies to |
+| `scope` | string | The resource ID of the Role Assignment |
+
+## Template references
+
+- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/roleAssignments)
diff --git a/carml/1.0.0/Microsoft.Authorization/roleAssignments/resourceGroup/version.json b/carml/1.0.0/Microsoft.Authorization/roleAssignments/resourceGroup/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleAssignments/resourceGroup/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/roleAssignments/subscription/deploy.bicep b/carml/1.0.0/Microsoft.Authorization/roleAssignments/subscription/deploy.bicep
new file mode 100644
index 000000000..bf5f0fcd9
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleAssignments/subscription/deploy.bicep
@@ -0,0 +1,344 @@
+targetScope = 'subscription'
+
+@sys.description('Required. 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 roleDefinitionIdOrName string
+
+@sys.description('Required. The Principal or Object ID of the Security Principal (User, Group, Service Principal, Managed Identity)')
+param principalId string
+
+@sys.description('Optional. Subscription ID of the subscription to assign the RBAC role to. If not provided, will use the current scope for deployment.')
+param subscriptionId string = subscription().subscriptionId
+
+@sys.description('Optional. Description of role assignment')
+param description string = ''
+
+@sys.description('Optional. ID of the delegated managed identity resource')
+param delegatedManagedIdentityResourceId string = ''
+
+@sys.description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to')
+param condition string = ''
+
+@sys.description('Optional. Version of the condition. Currently accepted value is "2.0"')
+@allowed([
+ '2.0'
+])
+param conditionVersion string = '2.0'
+
+@sys.description('Optional. The principal type of the assigned principal ID.')
+@allowed([
+ 'ServicePrincipal'
+ 'Group'
+ 'User'
+ 'ForeignGroup'
+ 'Device'
+ ''
+])
+param principalType string = ''
+
+var builtInRoleNames_var = {
+ 'AcrPush': '/providers/Microsoft.Authorization/roleDefinitions/8311e382-0749-4cb8-b61a-304f252e45ec'
+ 'API Management Service Contributor': '/providers/Microsoft.Authorization/roleDefinitions/312a565d-c81f-4fd8-895a-4e21e48d571c'
+ 'AcrPull': '/providers/Microsoft.Authorization/roleDefinitions/7f951dda-4ed3-4680-a7ca-43fe172d538d'
+ 'AcrImageSigner': '/providers/Microsoft.Authorization/roleDefinitions/6cef56e8-d556-48e5-a04f-b8e64114680f'
+ 'AcrDelete': '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'
+ 'AcrQuarantineReader': '/providers/Microsoft.Authorization/roleDefinitions/cdda3590-29a3-44f6-95f2-9f980659eb04'
+ 'AcrQuarantineWriter': '/providers/Microsoft.Authorization/roleDefinitions/c8d4ff99-41c3-41a8-9f60-21dfdad59608'
+ 'API Management Service Operator Role': '/providers/Microsoft.Authorization/roleDefinitions/e022efe7-f5ba-4159-bbe4-b44f577e9b61'
+ 'API Management Service Reader Role': '/providers/Microsoft.Authorization/roleDefinitions/71522526-b88f-4d52-b57f-d31fc3546d0d'
+ 'Application Insights Component Contributor': '/providers/Microsoft.Authorization/roleDefinitions/ae349356-3a1b-4a5e-921d-050484c6347e'
+ 'Application Insights Snapshot Debugger': '/providers/Microsoft.Authorization/roleDefinitions/08954f03-6346-4c2e-81c0-ec3a5cfae23b'
+ 'Attestation Reader': '/providers/Microsoft.Authorization/roleDefinitions/fd1bd22b-8476-40bc-a0bc-69b95687b9f3'
+ 'Automation Job Operator': '/providers/Microsoft.Authorization/roleDefinitions/4fe576fe-1146-4730-92eb-48519fa6bf9f'
+ 'Automation Runbook Operator': '/providers/Microsoft.Authorization/roleDefinitions/5fb5aef8-1081-4b8e-bb16-9d5d0385bab5'
+ 'Automation Operator': '/providers/Microsoft.Authorization/roleDefinitions/d3881f73-407a-4167-8283-e981cbba0404'
+ 'Avere Contributor': '/providers/Microsoft.Authorization/roleDefinitions/4f8fab4f-1852-4a58-a46a-8eaf358af14a'
+ 'Avere Operator': '/providers/Microsoft.Authorization/roleDefinitions/c025889f-8102-4ebf-b32c-fc0c6f0c6bd9'
+ 'Azure Kubernetes Service Cluster Admin Role': '/providers/Microsoft.Authorization/roleDefinitions/0ab0b1a8-8aac-4efd-b8c2-3ee1fb270be8'
+ 'Azure Kubernetes Service Cluster User Role': '/providers/Microsoft.Authorization/roleDefinitions/4abbcc35-e782-43d8-92c5-2d3f1bd2253f'
+ 'Azure Maps Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/423170ca-a8f6-4b0f-8487-9e4eb8f49bfa'
+ 'Azure Stack Registration Owner': '/providers/Microsoft.Authorization/roleDefinitions/6f12a6df-dd06-4f3e-bcb1-ce8be600526a'
+ 'Backup Contributor': '/providers/Microsoft.Authorization/roleDefinitions/5e467623-bb1f-42f4-a55d-6e525e11384b'
+ 'Billing Reader': '/providers/Microsoft.Authorization/roleDefinitions/fa23ad8b-c56e-40d8-ac0c-ce449e1d2c64'
+ 'Backup Operator': '/providers/Microsoft.Authorization/roleDefinitions/00c29273-979b-4161-815c-10b084fb9324'
+ 'Backup Reader': '/providers/Microsoft.Authorization/roleDefinitions/a795c7a0-d4a2-40c1-ae25-d81f01202912'
+ 'BizTalk Contributor': '/providers/Microsoft.Authorization/roleDefinitions/5e3c6656-6cfa-4708-81fe-0de47ac73342'
+ 'CDN Endpoint Contributor': '/providers/Microsoft.Authorization/roleDefinitions/426e0c7f-0c7e-4658-b36f-ff54d6c29b45'
+ 'CDN Endpoint Reader': '/providers/Microsoft.Authorization/roleDefinitions/871e35f6-b5c1-49cc-a043-bde969a0f2cd'
+ 'CDN Profile Contributor': '/providers/Microsoft.Authorization/roleDefinitions/ec156ff8-a8d1-4d15-830c-5b80698ca432'
+ 'CDN Profile Reader': '/providers/Microsoft.Authorization/roleDefinitions/8f96442b-4075-438f-813d-ad51ab4019af'
+ 'Classic Network Contributor': '/providers/Microsoft.Authorization/roleDefinitions/b34d265f-36f7-4a0d-a4d4-e158ca92e90f'
+ 'Classic Storage Account Contributor': '/providers/Microsoft.Authorization/roleDefinitions/86e8f5dc-a6e9-4c67-9d15-de283e8eac25'
+ 'Classic Storage Account Key Operator Service Role': '/providers/Microsoft.Authorization/roleDefinitions/985d6b00-f706-48f5-a6fe-d0ca12fb668d'
+ 'ClearDB MySQL DB Contributor': '/providers/Microsoft.Authorization/roleDefinitions/9106cda0-8a86-4e81-b686-29a22c54effe'
+ 'Classic Virtual Machine Contributor': '/providers/Microsoft.Authorization/roleDefinitions/d73bb868-a0df-4d4d-bd69-98a00b01fccb'
+ 'Cognitive Services User': '/providers/Microsoft.Authorization/roleDefinitions/a97b65f3-24c7-4388-baec-2e87135dc908'
+ 'Cognitive Services Contributor': '/providers/Microsoft.Authorization/roleDefinitions/25fbc0a9-bd7c-42a3-aa1a-3b75d497ee68'
+ 'CosmosBackupOperator': '/providers/Microsoft.Authorization/roleDefinitions/db7b14f2-5adf-42da-9f96-f2ee17bab5cb'
+ 'Contributor': '/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c'
+ 'Cosmos DB Account Reader Role': '/providers/Microsoft.Authorization/roleDefinitions/fbdf93bf-df7d-467e-a4d2-9458aa1360c8'
+ 'Cost Management Contributor': '/providers/Microsoft.Authorization/roleDefinitions/434105ed-43f6-45c7-a02f-909b2ba83430'
+ 'Cost Management Reader': '/providers/Microsoft.Authorization/roleDefinitions/72fafb9e-0641-4937-9268-a91bfd8191a3'
+ 'Data Box Contributor': '/providers/Microsoft.Authorization/roleDefinitions/add466c9-e687-43fc-8d98-dfcf8d720be5'
+ 'Data Box Reader': '/providers/Microsoft.Authorization/roleDefinitions/028f4ed7-e2a9-465e-a8f4-9c0ffdfdc027'
+ 'Data Factory Contributor': '/providers/Microsoft.Authorization/roleDefinitions/673868aa-7521-48a0-acc6-0f60742d39f5'
+ 'Data Purger': '/providers/Microsoft.Authorization/roleDefinitions/150f5e0c-0603-4f03-8c7f-cf70034c4e90'
+ 'Data Lake Analytics Developer': '/providers/Microsoft.Authorization/roleDefinitions/47b7735b-770e-4598-a7da-8b91488b4c88'
+ 'DevTest Labs User': '/providers/Microsoft.Authorization/roleDefinitions/76283e04-6283-4c54-8f91-bcf1374a3c64'
+ 'DocumentDB Account Contributor': '/providers/Microsoft.Authorization/roleDefinitions/5bd9cd88-fe45-4216-938b-f97437e15450'
+ 'DNS Zone Contributor': '/providers/Microsoft.Authorization/roleDefinitions/befefa01-2a29-4197-83a8-272ff33ce314'
+ 'EventGrid EventSubscription Contributor': '/providers/Microsoft.Authorization/roleDefinitions/428e0ff0-5e57-4d9c-a221-2c70d0e0a443'
+ 'EventGrid EventSubscription Reader': '/providers/Microsoft.Authorization/roleDefinitions/2414bbcf-6497-4faf-8c65-045460748405'
+ 'Graph Owner': '/providers/Microsoft.Authorization/roleDefinitions/b60367af-1334-4454-b71e-769d9a4f83d9'
+ 'HDInsight Domain Services Contributor': '/providers/Microsoft.Authorization/roleDefinitions/8d8d5a11-05d3-4bda-a417-a08778121c7c'
+ 'Intelligent Systems Account Contributor': '/providers/Microsoft.Authorization/roleDefinitions/03a6d094-3444-4b3d-88af-7477090a9e5e'
+ 'Key Vault Contributor': '/providers/Microsoft.Authorization/roleDefinitions/f25e0fa2-a7c8-4377-a976-54943a77a395'
+ 'Knowledge Consumer': '/providers/Microsoft.Authorization/roleDefinitions/ee361c5d-f7b5-4119-b4b6-892157c8f64c'
+ 'Lab Creator': '/providers/Microsoft.Authorization/roleDefinitions/b97fb8bc-a8b2-4522-a38b-dd33c7e65ead'
+ 'Log Analytics Reader': '/providers/Microsoft.Authorization/roleDefinitions/73c42c96-874c-492b-b04d-ab87d138a893'
+ 'Log Analytics Contributor': '/providers/Microsoft.Authorization/roleDefinitions/92aaf0da-9dab-42b6-94a3-d43ce8d16293'
+ 'Logic App Operator': '/providers/Microsoft.Authorization/roleDefinitions/515c2055-d9d4-4321-b1b9-bd0c9a0f79fe'
+ 'Logic App Contributor': '/providers/Microsoft.Authorization/roleDefinitions/87a39d53-fc1b-424a-814c-f7e04687dc9e'
+ 'Managed Application Operator Role': '/providers/Microsoft.Authorization/roleDefinitions/c7393b34-138c-406f-901b-d8cf2b17e6ae'
+ 'Managed Applications Reader': '/providers/Microsoft.Authorization/roleDefinitions/b9331d33-8a36-4f8c-b097-4f54124fdb44'
+ 'Managed Identity Operator': '/providers/Microsoft.Authorization/roleDefinitions/f1a07417-d97a-45cb-824c-7a7467783830'
+ 'Managed Identity Contributor': '/providers/Microsoft.Authorization/roleDefinitions/e40ec5ca-96e0-45a2-b4ff-59039f2c2b59'
+ 'Management Group Contributor': '/providers/Microsoft.Authorization/roleDefinitions/5d58bcaf-24a5-4b20-bdb6-eed9f69fbe4c'
+ 'Management Group Reader': '/providers/Microsoft.Authorization/roleDefinitions/ac63b705-f282-497d-ac71-919bf39d939d'
+ 'Monitoring Metrics Publisher': '/providers/Microsoft.Authorization/roleDefinitions/3913510d-42f4-4e42-8a64-420c390055eb'
+ 'Monitoring Reader': '/providers/Microsoft.Authorization/roleDefinitions/43d0d8ad-25c7-4714-9337-8ba259a9fe05'
+ 'Network Contributor': '/providers/Microsoft.Authorization/roleDefinitions/4d97b98b-1d4f-4787-a291-c67834d212e7'
+ 'Monitoring Contributor': '/providers/Microsoft.Authorization/roleDefinitions/749f88d5-cbae-40b8-bcfc-e573ddc772fa'
+ 'New Relic APM Account Contributor': '/providers/Microsoft.Authorization/roleDefinitions/5d28c62d-5b37-4476-8438-e587778df237'
+ 'Owner': '/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635'
+ 'Reader': '/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7'
+ 'Redis Cache Contributor': '/providers/Microsoft.Authorization/roleDefinitions/e0f68234-74aa-48ed-b826-c38b57376e17'
+ 'Reader and Data Access': '/providers/Microsoft.Authorization/roleDefinitions/c12c1c16-33a1-487b-954d-41c89c60f349'
+ 'Resource Policy Contributor': '/providers/Microsoft.Authorization/roleDefinitions/36243c78-bf99-498c-9df9-86d9f8d28608'
+ 'Scheduler Job Collections Contributor': '/providers/Microsoft.Authorization/roleDefinitions/188a0f2f-5c9e-469b-ae67-2aa5ce574b94'
+ 'Search Service Contributor': '/providers/Microsoft.Authorization/roleDefinitions/7ca78c08-252a-4471-8644-bb5ff32d4ba0'
+ 'Security Admin': '/providers/Microsoft.Authorization/roleDefinitions/fb1c8493-542b-48eb-b624-b4c8fea62acd'
+ 'Security Reader': '/providers/Microsoft.Authorization/roleDefinitions/39bc4728-0917-49c7-9d2c-d95423bc2eb4'
+ 'Spatial Anchors Account Contributor': '/providers/Microsoft.Authorization/roleDefinitions/8bbe83f1-e2a6-4df7-8cb4-4e04d4e5c827'
+ 'Site Recovery Contributor': '/providers/Microsoft.Authorization/roleDefinitions/6670b86e-a3f7-4917-ac9b-5d6ab1be4567'
+ 'Site Recovery Operator': '/providers/Microsoft.Authorization/roleDefinitions/494ae006-db33-4328-bf46-533a6560a3ca'
+ 'Spatial Anchors Account Reader': '/providers/Microsoft.Authorization/roleDefinitions/5d51204f-eb77-4b1c-b86a-2ec626c49413'
+ 'Site Recovery Reader': '/providers/Microsoft.Authorization/roleDefinitions/dbaa88c4-0c30-4179-9fb3-46319faa6149'
+ 'Spatial Anchors Account Owner': '/providers/Microsoft.Authorization/roleDefinitions/70bbe301-9835-447d-afdd-19eb3167307c'
+ 'SQL Managed Instance Contributor': '/providers/Microsoft.Authorization/roleDefinitions/4939a1f6-9ae0-4e48-a1e0-f2cbe897382d'
+ 'SQL DB Contributor': '/providers/Microsoft.Authorization/roleDefinitions/9b7fa17d-e63e-47b0-bb0a-15c516ac86ec'
+ 'SQL Security Manager': '/providers/Microsoft.Authorization/roleDefinitions/056cd41c-7e88-42e1-933e-88ba6a50c9c3'
+ 'Storage Account Contributor': '/providers/Microsoft.Authorization/roleDefinitions/17d1049b-9a84-46fb-8f53-869881c3d3ab'
+ 'SQL Server Contributor': '/providers/Microsoft.Authorization/roleDefinitions/6d8ee4ec-f05a-4a1d-8b00-a9b17e38b437'
+ 'Storage Account Key Operator Service Role': '/providers/Microsoft.Authorization/roleDefinitions/81a9662b-bebf-436f-a333-f67b29880f12'
+ 'Storage Blob Data Contributor': '/providers/Microsoft.Authorization/roleDefinitions/ba92f5b4-2d11-453d-a403-e96b0029c9fe'
+ 'Storage Blob Data Owner': '/providers/Microsoft.Authorization/roleDefinitions/b7e6dc6d-f1e8-4753-8033-0f276bb0955b'
+ 'Storage Blob Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/2a2b9908-6ea1-4ae2-8e65-a410df84e7d1'
+ 'Storage Queue Data Contributor': '/providers/Microsoft.Authorization/roleDefinitions/974c5e8b-45b9-4653-ba55-5f855dd0fb88'
+ 'Storage Queue Data Message Processor': '/providers/Microsoft.Authorization/roleDefinitions/8a0f0c08-91a1-4084-bc3d-661d67233fed'
+ 'Storage Queue Data Message Sender': '/providers/Microsoft.Authorization/roleDefinitions/c6a89b2d-59bc-44d0-9896-0f6e12d7b80a'
+ 'Storage Queue Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/19e7f393-937e-4f77-808e-94535e297925'
+ 'Support Request Contributor': '/providers/Microsoft.Authorization/roleDefinitions/cfd33db0-3dd1-45e3-aa9d-cdbdf3b6f24e'
+ 'Traffic Manager Contributor': '/providers/Microsoft.Authorization/roleDefinitions/a4b10055-b0c7-44c2-b00f-c7b5b3550cf7'
+ 'Virtual Machine Administrator Login': '/providers/Microsoft.Authorization/roleDefinitions/1c0163c0-47e6-4577-8991-ea5c82e286e4'
+ 'User Access Administrator': '/providers/Microsoft.Authorization/roleDefinitions/18d7d88d-d35e-4fb5-a5c3-7773c20a72d9'
+ 'Virtual Machine User Login': '/providers/Microsoft.Authorization/roleDefinitions/fb879df8-f326-4884-b1cf-06f3ad86be52'
+ 'Virtual Machine Contributor': '/providers/Microsoft.Authorization/roleDefinitions/9980e02c-c2be-4d73-94e8-173b1dc7cf3c'
+ 'Web Plan Contributor': '/providers/Microsoft.Authorization/roleDefinitions/2cc479cb-7b4d-49a8-b449-8c00fd0f0a4b'
+ 'Website Contributor': '/providers/Microsoft.Authorization/roleDefinitions/de139f84-1756-47ae-9be6-808fbbe84772'
+ 'Azure Service Bus Data Owner': '/providers/Microsoft.Authorization/roleDefinitions/090c5cfd-751d-490a-894a-3ce6f1109419'
+ 'Azure Event Hubs Data Owner': '/providers/Microsoft.Authorization/roleDefinitions/f526a384-b230-433a-b45c-95f59c4a2dec'
+ 'Attestation Contributor': '/providers/Microsoft.Authorization/roleDefinitions/bbf86eb8-f7b4-4cce-96e4-18cddf81d86e'
+ 'HDInsight Cluster Operator': '/providers/Microsoft.Authorization/roleDefinitions/61ed4efc-fab3-44fd-b111-e24485cc132a'
+ 'Cosmos DB Operator': '/providers/Microsoft.Authorization/roleDefinitions/230815da-be43-4aae-9cb4-875f7bd000aa'
+ 'Hybrid Server Resource Administrator': '/providers/Microsoft.Authorization/roleDefinitions/48b40c6e-82e0-4eb3-90d5-19e40f49b624'
+ 'Hybrid Server Onboarding': '/providers/Microsoft.Authorization/roleDefinitions/5d1e5ee4-7c68-4a71-ac8b-0739630a3dfb'
+ 'Azure Event Hubs Data Receiver': '/providers/Microsoft.Authorization/roleDefinitions/a638d3c7-ab3a-418d-83e6-5f17a39d4fde'
+ 'Azure Event Hubs Data Sender': '/providers/Microsoft.Authorization/roleDefinitions/2b629674-e913-4c01-ae53-ef4638d8f975'
+ 'Azure Service Bus Data Receiver': '/providers/Microsoft.Authorization/roleDefinitions/4f6d3b9b-027b-4f4c-9142-0e5a2a2247e0'
+ 'Azure Service Bus Data Sender': '/providers/Microsoft.Authorization/roleDefinitions/69a216fc-b8fb-44d8-bc22-1f3c2cd27a39'
+ 'Storage File Data SMB Share Reader': '/providers/Microsoft.Authorization/roleDefinitions/aba4ae5f-2193-4029-9191-0cb91df5e314'
+ 'Storage File Data SMB Share Contributor': '/providers/Microsoft.Authorization/roleDefinitions/0c867c2a-1d8c-454a-a3db-ab2ea1bdc8bb'
+ 'Private DNS Zone Contributor': '/providers/Microsoft.Authorization/roleDefinitions/b12aa53e-6015-4669-85d0-8515ebb3ae7f'
+ 'Storage Blob Delegator': '/providers/Microsoft.Authorization/roleDefinitions/db58b8e5-c6ad-4a2a-8342-4190687cbf4a'
+ 'Desktop Virtualization User': '/providers/Microsoft.Authorization/roleDefinitions/1d18fff3-a72a-46b5-b4a9-0b38a3cd7e63'
+ 'Storage File Data SMB Share Elevated Contributor': '/providers/Microsoft.Authorization/roleDefinitions/a7264617-510b-434b-a828-9731dc254ea7'
+ 'Blueprint Contributor': '/providers/Microsoft.Authorization/roleDefinitions/41077137-e803-4205-871c-5a86e6a753b4'
+ 'Blueprint Operator': '/providers/Microsoft.Authorization/roleDefinitions/437d2ced-4a38-4302-8479-ed2bcb43d090'
+ 'Azure Sentinel Contributor': '/providers/Microsoft.Authorization/roleDefinitions/ab8e14d6-4a74-4a29-9ba8-549422addade'
+ 'Azure Sentinel Responder': '/providers/Microsoft.Authorization/roleDefinitions/3e150937-b8fe-4cfb-8069-0eaf05ecd056'
+ 'Azure Sentinel Reader': '/providers/Microsoft.Authorization/roleDefinitions/8d289c81-5878-46d4-8554-54e1e3d8b5cb'
+ 'Workbook Reader': '/providers/Microsoft.Authorization/roleDefinitions/b279062a-9be3-42a0-92ae-8b3cf002ec4d'
+ 'Workbook Contributor': '/providers/Microsoft.Authorization/roleDefinitions/e8ddcd69-c73f-4f9f-9844-4100522f16ad'
+ 'SignalR AccessKey Reader': '/providers/Microsoft.Authorization/roleDefinitions/04165923-9d83-45d5-8227-78b77b0a687e'
+ 'SignalR/Web PubSub Contributor': '/providers/Microsoft.Authorization/roleDefinitions/8cf5e20a-e4b2-4e9d-b3a1-5ceb692c2761'
+ 'Azure Connected Machine Onboarding': '/providers/Microsoft.Authorization/roleDefinitions/b64e21ea-ac4e-4cdf-9dc9-5b892992bee7'
+ 'Azure Connected Machine Resource Administrator': '/providers/Microsoft.Authorization/roleDefinitions/cd570a14-e51a-42ad-bac8-bafd67325302'
+ 'Managed Services Registration assignment Delete Role': '/providers/Microsoft.Authorization/roleDefinitions/91c1777a-f3dc-4fae-b103-61d183457e46'
+ 'App Configuration Data Owner': '/providers/Microsoft.Authorization/roleDefinitions/5ae67dd6-50cb-40e7-96ff-dc2bfa4b606b'
+ 'App Configuration Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/516239f1-63e1-4d78-a4de-a74fb236a071'
+ 'Kubernetes Cluster - Azure Arc Onboarding': '/providers/Microsoft.Authorization/roleDefinitions/34e09817-6cbe-4d01-b1a2-e0eac5743d41'
+ 'Experimentation Contributor': '/providers/Microsoft.Authorization/roleDefinitions/7f646f1b-fa08-80eb-a22b-edd6ce5c915c'
+ 'Cognitive Services QnA Maker Reader': '/providers/Microsoft.Authorization/roleDefinitions/466ccd10-b268-4a11-b098-b4849f024126'
+ 'Cognitive Services QnA Maker Editor': '/providers/Microsoft.Authorization/roleDefinitions/f4cc2bf9-21be-47a1-bdf1-5c5804381025'
+ 'Experimentation Administrator': '/providers/Microsoft.Authorization/roleDefinitions/7f646f1b-fa08-80eb-a33b-edd6ce5c915c'
+ 'Remote Rendering Administrator': '/providers/Microsoft.Authorization/roleDefinitions/3df8b902-2a6f-47c7-8cc5-360e9b272a7e'
+ 'Remote Rendering Client': '/providers/Microsoft.Authorization/roleDefinitions/d39065c4-c120-43c9-ab0a-63eed9795f0a'
+ 'Managed Application Contributor Role': '/providers/Microsoft.Authorization/roleDefinitions/641177b8-a67a-45b9-a033-47bc880bb21e'
+ 'Security Assessment Contributor': '/providers/Microsoft.Authorization/roleDefinitions/612c2aa1-cb24-443b-ac28-3ab7272de6f5'
+ 'Tag Contributor': '/providers/Microsoft.Authorization/roleDefinitions/4a9ae827-6dc8-4573-8ac7-8239d42aa03f'
+ 'Integration Service Environment Developer': '/providers/Microsoft.Authorization/roleDefinitions/c7aa55d3-1abb-444a-a5ca-5e51e485d6ec'
+ 'Integration Service Environment Contributor': '/providers/Microsoft.Authorization/roleDefinitions/a41e2c5b-bd99-4a07-88f4-9bf657a760b8'
+ 'Azure Kubernetes Service Contributor Role': '/providers/Microsoft.Authorization/roleDefinitions/ed7f3fbd-7b88-4dd4-9017-9adb7ce333f8'
+ 'Azure Digital Twins Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/d57506d4-4c8d-48b1-8587-93c323f6a5a3'
+ 'Azure Digital Twins Data Owner': '/providers/Microsoft.Authorization/roleDefinitions/bcd981a7-7f74-457b-83e1-cceb9e632ffe'
+ 'Hierarchy Settings Administrator': '/providers/Microsoft.Authorization/roleDefinitions/350f8d15-c687-4448-8ae1-157740a3936d'
+ 'FHIR Data Contributor': '/providers/Microsoft.Authorization/roleDefinitions/5a1fc7df-4bf1-4951-a576-89034ee01acd'
+ 'FHIR Data Exporter': '/providers/Microsoft.Authorization/roleDefinitions/3db33094-8700-4567-8da5-1501d4e7e843'
+ 'FHIR Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/4c8d0bbc-75d3-4935-991f-5f3c56d81508'
+ 'FHIR Data Writer': '/providers/Microsoft.Authorization/roleDefinitions/3f88fce4-5892-4214-ae73-ba5294559913'
+ 'Experimentation Reader': '/providers/Microsoft.Authorization/roleDefinitions/49632ef5-d9ac-41f4-b8e7-bbe587fa74a1'
+ 'Object Understanding Account Owner': '/providers/Microsoft.Authorization/roleDefinitions/4dd61c23-6743-42fe-a388-d8bdd41cb745'
+ 'Azure Maps Data Contributor': '/providers/Microsoft.Authorization/roleDefinitions/8f5e0ce6-4f7b-4dcf-bddf-e6f48634a204'
+ 'Cognitive Services Custom Vision Contributor': '/providers/Microsoft.Authorization/roleDefinitions/c1ff6cc2-c111-46fe-8896-e0ef812ad9f3'
+ 'Cognitive Services Custom Vision Deployment': '/providers/Microsoft.Authorization/roleDefinitions/5c4089e1-6d96-4d2f-b296-c1bc7137275f'
+ 'Cognitive Services Custom Vision Labeler': '/providers/Microsoft.Authorization/roleDefinitions/88424f51-ebe7-446f-bc41-7fa16989e96c'
+ 'Cognitive Services Custom Vision Reader': '/providers/Microsoft.Authorization/roleDefinitions/93586559-c37d-4a6b-ba08-b9f0940c2d73'
+ 'Cognitive Services Custom Vision Trainer': '/providers/Microsoft.Authorization/roleDefinitions/0a5ae4ab-0d65-4eeb-be61-29fc9b54394b'
+ 'Key Vault Administrator': '/providers/Microsoft.Authorization/roleDefinitions/00482a5a-887f-4fb3-b363-3b7fe8e74483'
+ 'Key Vault Crypto Officer': '/providers/Microsoft.Authorization/roleDefinitions/14b46e9e-c2b7-41b4-b07b-48a6ebf60603'
+ 'Key Vault Crypto User': '/providers/Microsoft.Authorization/roleDefinitions/12338af0-0e69-4776-bea7-57ae8d297424'
+ 'Key Vault Secrets Officer': '/providers/Microsoft.Authorization/roleDefinitions/b86a8fe4-44ce-4948-aee5-eccb2c155cd7'
+ 'Key Vault Secrets User': '/providers/Microsoft.Authorization/roleDefinitions/4633458b-17de-408a-b874-0445c86b69e6'
+ 'Key Vault Certificates Officer': '/providers/Microsoft.Authorization/roleDefinitions/a4417e6f-fecd-4de8-b567-7b0420556985'
+ 'Key Vault Reader': '/providers/Microsoft.Authorization/roleDefinitions/21090545-7ca7-4776-b22c-e363652d74d2'
+ 'Key Vault Crypto Service Encryption User': '/providers/Microsoft.Authorization/roleDefinitions/e147488a-f6f5-4113-8e2d-b22465e65bf6'
+ 'Azure Arc Kubernetes Viewer': '/providers/Microsoft.Authorization/roleDefinitions/63f0a09d-1495-4db4-a681-037d84835eb4'
+ 'Azure Arc Kubernetes Writer': '/providers/Microsoft.Authorization/roleDefinitions/5b999177-9696-4545-85c7-50de3797e5a1'
+ 'Azure Arc Kubernetes Cluster Admin': '/providers/Microsoft.Authorization/roleDefinitions/8393591c-06b9-48a2-a542-1bd6b377f6a2'
+ 'Azure Arc Kubernetes Admin': '/providers/Microsoft.Authorization/roleDefinitions/dffb1e0c-446f-4dde-a09f-99eb5cc68b96'
+ 'Azure Kubernetes Service RBAC Cluster Admin': '/providers/Microsoft.Authorization/roleDefinitions/b1ff04bb-8a4e-4dc4-8eb5-8693973ce19b'
+ 'Azure Kubernetes Service RBAC Admin': '/providers/Microsoft.Authorization/roleDefinitions/3498e952-d568-435e-9b2c-8d77e338d7f7'
+ 'Azure Kubernetes Service RBAC Reader': '/providers/Microsoft.Authorization/roleDefinitions/7f6c6a51-bcf8-42ba-9220-52d62157d7db'
+ 'Azure Kubernetes Service RBAC Writer': '/providers/Microsoft.Authorization/roleDefinitions/a7ffa36f-339b-4b5c-8bdf-e2c188b2c0eb'
+ 'Services Hub Operator': '/providers/Microsoft.Authorization/roleDefinitions/82200a5b-e217-47a5-b665-6d8765ee745b'
+ 'Object Understanding Account Reader': '/providers/Microsoft.Authorization/roleDefinitions/d18777c0-1514-4662-8490-608db7d334b6'
+ 'Azure Arc Enabled Kubernetes Cluster User Role': '/providers/Microsoft.Authorization/roleDefinitions/00493d72-78f6-4148-b6c5-d3ce8e4799dd'
+ 'SignalR REST API Owner': '/providers/Microsoft.Authorization/roleDefinitions/fd53cd77-2268-407a-8f46-7e7863d0f521'
+ 'Collaborative Data Contributor': '/providers/Microsoft.Authorization/roleDefinitions/daa9e50b-21df-454c-94a6-a8050adab352'
+ 'Device Update Reader': '/providers/Microsoft.Authorization/roleDefinitions/e9dba6fb-3d52-4cf0-bce3-f06ce71b9e0f'
+ 'Device Update Administrator': '/providers/Microsoft.Authorization/roleDefinitions/02ca0879-e8e4-47a5-a61e-5c618b76e64a'
+ 'Device Update Content Administrator': '/providers/Microsoft.Authorization/roleDefinitions/0378884a-3af5-44ab-8323-f5b22f9f3c98'
+ 'Device Update Deployments Administrator': '/providers/Microsoft.Authorization/roleDefinitions/e4237640-0e3d-4a46-8fda-70bc94856432'
+ 'Device Update Deployments Reader': '/providers/Microsoft.Authorization/roleDefinitions/49e2f5d2-7741-4835-8efa-19e1fe35e47f'
+ 'Device Update Content Reader': '/providers/Microsoft.Authorization/roleDefinitions/d1ee9a80-8b14-47f0-bdc2-f4a351625a7b'
+ 'Cognitive Services Metrics Advisor Administrator': '/providers/Microsoft.Authorization/roleDefinitions/cb43c632-a144-4ec5-977c-e80c4affc34a'
+ 'Cognitive Services Metrics Advisor User': '/providers/Microsoft.Authorization/roleDefinitions/3b20f47b-3825-43cb-8114-4bd2201156a8'
+ 'AgFood Platform Service Reader': '/providers/Microsoft.Authorization/roleDefinitions/7ec7ccdc-f61e-41fe-9aaf-980df0a44eba'
+ 'AgFood Platform Service Contributor': '/providers/Microsoft.Authorization/roleDefinitions/8508508a-4469-4e45-963b-2518ee0bb728'
+ 'AgFood Platform Service Admin': '/providers/Microsoft.Authorization/roleDefinitions/f8da80de-1ff9-4747-ad80-a19b7f6079e3'
+ 'Managed HSM contributor': '/providers/Microsoft.Authorization/roleDefinitions/18500a29-7fe2-46b2-a342-b16a415e101d'
+ 'Security Detonation Chamber Submitter': '/providers/Microsoft.Authorization/roleDefinitions/0b555d9b-b4a7-4f43-b330-627f0e5be8f0'
+ 'SignalR REST API Reader': '/providers/Microsoft.Authorization/roleDefinitions/ddde6b66-c0df-4114-a159-3618637b3035'
+ 'SignalR Service Owner': '/providers/Microsoft.Authorization/roleDefinitions/7e4f1700-ea5a-4f59-8f37-079cfe29dce3'
+ 'Reservation Purchaser': '/providers/Microsoft.Authorization/roleDefinitions/f7b75c60-3036-4b75-91c3-6b41c27c1689'
+ 'Storage Account Backup Contributor Role': '/providers/Microsoft.Authorization/roleDefinitions/e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1'
+ 'Experimentation Metric Contributor': '/providers/Microsoft.Authorization/roleDefinitions/6188b7c9-7d01-4f99-a59f-c88b630326c0'
+ 'Project Babylon Data Curator': '/providers/Microsoft.Authorization/roleDefinitions/9ef4ef9c-a049-46b0-82ab-dd8ac094c889'
+ 'Project Babylon Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/c8d896ba-346d-4f50-bc1d-7d1c84130446'
+ 'Project Babylon Data Source Administrator': '/providers/Microsoft.Authorization/roleDefinitions/05b7651b-dc44-475e-b74d-df3db49fae0f'
+ 'Application Group Contributor': '/providers/Microsoft.Authorization/roleDefinitions/ca6382a4-1721-4bcf-a114-ff0c70227b6b'
+ 'Desktop Virtualization Reader': '/providers/Microsoft.Authorization/roleDefinitions/49a72310-ab8d-41df-bbb0-79b649203868'
+ 'Desktop Virtualization Contributor': '/providers/Microsoft.Authorization/roleDefinitions/082f0a83-3be5-4ba1-904c-961cca79b387'
+ 'Desktop Virtualization Workspace Contributor': '/providers/Microsoft.Authorization/roleDefinitions/21efdde3-836f-432b-bf3d-3e8e734d4b2b'
+ 'Desktop Virtualization User Session Operator': '/providers/Microsoft.Authorization/roleDefinitions/ea4bfff8-7fb4-485a-aadd-d4129a0ffaa6'
+ 'Desktop Virtualization Session Host Operator': '/providers/Microsoft.Authorization/roleDefinitions/2ad6aaab-ead9-4eaa-8ac5-da422f562408'
+ 'Desktop Virtualization Host Pool Reader': '/providers/Microsoft.Authorization/roleDefinitions/ceadfde2-b300-400a-ab7b-6143895aa822'
+ 'Desktop Virtualization Host Pool Contributor': '/providers/Microsoft.Authorization/roleDefinitions/e307426c-f9b6-4e81-87de-d99efb3c32bc'
+ 'Desktop Virtualization Application Group Reader': '/providers/Microsoft.Authorization/roleDefinitions/aebf23d0-b568-4e86-b8f9-fe83a2c6ab55'
+ 'Desktop Virtualization Application Group Contributor': '/providers/Microsoft.Authorization/roleDefinitions/86240b0e-9422-4c43-887b-b61143f32ba8'
+ 'Desktop Virtualization Workspace Reader': '/providers/Microsoft.Authorization/roleDefinitions/0fa44ee9-7a7d-466b-9bb2-2bf446b1204d'
+ 'Disk Backup Reader': '/providers/Microsoft.Authorization/roleDefinitions/3e5e47e6-65f7-47ef-90b5-e5dd4d455f24'
+ 'Disk Restore Operator': '/providers/Microsoft.Authorization/roleDefinitions/b50d9833-a0cb-478e-945f-707fcc997c13'
+ 'Disk Snapshot Contributor': '/providers/Microsoft.Authorization/roleDefinitions/7efff54f-a5b4-42b5-a1c5-5411624893ce'
+ 'Microsoft.Kubernetes connected cluster role': '/providers/Microsoft.Authorization/roleDefinitions/5548b2cf-c94c-4228-90ba-30851930a12f'
+ 'Security Detonation Chamber Submission Manager': '/providers/Microsoft.Authorization/roleDefinitions/a37b566d-3efa-4beb-a2f2-698963fa42ce'
+ 'Security Detonation Chamber Publisher': '/providers/Microsoft.Authorization/roleDefinitions/352470b3-6a9c-4686-b503-35deb827e500'
+ 'Collaborative Runtime Operator': '/providers/Microsoft.Authorization/roleDefinitions/7a6f0e70-c033-4fb1-828c-08514e5f4102'
+ 'CosmosRestoreOperator': '/providers/Microsoft.Authorization/roleDefinitions/5432c526-bc82-444a-b7ba-57c5b0b5b34f'
+ 'FHIR Data Converter': '/providers/Microsoft.Authorization/roleDefinitions/a1705bd2-3a8f-45a5-8683-466fcfd5cc24'
+ 'Azure Sentinel Automation Contributor': '/providers/Microsoft.Authorization/roleDefinitions/f4c81013-99ee-4d62-a7ee-b3f1f648599a'
+ 'Quota Request Operator': '/providers/Microsoft.Authorization/roleDefinitions/0e5f05e5-9ab9-446b-b98d-1e2157c94125'
+ 'EventGrid Contributor': '/providers/Microsoft.Authorization/roleDefinitions/1e241071-0855-49ea-94dc-649edcd759de'
+ 'Security Detonation Chamber Reader': '/providers/Microsoft.Authorization/roleDefinitions/28241645-39f8-410b-ad48-87863e2951d5'
+ 'Object Anchors Account Reader': '/providers/Microsoft.Authorization/roleDefinitions/4a167cdf-cb95-4554-9203-2347fe489bd9'
+ 'Object Anchors Account Owner': '/providers/Microsoft.Authorization/roleDefinitions/ca0835dd-bacc-42dd-8ed2-ed5e7230d15b'
+ 'WorkloadBuilder Migration Agent Role': '/providers/Microsoft.Authorization/roleDefinitions/d17ce0a2-0697-43bc-aac5-9113337ab61c'
+ 'Azure Spring Cloud Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/b5537268-8956-4941-a8f0-646150406f0c'
+ 'Cognitive Services Speech User': '/providers/Microsoft.Authorization/roleDefinitions/f2dc8367-1007-4938-bd23-fe263f013447'
+ 'Cognitive Services Speech Contributor': '/providers/Microsoft.Authorization/roleDefinitions/0e75ca1e-0464-4b4d-8b93-68208a576181'
+ 'Cognitive Services Face Recognizer': '/providers/Microsoft.Authorization/roleDefinitions/9894cab4-e18a-44aa-828b-cb588cd6f2d7'
+ 'Media Services Account Administrator': '/providers/Microsoft.Authorization/roleDefinitions/054126f8-9a2b-4f1c-a9ad-eca461f08466'
+ 'Media Services Live Events Administrator': '/providers/Microsoft.Authorization/roleDefinitions/532bc159-b25e-42c0-969e-a1d439f60d77'
+ 'Media Services Media Operator': '/providers/Microsoft.Authorization/roleDefinitions/e4395492-1534-4db2-bedf-88c14621589c'
+ 'Media Services Policy Administrator': '/providers/Microsoft.Authorization/roleDefinitions/c4bba371-dacd-4a26-b320-7250bca963ae'
+ 'Media Services Streaming Endpoints Administrator': '/providers/Microsoft.Authorization/roleDefinitions/99dba123-b5fe-44d5-874c-ced7199a5804'
+ 'Stream Analytics Query Tester': '/providers/Microsoft.Authorization/roleDefinitions/1ec5b3c1-b17e-4e25-8312-2acb3c3c5abf'
+ 'AnyBuild Builder': '/providers/Microsoft.Authorization/roleDefinitions/a2138dac-4907-4679-a376-736901ed8ad8'
+ 'IoT Hub Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/b447c946-2db7-41ec-983d-d8bf3b1c77e3'
+ 'IoT Hub Twin Contributor': '/providers/Microsoft.Authorization/roleDefinitions/494bdba2-168f-4f31-a0a1-191d2f7c028c'
+ 'IoT Hub Registry Contributor': '/providers/Microsoft.Authorization/roleDefinitions/4ea46cd5-c1b2-4a8e-910b-273211f9ce47'
+ 'IoT Hub Data Contributor': '/providers/Microsoft.Authorization/roleDefinitions/4fc6c259-987e-4a07-842e-c321cc9d413f'
+ 'Test Base Reader': '/providers/Microsoft.Authorization/roleDefinitions/15e0f5a1-3450-4248-8e25-e2afe88a9e85'
+ 'Search Index Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/1407120a-92aa-4202-b7e9-c0e197c71c8f'
+ 'Search Index Data Contributor': '/providers/Microsoft.Authorization/roleDefinitions/8ebe5a00-799e-43f5-93ac-243d3dce84a7'
+ 'Storage Table Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/76199698-9eea-4c19-bc75-cec21354c6b6'
+ 'Storage Table Data Contributor': '/providers/Microsoft.Authorization/roleDefinitions/0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3'
+ 'DICOM Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/e89c7a3c-2f64-4fa1-a847-3e4c9ba4283a'
+ 'DICOM Data Owner': '/providers/Microsoft.Authorization/roleDefinitions/58a3b984-7adf-4c20-983a-32417c86fbc8'
+ 'EventGrid Data Sender': '/providers/Microsoft.Authorization/roleDefinitions/d5a91429-5739-47e2-a06b-3470a27159e7'
+ 'Disk Pool Operator': '/providers/Microsoft.Authorization/roleDefinitions/60fc6e62-5479-42d4-8bf4-67625fcc2840'
+ 'AzureML Data Scientist': '/providers/Microsoft.Authorization/roleDefinitions/f6c7c914-8db3-469d-8ca1-694a8f32e121'
+ 'Grafana Admin': '/providers/Microsoft.Authorization/roleDefinitions/22926164-76b3-42b3-bc55-97df8dab3e41'
+ 'Azure Connected SQL Server Onboarding': '/providers/Microsoft.Authorization/roleDefinitions/e8113dce-c529-4d33-91fa-e9b972617508'
+ 'Azure Relay Sender': '/providers/Microsoft.Authorization/roleDefinitions/26baccc8-eea7-41f1-98f4-1762cc7f685d'
+ 'Azure Relay Owner': '/providers/Microsoft.Authorization/roleDefinitions/2787bf04-f1f5-4bfe-8383-c8a24483ee38'
+ 'Azure Relay Listener': '/providers/Microsoft.Authorization/roleDefinitions/26e0b698-aa6d-4085-9386-aadae190014d'
+ 'Grafana Viewer': '/providers/Microsoft.Authorization/roleDefinitions/60921a7e-fef1-4a43-9b16-a26c52ad4769'
+ 'Grafana Editor': '/providers/Microsoft.Authorization/roleDefinitions/a79a5197-3a5c-4973-a920-486035ffd60f'
+ 'Automation Contributor': '/providers/Microsoft.Authorization/roleDefinitions/f353d9bd-d4a6-484e-a77a-8050b599b867'
+ 'Kubernetes Extension Contributor': '/providers/Microsoft.Authorization/roleDefinitions/85cb6faf-e071-4c9b-8136-154b5a04f717'
+ 'Device Provisioning Service Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/10745317-c249-44a1-a5ce-3a4353c0bbd8'
+ 'Device Provisioning Service Data Contributor': '/providers/Microsoft.Authorization/roleDefinitions/dfce44e4-17b7-4bd1-a6d1-04996ec95633'
+ 'CodeSigning Certificate Profile Signer': '/providers/Microsoft.Authorization/roleDefinitions/2837e146-70d7-4cfd-ad55-7efa6464f958'
+ 'Azure Spring Cloud Service Registry Reader': '/providers/Microsoft.Authorization/roleDefinitions/cff1b556-2399-4e7e-856d-a8f754be7b65'
+ 'Azure Spring Cloud Service Registry Contributor': '/providers/Microsoft.Authorization/roleDefinitions/f5880b48-c26d-48be-b172-7927bfa1c8f1'
+ 'Azure Spring Cloud Config Server Reader': '/providers/Microsoft.Authorization/roleDefinitions/d04c6db6-4947-4782-9e91-30a88feb7be7'
+ 'Azure Spring Cloud Config Server Contributor': '/providers/Microsoft.Authorization/roleDefinitions/a06f5c24-21a7-4e1a-aa2b-f19eb6684f5b'
+ 'Azure VM Managed identities restore Contributor': '/providers/Microsoft.Authorization/roleDefinitions/6ae96244-5829-4925-a7d3-5975537d91dd'
+ 'Azure Maps Search and Render Data Reader': '/providers/Microsoft.Authorization/roleDefinitions/6be48352-4f82-47c9-ad5e-0acacefdb005'
+ 'Azure Maps Contributor': '/providers/Microsoft.Authorization/roleDefinitions/dba33070-676a-4fb0-87fa-064dc56ff7fb'
+}
+
+var roleDefinitionId_var = (contains(builtInRoleNames_var, roleDefinitionIdOrName) ? builtInRoleNames_var[roleDefinitionIdOrName] : roleDefinitionIdOrName)
+
+resource roleAssignment 'Microsoft.Authorization/roleAssignments@2021-04-01-preview' = {
+ name: guid(subscriptionId, roleDefinitionId_var, principalId)
+ properties: {
+ roleDefinitionId: roleDefinitionId_var
+ principalId: principalId
+ description: !empty(description) ? description : null
+ principalType: !empty(principalType) ? any(principalType) : null
+ delegatedManagedIdentityResourceId: !empty(delegatedManagedIdentityResourceId) ? delegatedManagedIdentityResourceId : null
+ conditionVersion: !empty(conditionVersion) && !empty(condition) ? conditionVersion : null
+ condition: !empty(condition) ? condition : null
+ }
+}
+
+@sys.description('The GUID of the Role Assignment')
+output name string = roleAssignment.name
+
+@sys.description('The resource ID of the Role Assignment')
+output scope string = subscription().id
+
+@sys.description('The scope this Role Assignment applies to')
+output resourceId string = subscriptionResourceId(subscriptionId, 'Microsoft.Authorization/roleAssignments', roleAssignment.name)
diff --git a/carml/1.0.0/Microsoft.Authorization/roleAssignments/subscription/readme.md b/carml/1.0.0/Microsoft.Authorization/roleAssignments/subscription/readme.md
new file mode 100644
index 000000000..54917e335
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleAssignments/subscription/readme.md
@@ -0,0 +1,34 @@
+# Role Assignment on Subscription level `[Microsoft.Authorization/roleAssignments/subscription]`
+
+With this module you can perform role assignments on a subscription level
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/roleAssignments` | 2021-04-01-preview |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `condition` | string | | | Optional. The conditions on the role assignment. This limits the resources it can be assigned to |
+| `conditionVersion` | string | `2.0` | `[2.0]` | Optional. Version of the condition. Currently accepted value is "2.0" |
+| `delegatedManagedIdentityResourceId` | string | | | Optional. ID of the delegated managed identity resource |
+| `description` | string | | | Optional. Description of role assignment |
+| `principalId` | string | | | Required. The Principal or Object ID of the Security Principal (User, Group, Service Principal, Managed Identity) |
+| `principalType` | string | | `[ServicePrincipal, Group, User, ForeignGroup, Device, ]` | Optional. The principal type of the assigned principal ID. |
+| `roleDefinitionIdOrName` | string | | | Required. 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' |
+| `subscriptionId` | string | `[subscription().subscriptionId]` | | Optional. Subscription ID of the subscription to assign the RBAC role to. If not provided, will use the current scope for deployment. |
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The GUID of the Role Assignment |
+| `resourceId` | string | The scope this Role Assignment applies to |
+| `scope` | string | The resource ID of the Role Assignment |
+
+## Template references
+
+- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/roleAssignments)
diff --git a/carml/1.0.0/Microsoft.Authorization/roleAssignments/subscription/version.json b/carml/1.0.0/Microsoft.Authorization/roleAssignments/subscription/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleAssignments/subscription/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/roleAssignments/version.json b/carml/1.0.0/Microsoft.Authorization/roleAssignments/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleAssignments/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/roleDefinitions/.parameters/mg.min.parameters.json b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/.parameters/mg.min.parameters.json
new file mode 100644
index 000000000..c4a88ba9e
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/.parameters/mg.min.parameters.json
@@ -0,0 +1,15 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "roleName": {
+ "value": "<>-az-testRole-mg-min"
+ },
+ "actions": {
+ "value": [
+ "Microsoft.Compute/galleries/read",
+ "Microsoft.Compute/galleries/images/read"
+ ]
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/roleDefinitions/.parameters/mg.parameters.json b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/.parameters/mg.parameters.json
new file mode 100644
index 000000000..d49ce1cae
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/.parameters/mg.parameters.json
@@ -0,0 +1,43 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "roleName": {
+ "value": "<>-az-testRole-mg"
+ },
+ "description": {
+ "value": "Test Custom Role Definition Standard (management group scope)"
+ },
+ "actions": {
+ "value": [
+ "Microsoft.Compute/galleries/*",
+ "Microsoft.Network/virtualNetworks/read"
+ ]
+ },
+ "notActions": {
+ "value": [
+ "Microsoft.Compute/images/write",
+ "Microsoft.Compute/images/delete",
+ "Microsoft.Network/virtualNetworks/subnets/join/action"
+ ]
+ },
+ "dataActions": {
+ "value": [
+ "Microsoft.Storage/storageAccounts/blobServices/*/read"
+ ]
+ },
+ "notDataActions": {
+ "value": [
+ "Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read"
+ ]
+ },
+ "assignableScopes": {
+ "value": [
+ "/providers/Microsoft.Management/managementGroups/<>"
+ ]
+ },
+ "managementGroupId": {
+ "value": "<>"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/roleDefinitions/.parameters/rg.min.parameters.json b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/.parameters/rg.min.parameters.json
new file mode 100644
index 000000000..cf6825cc0
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/.parameters/rg.min.parameters.json
@@ -0,0 +1,21 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "roleName": {
+ "value": "<>-az-testRole-rg-min"
+ },
+ "actions": {
+ "value": [
+ "Microsoft.Compute/galleries/read",
+ "Microsoft.Compute/galleries/images/read"
+ ]
+ },
+ "subscriptionId": {
+ "value": "<>"
+ },
+ "resourceGroupName": {
+ "value": "<>"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/roleDefinitions/.parameters/rg.parameters.json b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/.parameters/rg.parameters.json
new file mode 100644
index 000000000..c27ff2f86
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/.parameters/rg.parameters.json
@@ -0,0 +1,46 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "roleName": {
+ "value": "<>-az-testRole-rg"
+ },
+ "description": {
+ "value": "Test Custom Role Definition Standard (resource group scope)"
+ },
+ "actions": {
+ "value": [
+ "Microsoft.Compute/galleries/*",
+ "Microsoft.Network/virtualNetworks/read"
+ ]
+ },
+ "notActions": {
+ "value": [
+ "Microsoft.Compute/images/write",
+ "Microsoft.Compute/images/delete",
+ "Microsoft.Network/virtualNetworks/subnets/join/action"
+ ]
+ },
+ "dataActions": {
+ "value": [
+ "Microsoft.Storage/storageAccounts/blobServices/*/read"
+ ]
+ },
+ "notDataActions": {
+ "value": [
+ "Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read"
+ ]
+ },
+ "assignableScopes": {
+ "value": [
+ "/subscriptions/<>/resourceGroups/<>"
+ ]
+ },
+ "subscriptionId": {
+ "value": "<>"
+ },
+ "resourceGroupName": {
+ "value": "<>"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/roleDefinitions/.parameters/sub.min.parameters.json b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/.parameters/sub.min.parameters.json
new file mode 100644
index 000000000..87bbbc20b
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/.parameters/sub.min.parameters.json
@@ -0,0 +1,18 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "roleName": {
+ "value": "<>-az-testRole-sub-min"
+ },
+ "actions": {
+ "value": [
+ "Microsoft.Compute/galleries/read",
+ "Microsoft.Compute/galleries/images/read"
+ ]
+ },
+ "subscriptionId": {
+ "value": "<>"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/roleDefinitions/.parameters/sub.parameters.json b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/.parameters/sub.parameters.json
new file mode 100644
index 000000000..62e03ca98
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/.parameters/sub.parameters.json
@@ -0,0 +1,43 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "roleName": {
+ "value": "<>-az-testRole-sub"
+ },
+ "description": {
+ "value": "Test Custom Role Definition Standard (subscription scope)"
+ },
+ "actions": {
+ "value": [
+ "Microsoft.Compute/galleries/*",
+ "Microsoft.Network/virtualNetworks/read"
+ ]
+ },
+ "notActions": {
+ "value": [
+ "Microsoft.Compute/images/write",
+ "Microsoft.Compute/images/delete",
+ "Microsoft.Network/virtualNetworks/subnets/join/action"
+ ]
+ },
+ "dataActions": {
+ "value": [
+ "Microsoft.Storage/storageAccounts/blobServices/*/read"
+ ]
+ },
+ "notDataActions": {
+ "value": [
+ "Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read"
+ ]
+ },
+ "assignableScopes": {
+ "value": [
+ "/subscriptions/<>"
+ ]
+ },
+ "subscriptionId": {
+ "value": "<>"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/roleDefinitions/deploy.bicep b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/deploy.bicep
new file mode 100644
index 000000000..2fed913ce
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/deploy.bicep
@@ -0,0 +1,87 @@
+targetScope = 'managementGroup'
+
+@sys.description('Required. Name of the custom RBAC role to be created.')
+param roleName string
+
+@sys.description('Optional. Description of the custom RBAC role to be created.')
+param description string = ''
+
+@sys.description('Optional. List of allowed actions.')
+param actions array = []
+
+@sys.description('Optional. List of denied actions.')
+param notActions array = []
+
+@sys.description('Optional. List of allowed data actions. This is not supported if the assignableScopes contains Management Group Scopes')
+param dataActions array = []
+
+@sys.description('Optional. List of denied data actions. This is not supported if the assignableScopes contains Management Group Scopes')
+param notDataActions array = []
+
+@sys.description('Optional. The group ID of the Management Group where the Role Definition and Target Scope will be applied to. If not provided, will use the current scope for deployment.')
+param managementGroupId string = managementGroup().name
+
+@sys.description('Optional. The subscription ID where the Role Definition and Target Scope will be applied to. Use for both Subscription level and Resource Group Level.')
+param subscriptionId string = ''
+
+@sys.description('Optional. The name of the Resource Group where the Role Definition and Target Scope will be applied to.')
+param resourceGroupName string = ''
+
+@sys.description('Optional. Location for all resources.')
+param location string = deployment().location
+
+@sys.description('Optional. Role definition assignable scopes. If not provided, will use the current scope provided.')
+param assignableScopes array = []
+
+module roleDefinition_mg 'managementGroup/deploy.bicep' = if (empty(subscriptionId) && empty(resourceGroupName)) {
+ name: '${uniqueString(deployment().name, location)}-RoleDefinition-MG-Module'
+ scope: managementGroup(managementGroupId)
+ params: {
+ roleName: roleName
+ description: !empty(description) ? description : ''
+ actions: !empty(actions) ? actions : []
+ notActions: !empty(notActions) ? notActions : []
+ assignableScopes: !empty(assignableScopes) ? assignableScopes : []
+ managementGroupId: managementGroupId
+ }
+}
+
+module roleDefinition_sub 'subscription/deploy.bicep' = if (!empty(subscriptionId) && empty(resourceGroupName)) {
+ name: '${uniqueString(deployment().name, location)}-RoleDefinition-Sub-Module'
+ scope: subscription(subscriptionId)
+ params: {
+ roleName: roleName
+ description: !empty(description) ? description : ''
+ actions: !empty(actions) ? actions : []
+ notActions: !empty(notActions) ? notActions : []
+ dataActions: !empty(dataActions) ? dataActions : []
+ notDataActions: !empty(notDataActions) ? notDataActions : []
+ assignableScopes: !empty(assignableScopes) ? assignableScopes : []
+ subscriptionId: subscriptionId
+ }
+}
+
+module roleDefinition_rg 'resourceGroup/deploy.bicep' = if (!empty(resourceGroupName) && !empty(subscriptionId)) {
+ name: '${uniqueString(deployment().name, location)}-RoleDefinition-RG-Module'
+ scope: resourceGroup(subscriptionId, resourceGroupName)
+ params: {
+ roleName: roleName
+ description: !empty(description) ? description : ''
+ actions: !empty(actions) ? actions : []
+ notActions: !empty(notActions) ? notActions : []
+ dataActions: !empty(dataActions) ? dataActions : []
+ notDataActions: !empty(notDataActions) ? notDataActions : []
+ assignableScopes: !empty(assignableScopes) ? assignableScopes : []
+ subscriptionId: subscriptionId
+ resourceGroupName: resourceGroupName
+ }
+}
+
+@sys.description('The GUID of the Role Definition')
+output name string = empty(subscriptionId) && empty(resourceGroupName) ? roleDefinition_mg.outputs.name : (!empty(subscriptionId) && empty(resourceGroupName) ? roleDefinition_sub.outputs.name : roleDefinition_rg.outputs.name)
+
+@sys.description('The resource ID of the Role Definition')
+output resourceId string = empty(subscriptionId) && empty(resourceGroupName) ? roleDefinition_mg.outputs.resourceId : (!empty(subscriptionId) && empty(resourceGroupName) ? roleDefinition_sub.outputs.resourceId : roleDefinition_rg.outputs.resourceId)
+
+@sys.description('The scope this Role Definition applies to')
+output roleDefinitionScope string = empty(subscriptionId) && empty(resourceGroupName) ? roleDefinition_mg.outputs.scope : (!empty(subscriptionId) && empty(resourceGroupName) ? roleDefinition_sub.outputs.scope : roleDefinition_rg.outputs.scope)
diff --git a/carml/1.0.0/Microsoft.Authorization/roleDefinitions/managementGroup/deploy.bicep b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/managementGroup/deploy.bicep
new file mode 100644
index 000000000..b915817aa
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/managementGroup/deploy.bicep
@@ -0,0 +1,44 @@
+targetScope = 'managementGroup'
+
+@sys.description('Required. Name of the custom RBAC role to be created.')
+param roleName string
+
+@sys.description('Optional. Description of the custom RBAC role to be created.')
+param description string = ''
+
+@sys.description('Optional. List of allowed actions.')
+param actions array = []
+
+@sys.description('Optional. List of denied actions.')
+param notActions array = []
+
+@sys.description('Optional. The group ID of the Management Group where the Role Definition and Target Scope will be applied to. If not provided, will use the current scope for deployment.')
+param managementGroupId string = managementGroup().name
+
+@sys.description('Optional. Role definition assignable scopes. If not provided, will use the current scope provided.')
+param assignableScopes array = []
+
+resource roleDefinition 'Microsoft.Authorization/roleDefinitions@2018-01-01-preview' = {
+ name: guid(roleName, managementGroupId)
+ properties: {
+ roleName: roleName
+ description: description
+ type: 'customRole'
+ permissions: [
+ {
+ actions: actions
+ notActions: notActions
+ }
+ ]
+ assignableScopes: assignableScopes == [] ? array(tenantResourceId('Microsoft.Management/managementGroups', managementGroupId)) : assignableScopes
+ }
+}
+
+@sys.description('The GUID of the Role Definition')
+output name string = roleDefinition.name
+
+@sys.description('The scope this Role Definition applies to')
+output scope string = tenantResourceId('Microsoft.Management/managementGroups', managementGroupId)
+
+@sys.description('The resource ID of the Role Definition')
+output resourceId string = extensionResourceId(tenantResourceId('Microsoft.Management/managementGroups', managementGroupId), 'Microsoft.Authorization/roleDefinitions', roleDefinition.name)
diff --git a/carml/1.0.0/Microsoft.Authorization/roleDefinitions/managementGroup/readme.md b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/managementGroup/readme.md
new file mode 100644
index 000000000..50dc65f01
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/managementGroup/readme.md
@@ -0,0 +1,32 @@
+# Role Definitions on Management Group level `[Microsoft.Authorization/roleDefinitions/managementGroup]`
+
+With this module you can create role definitions on a management group level
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/roleDefinitions` | 2018-01-01-preview |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `actions` | array | `[]` | | Optional. List of allowed actions. |
+| `assignableScopes` | array | `[]` | | Optional. Role definition assignable scopes. If not provided, will use the current scope provided. |
+| `description` | string | | | Optional. Description of the custom RBAC role to be created. |
+| `managementGroupId` | string | `[managementGroup().name]` | | Optional. The group ID of the Management Group where the Role Definition and Target Scope will be applied to. If not provided, will use the current scope for deployment. |
+| `notActions` | array | `[]` | | Optional. List of denied actions. |
+| `roleName` | string | | | Required. Name of the custom RBAC role to be created. |
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The GUID of the Role Definition |
+| `resourceId` | string | The resource ID of the Role Definition |
+| `scope` | string | The scope this Role Definition applies to |
+
+## Template references
+
+- [Roledefinitions](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2018-01-01-preview/roleDefinitions)
diff --git a/carml/1.0.0/Microsoft.Authorization/roleDefinitions/managementGroup/version.json b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/managementGroup/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/managementGroup/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/roleDefinitions/readme.md b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/readme.md
new file mode 100644
index 000000000..5df05a832
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/readme.md
@@ -0,0 +1,103 @@
+# Role Definitions `[Microsoft.Authorization/roleDefinitions]`
+
+This module deploys custom RBAC Role Definitions across the management group, subscription or resource group scope.
+
+## Resource types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/roleDefinitions` | 2018-01-01-preview |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `actions` | array | `[]` | | Optional. List of allowed actions. |
+| `assignableScopes` | array | `[]` | | Optional. Role definition assignable scopes. If not provided, will use the current scope provided. |
+| `dataActions` | array | `[]` | | Optional. List of allowed data actions. This is not supported if the assignableScopes contains Management Group Scopes |
+| `description` | string | | | Optional. Description of the custom RBAC role to be created. |
+| `location` | string | `[deployment().location]` | | Optional. Location for all resources. |
+| `managementGroupId` | string | `[managementGroup().name]` | | Optional. The group ID of the Management Group where the Role Definition and Target Scope will be applied to. If not provided, will use the current scope for deployment. |
+| `notActions` | array | `[]` | | Optional. List of denied actions. |
+| `notDataActions` | array | `[]` | | Optional. List of denied data actions. This is not supported if the assignableScopes contains Management Group Scopes |
+| `resourceGroupName` | string | | | Optional. The name of the Resource Group where the Role Definition and Target Scope will be applied to. |
+| `roleName` | string | | | Required. Name of the custom RBAC role to be created. |
+| `subscriptionId` | string | | | Optional. The subscription ID where the Role Definition and Target Scope will be applied to. Use for both Subscription level and Resource Group Level. |
+
+### Parameter Usage: `managementGroupId`
+
+To deploy resource to a Management Group, provide the `managementGroupId` as an input parameter to the module.
+
+```json
+"managementGroupId": {
+ "value": "contoso-group"
+}
+```
+
+> `managementGroupId` is an optional parameter. If not provided, the deployment will use the management group defined in the current deployment scope (i.e. `managementGroup().name`).
+
+### Parameter Usage: `subscriptionId`
+
+To deploy resource to an Azure Subscription, provide the `subscriptionId` as an input parameter to the module. **Example**:
+
+```json
+"subscriptionId": {
+ "value": "12345678-b049-471c-95af-123456789012"
+}
+```
+
+### Parameter Usage: `resourceGroupName`
+
+To deploy resource to a Resource Group, provide the `subscriptionId` and `resourceGroupName` as an input parameter to the module. **Example**:
+
+```json
+"subscriptionId": {
+ "value": "12345678-b049-471c-95af-123456789012"
+},
+"resourceGroupName": {
+ "value": "target-resourceGroup"
+}
+```
+
+> The `subscriptionId` is used to enable deployment to a Resource Group Scope, allowing the use of the `resourceGroup()` function from a Management Group Scope. [Additional Details](https://github.com/Azure/bicep/pull/1420).
+
+## Module Usage Guidance
+
+In general, most of the resources under the `Microsoft.Authorization` namespace allows deploying resources at multiple scopes (management groups, subscriptions, resource groups). The `deploy.bicep` root module is simply an orchestrator module that targets sub-modules for different scopes as seen in the parameter usage section. All sub-modules for this namespace have folders that represent the target scope. For example, if the orchestrator module in the [root](deploy.bicep) needs to target 'subscription' level scopes. It will look at the relative path ['/subscription/deploy.bicep'](./subscription/deploy.bicep) and use this sub-module for the actual deployment, while still passing the same parameters from the root module.
+
+The above method is useful when you want to use a single point to interact with the module but rely on parameter combinations to achieve the target scope. But what if you want to incorporate this module in other modules with lower scopes? This would force you to deploy the module in scope `managementGroup` regardless and further require you to provide its ID with it. If you do not set the scope to management group, this would be the error that you can expect to face:
+
+```bicep
+Error BCP134: Scope "subscription" is not valid for this module. Permitted scopes: "managementGroup"
+```
+
+The solution is to have the option of directly targeting the sub-module that achieves the required scope. For example, if you have your own Bicep file wanting to create resources at the subscription level, and also use some of the modules from the `Microsoft.Authorization` namespace, then you can directly use the sub-module ['/subscription/deploy.bicep'](./subscription/deploy.bicep) as a path within your repository, or reference that same published module from the bicep registry. CARML also published the sub-modules so you would be able to reference it like the following:
+
+**Bicep Registry Reference**
+```bicep
+module roledefinition 'br:bicepregistry.azurecr.io/bicep/modules/microsoft.authorization.roledefinitions.subscription:version' = {}
+```
+**Local Path Reference**
+```bicep
+module roledefinition 'yourpath/arm/Microsoft.Authorization.roleDefinitions/subscription/deploy.bicep' = {}
+```
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The GUID of the Role Definition |
+| `resourceId` | string | The resource ID of the Role Definition |
+| `roleDefinitionScope` | string | The scope this Role Definition applies to |
+
+## Considerations
+
+This module can be deployed both at subscription or resource group level:
+
+- To deploy the module at resource group level, provide a valid name of an existing Resource Group in the `resourceGroupName` parameter and an existing subscription ID in the `subscriptionId` parameter.
+- To deploy the module at the subscription level, provide an existing subscription ID in the `subscriptionId` parameter.
+- To deploy the module at the management group level, provide an existing management group ID in the `managementGroupId` parameter.
+
+## Template references
+
+- [Roledefinitions](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2018-01-01-preview/roleDefinitions)
diff --git a/carml/1.0.0/Microsoft.Authorization/roleDefinitions/resourceGroup/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/resourceGroup/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/resourceGroup/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.Authorization/roleDefinitions/resourceGroup/deploy.bicep b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/resourceGroup/deploy.bicep
new file mode 100644
index 000000000..d55962d78
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/resourceGroup/deploy.bicep
@@ -0,0 +1,66 @@
+targetScope = 'resourceGroup'
+
+@sys.description('Required. Name of the custom RBAC role to be created.')
+param roleName string
+
+@sys.description('Optional. Description of the custom RBAC role to be created.')
+param description string = ''
+
+@sys.description('Optional. List of allowed actions.')
+param actions array = []
+
+@sys.description('Optional. List of denied actions.')
+param notActions array = []
+
+@sys.description('Optional. List of allowed data actions. This is not supported if the assignableScopes contains Management Group Scopes')
+param dataActions array = []
+
+@sys.description('Optional. List of denied data actions. This is not supported if the assignableScopes contains Management Group Scopes')
+param notDataActions array = []
+
+@sys.description('Optional. The subscription ID where the Role Definition and Target Scope will be applied to. If not provided, will use the current scope for deployment.')
+param subscriptionId string = subscription().subscriptionId
+
+@sys.description('Optional. The name of the Resource Group where the Role Definition and Target Scope will be applied to. If not provided, will use the current scope for deployment.')
+param resourceGroupName string = resourceGroup().name
+
+@sys.description('Optional. Role definition assignable scopes. If not provided, will use the current scope provided.')
+param assignableScopes array = []
+
+@sys.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 roleDefinition 'Microsoft.Authorization/roleDefinitions@2018-01-01-preview' = {
+ name: guid(roleName, subscriptionId, resourceGroupName)
+ properties: {
+ roleName: roleName
+ description: description
+ type: 'customRole'
+ permissions: [
+ {
+ actions: actions
+ notActions: notActions
+ dataActions: dataActions
+ notDataActions: notDataActions
+ }
+ ]
+ assignableScopes: assignableScopes == [] ? array(resourceGroup().id) : assignableScopes
+ }
+}
+
+@sys.description('The GUID of the Role Definition')
+output name string = roleDefinition.name
+
+@sys.description('The scope this Role Definition applies to')
+output scope string = resourceGroup().id
+
+@sys.description('The resource ID of the Role Definition')
+output resourceId string = roleDefinition.id
+
+@sys.description('The name of the resource group the role definition was created at')
+output resourceGroupName string = resourceGroup().name
diff --git a/carml/1.0.0/Microsoft.Authorization/roleDefinitions/resourceGroup/readme.md b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/resourceGroup/readme.md
new file mode 100644
index 000000000..f42b3bab2
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/resourceGroup/readme.md
@@ -0,0 +1,37 @@
+# Role Definitions on Resource Group level `[Microsoft.Authorization/roleDefinitions/resourceGroup]`
+
+With this module you can create role definitions on a resource group level
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/roleDefinitions` | 2018-01-01-preview |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `actions` | array | `[]` | | Optional. List of allowed actions. |
+| `assignableScopes` | array | `[]` | | Optional. Role definition assignable scopes. If not provided, will use the current scope provided. |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered. |
+| `dataActions` | array | `[]` | | Optional. List of allowed data actions. This is not supported if the assignableScopes contains Management Group Scopes |
+| `description` | string | | | Optional. Description of the custom RBAC role to be created. |
+| `notActions` | array | `[]` | | Optional. List of denied actions. |
+| `notDataActions` | array | `[]` | | Optional. List of denied data actions. This is not supported if the assignableScopes contains Management Group Scopes |
+| `resourceGroupName` | string | `[resourceGroup().name]` | | Optional. The name of the Resource Group where the Role Definition and Target Scope will be applied to. If not provided, will use the current scope for deployment. |
+| `roleName` | string | | | Required. Name of the custom RBAC role to be created. |
+| `subscriptionId` | string | `[subscription().subscriptionId]` | | Optional. The subscription ID where the Role Definition and Target Scope will be applied to. If not provided, will use the current scope for deployment. |
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The GUID of the Role Definition |
+| `resourceGroupName` | string | The name of the resource group the role definition was created at |
+| `resourceId` | string | The resource ID of the Role Definition |
+| `scope` | string | The scope this Role Definition applies to |
+
+## Template references
+
+- [Roledefinitions](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2018-01-01-preview/roleDefinitions)
diff --git a/carml/1.0.0/Microsoft.Authorization/roleDefinitions/resourceGroup/version.json b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/resourceGroup/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/resourceGroup/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/roleDefinitions/subscription/deploy.bicep b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/subscription/deploy.bicep
new file mode 100644
index 000000000..abc70bc7f
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/subscription/deploy.bicep
@@ -0,0 +1,52 @@
+targetScope = 'subscription'
+
+@sys.description('Required. Name of the custom RBAC role to be created.')
+param roleName string
+
+@sys.description('Optional. Description of the custom RBAC role to be created.')
+param description string = ''
+
+@sys.description('Optional. List of allowed actions.')
+param actions array = []
+
+@sys.description('Optional. List of denied actions.')
+param notActions array = []
+
+@sys.description('Optional. List of allowed data actions. This is not supported if the assignableScopes contains Management Group Scopes')
+param dataActions array = []
+
+@sys.description('Optional. List of denied data actions. This is not supported if the assignableScopes contains Management Group Scopes')
+param notDataActions array = []
+
+@sys.description('Optional. The subscription ID where the Role Definition and Target Scope will be applied to. If not provided, will use the current scope for deployment.')
+param subscriptionId string = subscription().subscriptionId
+
+@sys.description('Optional. Role definition assignable scopes. If not provided, will use the current scope provided.')
+param assignableScopes array = []
+
+resource roleDefinition 'Microsoft.Authorization/roleDefinitions@2018-01-01-preview' = {
+ name: guid(roleName, subscriptionId)
+ properties: {
+ roleName: roleName
+ description: description
+ type: 'customRole'
+ permissions: [
+ {
+ actions: actions
+ notActions: notActions
+ dataActions: dataActions
+ notDataActions: notDataActions
+ }
+ ]
+ assignableScopes: !empty(assignableScopes) ? assignableScopes : array(subscription().id)
+ }
+}
+
+@sys.description('The GUID of the Role Definition')
+output name string = roleDefinition.name
+
+@sys.description('The scope this Role Definition applies to')
+output scope string = subscription().id
+
+@sys.description('The resource ID of the Role Definition')
+output resourceId string = subscriptionResourceId(subscriptionId, 'Microsoft.Authorization/roleDefinitions', roleDefinition.name)
diff --git a/carml/1.0.0/Microsoft.Authorization/roleDefinitions/subscription/readme.md b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/subscription/readme.md
new file mode 100644
index 000000000..950830c0c
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/subscription/readme.md
@@ -0,0 +1,34 @@
+# Role Definitions on Subscription level `[Microsoft.Authorization/roleDefinitions/subscription]`
+
+With this module you can create role definitions on a subscription level
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/roleDefinitions` | 2018-01-01-preview |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `actions` | array | `[]` | | Optional. List of allowed actions. |
+| `assignableScopes` | array | `[]` | | Optional. Role definition assignable scopes. If not provided, will use the current scope provided. |
+| `dataActions` | array | `[]` | | Optional. List of allowed data actions. This is not supported if the assignableScopes contains Management Group Scopes |
+| `description` | string | | | Optional. Description of the custom RBAC role to be created. |
+| `notActions` | array | `[]` | | Optional. List of denied actions. |
+| `notDataActions` | array | `[]` | | Optional. List of denied data actions. This is not supported if the assignableScopes contains Management Group Scopes |
+| `roleName` | string | | | Required. Name of the custom RBAC role to be created. |
+| `subscriptionId` | string | `[subscription().subscriptionId]` | | Optional. The subscription ID where the Role Definition and Target Scope will be applied to. If not provided, will use the current scope for deployment. |
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The GUID of the Role Definition |
+| `resourceId` | string | The resource ID of the Role Definition |
+| `scope` | string | The scope this Role Definition applies to |
+
+## Template references
+
+- [Roledefinitions](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2018-01-01-preview/roleDefinitions)
diff --git a/carml/1.0.0/Microsoft.Authorization/roleDefinitions/subscription/version.json b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/subscription/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/subscription/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Authorization/roleDefinitions/version.json b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Authorization/roleDefinitions/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.Automation/automationAccounts/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/.bicep/nested_linkedService.bicep b/carml/1.0.0/Microsoft.Automation/automationAccounts/.bicep/nested_linkedService.bicep
new file mode 100644
index 000000000..a5db7f142
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/.bicep/nested_linkedService.bicep
@@ -0,0 +1,37 @@
+@description('Required. Name of the link')
+param name string
+
+@description('Required. Name of the Log Analytics workspace')
+param logAnalyticsWorkspaceName string
+
+@description('Required. The resource ID of the resource that will be linked to the workspace. This should be used for linking resources which require read access.')
+param resourceId string = ''
+
+@description('Optional. The resource ID of the resource that will be linked to the workspace. This should be used for linking resources which require write access. ')
+param writeAccessResourceId string = ''
+
+@description('Optional. Tags to configure in the resource.')
+param tags object = {}
+
+resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2021-06-01' existing = {
+ name: logAnalyticsWorkspaceName
+}
+
+resource linkedService 'Microsoft.OperationalInsights/workspaces/linkedServices@2020-03-01-preview' = {
+ name: name
+ parent: logAnalyticsWorkspace
+ tags: tags
+ properties: {
+ resourceId: !empty(resourceId) ? resourceId : null
+ writeAccessResourceId: !empty(writeAccessResourceId) ? writeAccessResourceId : null
+ }
+}
+
+@description('The name of the deployed linked service')
+output name string = linkedService.name
+
+@description('The resource ID of the deployed linked service')
+output resourceId string = linkedService.id
+
+@description('The resource group where the linked service is deployed')
+output resourceGroupName string = resourceGroup().name
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/.bicep/nested_privateEndpoint.bicep b/carml/1.0.0/Microsoft.Automation/automationAccounts/.bicep/nested_privateEndpoint.bicep
new file mode 100644
index 000000000..26e201e43
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/.bicep/nested_privateEndpoint.bicep
@@ -0,0 +1,52 @@
+param privateEndpointResourceId string
+param privateEndpointVnetLocation string
+param privateEndpointObj object
+param tags object
+
+var privateEndpointResourceName = last(split(privateEndpointResourceId, '/'))
+var privateEndpoint_var = {
+ name: (contains(privateEndpointObj, 'name') ? (empty(privateEndpointObj.name) ? '${privateEndpointResourceName}-${privateEndpointObj.service}' : privateEndpointObj.name) : '${privateEndpointResourceName}-${privateEndpointObj.service}')
+ subnetResourceId: privateEndpointObj.subnetResourceId
+ service: [
+ privateEndpointObj.service
+ ]
+ privateDnsZoneResourceIds: (contains(privateEndpointObj, 'privateDnsZoneResourceIds') ? ((empty(privateEndpointObj.privateDnsZoneResourceIds) ? [] : privateEndpointObj.privateDnsZoneResourceIds)) : [])
+ customDnsConfigs: (contains(privateEndpointObj, 'customDnsConfigs') ? (empty(privateEndpointObj.customDnsConfigs) ? null : privateEndpointObj.customDnsConfigs) : null)
+}
+
+resource privateEndpoint 'Microsoft.Network/privateEndpoints@2021-05-01' = {
+ name: privateEndpoint_var.name
+ location: privateEndpointVnetLocation
+ tags: tags
+ properties: {
+ privateLinkServiceConnections: [
+ {
+ name: privateEndpoint_var.name
+ properties: {
+ privateLinkServiceId: privateEndpointResourceId
+ groupIds: privateEndpoint_var.service
+ }
+ }
+ ]
+ manualPrivateLinkServiceConnections: []
+ subnet: {
+ id: privateEndpoint_var.subnetResourceId
+ }
+ customDnsConfigs: privateEndpoint_var.customDnsConfigs
+ }
+}
+
+resource privateDnsZoneGroups 'Microsoft.Network/privateEndpoints/privateDnsZoneGroups@2021-05-01' = {
+ name: '${privateEndpoint_var.name}/default'
+ properties: {
+ privateDnsZoneConfigs: [for privateDnsZoneResourceId in privateEndpoint_var.privateDnsZoneResourceIds: {
+ name: last(split(privateDnsZoneResourceId, '/'))
+ properties: {
+ privateDnsZoneId: privateDnsZoneResourceId
+ }
+ }]
+ }
+ dependsOn: [
+ privateEndpoint
+ ]
+}
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/.bicep/nested_rbac.bicep b/carml/1.0.0/Microsoft.Automation/automationAccounts/.bicep/nested_rbac.bicep
new file mode 100644
index 000000000..777f9d3bd
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/.bicep/nested_rbac.bicep
@@ -0,0 +1,36 @@
+param principalIds array
+param roleDefinitionIdOrName string
+param resourceId string
+
+var builtInRoleNames = {
+ 'Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')
+ 'Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')
+ 'Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')
+ 'Automation Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f353d9bd-d4a6-484e-a77a-8050b599b867')
+ 'Automation Job Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4fe576fe-1146-4730-92eb-48519fa6bf9f')
+ 'Automation Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'd3881f73-407a-4167-8283-e981cbba0404')
+ 'Automation Runbook Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5fb5aef8-1081-4b8e-bb16-9d5d0385bab5')
+ 'Log Analytics Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')
+ 'Log Analytics Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')
+ 'Managed Application Contributor Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')
+ 'Managed Application Operator Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')
+ 'Managed Applications Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')
+ 'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')
+ 'Monitoring Metrics Publisher': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')
+ 'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')
+ 'Resource Policy Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')
+ 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')
+}
+
+resource automationAccount 'Microsoft.Automation/automationAccounts@2020-01-13-preview' existing = {
+ name: last(split(resourceId, '/'))
+}
+
+resource roleAssignment 'Microsoft.Authorization/roleAssignments@2021-04-01-preview' = [for principalId in principalIds: {
+ name: guid(automationAccount.name, principalId, roleDefinitionIdOrName)
+ properties: {
+ roleDefinitionId: contains(builtInRoleNames, roleDefinitionIdOrName) ? builtInRoleNames[roleDefinitionIdOrName] : roleDefinitionIdOrName
+ principalId: principalId
+ }
+ scope: automationAccount
+}]
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/.bicep/nested_solution.bicep b/carml/1.0.0/Microsoft.Automation/automationAccounts/.bicep/nested_solution.bicep
new file mode 100644
index 000000000..b6cbf586e
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/.bicep/nested_solution.bicep
@@ -0,0 +1,43 @@
+@description('Required. Name of the solution')
+param name string
+
+@description('Required. Name of the Log Analytics workspace')
+param logAnalyticsWorkspaceName string
+
+@description('Optional. Location for all resources.')
+param location string = resourceGroup().location
+
+@description('Optional. The product of the deployed solution. For gallery solution, it is OMSGallery.')
+param product string = 'OMSGallery'
+
+@description('Optional. The publisher name of the deployed solution. For gallery solution, it is Microsoft.')
+param publisher string = 'Microsoft'
+
+resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2020-08-01' existing = {
+ name: logAnalyticsWorkspaceName
+}
+
+var solutionName = '${name}(${logAnalyticsWorkspace.name})'
+
+resource solution 'Microsoft.OperationsManagement/solutions@2015-11-01-preview' = {
+ name: solutionName
+ location: location
+ properties: {
+ workspaceResourceId: logAnalyticsWorkspace.id
+ }
+ plan: {
+ name: solutionName
+ promotionCode: ''
+ product: '${product}/${name}'
+ publisher: publisher
+ }
+}
+
+@description('The name of the deployed solution')
+output name string = solution.name
+
+@description('The resource ID of the deployed solution')
+output resourceId string = solution.id
+
+@description('The resource group where the solution is deployed')
+output resourceGroupName string = resourceGroup().name
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/.parameters/min.parameters.json b/carml/1.0.0/Microsoft.Automation/automationAccounts/.parameters/min.parameters.json
new file mode 100644
index 000000000..36d11228d
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/.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": "<>-wd-aut-min-001"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/.parameters/parameters.json b/carml/1.0.0/Microsoft.Automation/automationAccounts/.parameters/parameters.json
new file mode 100644
index 000000000..d95589e97
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/.parameters/parameters.json
@@ -0,0 +1,192 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-wd-aut-x-001"
+ },
+ "schedules": {
+ "value": [
+ {
+ "name": "TestSchedule",
+ "startTime": "",
+ "expiryTime": "9999-12-31T23:59:00+00:00",
+ "interval": 15,
+ "frequency": "Minute",
+ "timeZone": "Europe/Berlin",
+ "advancedSchedule": {}
+ }
+ ]
+ },
+ "modules": {
+ "value": [
+ {
+ "name": "PSWindowsUpdate",
+ "version": "latest",
+ "uri": "https://www.powershellgallery.com/api/v2/package"
+ }
+ ]
+ },
+ "runbooks": {
+ "value": [
+ {
+ "name": "TestRunbook",
+ "runbookType": "PowerShell",
+ "description": "Test runbook",
+ "uri": "https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/quickstarts/microsoft.automation/101-automation/scripts/AzureAutomationTutorial.ps1",
+ "version": "1.0.0.0"
+ }
+ ]
+ },
+ "jobSchedules": {
+ "value": [
+ {
+ "scheduleName": "TestSchedule",
+ "runbookName": "TestRunbook"
+ }
+ ]
+ },
+ "variables": {
+ "value": [
+ {
+ "name": "TestString",
+ "value": "\"TestString\"",
+ "description": "TestStringDescription"
+ },
+ {
+ "name": "TestInteger",
+ "value": "500",
+ "description": "TestIntegerDescription"
+ },
+ {
+ "name": "TestBoolean",
+ "value": "false",
+ "description": "TestBooleanDescription"
+ },
+ {
+ "name": "TestDateTime",
+ "value": "\"\\/Date(1637934042656)\\/\"",
+ "description": "TestDateTimeDescription"
+ },
+ {
+ "name": "TestEncryptedVariable",
+ "value": "\"TestEncryptedValue\"",
+ "description": "TestEncryptedDescription",
+ "isEncrypted": true
+ }
+ ]
+ },
+ "linkedWorkspaceId": {
+ "value": "/subscriptions/<>/resourcegroups/validation-rg/providers/microsoft.operationalinsights/workspaces/adp-<>-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": "22:00"
+ }
+ ]
+ },
+ "privateEndpoints": {
+ "value": [
+ {
+ "subnetResourceId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/adp-<>-az-vnet-x-001/subnets/<>-az-subnet-x-005-privateEndpoints",
+ "service": "Webhook"
+ },
+ {
+ "subnetResourceId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/adp-<>-az-vnet-x-001/subnets/<>-az-subnet-x-005-privateEndpoints",
+ "service": "DSCAndHybridWorker"
+ }
+ ]
+ },
+ "systemAssignedIdentity": {
+ "value": true
+ },
+ "userAssignedIdentities": {
+ "value": {
+ "/subscriptions/<>/resourcegroups/validation-rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/adp-<>-az-msi-x-001": {}
+ }
+ },
+ "roleAssignments": {
+ "value": [
+ {
+ "roleDefinitionIdOrName": "Reader",
+ "principalIds": [
+ "<>"
+ ]
+ }
+ ]
+ },
+ "diagnosticLogsRetentionInDays": {
+ "value": 7
+ },
+ "diagnosticStorageAccountId": {
+ "value": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Storage/storageAccounts/adp<>azsax001"
+ },
+ "diagnosticWorkspaceId": {
+ "value": "/subscriptions/<>/resourcegroups/validation-rg/providers/microsoft.operationalinsights/workspaces/adp-<>-az-law-x-001"
+ },
+ "diagnosticEventHubAuthorizationRuleId": {
+ "value": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.EventHub/namespaces/adp-<>-az-evhns-x-001/AuthorizationRules/RootManageSharedAccessKey"
+ },
+ "diagnosticEventHubName": {
+ "value": "adp-<>-az-evh-x-001"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/deploy.bicep b/carml/1.0.0/Microsoft.Automation/automationAccounts/deploy.bicep
new file mode 100644
index 000000000..b1caa69c5
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/deploy.bicep
@@ -0,0 +1,336 @@
+@description('Required. Name of the Automation Account.')
+param name string
+
+@description('Optional. Location for all resources.')
+param location string = resourceGroup().location
+
+@allowed([
+ 'Free'
+ 'Basic'
+])
+@description('Optional. SKU name of the account.')
+param skuName string = 'Basic'
+
+@description('Optional. List of modules to be created in the automation account.')
+param modules array = []
+
+@description('Optional. List of runbooks to be created in the automation account.')
+param runbooks array = []
+
+@description('Optional. List of schedules to be created in the automation account.')
+param schedules array = []
+
+@description('Optional. List of jobSchedules to be created in the automation account.')
+param jobSchedules array = []
+
+@description('Optional. List of variables to be created in the automation account.')
+param variables array = []
+
+@description('Optional. ID of the log analytics workspace to be linked to the deployed automation account.')
+param linkedWorkspaceId string = ''
+
+@description('Optional. List of gallerySolutions to be created in the linked log analytics workspace')
+param gallerySolutions array = []
+
+@description('Optional. List of softwareUpdateConfigurations to be created in the automation account')
+param softwareUpdateConfigurations array = []
+
+@description('Optional. Configuration Details for private endpoints.')
+param privateEndpoints array = []
+
+@minValue(0)
+@maxValue(365)
+@description('Optional. Specifies the number of days that logs will be kept for; a value of 0 will retain data indefinitely.')
+param diagnosticLogsRetentionInDays int = 365
+
+@description('Optional. Resource ID of the diagnostic storage account.')
+param diagnosticStorageAccountId string = ''
+
+@description('Optional. Resource ID of the diagnostic log analytics workspace.')
+param diagnosticWorkspaceId string = ''
+
+@description('Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to.')
+param diagnosticEventHubAuthorizationRuleId string = ''
+
+@description('Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category.')
+param diagnosticEventHubName string = ''
+
+@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 = {}
+
+@allowed([
+ 'CanNotDelete'
+ 'NotSpecified'
+ 'ReadOnly'
+])
+@description('Optional. Specify the type of lock.')
+param lock string = 'NotSpecified'
+
+@description('Optional. Array of role assignment objects that contain the \'roleDefinitionIdOrName\' and \'principalId\' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.')
+param roleAssignments array = []
+
+@description('Optional. Tags of the Automation Account resource.')
+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([
+ 'JobLogs'
+ 'JobStreams'
+ 'DscNodeStatus'
+])
+param logsToEnable array = [
+ 'JobLogs'
+ 'JobStreams'
+ 'DscNodeStatus'
+]
+
+@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 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 automationAccount 'Microsoft.Automation/automationAccounts@2020-01-13-preview' = {
+ name: name
+ location: location
+ tags: tags
+ properties: {
+ sku: {
+ name: skuName
+ }
+ }
+ identity: identity
+}
+
+module automationAccount_modules 'modules/deploy.bicep' = [for (module, index) in modules: {
+ name: '${uniqueString(deployment().name, location)}-AutoAccount-Module-${index}'
+ params: {
+ name: module.name
+ automationAccountName: automationAccount.name
+ version: module.version
+ uri: module.uri
+ location: location
+ tags: tags
+ }
+}]
+
+module automationAccount_schedules 'schedules/deploy.bicep' = [for (schedule, index) in schedules: {
+ name: '${uniqueString(deployment().name, location)}-AutoAccount-Schedule-${index}'
+ params: {
+ name: schedule.name
+ automationAccountName: automationAccount.name
+ advancedSchedule: contains(schedule, 'advancedSchedule') ? schedule.advancedSchedule : null
+ scheduleDescription: contains(schedule, 'description') ? schedule.description : ''
+ expiryTime: contains(schedule, 'expiryTime') ? schedule.expiryTime : ''
+ frequency: contains(schedule, 'frequency') ? schedule.frequency : 'OneTime'
+ interval: contains(schedule, 'interval') ? schedule.interval : 0
+ startTime: contains(schedule, 'startTime') ? schedule.startTime : ''
+ timeZone: contains(schedule, 'timeZone') ? schedule.timeZone : ''
+ }
+}]
+
+module automationAccount_runbooks 'runbooks/deploy.bicep' = [for (runbook, index) in runbooks: {
+ name: '${uniqueString(deployment().name, location)}-AutoAccount-Runbook-${index}'
+ params: {
+ name: runbook.name
+ automationAccountName: automationAccount.name
+ runbookType: runbook.runbookType
+ runbookDescription: contains(runbook, 'description') ? runbook.description : ''
+ uri: contains(runbook, 'uri') ? runbook.uri : ''
+ version: contains(runbook, 'version') ? runbook.version : ''
+ location: location
+ tags: tags
+ }
+}]
+
+module automationAccount_jobSchedules 'jobSchedules/deploy.bicep' = [for (jobSchedule, index) in jobSchedules: {
+ name: '${uniqueString(deployment().name, location)}-AutoAccount-JobSchedule-${index}'
+ params: {
+ automationAccountName: automationAccount.name
+ runbookName: jobSchedule.runbookName
+ scheduleName: jobSchedule.scheduleName
+ parameters: contains(jobSchedule, 'parameters') ? jobSchedule.parameters : {}
+ runOn: contains(jobSchedule, 'runOn') ? jobSchedule.runOn : ''
+ }
+ dependsOn: [
+ automationAccount_schedules
+ automationAccount_runbooks
+ ]
+}]
+
+module automationAccount_variables 'variables/deploy.bicep' = [for (variable, index) in variables: {
+ name: '${uniqueString(deployment().name, location)}-AutoAccount-Variable-${index}'
+ params: {
+ automationAccountName: automationAccount.name
+ name: variable.name
+ description: contains(variable, 'description') ? variable.description : ''
+ value: variable.value
+ isEncrypted: contains(variable, 'isEncrypted') ? variable.isEncrypted : false
+ }
+}]
+
+module automationAccount_linkedService '.bicep/nested_linkedService.bicep' = if (!empty(linkedWorkspaceId)) {
+ name: '${uniqueString(deployment().name, location)}-AutoAccount-LinkedService'
+ params: {
+ name: 'automation'
+ logAnalyticsWorkspaceName: last(split(linkedWorkspaceId, '/'))
+ resourceId: automationAccount.id
+ tags: tags
+ }
+ // This is to support linked services to law in different subscription and resource group than the automation account.
+ // The current scope is used by default if no linked service is intended to be created.
+ scope: resourceGroup(!empty(linkedWorkspaceId) ? split(linkedWorkspaceId, '/')[2] : subscription().subscriptionId, !empty(linkedWorkspaceId) ? split(linkedWorkspaceId, '/')[4] : resourceGroup().name)
+}
+
+module automationAccount_solutions '.bicep/nested_solution.bicep' = [for (gallerySolution, index) in gallerySolutions: if (!empty(linkedWorkspaceId)) {
+ name: '${uniqueString(deployment().name, location)}-AutoAccount-Solution-${index}'
+ params: {
+ name: gallerySolution
+ location: location
+ logAnalyticsWorkspaceName: last(split(linkedWorkspaceId, '/'))
+ }
+ // This is to support solution to law in different subscription and resource group than the automation account.
+ // The current scope is used by default if no linked service is intended to be created.
+ scope: resourceGroup(!empty(linkedWorkspaceId) ? split(linkedWorkspaceId, '/')[2] : subscription().subscriptionId, !empty(linkedWorkspaceId) ? split(linkedWorkspaceId, '/')[4] : resourceGroup().name)
+ dependsOn: [
+ automationAccount_linkedService
+ ]
+}]
+
+module automationAccount_softwareUpdateConfigurations 'softwareUpdateConfigurations/deploy.bicep' = [for (softwareUpdateConfiguration, index) in softwareUpdateConfigurations: {
+ name: '${uniqueString(deployment().name, location)}-AutoAccount-SwUpdateConfig-${index}'
+ params: {
+ name: softwareUpdateConfiguration.name
+ automationAccountName: automationAccount.name
+ frequency: softwareUpdateConfiguration.frequency
+ operatingSystem: softwareUpdateConfiguration.operatingSystem
+ rebootSetting: softwareUpdateConfiguration.rebootSetting
+ azureVirtualMachines: contains(softwareUpdateConfiguration, 'azureVirtualMachines') ? softwareUpdateConfiguration.azureVirtualMachines : []
+ excludeUpdates: contains(softwareUpdateConfiguration, 'excludeUpdates') ? softwareUpdateConfiguration.excludeUpdates : []
+ expiryTime: contains(softwareUpdateConfiguration, 'expiryTime') ? softwareUpdateConfiguration.expiryTime : ''
+ expiryTimeOffsetMinutes: contains(softwareUpdateConfiguration, 'expiryTimeOffsetMinutes') ? softwareUpdateConfiguration.expiryTimeOffsetMinute : 0
+ includeUpdates: contains(softwareUpdateConfiguration, 'includeUpdates') ? softwareUpdateConfiguration.includeUpdates : []
+ interval: contains(softwareUpdateConfiguration, 'interval') ? softwareUpdateConfiguration.interval : 1
+ isEnabled: contains(softwareUpdateConfiguration, 'isEnabled') ? softwareUpdateConfiguration.isEnabled : true
+ maintenanceWindow: contains(softwareUpdateConfiguration, 'maintenanceWindow') ? softwareUpdateConfiguration.maintenanceWindow : 'PT2H'
+ monthDays: contains(softwareUpdateConfiguration, 'monthDays') ? softwareUpdateConfiguration.monthDays : []
+ monthlyOccurrences: contains(softwareUpdateConfiguration, 'monthlyOccurrences') ? softwareUpdateConfiguration.monthlyOccurrences : []
+ nextRun: contains(softwareUpdateConfiguration, 'nextRun') ? softwareUpdateConfiguration.nextRun : ''
+ nextRunOffsetMinutes: contains(softwareUpdateConfiguration, 'nextRunOffsetMinutes') ? softwareUpdateConfiguration.nextRunOffsetMinutes : 0
+ nonAzureComputerNames: contains(softwareUpdateConfiguration, 'nonAzureComputerNames') ? softwareUpdateConfiguration.nonAzureComputerNames : []
+ nonAzureQueries: contains(softwareUpdateConfiguration, 'nonAzureQueries') ? softwareUpdateConfiguration.nonAzureQueries : []
+ postTaskParameters: contains(softwareUpdateConfiguration, 'postTaskParameters') ? softwareUpdateConfiguration.postTaskParameters : {}
+ postTaskSource: contains(softwareUpdateConfiguration, 'postTaskSource') ? softwareUpdateConfiguration.postTaskSource : ''
+ preTaskParameters: contains(softwareUpdateConfiguration, 'preTaskParameters') ? softwareUpdateConfiguration.preTaskParameters : {}
+ preTaskSource: contains(softwareUpdateConfiguration, 'preTaskSource') ? softwareUpdateConfiguration.preTaskSource : ''
+ scheduleDescription: contains(softwareUpdateConfiguration, 'scheduleDescription') ? softwareUpdateConfiguration.scheduleDescription : ''
+ scopeByLocations: contains(softwareUpdateConfiguration, 'scopeByLocations') ? softwareUpdateConfiguration.scopeByLocations : []
+ scopeByResources: contains(softwareUpdateConfiguration, 'scopeByResources') ? softwareUpdateConfiguration.scopeByResources : [
+ subscription().id
+ ]
+ scopeByTags: contains(softwareUpdateConfiguration, 'scopeByTags') ? softwareUpdateConfiguration.scopeByTags : {}
+ scopeByTagsOperation: contains(softwareUpdateConfiguration, 'scopeByTagsOperation') ? softwareUpdateConfiguration.scopeByTagsOperation : 'All'
+ startTime: contains(softwareUpdateConfiguration, 'startTime') ? softwareUpdateConfiguration.startTime : ''
+ timeZone: contains(softwareUpdateConfiguration, 'timeZone') ? softwareUpdateConfiguration.timeZone : 'UTC'
+ updateClassifications: contains(softwareUpdateConfiguration, 'updateClassifications') ? softwareUpdateConfiguration.updateClassifications : [
+ 'Critical'
+ 'Security'
+ ]
+ weekDays: contains(softwareUpdateConfiguration, 'weekDays') ? softwareUpdateConfiguration.weekDays : []
+ }
+ dependsOn: [
+ automationAccount_solutions
+ ]
+}]
+
+resource automationAccount_lock 'Microsoft.Authorization/locks@2017-04-01' = if (lock != 'NotSpecified') {
+ name: '${automationAccount.name}-AutoAccount-${lock}-lock'
+ properties: {
+ level: lock
+ notes: lock == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot modify the resource or child resources.'
+ }
+ scope: automationAccount
+}
+
+resource automationAccount_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if ((!empty(diagnosticStorageAccountId)) || (!empty(diagnosticWorkspaceId)) || (!empty(diagnosticEventHubAuthorizationRuleId)) || (!empty(diagnosticEventHubName))) {
+ name: '${automationAccount.name}-AutoAccount-diagnosticSettings'
+ properties: {
+ storageAccountId: !empty(diagnosticStorageAccountId) ? diagnosticStorageAccountId : null
+ workspaceId: !empty(diagnosticWorkspaceId) ? diagnosticWorkspaceId : null
+ eventHubAuthorizationRuleId: !empty(diagnosticEventHubAuthorizationRuleId) ? diagnosticEventHubAuthorizationRuleId : null
+ eventHubName: !empty(diagnosticEventHubName) ? diagnosticEventHubName : null
+ metrics: diagnosticsMetrics
+ logs: diagnosticsLogs
+ }
+ scope: automationAccount
+}
+
+module automationAccount_privateEndpoints '.bicep/nested_privateEndpoint.bicep' = [for (endpoint, index) in privateEndpoints: if (!empty(privateEndpoints)) {
+ name: '${uniqueString(deployment().name, location)}-AutoAccount-PrivateEndpoint-${index}'
+ params: {
+ privateEndpointResourceId: automationAccount.id
+ privateEndpointVnetLocation: !empty(privateEndpoints) ? reference(split(endpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location : 'dummy'
+ privateEndpointObj: endpoint
+ tags: tags
+ }
+}]
+
+module automationAccount_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: {
+ name: '${uniqueString(deployment().name, location)}-AutoAccount-Rbac-${index}'
+ params: {
+ principalIds: roleAssignment.principalIds
+ roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName
+ resourceId: automationAccount.id
+ }
+}]
+
+@description('The name of the deployed automation account')
+output name string = automationAccount.name
+
+@description('The resource ID of the deployed automation account')
+output resourceId string = automationAccount.id
+
+@description('The resource group of the deployed automation account')
+output resourceGroupName string = resourceGroup().name
+
+@description('The principal ID of the system assigned identity.')
+output systemAssignedPrincipalId string = systemAssignedIdentity && contains(automationAccount.identity, 'principalId') ? automationAccount.identity.principalId : ''
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/jobSchedules/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.Automation/automationAccounts/jobSchedules/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/jobSchedules/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/jobSchedules/deploy.bicep b/carml/1.0.0/Microsoft.Automation/automationAccounts/jobSchedules/deploy.bicep
new file mode 100644
index 000000000..f21d47cd9
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/jobSchedules/deploy.bicep
@@ -0,0 +1,53 @@
+@description('Optional. Name of the Automation Account job schedule. Must be a GUID. If not provided, a new GUID is generated.')
+param name string = newGuid()
+
+@description('Required. Name of the parent Automation Account.')
+param automationAccountName string
+
+@description('Required. The runbook property associated with the entity.')
+param runbookName string
+
+@description('Required. The schedule property associated with the entity.')
+param scheduleName string
+
+@description('Optional. List of job properties.')
+param parameters object = {}
+
+@description('Optional. The hybrid worker group that the scheduled job should run on.')
+param runOn string = ''
+
+@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 automationAccount 'Microsoft.Automation/automationAccounts@2020-01-13-preview' existing = {
+ name: automationAccountName
+}
+
+resource jobSchedule 'Microsoft.Automation/automationAccounts/jobSchedules@2020-01-13-preview' = {
+ name: name
+ parent: automationAccount
+ properties: {
+ parameters: parameters
+ runbook: {
+ name: runbookName
+ }
+ runOn: !empty(runOn) ? runOn : null
+ schedule: {
+ name: scheduleName
+ }
+ }
+}
+
+@description('The name of the deployed job schedule')
+output name string = jobSchedule.name
+
+@description('The resource ID of the deployed job schedule')
+output resourceId string = jobSchedule.id
+
+@description('The resource group of the deployed job schedule')
+output resourceGroupName string = resourceGroup().name
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/jobSchedules/readme.md b/carml/1.0.0/Microsoft.Automation/automationAccounts/jobSchedules/readme.md
new file mode 100644
index 000000000..6299676c1
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/jobSchedules/readme.md
@@ -0,0 +1,33 @@
+# Automation Account Job Schedules `[Microsoft.Automation/automationAccounts/jobSchedules]`
+
+This module deploys an Azure Automation Account Job Schedule.
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Automation/automationAccounts/jobSchedules` | 2020-01-13-preview |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `automationAccountName` | string | | | Required. Name of the parent Automation Account. |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered. |
+| `name` | string | `[newGuid()]` | | Optional. Name of the Automation Account job schedule. Must be a GUID. If not provided, a new GUID is generated. |
+| `parameters` | object | `{object}` | | Optional. List of job properties. |
+| `runbookName` | string | | | Required. The runbook property associated with the entity. |
+| `runOn` | string | | | Optional. The hybrid worker group that the scheduled job should run on. |
+| `scheduleName` | string | | | Required. The schedule property associated with the entity. |
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The name of the deployed job schedule |
+| `resourceGroupName` | string | The resource group of the deployed job schedule |
+| `resourceId` | string | The resource ID of the deployed job schedule |
+
+## Template references
+
+- [Automationaccounts/Jobschedules](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Automation/2020-01-13-preview/automationAccounts/jobSchedules)
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/jobSchedules/version.json b/carml/1.0.0/Microsoft.Automation/automationAccounts/jobSchedules/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/jobSchedules/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/modules/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.Automation/automationAccounts/modules/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/modules/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/modules/deploy.bicep b/carml/1.0.0/Microsoft.Automation/automationAccounts/modules/deploy.bicep
new file mode 100644
index 000000000..429f29d1a
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/modules/deploy.bicep
@@ -0,0 +1,51 @@
+@description('Required. Name of the Automation Account module.')
+param name string
+
+@description('Required. Name of the parent Automation Account.')
+param automationAccountName string
+
+@description('Required. Module package uri, e.g. https://www.powershellgallery.com/api/v2/package.')
+param uri string
+
+@description('Optional. Module version or specify latest to get the latest version.')
+param version string = 'latest'
+
+@description('Optional. Location for all resources.')
+param location string = resourceGroup().location
+
+@description('Optional. Tags of the Automation Account resource.')
+param tags object = {}
+
+@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 automationAccount 'Microsoft.Automation/automationAccounts@2020-01-13-preview' existing = {
+ name: automationAccountName
+}
+
+resource module 'Microsoft.Automation/automationAccounts/modules@2020-01-13-preview' = {
+ name: name
+ parent: automationAccount
+ location: location
+ tags: tags
+ properties: {
+ contentLink: {
+ uri: version != 'latest' ? '${uri}/${name}/${version}' : '${uri}/${name}'
+ version: version != 'latest' ? version : null
+ }
+ }
+}
+
+@description('The name of the deployed module')
+output name string = module.name
+
+@description('The resource ID of the deployed module')
+output resourceId string = module.id
+
+@description('The resource group of the deployed module')
+output resourceGroupName string = resourceGroup().name
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/modules/readme.md b/carml/1.0.0/Microsoft.Automation/automationAccounts/modules/readme.md
new file mode 100644
index 000000000..23a712f1f
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/modules/readme.md
@@ -0,0 +1,50 @@
+# Automation Account Modules `[Microsoft.Automation/automationAccounts/modules]`
+
+This module deploys an Azure Automation Account Module.
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Automation/automationAccounts/modules` | 2020-01-13-preview |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `automationAccountName` | string | | | Required. Name of the parent Automation Account. |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered. |
+| `location` | string | `[resourceGroup().location]` | | Optional. Location for all resources. |
+| `name` | string | | | Required. Name of the Automation Account module. |
+| `tags` | object | `{object}` | | Optional. Tags of the Automation Account resource. |
+| `uri` | string | | | Required. Module package uri, e.g. https://www.powershellgallery.com/api/v2/package. |
+| `version` | string | `latest` | | Optional. Module version or specify latest to get the latest version. |
+
+### 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"
+ }
+}
+```
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The name of the deployed module |
+| `resourceGroupName` | string | The resource group of the deployed module |
+| `resourceId` | string | The resource ID of the deployed module |
+
+## Template references
+
+- [Automationaccounts/Modules](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Automation/2020-01-13-preview/automationAccounts/modules)
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/modules/version.json b/carml/1.0.0/Microsoft.Automation/automationAccounts/modules/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/modules/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/readme.md b/carml/1.0.0/Microsoft.Automation/automationAccounts/readme.md
new file mode 100644
index 000000000..8a35a9b67
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/readme.md
@@ -0,0 +1,166 @@
+# Automation Accounts `[Microsoft.Automation/automationAccounts]`
+
+This module deploys an Azure Automation Account.
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/locks` | 2017-04-01 |
+| `Microsoft.Authorization/roleAssignments` | 2021-04-01-preview |
+| `Microsoft.Automation/automationAccounts` | 2020-01-13-preview |
+| `Microsoft.Automation/automationAccounts/jobSchedules` | 2020-01-13-preview |
+| `Microsoft.Automation/automationAccounts/modules` | 2020-01-13-preview |
+| `Microsoft.Automation/automationAccounts/runbooks` | 2019-06-01 |
+| `Microsoft.Automation/automationAccounts/schedules` | 2020-01-13-preview |
+| `Microsoft.Automation/automationAccounts/softwareUpdateConfigurations` | 2019-06-01 |
+| `Microsoft.Automation/automationAccounts/variables` | 2020-01-13-preview |
+| `Microsoft.Insights/diagnosticSettings` | 2021-05-01-preview |
+| `Microsoft.Network/privateEndpoints` | 2021-05-01 |
+| `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | 2021-05-01 |
+| `Microsoft.OperationalInsights/workspaces/linkedServices` | 2020-03-01-preview |
+| `Microsoft.OperationsManagement/solutions` | 2015-11-01-preview |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered. |
+| `diagnosticEventHubAuthorizationRuleId` | string | | | Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. |
+| `diagnosticEventHubName` | string | | | Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. |
+| `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. |
+| `diagnosticWorkspaceId` | string | | | Optional. Resource ID of the diagnostic log analytics workspace. |
+| `gallerySolutions` | array | `[]` | | Optional. List of gallerySolutions to be created in the linked log analytics workspace |
+| `jobSchedules` | _[jobSchedules](jobSchedules/readme.md)_ array | `[]` | | Optional. List of jobSchedules to be created in the automation account. |
+| `linkedWorkspaceId` | string | | | Optional. ID of the log analytics workspace to be linked to the deployed automation account. |
+| `location` | string | `[resourceGroup().location]` | | Optional. Location for all resources. |
+| `lock` | string | `NotSpecified` | `[CanNotDelete, NotSpecified, ReadOnly]` | Optional. Specify the type of lock. |
+| `logsToEnable` | array | `[JobLogs, JobStreams, DscNodeStatus]` | `[JobLogs, JobStreams, DscNodeStatus]` | Optional. The name of logs that will be streamed. |
+| `metricsToEnable` | array | `[AllMetrics]` | `[AllMetrics]` | Optional. The name of metrics that will be streamed. |
+| `modules` | _[modules](modules/readme.md)_ array | `[]` | | Optional. List of modules to be created in the automation account. |
+| `name` | string | | | Required. Name of the Automation Account. |
+| `privateEndpoints` | array | `[]` | | Optional. Configuration Details for private endpoints. |
+| `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'. |
+| `runbooks` | _[runbooks](runbooks/readme.md)_ array | `[]` | | Optional. List of runbooks to be created in the automation account. |
+| `schedules` | _[schedules](schedules/readme.md)_ array | `[]` | | Optional. List of schedules to be created in the automation account. |
+| `skuName` | string | `Basic` | `[Free, Basic]` | Optional. SKU name of the account. |
+| `softwareUpdateConfigurations` | _[softwareUpdateConfigurations](softwareUpdateConfigurations/readme.md)_ array | `[]` | | Optional. List of softwareUpdateConfigurations to be created in the automation account |
+| `systemAssignedIdentity` | bool | `False` | | Optional. Enables system assigned managed identity on the resource. |
+| `tags` | object | `{object}` | | Optional. Tags of the Automation Account resource. |
+| `userAssignedIdentities` | object | `{object}` | | Optional. The ID(s) to assign to the resource. |
+| `variables` | _[variables](variables/readme.md)_ array | `[]` | | Optional. List of variables to be created in the automation account. |
+
+### Parameter Usage: `privateEndpoints`
+
+To use Private Endpoint the following dependencies must be deployed:
+
+- Destination subnet must be created with the following configuration option - `"privateEndpointNetworkPolicies": "Disabled"`. Setting this option acknowledges that NSG rules are not applied to Private Endpoints (this capability is coming soon). A full example is available in the Virtual Network Module.
+- Although not strictly required, it is highly recommended to first create a private DNS Zone to host Private Endpoint DNS records. See [Azure Private Endpoint DNS configuration](https://docs.microsoft.com/en-us/azure/private-link/private-endpoint-dns) for more information.
+
+```json
+"privateEndpoints": {
+ "value": [
+ // Example showing all available fields
+ {
+ "name": "sxx-az-pe", // Optional: Name will be automatically generated if one is not provided here
+ "subnetResourceId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/sxx-az-vnet-x-001/subnets/sxx-az-subnet-x-001",
+ "service": "blob",
+ "privateDnsZoneResourceIds": [ // Optional: No DNS record will be created if a private DNS zone Resource ID is not specified
+ "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/privateDnsZones/privatelink.blob.core.windows.net"
+ ],
+ "customDnsConfigs": [ // Optional
+ {
+ "fqdn": "customname.test.local",
+ "ipAddresses": [
+ "10.10.10.10"
+ ]
+ }
+ ]
+ },
+ // Example showing only mandatory fields
+ {
+ "subnetResourceId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/sxx-az-vnet-x-001/subnets/sxx-az-subnet-x-001",
+ "service": "file"
+ }
+ ]
+}
+```
+
+### Parameter Usage: `roleAssignments`
+
+```json
+"roleAssignments": {
+ "value": [
+ {
+ "roleDefinitionIdOrName": "Reader",
+ "principalIds": [
+ "12345678-1234-1234-1234-123456789012", // object 1
+ "78945612-1234-1234-1234-123456789012" // object 2
+ ]
+ },
+ {
+ "roleDefinitionIdOrName": "/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11",
+ "principalIds": [
+ "12345678-1234-1234-1234-123456789012" // object 1
+ ]
+ }
+ ]
+}
+```
+
+### 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 |
+| :-- | :-- | :-- |
+| `name` | string | The name of the deployed automation account |
+| `resourceGroupName` | string | The resource group of the deployed automation account |
+| `resourceId` | string | The resource ID of the deployed automation account |
+| `systemAssignedPrincipalId` | string | The principal ID of the system assigned identity. |
+
+## Template references
+
+- [Automationaccounts](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Automation/2020-01-13-preview/automationAccounts)
+- [Automationaccounts/Jobschedules](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Automation/2020-01-13-preview/automationAccounts/jobSchedules)
+- [Automationaccounts/Modules](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Automation/2020-01-13-preview/automationAccounts/modules)
+- [Automationaccounts/Runbooks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Automation/2019-06-01/automationAccounts/runbooks)
+- [Automationaccounts/Schedules](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Automation/2020-01-13-preview/automationAccounts/schedules)
+- [Automationaccounts/Softwareupdateconfigurations](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Automation/2019-06-01/automationAccounts/softwareUpdateConfigurations)
+- [Automationaccounts/Variables](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Automation/2020-01-13-preview/automationAccounts/variables)
+- [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/2017-04-01/locks)
+- [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-05-01/privateEndpoints/privateDnsZoneGroups)
+- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/roleAssignments)
+- [Solutions](https://docs.microsoft.com/en-us/azure/templates/Microsoft.OperationsManagement/2015-11-01-preview/solutions)
+- [Workspaces/Linkedservices](https://docs.microsoft.com/en-us/azure/templates/Microsoft.OperationalInsights/2020-03-01-preview/workspaces/linkedServices)
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/runbooks/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.Automation/automationAccounts/runbooks/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/runbooks/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/runbooks/deploy.bicep b/carml/1.0.0/Microsoft.Automation/automationAccounts/runbooks/deploy.bicep
new file mode 100644
index 000000000..48be20cae
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/runbooks/deploy.bicep
@@ -0,0 +1,90 @@
+@description('Required. Name of the Automation Account runbook.')
+param name string
+
+@description('Required. Name of the parent Automation Account.')
+param automationAccountName string
+
+@allowed([
+ 'Graph'
+ 'GraphPowerShell'
+ 'GraphPowerShellWorkflow'
+ 'PowerShell'
+ 'PowerShellWorkflow'
+])
+@description('Required. The type of the runbook.')
+param runbookType string
+
+@description('Optional. The description of the runbook.')
+param runbookDescription string = ''
+
+@description('Optional. The uri of the runbook content.')
+param uri string = ''
+
+@description('Optional. The version of the runbook content.')
+param version string = ''
+
+@description('Optional. ID of the runbook storage account.')
+param scriptStorageAccountId string = ''
+
+@description('Optional. Time used as a basis for e.g. the schedule start date.')
+param baseTime string = utcNow('u')
+
+@description('Optional. SAS token validity length. Usage: \'PT8H\' - valid for 8 hours; \'P5D\' - valid for 5 days; \'P1Y\' - valid for 1 year. When not provided, the SAS token will be valid for 8 hours.')
+param sasTokenValidityLength string = 'PT8H'
+
+@description('Optional. Location for all resources.')
+param location string = resourceGroup().location
+
+@description('Optional. Tags of the Automation Account resource.')
+param tags object = {}
+
+@description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered.')
+param cuaId string = ''
+
+var accountSasProperties = {
+ signedServices: 'b'
+ signedPermission: 'r'
+ signedExpiry: dateTimeAdd(baseTime, sasTokenValidityLength)
+ signedResourceTypes: 'o'
+ signedProtocol: 'https'
+}
+
+module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) {
+ name: 'pid-${cuaId}'
+ params: {}
+}
+
+resource automationAccount 'Microsoft.Automation/automationAccounts@2020-01-13-preview' existing = {
+ name: automationAccountName
+}
+
+resource storageAccount 'Microsoft.Storage/storageAccounts@2021-06-01' existing = if (!empty(scriptStorageAccountId)) {
+ name: last(split(scriptStorageAccountId, '/'))
+ scope: resourceGroup(split(scriptStorageAccountId, '/')[2], split(scriptStorageAccountId, '/')[4])
+}
+
+var publishContentLink = empty(uri) ? null : {
+ uri: !empty(uri) ? (empty(scriptStorageAccountId) ? uri : '${uri}${storageAccount.listAccountSas('2021-04-01', accountSasProperties).accountSasToken}') : null
+ version: !empty(version) ? version : null
+}
+
+resource runbook 'Microsoft.Automation/automationAccounts/runbooks@2019-06-01' = {
+ name: name
+ parent: automationAccount
+ location: location
+ tags: tags
+ properties: {
+ runbookType: runbookType
+ description: runbookDescription
+ publishContentLink: !empty(uri) ? publishContentLink : null
+ }
+}
+
+@description('The name of the deployed runbook')
+output name string = runbook.name
+
+@description('The resource ID of the deployed runbook')
+output resourceId string = runbook.id
+
+@description('The resource group of the deployed runbook')
+output resourceGroupName string = resourceGroup().name
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/runbooks/readme.md b/carml/1.0.0/Microsoft.Automation/automationAccounts/runbooks/readme.md
new file mode 100644
index 000000000..ef083883f
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/runbooks/readme.md
@@ -0,0 +1,55 @@
+# Automation Account Runbooks `[Microsoft.Automation/automationAccounts/runbooks]`
+
+This module deploys an Azure Automation Account Runbook.
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Automation/automationAccounts/runbooks` | 2019-06-01 |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `automationAccountName` | string | | | Required. Name of the parent Automation Account. |
+| `baseTime` | string | `[utcNow('u')]` | | Optional. Time used as a basis for e.g. the schedule start date. |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered. |
+| `location` | string | `[resourceGroup().location]` | | Optional. Location for all resources. |
+| `name` | string | | | Required. Name of the Automation Account runbook. |
+| `runbookDescription` | string | | | Optional. The description of the runbook. |
+| `runbookType` | string | | `[Graph, GraphPowerShell, GraphPowerShellWorkflow, PowerShell, PowerShellWorkflow]` | Required. The type of the runbook. |
+| `sasTokenValidityLength` | string | `PT8H` | | Optional. SAS token validity length. Usage: 'PT8H' - valid for 8 hours; 'P5D' - valid for 5 days; 'P1Y' - valid for 1 year. When not provided, the SAS token will be valid for 8 hours. |
+| `scriptStorageAccountId` | string | | | Optional. ID of the runbook storage account. |
+| `tags` | object | `{object}` | | Optional. Tags of the Automation Account resource. |
+| `uri` | string | | | Optional. The uri of the runbook content. |
+| `version` | string | | | Optional. The version of the runbook content. |
+
+### 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"
+ }
+}
+```
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The name of the deployed runbook |
+| `resourceGroupName` | string | The resource group of the deployed runbook |
+| `resourceId` | string | The resource ID of the deployed runbook |
+
+## Template references
+
+- [Automationaccounts/Runbooks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Automation/2019-06-01/automationAccounts/runbooks)
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/runbooks/version.json b/carml/1.0.0/Microsoft.Automation/automationAccounts/runbooks/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/runbooks/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/schedules/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.Automation/automationAccounts/schedules/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/schedules/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/schedules/deploy.bicep b/carml/1.0.0/Microsoft.Automation/automationAccounts/schedules/deploy.bicep
new file mode 100644
index 000000000..ded932f9b
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/schedules/deploy.bicep
@@ -0,0 +1,77 @@
+@description('Required. Name of the Automation Account schedule.')
+param name string
+
+@description('Required. Name of the parent Automation Account.')
+param automationAccountName string
+
+@description('Optional. The properties of the create Advanced Schedule.')
+@metadata({
+ monthDays: 'Days of the month that the job should execute on. Must be between 1 and 31.'
+ monthlyOccurrences: 'Occurrences of days within a month.'
+ weekDays: 'Days of the week that the job should execute on.'
+})
+param advancedSchedule object = {}
+
+@description('Optional. The description of the schedule.')
+param scheduleDescription string = ''
+
+@description('Optional. The end time of the schedule.')
+param expiryTime string = ''
+
+@allowed([
+ 'Day'
+ 'Hour'
+ 'Minute'
+ 'Month'
+ 'OneTime'
+ 'Week'
+])
+@description('Optional. The frequency of the schedule.')
+param frequency string = 'OneTime'
+
+@description('Optional. Anything')
+param interval int = 0
+
+@description('Optional. The start time of the schedule.')
+param startTime string = ''
+
+@description('Optional. The time zone of the schedule.')
+param timeZone string = ''
+
+@description('Optional. Time used as a basis for e.g. the schedule start date.')
+param baseTime string = utcNow('u')
+
+@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 automationAccount 'Microsoft.Automation/automationAccounts@2020-01-13-preview' existing = {
+ name: automationAccountName
+}
+
+resource schedule 'Microsoft.Automation/automationAccounts/schedules@2020-01-13-preview' = {
+ name: name
+ parent: automationAccount
+ properties: {
+ advancedSchedule: !empty(advancedSchedule) ? advancedSchedule : null
+ description: !empty(scheduleDescription) ? scheduleDescription : null
+ expiryTime: !empty(expiryTime) ? expiryTime : null
+ frequency: !empty(frequency) ? frequency : 'OneTime'
+ interval: (interval != 0) ? interval : null
+ startTime: !empty(startTime) ? startTime : dateTimeAdd(baseTime, 'PT10M')
+ timeZone: !empty(timeZone) ? timeZone : null
+ }
+}
+
+@description('The name of the deployed schedule')
+output name string = schedule.name
+
+@description('The resource ID of the deployed schedule')
+output resourceId string = schedule.id
+
+@description('The resource group of the deployed schedule')
+output resourceGroupName string = resourceGroup().name
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/schedules/readme.md b/carml/1.0.0/Microsoft.Automation/automationAccounts/schedules/readme.md
new file mode 100644
index 000000000..623e5c3f8
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/schedules/readme.md
@@ -0,0 +1,37 @@
+# Automation Account Schedules `[Microsoft.Automation/automationAccounts/schedules]`
+
+This module deploys an Azure Automation Account Schedule.
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Automation/automationAccounts/schedules` | 2020-01-13-preview |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `advancedSchedule` | object | `{object}` | | Optional. The properties of the create Advanced Schedule. |
+| `automationAccountName` | string | | | Required. Name of the parent Automation Account. |
+| `baseTime` | string | `[utcNow('u')]` | | Optional. Time used as a basis for e.g. the schedule start date. |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered. |
+| `expiryTime` | string | | | Optional. The end time of the schedule. |
+| `frequency` | string | `OneTime` | `[Day, Hour, Minute, Month, OneTime, Week]` | Optional. The frequency of the schedule. |
+| `interval` | int | | | Optional. Anything |
+| `name` | string | | | Required. Name of the Automation Account schedule. |
+| `scheduleDescription` | string | | | Optional. The description of the schedule. |
+| `startTime` | string | | | Optional. The start time of the schedule. |
+| `timeZone` | string | | | Optional. The time zone of the schedule. |
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The name of the deployed schedule |
+| `resourceGroupName` | string | The resource group of the deployed schedule |
+| `resourceId` | string | The resource ID of the deployed schedule |
+
+## Template references
+
+- [Automationaccounts/Schedules](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Automation/2020-01-13-preview/automationAccounts/schedules)
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/schedules/version.json b/carml/1.0.0/Microsoft.Automation/automationAccounts/schedules/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/schedules/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/softwareUpdateConfigurations/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.Automation/automationAccounts/softwareUpdateConfigurations/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/softwareUpdateConfigurations/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/softwareUpdateConfigurations/deploy.bicep b/carml/1.0.0/Microsoft.Automation/automationAccounts/softwareUpdateConfigurations/deploy.bicep
new file mode 100644
index 000000000..447aac7b6
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/softwareUpdateConfigurations/deploy.bicep
@@ -0,0 +1,266 @@
+@description('Required. The name of the Deployment schedule.')
+param name string
+
+@description('Required. Name of the parent Automation Account')
+param automationAccountName string
+
+@description('Required. The operating system to be configured by the deployment schedule.')
+@allowed([
+ 'Windows'
+ 'Linux'
+])
+param operatingSystem string
+
+@description('Required. Reboot setting for the deployment schedule.')
+@allowed([
+ 'IfRequired'
+ 'Never'
+ 'RebootOnly'
+ 'Always'
+])
+param rebootSetting string
+
+@description('Required. The frequency of the deployment schedule. When using \'Hour\', \'Day\', \'Week\' or \'Month\', an interval needs to be provided.')
+@allowed([
+ 'OneTime'
+ 'Hour'
+ 'Day'
+ 'Week'
+ 'Month'
+])
+param frequency string
+
+@description('Optional. Maximum time allowed for the deployment schedule to run. Duration needs to be specified using the format PT[n]H[n]M[n]S as per ISO8601')
+param maintenanceWindow string = 'PT2H'
+
+@description('Optional. Update classification included in the deployment schedule.')
+@allowed([
+ 'Critical'
+ 'Security'
+ 'UpdateRollup'
+ 'FeaturePack'
+ 'ServicePack'
+ 'Definition'
+ 'Tools'
+ 'Updates'
+ 'Other'
+])
+param updateClassifications array = [
+ 'Critical'
+ 'Security'
+]
+
+@description('Optional. KB numbers or Linux packages excluded in the deployment schedule.')
+param excludeUpdates array = []
+
+@description('Optional. KB numbers or Linux packages included in the deployment schedule.')
+param includeUpdates array = []
+
+@description('Optional. Specify the resources to scope the deployment schedule to.')
+param scopeByResources array = [
+ subscription().id
+]
+
+@description('Optional. Specify tags to which to scope the deployment schedule to.')
+param scopeByTags object = {}
+
+@description('Optional. Enables the scopeByTags to require All (Tag A and Tag B) or Any (Tag A or Tag B).')
+@allowed([
+ 'All'
+ 'Any'
+])
+param scopeByTagsOperation string = 'All'
+
+@description('Optional. Specify locations to which to scope the deployment schedule to.')
+param scopeByLocations array = []
+
+@description('Optional. Parameters provided to the task running before the deployment schedule.')
+param preTaskParameters object = {}
+
+@description('Optional. The source of the task running before the deployment schedule.')
+param preTaskSource string = ''
+
+@description('Optional. Parameters provided to the task running after the deployment schedule.')
+param postTaskParameters object = {}
+
+@description('Optional. The source of the task running after the deployment schedule.')
+param postTaskSource string = ''
+
+@description('Optional. The interval of the frequency for the deployment schedule. 1 Hour is every hour, 2 Day is every second day, etc.')
+@maxValue(100)
+param interval int = 1
+
+@description('Optional. Enables the deployment schedule.')
+param isEnabled bool = true
+
+@description('Optional. Time zone for the deployment schedule. IANA ID or a Windows Time Zone ID.')
+param timeZone string = 'UTC'
+
+@description('Optional. Array of functions from a Log Analytics workspace, used to scope the deployment schedule.')
+param nonAzureQueries array = []
+
+@description('Optional. List of azure resource IDs for azure virtual machines in scope for the deployment schedule.')
+param azureVirtualMachines array = []
+
+@description('Optional. List of names of non-azure machines in scope for the deployment schedule.')
+param nonAzureComputerNames array = []
+
+@description('Optional. Required when used with frequency \'Week\'. Specified the day of the week to run the deployment schedule.')
+@allowed([
+ 'Monday'
+ 'Tuesday'
+ 'Wednesday'
+ 'Thursday'
+ 'Friday'
+ 'Saturday'
+ 'Sunday'
+])
+param weekDays array = []
+
+@description('Optional. Can be used with frequency \'Month\'. Provides the specific days of the month to run the deployment schedule.')
+@allowed([
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+])
+param monthDays array = []
+
+@description('Optional. Can be used with frequency \'Month\'. Provides the pattern/cadence for running the deployment schedule in a month. Takes objects formed like this {occurance(int),day(string)}. Day is the name of the day to run the deployment schedule, the occurance specifies which occurance of that day to run the deployment schedule.')
+param monthlyOccurrences array = []
+
+@description('Optional. The start time of the deployment schedule in ISO 8601 format. To specify a specific time use YYYY-MM-DDTHH:MM:SS, 2021-12-31T23:00:00. For schedules where we want to start the deployment as soon as possible, specify the time segment only in 24 hour format, HH:MM, 22:00.')
+param startTime string = ''
+
+@description('Optional. The end time of the deployment schedule in ISO 8601 format. YYYY-MM-DDTHH:MM:SS, 2021-12-31T23:00:00')
+param expiryTime string = ''
+
+@description('Optional. The expiry time\'s offset in minutes.')
+param expiryTimeOffsetMinutes int = 0
+
+@description('Optional. The next time the deployment schedule runs in ISO 8601 format. YYYY-MM-DDTHH:MM:SS, 2021-12-31T23:00:00')
+param nextRun string = ''
+
+@description('Optional. The next run\'s offset in minutes.')
+param nextRunOffsetMinutes int = 0
+
+@description('Optional. The schedules description.')
+param scheduleDescription string = ''
+
+@description('Generated. Do not touch. Is used to provide the base time for time comparison for startTime. If startTime is specified in HH:MM format, baseTime is used to check if the provided startTime has passed, adding one day before setting the deployment schedule.')
+param baseTime string = utcNow('u')
+
+@description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered')
+param cuaId string = ''
+
+var updateClassifications_var = '${replace(replace(replace(replace(string(updateClassifications), ',', ', '), '[', ''), ']', ''), '"', '')}'
+
+module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) {
+ name: 'pid-${cuaId}'
+ params: {}
+}
+
+resource automationAccount 'Microsoft.Automation/automationAccounts@2020-01-13-preview' existing = {
+ name: automationAccountName
+}
+
+resource softwareUpdateConfiguration 'Microsoft.Automation/automationAccounts/softwareUpdateConfigurations@2019-06-01' = {
+ name: name
+ parent: automationAccount
+ properties: {
+ updateConfiguration: {
+ operatingSystem: operatingSystem
+ duration: maintenanceWindow
+ linux: ((operatingSystem == 'Linux') ? {
+ excludedPackageNameMasks: excludeUpdates
+ includedPackageNameMasks: includeUpdates
+ includedPackageClassifications: updateClassifications_var
+ rebootSetting: rebootSetting
+ } : null)
+ windows: ((operatingSystem == 'Windows') ? {
+ excludedKbNumbers: excludeUpdates
+ includedKbNumbers: includeUpdates
+ includedUpdateClassifications: updateClassifications_var
+ rebootSetting: rebootSetting
+ } : null)
+ targets: {
+ azureQueries: [
+ {
+ scope: scopeByResources
+ tagSettings: {
+ tags: scopeByTags
+ filterOperator: scopeByTagsOperation
+ }
+ locations: scopeByLocations
+ }
+ ]
+ nonAzureQueries: nonAzureQueries
+ }
+ azureVirtualMachines: azureVirtualMachines
+ nonAzureComputerNames: nonAzureComputerNames
+ }
+ tasks: {
+ preTask: {
+ parameters: (empty(preTaskParameters) ? null : preTaskParameters)
+ source: (empty(preTaskSource) ? null : preTaskSource)
+ }
+ postTask: {
+ parameters: (empty(postTaskParameters) ? null : postTaskParameters)
+ source: (empty(postTaskSource) ? null : postTaskSource)
+ }
+ }
+ scheduleInfo: {
+ interval: interval
+ frequency: frequency
+ isEnabled: isEnabled
+ timeZone: timeZone
+ advancedSchedule: {
+ weekDays: (empty(weekDays) ? null : weekDays)
+ monthDays: (empty(monthDays) ? null : monthDays)
+ monthlyOccurrences: (empty(monthlyOccurrences) ? null : monthlyOccurrences)
+ }
+ startTime: (empty(startTime) ? dateTimeAdd(baseTime, 'PT10M') : startTime)
+ expiryTime: expiryTime
+ expiryTimeOffsetMinutes: expiryTimeOffsetMinutes
+ nextRun: nextRun
+ nextRunOffsetMinutes: nextRunOffsetMinutes
+ description: scheduleDescription
+ }
+ }
+}
+
+@description('The name of the deployed softwareUpdateConfiguration')
+output name string = softwareUpdateConfiguration.name
+
+@description('The resource ID of the deployed softwareUpdateConfiguration')
+output resourceId string = softwareUpdateConfiguration.id
+
+@description('The resource group of the deployed softwareUpdateConfiguration')
+output resourceGroupName string = resourceGroup().name
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/softwareUpdateConfigurations/readme.md b/carml/1.0.0/Microsoft.Automation/automationAccounts/softwareUpdateConfigurations/readme.md
new file mode 100644
index 000000000..7476b7a8a
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/softwareUpdateConfigurations/readme.md
@@ -0,0 +1,105 @@
+# Automation Account Software Update Configurations `[Microsoft.Automation/automationAccounts/softwareUpdateConfigurations]`
+
+This module deploys an Azure Automation Account Software update Configuration.
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Automation/automationAccounts/softwareUpdateConfigurations` | 2019-06-01 |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `automationAccountName` | string | | | Required. Name of the parent Automation Account |
+| `azureVirtualMachines` | array | `[]` | | Optional. List of azure resource IDs for azure virtual machines in scope for the deployment schedule. |
+| `baseTime` | string | `[utcNow('u')]` | | Generated. Do not touch. Is used to provide the base time for time comparison for startTime. If startTime is specified in HH:MM format, baseTime is used to check if the provided startTime has passed, adding one day before setting the deployment schedule. |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered |
+| `excludeUpdates` | array | `[]` | | Optional. KB numbers or Linux packages excluded in the deployment schedule. |
+| `expiryTime` | string | | | Optional. The end time of the deployment schedule in ISO 8601 format. YYYY-MM-DDTHH:MM:SS, 2021-12-31T23:00:00 |
+| `expiryTimeOffsetMinutes` | int | | | Optional. The expiry time's offset in minutes. |
+| `frequency` | string | | `[OneTime, Hour, Day, Week, Month]` | Required. The frequency of the deployment schedule. When using 'Hour', 'Day', 'Week' or 'Month', an interval needs to be provided. |
+| `includeUpdates` | array | `[]` | | Optional. KB numbers or Linux packages included in the deployment schedule. |
+| `interval` | int | `1` | | Optional. The interval of the frequency for the deployment schedule. 1 Hour is every hour, 2 Day is every second day, etc. |
+| `isEnabled` | bool | `True` | | Optional. Enables the deployment schedule. |
+| `maintenanceWindow` | string | `PT2H` | | Optional. Maximum time allowed for the deployment schedule to run. Duration needs to be specified using the format PT[n]H[n]M[n]S as per ISO8601 |
+| `monthDays` | array | `[]` | `[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]` | Optional. Can be used with frequency 'Month'. Provides the specific days of the month to run the deployment schedule. |
+| `monthlyOccurrences` | array | `[]` | | Optional. Can be used with frequency 'Month'. Provides the pattern/cadence for running the deployment schedule in a month. Takes objects formed like this {occurance(int),day(string)}. Day is the name of the day to run the deployment schedule, the occurance specifies which occurance of that day to run the deployment schedule. |
+| `name` | string | | | Required. The name of the Deployment schedule. |
+| `nextRun` | string | | | Optional. The next time the deployment schedule runs in ISO 8601 format. YYYY-MM-DDTHH:MM:SS, 2021-12-31T23:00:00 |
+| `nextRunOffsetMinutes` | int | | | Optional. The next run's offset in minutes. |
+| `nonAzureComputerNames` | array | `[]` | | Optional. List of names of non-azure machines in scope for the deployment schedule. |
+| `nonAzureQueries` | array | `[]` | | Optional. Array of functions from a Log Analytics workspace, used to scope the deployment schedule. |
+| `operatingSystem` | string | | `[Windows, Linux]` | Required. The operating system to be configured by the deployment schedule. |
+| `postTaskParameters` | object | `{object}` | | Optional. Parameters provided to the task running after the deployment schedule. |
+| `postTaskSource` | string | | | Optional. The source of the task running after the deployment schedule. |
+| `preTaskParameters` | object | `{object}` | | Optional. Parameters provided to the task running before the deployment schedule. |
+| `preTaskSource` | string | | | Optional. The source of the task running before the deployment schedule. |
+| `rebootSetting` | string | | `[IfRequired, Never, RebootOnly, Always]` | Required. Reboot setting for the deployment schedule. |
+| `scheduleDescription` | string | | | Optional. The schedules description. |
+| `scopeByLocations` | array | `[]` | | Optional. Specify locations to which to scope the deployment schedule to. |
+| `scopeByResources` | array | `[[subscription().id]]` | | Optional. Specify the resources to scope the deployment schedule to. |
+| `scopeByTags` | object | `{object}` | | Optional. Specify tags to which to scope the deployment schedule to. |
+| `scopeByTagsOperation` | string | `All` | `[All, Any]` | Optional. Enables the scopeByTags to require All (Tag A and Tag B) or Any (Tag A or Tag B). |
+| `startTime` | string | | | Optional. The start time of the deployment schedule in ISO 8601 format. To specify a specific time use YYYY-MM-DDTHH:MM:SS, 2021-12-31T23:00:00. For schedules where we want to start the deployment as soon as possible, specify the time segment only in 24 hour format, HH:MM, 22:00. |
+| `timeZone` | string | `UTC` | | Optional. Time zone for the deployment schedule. IANA ID or a Windows Time Zone ID. |
+| `updateClassifications` | array | `[Critical, Security]` | `[Critical, Security, UpdateRollup, FeaturePack, ServicePack, Definition, Tools, Updates, Other]` | Optional. Update classification included in the deployment schedule. |
+| `weekDays` | array | `[]` | `[Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday]` | Optional. Required when used with frequency 'Week'. Specified the day of the week to run the deployment schedule. |
+
+### Parameter Usage: `scopeByTags`
+
+Provide tag keys, with an array of values, filtering in machines that should be included in the deployment schedule.
+
+| Property name | Type | Possible values | Description |
+| :------------ | :---- | :-------------- | :---------- |
+| \ | array | string | tag values |
+
+```json
+"scopeByTags": {
+ "value": {
+ "Update": [
+ "Automatic"
+ ],
+ "MaintenanceWindow": [
+ "1-Sat-22"
+ ]
+ }
+}
+```
+
+### Parameter Usage: `monthlyOccurrences`
+
+Occurrences of days within a month.
+
+| Property name | Type | Possible values | Description |
+| :------------ | :----- | :------------------------------------------------------------- | :----------------------------------------------------------------------------------- |
+| `occurance` | int | 1-5 | Occurrence of the week within the month. Must be between 1 and 5, where 5 is "last". |
+| `day` | string | Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday | Day of the occurrence. |
+
+```json
+"monthlyOccurrences": {
+ "value": [
+ {
+ "occurrence": 1,
+ "day": "Monday"
+ },
+ {
+ "occurrence": 2,
+ "day": "Friday"
+ }
+ ]
+}
+```
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The name of the deployed softwareUpdateConfiguration |
+| `resourceGroupName` | string | The resource group of the deployed softwareUpdateConfiguration |
+| `resourceId` | string | The resource ID of the deployed softwareUpdateConfiguration |
+
+## Template references
+
+- [Automationaccounts/Softwareupdateconfigurations](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Automation/2019-06-01/automationAccounts/softwareUpdateConfigurations)
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/softwareUpdateConfigurations/version.json b/carml/1.0.0/Microsoft.Automation/automationAccounts/softwareUpdateConfigurations/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/softwareUpdateConfigurations/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/variables/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.Automation/automationAccounts/variables/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/variables/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/variables/deploy.bicep b/carml/1.0.0/Microsoft.Automation/automationAccounts/variables/deploy.bicep
new file mode 100644
index 000000000..6473a994f
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/variables/deploy.bicep
@@ -0,0 +1,45 @@
+@sys.description('Required. Name of the parent Automation Account')
+param automationAccountName string
+
+@sys.description('Required. The name of the variable.')
+param name string
+
+@sys.description('Required. The value of the variable.')
+param value string
+
+@sys.description('Optional. The description of the variable.')
+param description string = ''
+
+@sys.description('Optional. If the variable should be encrypted.')
+param isEncrypted bool = false
+
+@sys.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 automationAccount 'Microsoft.Automation/automationAccounts@2021-06-22' existing = {
+ name: automationAccountName
+}
+
+resource variable 'Microsoft.Automation/automationAccounts/variables@2020-01-13-preview' = {
+ name: name
+ parent: automationAccount
+ properties: {
+ description: description
+ isEncrypted: isEncrypted
+ value: value
+ }
+}
+
+@sys.description('The name of the deployed variable')
+output name string = variable.name
+
+@sys.description('The resource ID of the deployed variable')
+output resourceId string = variable.id
+
+@sys.description('The resource group of the deployed variable')
+output resourceGroupName string = resourceGroup().name
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/variables/readme.md b/carml/1.0.0/Microsoft.Automation/automationAccounts/variables/readme.md
new file mode 100644
index 000000000..3ebee7601
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/variables/readme.md
@@ -0,0 +1,56 @@
+# Automation Account Variables `[Microsoft.Automation/automationAccounts/variables]`
+
+This module deploys a variable to an Azure Automation Account.
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Automation/automationAccounts/variables` | 2020-01-13-preview |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `automationAccountName` | string | | | Required. Name of the parent Automation Account |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered |
+| `description` | string | | | Optional. The description of the variable. |
+| `isEncrypted` | bool | | | Optional. If the variable should be encrypted. |
+| `name` | string | | | Required. The name of the variable. |
+| `value` | string | | | Required. The value of the variable. |
+
+### Parameter Usage: `value`
+
+```json
+ //Boolean format
+ "value": {
+ "value": "false"
+ }
+
+ //DateTime format
+ "value": {
+ "value": "\"\\/Date(1637934042656)\\/\""
+ }
+
+ //Integer format
+ "value": {
+ "value": "500"
+ }
+
+ //String format
+ "value": {
+ "value": "\"TestString\""
+ }
+```
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The name of the deployed variable |
+| `resourceGroupName` | string | The resource group of the deployed variable |
+| `resourceId` | string | The resource ID of the deployed variable |
+
+## Template references
+
+- [Automationaccounts/Variables](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Automation/2020-01-13-preview/automationAccounts/variables)
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/variables/version.json b/carml/1.0.0/Microsoft.Automation/automationAccounts/variables/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/variables/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Automation/automationAccounts/version.json b/carml/1.0.0/Microsoft.Automation/automationAccounts/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Automation/automationAccounts/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Batch/batchAccounts/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.Batch/batchAccounts/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Batch/batchAccounts/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.Batch/batchAccounts/.parameters/parameters.json b/carml/1.0.0/Microsoft.Batch/batchAccounts/.parameters/parameters.json
new file mode 100644
index 000000000..340396fc9
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Batch/batchAccounts/.parameters/parameters.json
@@ -0,0 +1,24 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>azbaweux001"
+ },
+ "diagnosticLogsRetentionInDays": {
+ "value": 7
+ },
+ "diagnosticStorageAccountId": {
+ "value": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Storage/storageAccounts/adp<>azsax001"
+ },
+ "diagnosticWorkspaceId": {
+ "value": "/subscriptions/<>/resourcegroups/validation-rg/providers/microsoft.operationalinsights/workspaces/adp-<>-az-law-x-001"
+ },
+ "diagnosticEventHubAuthorizationRuleId": {
+ "value": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.EventHub/namespaces/adp-<>-az-evhns-x-001/AuthorizationRules/RootManageSharedAccessKey"
+ },
+ "diagnosticEventHubName": {
+ "value": "adp-<>-az-evh-x-001"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Batch/batchAccounts/deploy.bicep b/carml/1.0.0/Microsoft.Batch/batchAccounts/deploy.bicep
new file mode 100644
index 000000000..56f965ed4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Batch/batchAccounts/deploy.bicep
@@ -0,0 +1,114 @@
+@description('Required. Name of the Azure Batch')
+param name string
+
+@description('Optional. Location for all Resources.')
+param location string = resourceGroup().location
+
+@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 the diagnostic log analytics workspace.')
+param diagnosticWorkspaceId string = ''
+
+@description('Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to.')
+param diagnosticEventHubAuthorizationRuleId string = ''
+
+@description('Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category.')
+param diagnosticEventHubName string = ''
+
+@allowed([
+ 'CanNotDelete'
+ 'NotSpecified'
+ 'ReadOnly'
+])
+@description('Optional. Specify the type of lock.')
+param lock string = 'NotSpecified'
+
+@description('Optional. Tags of the resource.')
+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([
+ 'ServiceLog'
+])
+param logsToEnable array = [
+ 'ServiceLog'
+]
+
+@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
+ }
+}]
+
+module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) {
+ name: 'pid-${cuaId}'
+ params: {}
+}
+
+resource batchAccount 'Microsoft.Batch/batchAccounts@2020-09-01' = {
+ name: name
+ location: location
+ tags: tags
+ properties: {}
+}
+
+resource batchAccount_lock 'Microsoft.Authorization/locks@2017-04-01' = if (lock != 'NotSpecified') {
+ name: '${batchAccount.name}-${lock}-lock'
+ properties: {
+ level: lock
+ notes: (lock == 'CanNotDelete') ? 'Cannot delete resource or child resources.' : 'Cannot modify the resource or child resources.'
+ }
+ scope: batchAccount
+}
+
+resource batchAccount_diagnosticSettings 'Microsoft.Insights/diagnosticsettings@2021-05-01-preview' = if ((!empty(diagnosticStorageAccountId)) || (!empty(diagnosticWorkspaceId)) || (!empty(diagnosticEventHubAuthorizationRuleId)) || (!empty(diagnosticEventHubName))) {
+ name: '${batchAccount.name}-diagnosticSettings'
+ properties: {
+ storageAccountId: !empty(diagnosticStorageAccountId) ? diagnosticStorageAccountId : null
+ workspaceId: !empty(diagnosticWorkspaceId) ? diagnosticWorkspaceId : null
+ eventHubAuthorizationRuleId: !empty(diagnosticEventHubAuthorizationRuleId) ? diagnosticEventHubAuthorizationRuleId : null
+ eventHubName: !empty(diagnosticEventHubName) ? diagnosticEventHubName : null
+ metrics: diagnosticsMetrics
+ logs: diagnosticsLogs
+ }
+ scope: batchAccount
+}
+
+@description('The name of the batch account')
+output name string = batchAccount.name
+
+@description('The resource ID of the batch account')
+output resourceId string = batchAccount.id
+
+@description('The resource group the batch account was deployed into')
+output resourceGroupName string = resourceGroup().name
diff --git a/carml/1.0.0/Microsoft.Batch/batchAccounts/readme.md b/carml/1.0.0/Microsoft.Batch/batchAccounts/readme.md
new file mode 100644
index 000000000..ae2cce7e1
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Batch/batchAccounts/readme.md
@@ -0,0 +1,57 @@
+# Batch Accounts `[Microsoft.Batch/batchAccounts]`
+
+## Resource types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/locks` | 2017-04-01 |
+| `Microsoft.Batch/batchAccounts` | 2020-09-01 |
+| `Microsoft.Insights/diagnosticSettings` | 2021-05-01-preview |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered |
+| `diagnosticEventHubAuthorizationRuleId` | string | | | Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. |
+| `diagnosticEventHubName` | string | | | Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. |
+| `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. |
+| `diagnosticWorkspaceId` | string | | | Optional. Resource ID of the diagnostic log analytics workspace. |
+| `location` | string | `[resourceGroup().location]` | | Optional. Location for all Resources. |
+| `lock` | string | `NotSpecified` | `[CanNotDelete, NotSpecified, ReadOnly]` | Optional. Specify the type of lock. |
+| `logsToEnable` | array | `[ServiceLog]` | `[ServiceLog]` | 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 Azure Batch |
+| `tags` | object | `{object}` | | Optional. Tags of the resource. |
+
+### 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"
+ }
+}
+```
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The name of the batch account |
+| `resourceGroupName` | string | The resource group the batch account was deployed into |
+| `resourceId` | string | The resource ID of the batch account |
+
+## Template references
+
+- [Batchaccounts](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Batch/2020-09-01/batchAccounts)
+- [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/2017-04-01/locks)
diff --git a/carml/1.0.0/Microsoft.Batch/batchAccounts/version.json b/carml/1.0.0/Microsoft.Batch/batchAccounts/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Batch/batchAccounts/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.CognitiveServices/accounts/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.CognitiveServices/accounts/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.CognitiveServices/accounts/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.CognitiveServices/accounts/.bicep/nested_privateEndpoints.bicep b/carml/1.0.0/Microsoft.CognitiveServices/accounts/.bicep/nested_privateEndpoints.bicep
new file mode 100644
index 000000000..4e7cd75dc
--- /dev/null
+++ b/carml/1.0.0/Microsoft.CognitiveServices/accounts/.bicep/nested_privateEndpoints.bicep
@@ -0,0 +1,49 @@
+param privateEndpointResourceId string
+param privateEndpointVnetLocation string
+param privateEndpoint object
+param tags object
+
+var privateEndpointResourceName = last(split(privateEndpointResourceId, '/'))
+var privateEndpoint_var = {
+ name: (contains(privateEndpoint, 'name') ? (empty(privateEndpoint.name) ? '${privateEndpointResourceName}-${privateEndpoint.service}' : privateEndpoint.name) : '${privateEndpointResourceName}-${privateEndpoint.service}')
+ subnetResourceId: privateEndpoint.subnetResourceId
+ service: [
+ privateEndpoint.service
+ ]
+ privateDnsZoneResourceIds: (contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [])
+ customDnsConfigs: (contains(privateEndpoint, 'customDnsConfigs') ? (empty(privateEndpoint.customDnsConfigs) ? null : privateEndpoint.customDnsConfigs) : null)
+}
+
+resource privateEndpoint_resource 'Microsoft.Network/privateEndpoints@2021-05-01' = {
+ name: privateEndpoint_var.name
+ location: privateEndpointVnetLocation
+ tags: tags
+ properties: {
+ privateLinkServiceConnections: [
+ {
+ name: privateEndpoint_var.name
+ properties: {
+ privateLinkServiceId: privateEndpointResourceId
+ groupIds: privateEndpoint_var.service
+ }
+ }
+ ]
+ manualPrivateLinkServiceConnections: []
+ subnet: {
+ id: privateEndpoint_var.subnetResourceId
+ }
+ customDnsConfigs: privateEndpoint_var.customDnsConfigs
+ }
+}
+
+resource privateDnsZoneGroup 'Microsoft.Network/privateEndpoints/privateDnsZoneGroups@2021-02-01' = if (!empty(privateEndpoint_var.privateDnsZoneResourceIds)) {
+ name: '${privateEndpoint_resource.name}/default'
+ properties: {
+ privateDnsZoneConfigs: [for privateDnsZoneResourceId in privateEndpoint_var.privateDnsZoneResourceIds: {
+ name: last(split(privateDnsZoneResourceId, '/'))
+ properties: {
+ privateDnsZoneId: privateDnsZoneResourceId
+ }
+ }]
+ }
+}
diff --git a/carml/1.0.0/Microsoft.CognitiveServices/accounts/.bicep/nested_rbac.bicep b/carml/1.0.0/Microsoft.CognitiveServices/accounts/.bicep/nested_rbac.bicep
new file mode 100644
index 000000000..fa64b26cb
--- /dev/null
+++ b/carml/1.0.0/Microsoft.CognitiveServices/accounts/.bicep/nested_rbac.bicep
@@ -0,0 +1,49 @@
+param principalIds array
+param roleDefinitionIdOrName string
+param resourceId string
+
+var builtInRoleNames = {
+ 'Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')
+ 'Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')
+ 'Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')
+ 'Azure Service Deploy Release Management Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '21d96096-b162-414a-8302-d8354f9d91b2')
+ 'Cognitive Services Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '25fbc0a9-bd7c-42a3-aa1a-3b75d497ee68')
+ 'Cognitive Services Custom Vision Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c1ff6cc2-c111-46fe-8896-e0ef812ad9f3')
+ 'Cognitive Services Custom Vision Deployment': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5c4089e1-6d96-4d2f-b296-c1bc7137275f')
+ 'Cognitive Services Custom Vision Labeler': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '88424f51-ebe7-446f-bc41-7fa16989e96c')
+ 'Cognitive Services Custom Vision Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '93586559-c37d-4a6b-ba08-b9f0940c2d73')
+ 'Cognitive Services Custom Vision Trainer': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0a5ae4ab-0d65-4eeb-be61-29fc9b54394b')
+ 'Cognitive Services Data Reader (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b59867f0-fa02-499b-be73-45a86b5b3e1c')
+ 'Cognitive Services Face Recognizer': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9894cab4-e18a-44aa-828b-cb588cd6f2d7')
+ 'Cognitive Services Metrics Advisor Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'cb43c632-a144-4ec5-977c-e80c4affc34a')
+ 'Cognitive Services Metrics Advisor User': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3b20f47b-3825-43cb-8114-4bd2201156a8')
+ 'Cognitive Services QnA Maker Editor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f4cc2bf9-21be-47a1-bdf1-5c5804381025')
+ 'Cognitive Services QnA Maker Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '466ccd10-b268-4a11-b098-b4849f024126')
+ 'Cognitive Services Speech Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0e75ca1e-0464-4b4d-8b93-68208a576181')
+ 'Cognitive Services Speech User': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f2dc8367-1007-4938-bd23-fe263f013447')
+ 'Cognitive Services User': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a97b65f3-24c7-4388-baec-2e87135dc908')
+ 'Log Analytics Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')
+ 'Log Analytics Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')
+ 'Managed Application Contributor Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')
+ 'Managed Application Operator Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')
+ 'Managed Applications Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')
+ 'masterreader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a48d7796-14b4-4889-afef-fbb65a93e5a2')
+ 'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')
+ 'Monitoring Metrics Publisher': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')
+ 'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')
+ 'Resource Policy Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')
+ 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')
+}
+
+resource account 'Microsoft.CognitiveServices/accounts@2017-04-18' existing = {
+ name: last(split(resourceId, '/'))
+}
+
+resource roleAssignment 'Microsoft.Authorization/roleAssignments@2021-04-01-preview' = [for principalId in principalIds: {
+ name: guid(account.name, principalId, roleDefinitionIdOrName)
+ properties: {
+ roleDefinitionId: contains(builtInRoleNames, roleDefinitionIdOrName) ? builtInRoleNames[roleDefinitionIdOrName] : roleDefinitionIdOrName
+ principalId: principalId
+ }
+ scope: account
+}]
diff --git a/carml/1.0.0/Microsoft.CognitiveServices/accounts/.parameters/parameters.json b/carml/1.0.0/Microsoft.CognitiveServices/accounts/.parameters/parameters.json
new file mode 100644
index 000000000..bc8e4e4d6
--- /dev/null
+++ b/carml/1.0.0/Microsoft.CognitiveServices/accounts/.parameters/parameters.json
@@ -0,0 +1,51 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-az-cgs-x-001"
+ },
+ "kind": {
+ "value": "Face"
+ },
+ "sku": {
+ "value": "F0"
+ },
+ "cuaId": {
+ "value": "00000000-0000-0000-0000-000000000000"
+ },
+ "roleAssignments": {
+ "value": [
+ {
+ "roleDefinitionIdOrName": "Reader",
+ "principalIds": [
+ "<>"
+ ]
+ }
+ ]
+ },
+ "systemAssignedIdentity": {
+ "value": true
+ },
+ "userAssignedIdentities": {
+ "value": {
+ "/subscriptions/<>/resourcegroups/validation-rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/adp-<>-az-msi-x-001": {}
+ }
+ },
+ "diagnosticLogsRetentionInDays": {
+ "value": 7
+ },
+ "diagnosticStorageAccountId": {
+ "value": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Storage/storageAccounts/adp<>azsax001"
+ },
+ "diagnosticWorkspaceId": {
+ "value": "/subscriptions/<>/resourcegroups/validation-rg/providers/microsoft.operationalinsights/workspaces/adp-<>-az-law-x-001"
+ },
+ "diagnosticEventHubAuthorizationRuleId": {
+ "value": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.EventHub/namespaces/adp-<>-az-evhns-x-001/AuthorizationRules/RootManageSharedAccessKey"
+ },
+ "diagnosticEventHubName": {
+ "value": "adp-<>-az-evh-x-001"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.CognitiveServices/accounts/deploy.bicep b/carml/1.0.0/Microsoft.CognitiveServices/accounts/deploy.bicep
new file mode 100644
index 000000000..41343fb13
--- /dev/null
+++ b/carml/1.0.0/Microsoft.CognitiveServices/accounts/deploy.bicep
@@ -0,0 +1,237 @@
+@description('Required. The name of Cognitive Services account')
+param name string
+
+@description('Required. Kind of the Cognitive Services. Use \'Get-AzCognitiveServicesAccountSku\' to determine a valid combinations of \'kind\' and \'sku\' for your Azure region.')
+@allowed([
+ 'AnomalyDetector'
+ 'Bing.Autosuggest.v7'
+ 'Bing.CustomSearch'
+ 'Bing.EntitySearch'
+ 'Bing.Search.v7'
+ 'Bing.SpellCheck.v7'
+ 'CognitiveServices'
+ 'ComputerVision'
+ 'ContentModerator'
+ 'CustomVision.Prediction'
+ 'CustomVision.Training'
+ 'Face'
+ 'FormRecognizer'
+ 'ImmersiveReader'
+ 'Internal.AllInOne'
+ 'LUIS'
+ 'LUIS.Authoring'
+ 'Personalizer'
+ 'QnAMaker'
+ 'SpeechServices'
+ 'TextAnalytics'
+ 'TextTranslation'
+])
+param kind string
+
+@description('Optional. SKU of the Cognitive Services resource. Use \'Get-AzCognitiveServicesAccountSku\' to determine a valid combinations of \'kind\' and \'sku\' for your Azure region.')
+@allowed([
+ 'C2'
+ 'C3'
+ 'C4'
+ 'F0'
+ 'F1'
+ 'S'
+ 'S0'
+ 'S1'
+ 'S10'
+ 'S2'
+ 'S3'
+ 'S4'
+ 'S5'
+ 'S6'
+ 'S7'
+ 'S8'
+ 'S9'
+])
+param sku string = 'S0'
+
+@description('Optional. Location for all Resources.')
+param location string = resourceGroup().location
+
+@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 the diagnostic log analytics workspace.')
+param diagnosticWorkspaceId string = ''
+
+@description('Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to.')
+param diagnosticEventHubAuthorizationRuleId string = ''
+
+@description('Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category.')
+param diagnosticEventHubName string = ''
+
+@description('Optional. Subdomain name used for token-based authentication. Required if \'networkAcls\' are set.')
+param customSubDomainName string = ''
+
+@description('Optional. Subdomain name used for token-based authentication. Must be set if \'networkAcls\' are set.')
+@allowed([
+ 'Enabled'
+ 'Disabled'
+])
+param publicNetworkAccess string = 'Enabled'
+
+@description('Optional. Service endpoint object information')
+param networkAcls 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 = {}
+
+@allowed([
+ 'CanNotDelete'
+ 'NotSpecified'
+ 'ReadOnly'
+])
+@description('Optional. Specify the type of lock.')
+param lock string = 'NotSpecified'
+
+@description('Optional. Configuration Details for private endpoints.')
+param privateEndpoints array = []
+
+@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 resource.')
+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'
+ 'RequestResponse'
+])
+param logsToEnable array = [
+ 'Audit'
+ 'RequestResponse'
+]
+
+@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 identityType = systemAssignedIdentity ? (!empty(userAssignedIdentities) ? 'SystemAssigned,UserAssigned' : 'SystemAssigned') : (!empty(userAssignedIdentities) ? 'UserAssigned' : 'None')
+
+var identity = identityType != 'None' ? {
+ type: identityType
+ userAssignedIdentities: !empty(userAssignedIdentities) ? userAssignedIdentities : null
+} : null
+
+var networkAcls_var = {
+ defaultAction: ((empty(networkAcls)) ? null : networkAcls.defaultAction)
+ virtualNetworkRules: ((empty(networkAcls)) ? null : ((length(networkAcls.virtualNetworkRules) == 0) ? [] : networkAcls.virtualNetworkRules))
+ ipRules: ((empty(networkAcls)) ? null : ((length(networkAcls.ipRules) == 0) ? [] : networkAcls.ipRules))
+}
+
+module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) {
+ name: 'pid-${cuaId}'
+ params: {}
+}
+
+resource cognitiveServices 'Microsoft.CognitiveServices/accounts@2017-04-18' = {
+ name: name
+ kind: kind
+ identity: identity
+ location: location
+ tags: tags
+ sku: {
+ name: sku
+ }
+ properties: {
+ customSubDomainName: (empty(customSubDomainName) ? null : customSubDomainName)
+ networkAcls: ((empty(networkAcls)) ? null : networkAcls_var)
+ publicNetworkAccess: publicNetworkAccess
+ }
+}
+
+resource cognitiveServices_lock 'Microsoft.Authorization/locks@2017-04-01' = if (lock != 'NotSpecified') {
+ name: '${cognitiveServices.name}-${lock}-lock'
+ properties: {
+ level: lock
+ notes: (lock == 'CanNotDelete') ? 'Cannot delete resource or child resources.' : 'Cannot modify the resource or child resources.'
+ }
+ scope: cognitiveServices
+}
+
+resource cognitiveServices_diagnosticSettingName 'Microsoft.Insights/diagnosticsettings@2021-05-01-preview' = if ((!empty(diagnosticStorageAccountId)) || (!empty(diagnosticWorkspaceId)) || (!empty(diagnosticEventHubAuthorizationRuleId)) || (!empty(diagnosticEventHubName))) {
+ name: '${cognitiveServices.name}-diagnosticSettings'
+ properties: {
+ storageAccountId: !empty(diagnosticStorageAccountId) ? diagnosticStorageAccountId : null
+ workspaceId: !empty(diagnosticWorkspaceId) ? diagnosticWorkspaceId : null
+ eventHubAuthorizationRuleId: !empty(diagnosticEventHubAuthorizationRuleId) ? diagnosticEventHubAuthorizationRuleId : null
+ eventHubName: !empty(diagnosticEventHubName) ? diagnosticEventHubName : null
+ metrics: diagnosticsMetrics
+ logs: diagnosticsLogs
+ }
+ scope: cognitiveServices
+}
+
+module cognitiveServices_privateEndpoints '.bicep/nested_privateEndpoints.bicep' = [for (privateEndpoint, index) in privateEndpoints: {
+ name: '${uniqueString(deployment().name, location)}-CognitiveServices-PrivateEndpoint-${index}'
+ params: {
+ privateEndpointResourceId: cognitiveServices.id
+ privateEndpointVnetLocation: (empty(privateEndpoints) ? 'dummy' : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location)
+ privateEndpoint: privateEndpoint
+ tags: tags
+ }
+}]
+
+module cognitiveServices_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: {
+ name: '${uniqueString(deployment().name, location)}-CognitiveServices-Rbac-${index}'
+ params: {
+ principalIds: roleAssignment.principalIds
+ roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName
+ resourceId: cognitiveServices.id
+ }
+}]
+
+@description('The name of the cognitive services account')
+output name string = cognitiveServices.name
+
+@description('The resource ID of the cognitive services account')
+output resourceId string = cognitiveServices.id
+
+@description('The resource group the cognitive services account was deployed into')
+output resourceGroupName string = resourceGroup().name
+
+@description('The service endpoint of the cognitive services account')
+output endpoint string = cognitiveServices.properties.endpoint
+
+@description('The principal ID of the system assigned identity.')
+output systemAssignedPrincipalId string = systemAssignedIdentity && contains(cognitiveServices.identity, 'principalId') ? cognitiveServices.identity.principalId : ''
diff --git a/carml/1.0.0/Microsoft.CognitiveServices/accounts/readme.md b/carml/1.0.0/Microsoft.CognitiveServices/accounts/readme.md
new file mode 100644
index 000000000..0868c9369
--- /dev/null
+++ b/carml/1.0.0/Microsoft.CognitiveServices/accounts/readme.md
@@ -0,0 +1,208 @@
+# Cognitive Services `[Microsoft.CognitiveServices/accounts]`
+
+This module deploys different kinds of cognitive services resources
+
+## Resource types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/locks` | 2017-04-01 |
+| `Microsoft.Authorization/roleAssignments` | 2021-04-01-preview |
+| `Microsoft.CognitiveServices/accounts` | 2017-04-18 |
+| `Microsoft.Insights/diagnosticSettings` | 2021-05-01-preview |
+| `Microsoft.Network/privateEndpoints` | 2021-05-01 |
+| `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | 2021-02-01 |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered |
+| `customSubDomainName` | string | | | Optional. Subdomain name used for token-based authentication. Required if 'networkAcls' are set. |
+| `diagnosticEventHubAuthorizationRuleId` | string | | | Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. |
+| `diagnosticEventHubName` | string | | | Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. |
+| `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. |
+| `diagnosticWorkspaceId` | string | | | Optional. Resource ID of the diagnostic log analytics workspace. |
+| `kind` | string | | `[AnomalyDetector, Bing.Autosuggest.v7, Bing.CustomSearch, Bing.EntitySearch, Bing.Search.v7, Bing.SpellCheck.v7, CognitiveServices, ComputerVision, ContentModerator, CustomVision.Prediction, CustomVision.Training, Face, FormRecognizer, ImmersiveReader, Internal.AllInOne, LUIS, LUIS.Authoring, Personalizer, QnAMaker, SpeechServices, TextAnalytics, TextTranslation]` | Required. Kind of the Cognitive Services. Use 'Get-AzCognitiveServicesAccountSku' to determine a valid combinations of 'kind' and 'sku' for your Azure region. |
+| `location` | string | `[resourceGroup().location]` | | Optional. Location for all Resources. |
+| `lock` | string | `NotSpecified` | `[CanNotDelete, NotSpecified, ReadOnly]` | Optional. Specify the type of lock. |
+| `logsToEnable` | array | `[Audit, RequestResponse]` | `[Audit, RequestResponse]` | 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 name of Cognitive Services account |
+| `networkAcls` | object | `{object}` | | Optional. Service endpoint object information |
+| `privateEndpoints` | array | `[]` | | Optional. Configuration Details for private endpoints. |
+| `publicNetworkAccess` | string | `Enabled` | `[Enabled, Disabled]` | Optional. Subdomain name used for token-based authentication. Must be set if 'networkAcls' are set. |
+| `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' |
+| `sku` | string | `S0` | `[C2, C3, C4, F0, F1, S, S0, S1, S10, S2, S3, S4, S5, S6, S7, S8, S9]` | Optional. SKU of the Cognitive Services resource. Use 'Get-AzCognitiveServicesAccountSku' to determine a valid combinations of 'kind' and 'sku' for your Azure region. |
+| `systemAssignedIdentity` | bool | | | Optional. Enables system assigned managed identity on the resource. |
+| `tags` | object | `{object}` | | Optional. Tags of the resource. |
+| `userAssignedIdentities` | object | `{object}` | | Optional. The ID(s) to assign to the resource. |
+
+### Parameter Usage: `privateEndpoints`
+
+To use Private Endpoint the following dependencies must be deployed:
+
+- Destination subnet must be created with the following configuration option - `"privateEndpointNetworkPolicies": "Disabled"`. Setting this option acknowledges that NSG rules are not applied to Private Endpoints (this capability is coming soon). A full example is available in the Virtual Network Module.
+- Although not strictly required, it is highly recommended to first create a private DNS Zone to host Private Endpoint DNS records. See [Azure Private Endpoint DNS configuration](https://docs.microsoft.com/en-us/azure/private-link/private-endpoint-dns) for more information.
+
+```json
+"privateEndpoints": {
+ "value": [
+ // Example showing all available fields
+ {
+ "name": "sxx-az-pe", // Optional: Name will be automatically generated if one is not provided here
+ "subnetResourceId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/sxx-az-vnet-x-001/subnets/sxx-az-subnet-x-001",
+ "service": "blob",
+ "privateDnsZoneResourceIds": [ // Optional: No DNS record will be created if a private DNS zone Resource ID is not specified
+ "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/privateDnsZones/privatelink.blob.core.windows.net"
+ ],
+ "customDnsConfigs": [ // Optional
+ {
+ "fqdn": "customname.test.local",
+ "ipAddresses": [
+ "10.10.10.10"
+ ]
+ }
+ ]
+ },
+ // Example showing only mandatory fields
+ {
+ "subnetResourceId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/sxx-az-vnet-x-001/subnets/sxx-az-subnet-x-001",
+ "service": "file"
+ }
+ ]
+}
+```
+
+### Parameter Usage: `roleAssignments`
+
+```json
+"roleAssignments": {
+ "value": [
+ {
+ "roleDefinitionIdOrName": "Reader",
+ "principalIds": [
+ "12345678-1234-1234-1234-123456789012", // object 1
+ "78945612-1234-1234-1234-123456789012" // object 2
+ ]
+ },
+ {
+ "roleDefinitionIdOrName": "/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11",
+ "principalIds": [
+ "12345678-1234-1234-1234-123456789012" // object 1
+ ]
+ }
+ ]
+}
+```
+
+### Parameter Usage: `privateEndpoints`
+
+To use Private Endpoint the following dependencies must be deployed:
+
+- Destination subnet must be created with the following configuration option - `"privateEndpointNetworkPolicies": "Disabled"`. Setting this option acknowledges that NSG rules are not applied to Private Endpoints (this capability is coming soon). A full example is available in the Virtual Network Module.
+
+- Although not strictly required, it is highly recommened to first create a private DNS Zone to host Private Endpoint DNS records. See [Azure Private Endpoint DNS configuration](https://docs.microsoft.com/en-us/azure/private-link/private-endpoint-dns) for more information.
+
+```json
+"privateEndpoints": {
+ "value": [
+ // Example showing all available fields
+ {
+ "name": "sxx-az-pe", // Optional: Name will be automatically generated if one is not provided here
+ "subnetResourceId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/sxx-az-vnet-x-001/subnets/sxx-az-subnet-x-001",
+ "service": "vault",
+ "privateDnsZoneResourceIds": [ // Optional: No DNS record will be created if a private DNS zone Resource ID is not specified
+ "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/privateDnsZones/privatelink.vaultcore.azure.net"
+ ],
+ "customDnsConfigs": [ // Optional
+ {
+ "fqdn": "customname.test.local",
+ "ipAddresses": [
+ "10.10.10.10"
+ ]
+ }
+ ]
+ }
+ ]
+}
+```
+
+### 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: `networkAcls`
+
+```json
+"networkAcls": {
+ "value": {
+ "defaultAction": "Deny",
+ "virtualNetworkRules": [
+ {
+ "id": "/subscriptions//resourceGroups/resourceGroup/providers/Microsoft.Network/virtualNetworks//subnets/",
+ "ignoreMissingVnetServiceEndpoint": false
+ }
+ ],
+ "ipRules": [
+ {
+ "value": "1.1.1.1"
+ },
+ {
+ "value": ""
+ }
+ ]
+ }
+},
+```
+
+### 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 |
+| :-- | :-- | :-- |
+| `endpoint` | string | The service endpoint of the cognitive services account |
+| `name` | string | The name of the cognitive services account |
+| `resourceGroupName` | string | The resource group the cognitive services account was deployed into |
+| `resourceId` | string | The resource ID of the cognitive services account |
+| `systemAssignedPrincipalId` | string | The principal ID of the system assigned identity. |
+
+## Considerations
+
+- Not all combinations of parameters `kind` and `sku` are valid and they may vary in different Azure Regions. Please use PowerShell CmdLet `Get-AzCognitiveServicesAccountSku` or another methods to determine valid values in your region.
+- Not all kinds of Cognitive Services support virtual networks. Please visit the link below to determine supported services.
+
+## Template references
+
+- [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)
+- [Locks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2017-04-01/locks)
+- [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)
+- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/roleAssignments)
diff --git a/carml/1.0.0/Microsoft.CognitiveServices/accounts/version.json b/carml/1.0.0/Microsoft.CognitiveServices/accounts/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.CognitiveServices/accounts/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Compute/availabilitySets/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.Compute/availabilitySets/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/availabilitySets/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.Compute/availabilitySets/.bicep/nested_rbac.bicep b/carml/1.0.0/Microsoft.Compute/availabilitySets/.bicep/nested_rbac.bicep
new file mode 100644
index 000000000..028ee46c6
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/availabilitySets/.bicep/nested_rbac.bicep
@@ -0,0 +1,40 @@
+param principalIds array
+param roleDefinitionIdOrName string
+param resourceId string
+
+var builtInRoleNames = {
+ 'Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')
+ 'Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')
+ 'Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')
+ 'Avere Cluster Create': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a7b1b19a-0e83-4fe5-935c-faaefbfd18c3')
+ 'Avere Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')
+ 'Azure Service Deploy Release Management Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '21d96096-b162-414a-8302-d8354f9d91b2')
+ 'CAL-Custom-Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b266cd7-0bba-4ae2-8423-90ede5e1e898')
+ 'DevTest Labs User': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')
+ 'Log Analytics Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')
+ 'Log Analytics Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')
+ 'Managed Application Contributor Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')
+ 'Managed Application Operator Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')
+ 'Managed Applications Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')
+ 'masterreader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a48d7796-14b4-4889-afef-fbb65a93e5a2')
+ 'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')
+ 'Monitoring Metrics Publisher': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')
+ 'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')
+ 'Reservation Purchaser': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f7b75c60-3036-4b75-91c3-6b41c27c1689')
+ 'Resource Policy Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')
+ 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')
+ 'Virtual Machine Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')
+}
+
+resource availabilitySet 'Microsoft.Compute/availabilitySets@2021-04-01' existing = {
+ name: last(split(resourceId, '/'))
+}
+
+resource roleAssignment 'Microsoft.Authorization/roleAssignments@2021-04-01-preview' = [for principalId in principalIds: {
+ name: guid(availabilitySet.name, principalId, roleDefinitionIdOrName)
+ properties: {
+ roleDefinitionId: contains(builtInRoleNames, roleDefinitionIdOrName) ? builtInRoleNames[roleDefinitionIdOrName] : roleDefinitionIdOrName
+ principalId: principalId
+ }
+ scope: availabilitySet
+}]
diff --git a/carml/1.0.0/Microsoft.Compute/availabilitySets/.parameters/min.parameters.json b/carml/1.0.0/Microsoft.Compute/availabilitySets/.parameters/min.parameters.json
new file mode 100644
index 000000000..99d2414f7
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/availabilitySets/.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": "<>-az-avs-min-001"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Compute/availabilitySets/.parameters/parameters.json b/carml/1.0.0/Microsoft.Compute/availabilitySets/.parameters/parameters.json
new file mode 100644
index 000000000..cfa2eab50
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/availabilitySets/.parameters/parameters.json
@@ -0,0 +1,22 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-az-avs-x-001"
+ },
+ "roleAssignments": {
+ "value": [
+ {
+ "roleDefinitionIdOrName": "Reader",
+ "principalIds": [
+ "<>"
+ ]
+ }
+ ]
+ },
+ "proximityPlacementGroupId": {
+ "value": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Compute/proximityPlacementGroups/adp-<>-az-ppg-x-001"
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Compute/availabilitySets/deploy.bicep b/carml/1.0.0/Microsoft.Compute/availabilitySets/deploy.bicep
new file mode 100644
index 000000000..008953afd
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/availabilitySets/deploy.bicep
@@ -0,0 +1,82 @@
+@description('Required. The name of the availability set that is being created.')
+param name string
+
+@description('Optional. The number of fault domains to use.')
+param availabilitySetFaultDomain int = 2
+
+@description('Optional. The number of update domains to use.')
+param availabilitySetUpdateDomain int = 5
+
+@description('Optional. Sku of the availability set. Use \'Aligned\' for virtual machines with managed disks and \'Classic\' for virtual machines with unmanaged disks.')
+param availabilitySetSku string = 'Aligned'
+
+@description('Optional. Resource ID of a proximity placement group.')
+param proximityPlacementGroupId string = ''
+
+@description('Optional. Resource location.')
+param location string = resourceGroup().location
+
+@allowed([
+ 'CanNotDelete'
+ 'NotSpecified'
+ 'ReadOnly'
+])
+@description('Optional. Specify the type of lock.')
+param lock string = 'NotSpecified'
+
+@description('Optional. Array of role assignment objects that contain the \'roleDefinitionIdOrName\' and \'principalId\' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'')
+param roleAssignments array = []
+
+@description('Optional. Tags of the availability set resource.')
+param tags object = {}
+
+@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 availabilitySet 'Microsoft.Compute/availabilitySets@2021-07-01' = {
+ name: name
+ location: location
+ tags: tags
+ properties: {
+ platformFaultDomainCount: availabilitySetFaultDomain
+ platformUpdateDomainCount: availabilitySetUpdateDomain
+ proximityPlacementGroup: !empty(proximityPlacementGroupId) ? {
+ id: proximityPlacementGroupId
+ } : null
+ }
+ sku: {
+ name: availabilitySetSku
+ }
+}
+
+resource availabilitySet_lock 'Microsoft.Authorization/locks@2017-04-01' = if (lock != 'NotSpecified') {
+ name: '${availabilitySet.name}-${lock}-lock'
+ properties: {
+ level: lock
+ notes: lock == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot modify the resource or child resources.'
+ }
+ scope: availabilitySet
+}
+
+module availabilitySet_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: {
+ name: '${uniqueString(deployment().name, location)}-AvSet-Rbac-${index}'
+ params: {
+ principalIds: roleAssignment.principalIds
+ roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName
+ resourceId: availabilitySet.id
+ }
+}]
+
+@description('The name of the availability set')
+output name string = availabilitySet.name
+
+@description('The resource ID of the availability set')
+output resourceId string = availabilitySet.id
+
+@description('The resource group the availability set was deployed into')
+output resourceGroupName string = resourceGroup().name
diff --git a/carml/1.0.0/Microsoft.Compute/availabilitySets/readme.md b/carml/1.0.0/Microsoft.Compute/availabilitySets/readme.md
new file mode 100644
index 000000000..e21c36dac
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/availabilitySets/readme.md
@@ -0,0 +1,79 @@
+# Availability Sets `[Microsoft.Compute/availabilitySets]`
+
+This template deploys an availability set
+
+## Resource types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/locks` | 2017-04-01 |
+| `Microsoft.Authorization/roleAssignments` | 2021-04-01-preview |
+| `Microsoft.Compute/availabilitySets` | 2021-07-01 |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `availabilitySetFaultDomain` | int | `2` | | Optional. The number of fault domains to use. |
+| `availabilitySetSku` | string | `Aligned` | | Optional. Sku of the availability set. Use 'Aligned' for virtual machines with managed disks and 'Classic' for virtual machines with unmanaged disks. |
+| `availabilitySetUpdateDomain` | int | `5` | | Optional. The number of update domains to use. |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered |
+| `location` | string | `[resourceGroup().location]` | | Optional. Resource location. |
+| `lock` | string | `NotSpecified` | `[CanNotDelete, NotSpecified, ReadOnly]` | Optional. Specify the type of lock. |
+| `name` | string | | | Required. The name of the availability set that is being created. |
+| `proximityPlacementGroupId` | string | | | Optional. Resource ID of a proximity placement 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' |
+| `tags` | object | `{object}` | | Optional. Tags of the availability set resource. |
+
+### Parameter Usage: `roleAssignments`
+
+```json
+"roleAssignments": {
+ "value": [
+ {
+ "roleDefinitionIdOrName": "Reader",
+ "principalIds": [
+ "12345678-1234-1234-1234-123456789012", // object 1
+ "78945612-1234-1234-1234-123456789012" // object 2
+ ]
+ },
+ {
+ "roleDefinitionIdOrName": "/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11",
+ "principalIds": [
+ "12345678-1234-1234-1234-123456789012" // object 1
+ ]
+ }
+ ]
+}
+```
+
+### 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"
+ }
+}
+```
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The name of the availability set |
+| `resourceGroupName` | string | The resource group the availability set was deployed into |
+| `resourceId` | string | The resource ID of the availability set |
+
+## Template references
+
+- [Availabilitysets](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Compute/2021-07-01/availabilitySets)
+- [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/roleAssignments)
diff --git a/carml/1.0.0/Microsoft.Compute/availabilitySets/version.json b/carml/1.0.0/Microsoft.Compute/availabilitySets/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/availabilitySets/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Compute/diskEncryptionSets/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.Compute/diskEncryptionSets/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/diskEncryptionSets/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.Compute/diskEncryptionSets/.bicep/nested_kvAccessPolicy.bicep b/carml/1.0.0/Microsoft.Compute/diskEncryptionSets/.bicep/nested_kvAccessPolicy.bicep
new file mode 100644
index 000000000..64765196a
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/diskEncryptionSets/.bicep/nested_kvAccessPolicy.bicep
@@ -0,0 +1,36 @@
+@description('Required. The name of the key vault')
+param keyVaultName string
+
+@description('Optional. An array of 0 to 16 identities that have access to the key vault. All identities in the array must use the same tenant ID as the key vault\'s tenant ID.')
+param accessPolicies array = []
+
+@description('Optional. The access policy name')
+param name string = 'add'
+
+var formattedAccessPolicies = [for accessPolicy in accessPolicies: {
+ applicationId: contains(accessPolicy, 'applicationId') ? accessPolicy.applicationId : ''
+ objectId: contains(accessPolicy, 'objectId') ? accessPolicy.objectId : ''
+ permissions: accessPolicy.permissions
+ tenantId: contains(accessPolicy, 'tenantId') ? accessPolicy.tenantId : tenant().tenantId
+}]
+
+resource keyVault 'Microsoft.KeyVault/vaults@2021-06-01-preview' existing = {
+ name: keyVaultName
+}
+
+resource policies 'Microsoft.KeyVault/vaults/accessPolicies@2021-06-01-preview' = {
+ name: name
+ parent: keyVault
+ properties: {
+ accessPolicies: formattedAccessPolicies
+ }
+}
+
+@description('The name of the resource group the access policies assignment was created in.')
+output resourceGroupName string = resourceGroup().name
+
+@description('The name of the access policies assignment')
+output name string = policies.name
+
+@description('The resource ID of the access policies assignment')
+output resourceId string = policies.id
diff --git a/carml/1.0.0/Microsoft.Compute/diskEncryptionSets/.bicep/nested_rbac.bicep b/carml/1.0.0/Microsoft.Compute/diskEncryptionSets/.bicep/nested_rbac.bicep
new file mode 100644
index 000000000..8528dbdda
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/diskEncryptionSets/.bicep/nested_rbac.bicep
@@ -0,0 +1,38 @@
+param principalIds array
+param roleDefinitionIdOrName string
+param resourceId string
+
+var builtInRoleNames = {
+ 'Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')
+ 'Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')
+ 'Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')
+ 'Avere Cluster Create': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a7b1b19a-0e83-4fe5-935c-faaefbfd18c3')
+ 'Avere Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')
+ 'Azure Service Deploy Release Management Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '21d96096-b162-414a-8302-d8354f9d91b2')
+ 'CAL-Custom-Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b266cd7-0bba-4ae2-8423-90ede5e1e898')
+ 'Log Analytics Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')
+ 'Log Analytics Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')
+ 'Managed Application Contributor Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')
+ 'Managed Application Operator Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')
+ 'Managed Applications Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')
+ 'masterreader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a48d7796-14b4-4889-afef-fbb65a93e5a2')
+ 'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')
+ 'Monitoring Metrics Publisher': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')
+ 'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')
+ 'Reservation Purchaser': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f7b75c60-3036-4b75-91c3-6b41c27c1689')
+ 'Resource Policy Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')
+ 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')
+}
+
+resource diskEncryptionSet 'Microsoft.Compute/diskEncryptionSets@2020-12-01' existing = {
+ name: last(split(resourceId, '/'))
+}
+
+resource roleAssignment 'Microsoft.Authorization/roleAssignments@2021-04-01-preview' = [for principalId in principalIds: {
+ name: guid(diskEncryptionSet.name, principalId, roleDefinitionIdOrName)
+ properties: {
+ roleDefinitionId: contains(builtInRoleNames, roleDefinitionIdOrName) ? builtInRoleNames[roleDefinitionIdOrName] : roleDefinitionIdOrName
+ principalId: principalId
+ }
+ scope: diskEncryptionSet
+}]
diff --git a/carml/1.0.0/Microsoft.Compute/diskEncryptionSets/.parameters/parameters.json b/carml/1.0.0/Microsoft.Compute/diskEncryptionSets/.parameters/parameters.json
new file mode 100644
index 000000000..9ad9ed7c5
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/diskEncryptionSets/.parameters/parameters.json
@@ -0,0 +1,25 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-az-des-x-001"
+ },
+ "keyVaultId": {
+ "value": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.KeyVault/vaults/adp-<>-az-kv-x-001"
+ },
+ "keyUrl": {
+ "value": "https://adp-<>-az-kv-x-001.vault.azure.net/keys/keyEncryptionKey/bc3bb46d95c64367975d722f473eeae5" // ID must be updated for new keys
+ },
+ "roleAssignments": {
+ "value": [
+ {
+ "roleDefinitionIdOrName": "Reader",
+ "principalIds": [
+ "<>"
+ ]
+ }
+ ]
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Compute/diskEncryptionSets/deploy.bicep b/carml/1.0.0/Microsoft.Compute/diskEncryptionSets/deploy.bicep
new file mode 100644
index 000000000..26cc93f6a
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/diskEncryptionSets/deploy.bicep
@@ -0,0 +1,102 @@
+@description('Required. The name of the disk encryption set that is being created.')
+param name string
+
+@description('Optional. Resource location.')
+param location string = resourceGroup().location
+
+@description('Required. Resource ID of the KeyVault containing the key or secret.')
+param keyVaultId string
+
+@description('Required. Key URL (with version) pointing to a key or secret in KeyVault.')
+param keyUrl string
+
+@description('Optional. The type of key used to encrypt the data of the disk. For security reasons, it is recommended to set encryptionType to EncryptionAtRestWithPlatformAndCustomerKeys')
+@allowed([
+ 'EncryptionAtRestWithCustomerKey'
+ 'EncryptionAtRestWithPlatformAndCustomerKeys'
+])
+param encryptionType string = 'EncryptionAtRestWithPlatformAndCustomerKeys'
+
+@description('Optional. Set this flag to true to enable auto-updating of this disk encryption set to the latest key version.')
+param rotationToLatestKeyVersionEnabled bool = false
+
+@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 disk encryption resource.')
+param tags object = {}
+
+@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 diskEncryptionSet 'Microsoft.Compute/diskEncryptionSets@2021-04-01' = {
+ name: name
+ location: location
+ tags: tags
+ identity: {
+ type: 'SystemAssigned'
+ }
+ properties: {
+ activeKey: {
+ sourceVault: {
+ id: keyVaultId
+ }
+ keyUrl: keyUrl
+ }
+ encryptionType: encryptionType
+ rotationToLatestKeyVersionEnabled: rotationToLatestKeyVersionEnabled
+ }
+}
+
+module keyVaultAccessPolicies '.bicep/nested_kvAccessPolicy.bicep' = {
+ name: '${uniqueString(deployment().name, location)}-DiskEncrSet-KVAccessPolicies'
+ params: {
+ keyVaultName: last(split(keyVaultId, '/'))
+ accessPolicies: [
+ {
+ tenantId: subscription().tenantId
+ objectId: diskEncryptionSet.identity.principalId
+ permissions: {
+ keys: [
+ 'get'
+ 'wrapKey'
+ 'unwrapKey'
+ ]
+ secrets: []
+ certificates: []
+ }
+ }
+ ]
+ }
+ // This is to support access policies to KV in different subscription and resource group than the disk encryption set.
+ scope: resourceGroup(split(keyVaultId, '/')[2], split(keyVaultId, '/')[4])
+}
+
+module diskEncryptionSet_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: {
+ name: '${uniqueString(deployment().name, location)}-DiskEncrSet-Rbac-${index}'
+ params: {
+ principalIds: roleAssignment.principalIds
+ roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName
+ resourceId: diskEncryptionSet.id
+ }
+}]
+
+@description('The resource ID of the disk encryption set')
+output resourceId string = diskEncryptionSet.id
+
+@description('The name of the disk encryption set')
+output name string = diskEncryptionSet.name
+
+@description('The resource group the disk encryption set was deployed into')
+output resourceGroupName string = resourceGroup().name
+
+@description('The principal ID of the disk encryption set')
+output systemAssignedPrincipalId string = diskEncryptionSet.identity.principalId
+
+@description('The name of the key vault with the disk encryption key')
+output keyVaultName string = last(split(keyVaultId, '/'))
diff --git a/carml/1.0.0/Microsoft.Compute/diskEncryptionSets/readme.md b/carml/1.0.0/Microsoft.Compute/diskEncryptionSets/readme.md
new file mode 100644
index 000000000..c3c63428f
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/diskEncryptionSets/readme.md
@@ -0,0 +1,80 @@
+# Disk Encryption Sets `[Microsoft.Compute/diskEncryptionSets]`
+
+This template deploys a disk encryption set.
+
+## Resource types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/roleAssignments` | 2021-04-01-preview |
+| `Microsoft.Compute/diskEncryptionSets` | 2021-04-01 |
+| `Microsoft.KeyVault/vaults/accessPolicies` | 2021-06-01-preview |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered |
+| `encryptionType` | string | `EncryptionAtRestWithPlatformAndCustomerKeys` | `[EncryptionAtRestWithCustomerKey, EncryptionAtRestWithPlatformAndCustomerKeys]` | Optional. The type of key used to encrypt the data of the disk. For security reasons, it is recommended to set 'encryptionType' to 'EncryptionAtRestWithPlatformAndCustomerKeys' |
+| `keyUrl` | string | | | Required. Key URL (with version) pointing to a key or secret in KeyVault. |
+| `keyVaultId` | string | | | Required. Resource ID of the KeyVault containing the key or secret. |
+| `location` | string | `[resourceGroup().location]` | | Optional. Resource location. |
+| `name` | string | | | Required. The name of the disk encryption set that is being created. |
+| `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' |
+| `rotationToLatestKeyVersionEnabled` | bool | | | Optional. Set this flag to true to enable auto-updating of this disk encryption set to the latest key version. |
+| `tags` | object | `{object}` | | Optional. Tags of the disk encryption resource. |
+
+### Parameter Usage: `roleAssignments`
+
+```json
+"roleAssignments": {
+ "value": [
+ {
+ "roleDefinitionIdOrName": "Reader",
+ "principalIds": [
+ "12345678-1234-1234-1234-123456789012", // object 1
+ "78945612-1234-1234-1234-123456789012" // object 2
+ ]
+ },
+ {
+ "roleDefinitionIdOrName": "/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11",
+ "principalIds": [
+ "12345678-1234-1234-1234-123456789012" // object 1
+ ]
+ }
+ ]
+}
+```
+
+### 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"
+ }
+}
+```
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `keyVaultName` | string | The name of the key vault with the disk encryption key |
+| `name` | string | The name of the disk encryption set |
+| `resourceGroupName` | string | The resource group the disk encryption set was deployed into |
+| `resourceId` | string | The resource ID of the disk encryption set |
+| `systemAssignedPrincipalId` | string | The principal ID of the disk encryption set |
+
+## Template references
+
+- [Diskencryptionsets](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Compute/2021-04-01/diskEncryptionSets)
+- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/roleAssignments)
+- [Vaults/Accesspolicies](https://docs.microsoft.com/en-us/azure/templates/Microsoft.KeyVault/2021-06-01-preview/vaults/accessPolicies)
diff --git a/carml/1.0.0/Microsoft.Compute/diskEncryptionSets/version.json b/carml/1.0.0/Microsoft.Compute/diskEncryptionSets/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/diskEncryptionSets/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Compute/disks/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.Compute/disks/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/disks/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.Compute/disks/.bicep/nested_rbac.bicep b/carml/1.0.0/Microsoft.Compute/disks/.bicep/nested_rbac.bicep
new file mode 100644
index 000000000..30579bd53
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/disks/.bicep/nested_rbac.bicep
@@ -0,0 +1,39 @@
+param principalIds array
+param roleDefinitionIdOrName string
+param resourceId string
+
+var builtInRoleNames = {
+ 'Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')
+ 'Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')
+ 'Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')
+ 'Avere Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')
+ 'Disk Backup Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3e5e47e6-65f7-47ef-90b5-e5dd4d455f24')
+ 'Disk Pool Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '60fc6e62-5479-42d4-8bf4-67625fcc2840')
+ 'Disk Restore Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b50d9833-a0cb-478e-945f-707fcc997c13')
+ 'Disk Snapshot Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7efff54f-a5b4-42b5-a1c5-5411624893ce')
+ 'Log Analytics Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')
+ 'Log Analytics Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')
+ 'Managed Application Contributor Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')
+ 'Managed Application Operator Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')
+ 'Managed Applications Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')
+ 'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')
+ 'Monitoring Metrics Publisher': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')
+ 'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')
+ 'Reservation Purchaser': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f7b75c60-3036-4b75-91c3-6b41c27c1689')
+ 'Resource Policy Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')
+ 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')
+ 'Virtual Machine Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')
+}
+
+resource disk 'Microsoft.Compute/disks@2021-08-01' existing = {
+ name: last(split(resourceId, '/'))
+}
+
+resource roleAssignment 'Microsoft.Authorization/roleAssignments@2021-04-01-preview' = [for principalId in principalIds: {
+ name: guid(disk.name, principalId, roleDefinitionIdOrName)
+ properties: {
+ roleDefinitionId: contains(builtInRoleNames, roleDefinitionIdOrName) ? builtInRoleNames[roleDefinitionIdOrName] : roleDefinitionIdOrName
+ principalId: principalId
+ }
+ scope: disk
+}]
diff --git a/carml/1.0.0/Microsoft.Compute/disks/.parameters/image.parameters.json b/carml/1.0.0/Microsoft.Compute/disks/.parameters/image.parameters.json
new file mode 100644
index 000000000..d6934ac64
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/disks/.parameters/image.parameters.json
@@ -0,0 +1,28 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-az-disk-image-001"
+ },
+ "sku": {
+ "value": "Standard_LRS"
+ },
+ "createOption": {
+ "value": "FromImage"
+ },
+ "imageReferenceId": {
+ "value": "/Subscriptions/<>/Providers/Microsoft.Compute/Locations/westeurope/Publishers/MicrosoftWindowsServer/ArtifactTypes/VMImage/Offers/WindowsServer/Skus/2016-Datacenter/Versions/14393.4906.2112080838"
+ },
+ "roleAssignments": {
+ "value": [
+ {
+ "roleDefinitionIdOrName": "Reader",
+ "principalIds": [
+ "<>"
+ ]
+ }
+ ]
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Compute/disks/.parameters/import.parameters.json b/carml/1.0.0/Microsoft.Compute/disks/.parameters/import.parameters.json
new file mode 100644
index 000000000..a09908e11
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/disks/.parameters/import.parameters.json
@@ -0,0 +1,31 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-az-disk-import-001"
+ },
+ "sku": {
+ "value": "Standard_LRS"
+ },
+ "createOption": {
+ "value": "Import"
+ },
+ "sourceUri": {
+ "value": "https://adp<>azsax001.blob.core.windows.net/vhds/adp-<>-az-imgt-x-001.vhd"
+ },
+ "storageAccountId": {
+ "value": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Storage/storageAccounts/adp<>azsax001"
+ },
+ "roleAssignments": {
+ "value": [
+ {
+ "roleDefinitionIdOrName": "Reader",
+ "principalIds": [
+ "<>"
+ ]
+ }
+ ]
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Compute/disks/.parameters/min.parameters.json b/carml/1.0.0/Microsoft.Compute/disks/.parameters/min.parameters.json
new file mode 100644
index 000000000..d19f33a37
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/disks/.parameters/min.parameters.json
@@ -0,0 +1,25 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-az-disk-min-001"
+ },
+ "sku": {
+ "value": "Standard_LRS"
+ },
+ "diskSizeGB": {
+ "value": 1
+ },
+ "roleAssignments": {
+ "value": [
+ {
+ "roleDefinitionIdOrName": "Reader",
+ "principalIds": [
+ "<>"
+ ]
+ }
+ ]
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Compute/disks/.parameters/parameters.json b/carml/1.0.0/Microsoft.Compute/disks/.parameters/parameters.json
new file mode 100644
index 000000000..3608893d9
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/disks/.parameters/parameters.json
@@ -0,0 +1,40 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-az-disk-x-001"
+ },
+ "sku": {
+ "value": "UltraSSD_LRS"
+ },
+ "diskSizeGB": {
+ "value": 128
+ },
+ "logicalSectorSize": {
+ "value": 512
+ },
+ "diskIOPSReadWrite": {
+ "value": 500
+ },
+ "diskMBpsReadWrite": {
+ "value": 60
+ },
+ "osType": {
+ "value": "Windows"
+ },
+ "publicNetworkAccess": {
+ "value": "Enabled"
+ },
+ "roleAssignments": {
+ "value": [
+ {
+ "roleDefinitionIdOrName": "Reader",
+ "principalIds": [
+ "<>"
+ ]
+ }
+ ]
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Compute/disks/deploy.bicep b/carml/1.0.0/Microsoft.Compute/disks/deploy.bicep
new file mode 100644
index 000000000..e66713dc5
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/disks/deploy.bicep
@@ -0,0 +1,188 @@
+@description('Required. The name of the disk that is being created.')
+param name string
+
+@description('Optional. Resource location.')
+param location string = resourceGroup().location
+
+@allowed([
+ 'Standard_LRS'
+ 'Premium_LRS'
+ 'StandardSSD_LRS'
+ 'UltraSSD_LRS'
+ 'Premium_ZRS'
+ 'Premium_ZRS'
+])
+@description('Required. The disks sku name. Can be .')
+param sku string
+
+@description('Optional. Set to true to enable bursting beyond the provisioned performance target of the disk.')
+param burstingEnabled bool = false
+
+@description('Optional. Percentage complete for the background copy when a resource is created via the CopyStart operation.')
+param completionPercent int = 100
+
+@allowed([
+ 'Attach'
+ 'Copy'
+ 'CopyStart'
+ 'Empty'
+ 'FromImage'
+ 'Import'
+ 'ImportSecure'
+ 'Restore'
+ 'Upload'
+ 'UploadPreparedSecure'
+])
+@description('Optional. Sources of a disk creation.')
+param createOption string = 'Empty'
+
+@description('Optional. A relative uri containing either a Platform Image Repository or user image reference.')
+param imageReferenceId string = ''
+
+@description('Optional. Logical sector size in bytes for Ultra disks. Supported values are 512 ad 4096.')
+param logicalSectorSize int = 4096
+
+@description('Optional. If create option is ImportSecure, this is the URI of a blob to be imported into VM guest state.')
+param securityDataUri string = ''
+
+@description('Optional. If create option is Copy, this is the ARM id of the source snapshot or disk.')
+param sourceResourceId string = ''
+
+@description('Optional. If create option is Import, this is the URI of a blob to be imported into a managed disk.')
+param sourceUri string = ''
+
+@description('Optional. Required if create option is Import. The Azure Resource Manager identifier of the storage account containing the blob to import as a disk')
+param storageAccountId string = ''
+
+@description('Optional. If create option is Upload, this is the size of the contents of the upload including the VHD footer.')
+param uploadSizeBytes int = 20972032
+
+@description('Optional. If create option is empty, this field is mandatory and it indicates the size of the disk to create.')
+param diskSizeGB int = 0
+
+@description('Optional. The number of IOPS allowed for this disk; only settable for UltraSSD disks.')
+param diskIOPSReadWrite int = 0
+
+@description('Optional. The bandwidth allowed for this disk; only settable for UltraSSD disks.')
+param diskMBpsReadWrite int = 0
+
+@allowed([
+ 'V1'
+ 'V2'
+])
+@description('Optional. The hypervisor generation of the Virtual Machine. Applicable to OS disks only.')
+param hyperVGeneration string = 'V2'
+
+@description('Optional. The maximum number of VMs that can attach to the disk at the same time. Default value is 0.')
+param maxShares int = 1
+
+@allowed([
+ 'AllowAll'
+ 'AllowPrivate'
+ 'DenyAll'
+])
+@description('Optional. Policy for accessing the disk via network.')
+param networkAccessPolicy string = 'DenyAll'
+
+@allowed([
+ 'Windows'
+ 'Linux'
+ ''
+])
+@description('Optional. Sources of a disk creation.')
+param osType string = ''
+
+@allowed([
+ 'Disabled'
+ 'Enabled'
+])
+@description('Optional. Policy for controlling export on the disk.')
+param publicNetworkAccess string = 'Disabled'
+
+@description('Optional. True if the image from which the OS disk is created supports accelerated networking.')
+param acceleratedNetwork bool = false
+
+@allowed([
+ 'CanNotDelete'
+ 'NotSpecified'
+ 'ReadOnly'
+])
+@description('Optional. Specify the type of lock.')
+param lock string = 'NotSpecified'
+
+@description('Optional. Array of role assignment objects that contain the \'roleDefinitionIdOrName\' and \'principalId\' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'')
+param roleAssignments array = []
+
+@description('Optional. Tags of the availability set resource.')
+param tags object = {}
+
+@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 disk 'Microsoft.Compute/disks@2021-08-01' = {
+ name: name
+ location: location
+ tags: tags
+ sku: {
+ name: sku
+ }
+ properties: {
+ burstingEnabled: burstingEnabled
+ completionPercent: completionPercent
+ creationData: {
+ createOption: createOption
+ imageReference: createOption != 'FromImage' ? null : {
+ id: imageReferenceId
+ }
+ logicalSectorSize: contains(sku, 'Ultra') ? logicalSectorSize : null
+ securityDataUri: createOption == 'ImportSecure' ? securityDataUri : null
+ sourceResourceId: createOption == 'Copy' ? sourceResourceId : null
+ sourceUri: createOption == 'Import' ? sourceUri : null
+ storageAccountId: createOption == 'Import' ? storageAccountId : null
+ uploadSizeBytes: createOption == 'Upload' ? uploadSizeBytes : null
+ }
+ diskIOPSReadWrite: contains(sku, 'Ultra') ? diskIOPSReadWrite : null
+ diskMBpsReadWrite: contains(sku, 'Ultra') ? diskMBpsReadWrite : null
+ diskSizeGB: createOption == 'Empty' ? diskSizeGB : null
+ hyperVGeneration: empty(osType) ? null : hyperVGeneration
+ maxShares: maxShares
+ networkAccessPolicy: networkAccessPolicy
+ osType: empty(osType) ? null : osType
+ publicNetworkAccess: publicNetworkAccess
+ supportedCapabilities: empty(osType) ? {} : {
+ acceleratedNetwork: acceleratedNetwork
+ }
+ }
+}
+
+resource disk_lock 'Microsoft.Authorization/locks@2017-04-01' = if (lock != 'NotSpecified') {
+ name: '${disk.name}-${lock}-lock'
+ properties: {
+ level: lock
+ notes: lock == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot modify the resource or child resources.'
+ }
+ scope: disk
+}
+
+module disk_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: {
+ name: '${uniqueString(deployment().name, location)}-AvSet-Rbac-${index}'
+ params: {
+ principalIds: roleAssignment.principalIds
+ roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName
+ resourceId: disk.id
+ }
+}]
+
+@description('The resource group the disk was deployed into')
+output resourceGroupName string = resourceGroup().name
+
+@description('The resource ID of the disk')
+output resourceId string = disk.id
+
+@description('The name of the disk')
+output name string = disk.name
diff --git a/carml/1.0.0/Microsoft.Compute/disks/readme.md b/carml/1.0.0/Microsoft.Compute/disks/readme.md
new file mode 100644
index 000000000..1953fa2e6
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/disks/readme.md
@@ -0,0 +1,95 @@
+# Compute Disks `[Microsoft.Compute/disks]`
+
+This template deploys a disk
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/locks` | 2017-04-01 |
+| `Microsoft.Authorization/roleAssignments` | 2021-04-01-preview |
+| `Microsoft.Compute/disks` | 2021-08-01 |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `acceleratedNetwork` | bool | | | Optional. True if the image from which the OS disk is created supports accelerated networking. |
+| `burstingEnabled` | bool | | | Optional. Set to true to enable bursting beyond the provisioned performance target of the disk. |
+| `completionPercent` | int | `100` | | Optional. Percentage complete for the background copy when a resource is created via the CopyStart operation. |
+| `createOption` | string | `Empty` | `[Attach, Copy, CopyStart, Empty, FromImage, Import, ImportSecure, Restore, Upload, UploadPreparedSecure]` | Optional. Sources of a disk creation. |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered |
+| `diskIOPSReadWrite` | int | | | Optional. The number of IOPS allowed for this disk; only settable for UltraSSD disks. |
+| `diskMBpsReadWrite` | int | | | Optional. The bandwidth allowed for this disk; only settable for UltraSSD disks. |
+| `diskSizeGB` | int | | | Optional. If create option is empty, this field is mandatory and it indicates the size of the disk to create. |
+| `hyperVGeneration` | string | `V2` | `[V1, V2]` | Optional. The hypervisor generation of the Virtual Machine. Applicable to OS disks only. |
+| `imageReferenceId` | string | | | Optional. A relative uri containing either a Platform Image Repository or user image reference. |
+| `location` | string | `[resourceGroup().location]` | | Optional. Resource location. |
+| `lock` | string | `NotSpecified` | `[CanNotDelete, NotSpecified, ReadOnly]` | Optional. Specify the type of lock. |
+| `logicalSectorSize` | int | `4096` | | Optional. Logical sector size in bytes for Ultra disks. Supported values are 512 ad 4096. |
+| `maxShares` | int | `1` | | Optional. The maximum number of VMs that can attach to the disk at the same time. Default value is 0. |
+| `name` | string | | | Required. The name of the disk that is being created. |
+| `networkAccessPolicy` | string | `DenyAll` | `[AllowAll, AllowPrivate, DenyAll]` | Optional. Policy for accessing the disk via network. |
+| `osType` | string | | `[Windows, Linux, ]` | Optional. Sources of a disk creation. |
+| `publicNetworkAccess` | string | `Disabled` | `[Disabled, Enabled]` | Optional. Policy for controlling export on the disk. |
+| `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' |
+| `securityDataUri` | string | | | Optional. If create option is ImportSecure, this is the URI of a blob to be imported into VM guest state. |
+| `sku` | string | | `[Standard_LRS, Premium_LRS, StandardSSD_LRS, UltraSSD_LRS, Premium_ZRS, Premium_ZRS]` | Required. The disks sku name. Can be . |
+| `sourceResourceId` | string | | | Optional. If create option is Copy, this is the ARM ID of the source snapshot or disk. |
+| `sourceUri` | string | | | Optional. If create option is Import, this is the URI of a blob to be imported into a managed disk. |
+| `storageAccountId` | string | | | Optional. Required if create option is Import. The Azure Resource Manager identifier of the storage account containing the blob to import as a disk |
+| `tags` | object | `{object}` | | Optional. Tags of the availability set resource. |
+| `uploadSizeBytes` | int | `20972032` | | Optional. If create option is Upload, this is the size of the contents of the upload including the VHD footer. |
+
+### Parameter Usage: `roleAssignments`
+
+```json
+"roleAssignments": {
+ "value": [
+ {
+ "roleDefinitionIdOrName": "Reader",
+ "principalIds": [
+ "12345678-1234-1234-1234-123456789012", // object 1
+ "78945612-1234-1234-1234-123456789012" // object 2
+ ]
+ },
+ {
+ "roleDefinitionIdOrName": "/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11",
+ "principalIds": [
+ "12345678-1234-1234-1234-123456789012" // object 1
+ ]
+ }
+ ]
+}
+```
+
+### 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"
+ }
+}
+```
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The name of the disk |
+| `resourceGroupName` | string | The resource group the disk was deployed into |
+| `resourceId` | string | The resource ID of the disk |
+
+## Template references
+
+- [Disks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Compute/2021-08-01/disks)
+- [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/roleAssignments)
diff --git a/carml/1.0.0/Microsoft.Compute/disks/version.json b/carml/1.0.0/Microsoft.Compute/disks/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/disks/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Compute/galleries/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.Compute/galleries/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/galleries/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.Compute/galleries/.bicep/nested_rbac.bicep b/carml/1.0.0/Microsoft.Compute/galleries/.bicep/nested_rbac.bicep
new file mode 100644
index 000000000..18ddea9d6
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/galleries/.bicep/nested_rbac.bicep
@@ -0,0 +1,34 @@
+param principalIds array
+param roleDefinitionIdOrName string
+param resourceId string
+
+var builtInRoleNames = {
+ 'Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')
+ 'Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')
+ 'Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')
+ 'Avere Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')
+ 'Log Analytics Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')
+ 'Log Analytics Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')
+ 'Managed Application Contributor Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')
+ 'Managed Application Operator Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')
+ 'Managed Applications Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')
+ 'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')
+ 'Monitoring Metrics Publisher': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')
+ 'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')
+ 'Reservation Purchaser': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f7b75c60-3036-4b75-91c3-6b41c27c1689')
+ 'Resource Policy Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')
+ 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')
+}
+
+resource gallery 'Microsoft.Compute/galleries@2020-09-30' existing = {
+ name: last(split(resourceId, '/'))
+}
+
+resource roleAssignment 'Microsoft.Authorization/roleAssignments@2021-04-01-preview' = [for principalId in principalIds: {
+ name: guid(gallery.name, principalId, roleDefinitionIdOrName)
+ properties: {
+ roleDefinitionId: contains(builtInRoleNames, roleDefinitionIdOrName) ? builtInRoleNames[roleDefinitionIdOrName] : roleDefinitionIdOrName
+ principalId: principalId
+ }
+ scope: gallery
+}]
diff --git a/carml/1.0.0/Microsoft.Compute/galleries/.parameters/images.parameters.json b/carml/1.0.0/Microsoft.Compute/galleries/.parameters/images.parameters.json
new file mode 100644
index 000000000..78a802c19
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/galleries/.parameters/images.parameters.json
@@ -0,0 +1,50 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>azsigweuimages001"
+ },
+ "images": {
+ "value": [
+ {
+ "name": "<>-az-imgd-x-003"
+ },
+ {
+ "name": "<>-az-imgd-x-001",
+ "osType": "Windows",
+ "osState": "Generalized",
+ "publisher": "MicrosoftWindowsServer",
+ "offer": "WindowsServer",
+ "sku": "2022-datacenter-azure-edition",
+ "minRecommendedvCPUs": 2,
+ "maxRecommendedvCPUs": 8,
+ "minRecommendedMemory": 4,
+ "maxRecommendedMemory": 16,
+ "hyperVGeneration": "V1",
+ "roleAssignments": [
+ {
+ "roleDefinitionIdOrName": "Reader",
+ "principalIds": [
+ "<>"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "<>-az-imgd-x-002",
+ "osType": "Linux",
+ "osState": "Generalized",
+ "publisher": "canonical",
+ "offer": "0001-com-ubuntu-server-focal",
+ "sku": "20_04-lts-gen2",
+ "minRecommendedvCPUs": 1,
+ "maxRecommendedvCPUs": 4,
+ "minRecommendedMemory": 4,
+ "maxRecommendedMemory": 32,
+ "hyperVGeneration": "V2"
+ }
+ ]
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Compute/galleries/.parameters/parameters.json b/carml/1.0.0/Microsoft.Compute/galleries/.parameters/parameters.json
new file mode 100644
index 000000000..ccacaf074
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/galleries/.parameters/parameters.json
@@ -0,0 +1,19 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>azsigweux001"
+ },
+ "roleAssignments": {
+ "value": [
+ {
+ "roleDefinitionIdOrName": "Reader",
+ "principalIds": [
+ "<>"
+ ]
+ }
+ ]
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Compute/galleries/deploy.bicep b/carml/1.0.0/Microsoft.Compute/galleries/deploy.bicep
new file mode 100644
index 000000000..7c6cac679
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/galleries/deploy.bicep
@@ -0,0 +1,101 @@
+@minLength(1)
+@description('Required. Name of the Azure Shared Image Gallery')
+param name string
+
+@description('Optional. Location for all resources.')
+param location string = resourceGroup().location
+
+@description('Optional. Description of the Azure Shared Image Gallery')
+param galleryDescription string = ''
+
+@description('Optional. Images to create')
+param images array = []
+
+@allowed([
+ 'CanNotDelete'
+ 'NotSpecified'
+ 'ReadOnly'
+])
+@description('Optional. Specify the type of lock.')
+param lock string = 'NotSpecified'
+
+@description('Optional. Array of role assignment objects that contain the \'roleDefinitionIdOrName\' and \'principalId\' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'')
+param roleAssignments array = []
+
+@description('Optional. Tags for all resources.')
+param tags object = {}
+
+@description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered')
+param cuaId string = ''
+
+module pidName '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) {
+ name: 'pid-${cuaId}'
+ params: {}
+}
+
+resource gallery 'Microsoft.Compute/galleries@2020-09-30' = {
+ name: name
+ location: location
+ tags: tags
+ properties: {
+ description: galleryDescription
+ identifier: {}
+ }
+}
+
+resource gallery_lock 'Microsoft.Authorization/locks@2017-04-01' = if (lock != 'NotSpecified') {
+ name: '${gallery.name}-${lock}-lock'
+ properties: {
+ level: lock
+ notes: (lock == 'CanNotDelete') ? 'Cannot delete resource or child resources.' : 'Cannot modify the resource or child resources.'
+ }
+ scope: gallery
+}
+
+module gallery_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: {
+ name: '${uniqueString(deployment().name, location)}-Gallery-Rbac-${index}'
+ params: {
+ principalIds: roleAssignment.principalIds
+ roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName
+ resourceId: gallery.id
+ }
+}]
+
+// Images
+module galleries_images 'images/deploy.bicep' = [for (image, index) in images: {
+ name: '${uniqueString(deployment().name, location)}-Gallery-Image-${index}'
+ params: {
+ name: image.name
+ galleryName: gallery.name
+ osType: contains(image, 'osType') ? image.osType : 'Windows'
+ osState: contains(image, 'osState') ? image.osState : 'Generalized'
+ publisher: contains(image, 'publisher') ? image.publisher : 'MicrosoftWindowsServer'
+ offer: contains(image, 'offer') ? image.offer : 'WindowsServer'
+ sku: contains(image, 'sku') ? image.sku : '2019-Datacenter'
+ minRecommendedvCPUs: contains(image, 'minRecommendedvCPUs') ? image.minRecommendedvCPUs : 1
+ maxRecommendedvCPUs: contains(image, 'maxRecommendedvCPUs') ? image.maxRecommendedvCPUs : 4
+ minRecommendedMemory: contains(image, 'minRecommendedMemory') ? image.minRecommendedMemory : 4
+ maxRecommendedMemory: contains(image, 'maxRecommendedMemory') ? image.maxRecommendedMemory : 16
+ hyperVGeneration: contains(image, 'hyperVGeneration') ? image.hyperVGeneration : 'V1'
+ /* imageDefinitionDescription: contains(image, 'imageDefinitionDescription') ? image.imageDefinitionDescription : ''
+ eula: contains(image, 'eula') ? image.eula : ''
+ privacyStatementUri: contains(image, 'privacyStatementUri') ? image.privacyStatementUri : ''
+ releaseNoteUri: contains(image, 'releaseNoteUri') ? image.releaseNoteUri : ''
+ productName: contains(image, 'productName') ? image.productName : ''
+ planName: contains(image, 'planName') ? image.planName : ''
+ planPublisherName: contains(image, 'planPublisherName') ? image.planPublisherName : ''
+ endOfLife: contains(image, 'endOfLife') ? image.endOfLife : ''
+ excludedDiskTypes: contains(image, 'excludedDiskTypes') ? image.excludedDiskTypes : [] */
+ roleAssignments: contains(image, 'roleAssignments') ? image.roleAssignments : []
+ tags: contains(image, 'tags') ? image.tags : {}
+ }
+}]
+
+@description('The resource ID of the deployed image gallery')
+output resourceId string = gallery.id
+
+@description('The resource group of the deployed image gallery')
+output resourceGroupName string = resourceGroup().name
+
+@description('The name of the deployed image gallery')
+output name string = gallery.name
diff --git a/carml/1.0.0/Microsoft.Compute/galleries/images/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.Compute/galleries/images/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/galleries/images/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.Compute/galleries/images/.bicep/nested_rbac.bicep b/carml/1.0.0/Microsoft.Compute/galleries/images/.bicep/nested_rbac.bicep
new file mode 100644
index 000000000..537bc8351
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/galleries/images/.bicep/nested_rbac.bicep
@@ -0,0 +1,36 @@
+param principalIds array
+param roleDefinitionIdOrName string
+param resourceId string
+
+var builtInRoleNames = {
+ 'Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')
+ 'Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')
+ 'Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')
+ 'Avere Cluster Create': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a7b1b19a-0e83-4fe5-935c-faaefbfd18c3')
+ 'Avere Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')
+ 'Azure Service Deploy Release Management Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '21d96096-b162-414a-8302-d8354f9d91b2')
+ 'CAL-Custom-Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b266cd7-0bba-4ae2-8423-90ede5e1e898')
+ 'Log Analytics Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')
+ 'Log Analytics Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')
+ 'Managed Application Contributor Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')
+ 'Managed Application Operator Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')
+ 'Managed Applications Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')
+ 'masterreader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a48d7796-14b4-4889-afef-fbb65a93e5a2')
+ 'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')
+ 'Monitoring Metrics Publisher': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')
+ 'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')
+ 'myCustomRoleAtSub': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '60cb79d9-783a-50a4-9f05-d4c579fb8ce3')
+}
+
+resource galleryImage 'Microsoft.Compute/galleries/images@2020-09-30' existing = {
+ name: '${split(resourceId, '/')[8]}/${split(resourceId, '/')[10]}'
+}
+
+resource roleAssignment 'Microsoft.Authorization/roleAssignments@2021-04-01-preview' = [for principalId in principalIds: {
+ name: guid(galleryImage.name, principalId, roleDefinitionIdOrName)
+ properties: {
+ roleDefinitionId: contains(builtInRoleNames, roleDefinitionIdOrName) ? builtInRoleNames[roleDefinitionIdOrName] : roleDefinitionIdOrName
+ principalId: principalId
+ }
+ scope: galleryImage
+}]
diff --git a/carml/1.0.0/Microsoft.Compute/galleries/images/deploy.bicep b/carml/1.0.0/Microsoft.Compute/galleries/images/deploy.bicep
new file mode 100644
index 000000000..5b2bc6b5d
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/galleries/images/deploy.bicep
@@ -0,0 +1,165 @@
+@description('Required. Name of the image definition.')
+param name string
+
+@description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered')
+param cuaId string = ''
+
+@description('Optional. Location for all resources.')
+param location string = resourceGroup().location
+
+@description('Required. Name of the Azure Shared Image Gallery')
+@minLength(1)
+param galleryName string
+
+@description('Optional. OS type of the image to be created.')
+@allowed([
+ 'Windows'
+ 'Linux'
+])
+param osType string = 'Windows'
+
+@description('Optional. This property allows the user to specify whether the virtual machines created under this image are \'Generalized\' or \'Specialized\'.')
+@allowed([
+ 'Generalized'
+ 'Specialized'
+])
+param osState string = 'Generalized'
+
+@description('Optional. The name of the gallery Image Definition publisher.')
+param publisher string = 'MicrosoftWindowsServer'
+
+@description('Optional. The name of the gallery Image Definition offer.')
+param offer string = 'WindowsServer'
+
+@description('Optional. The name of the gallery Image Definition SKU.')
+param sku string = '2019-Datacenter'
+
+@description('Optional. The minimum number of the CPU cores recommended for this image.')
+@minValue(1)
+@maxValue(128)
+param minRecommendedvCPUs int = 1
+
+@description('Optional. The maximum number of the CPU cores recommended for this image.')
+@minValue(1)
+@maxValue(128)
+param maxRecommendedvCPUs int = 4
+
+@description('Optional. The minimum amount of RAM in GB recommended for this image.')
+@minValue(1)
+@maxValue(4000)
+param minRecommendedMemory int = 4
+
+@description('Optional. The maximum amount of RAM in GB recommended for this image.')
+@minValue(1)
+@maxValue(4000)
+param maxRecommendedMemory int = 16
+
+@description('Optional. The hypervisor generation of the Virtual Machine. Applicable to OS disks only. - V1 or V2')
+@allowed([
+ 'V1'
+ 'V2'
+])
+param hyperVGeneration string = 'V1'
+/*
+@description('Optional. The description of this gallery Image Definition resource. This property is updatable.')
+param imageDefinitionDescription string = ''
+
+@description('Optional. The Eula agreement for the gallery Image Definition. Has to be a valid URL.')
+param eula string = ''
+
+@description('Optional. The privacy statement uri. Has to be a valid URL.')
+param privacyStatementUri string = ''
+
+@description('Optional. The release note uri. Has to be a valid URL.')
+param releaseNoteUri string = ''
+
+@description('Optional. The product ID.')
+param productName string = ''
+
+@description('Optional. The plan ID.')
+param planName string = ''
+
+@description('Optional. The publisher ID.')
+param planPublisherName string = ''
+
+@description('Optional. The end of life date of the gallery Image Definition. This property can be used for decommissioning purposes. This property is updatable. Allowed format: 2020-01-10T23:00:00.000Z')
+param endOfLife string = ''
+
+@description('Optional. List of the excluded disk types. E.g. Standard_LRS')
+param excludedDiskTypes array = []
+*/
+@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 for all resources.')
+param tags object = {}
+
+module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) {
+ name: 'pid-${cuaId}'
+ params: {}
+}
+
+resource gallery 'Microsoft.Compute/galleries@2020-09-30' existing = {
+ name: galleryName
+}
+
+resource image 'Microsoft.Compute/galleries/images@2020-09-30' = {
+ name: name
+ parent: gallery
+ location: location
+ tags: tags
+ properties: {
+ osType: osType
+ osState: osState
+ identifier: {
+ publisher: publisher
+ offer: offer
+ sku: sku
+ }
+ recommended: {
+ vCPUs: {
+ min: minRecommendedvCPUs
+ max: maxRecommendedvCPUs
+ }
+ memory: {
+ min: minRecommendedMemory
+ max: maxRecommendedMemory
+ }
+ }
+ hyperVGeneration: hyperVGeneration
+
+ /// Options below break the VM creation from Image Gallery. Therefore, it's commented out for AVD
+
+ /* description: imageDefinitionDescription
+ eula: eula
+ privacyStatementUri: privacyStatementUri
+ releaseNoteUri: releaseNoteUri
+ purchasePlan: {
+ product: !empty(productName) ? productName : null
+ name: !empty(planName) ? planName : null
+ publisher: !empty(planPublisherName) ? planPublisherName : null
+ }
+ endOfLifeDate: endOfLife
+ disallowed: {
+ diskTypes: excludedDiskTypes
+ } */
+ }
+}
+
+module galleryImage_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: {
+ name: '${deployment().name}-Rbac-${index}'
+ params: {
+ principalIds: roleAssignment.principalIds
+ roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName
+ resourceId: image.id
+ }
+}]
+
+@description('The resource group the image was deployed into')
+output resourceGroupName string = resourceGroup().name
+
+@description('The resource ID of the image')
+output resourceId string = image.id
+
+@description('The name of the image')
+output name string = image.name
diff --git a/carml/1.0.0/Microsoft.Compute/galleries/images/imageDefinition.bicep b/carml/1.0.0/Microsoft.Compute/galleries/images/imageDefinition.bicep
new file mode 100644
index 000000000..7a287977a
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/galleries/images/imageDefinition.bicep
@@ -0,0 +1,88 @@
+param imageDefinitionPropertiesName object
+param location string
+param SIGname string
+@description('Optional. OS type of the image to be created.')
+@allowed([
+ 'Windows'
+ 'Linux'
+])
+param osType string = 'Windows'
+
+@description('Optional. This property allows the user to specify whether the virtual machines created under this image are \'Generalized\' or \'Specialized\'.')
+@allowed([
+ 'Generalized'
+ 'Specialized'
+])
+param osState string = 'Generalized'
+
+@description('Optional. The hypervisor generation of the Virtual Machine. Applicable to OS disks only. - V1 or V2')
+@allowed([
+ 'V1'
+ 'V2'
+])
+param hyperVGeneration string = 'V1'
+
+@description('Optional. The name of the gallery Image Definition publisher.')
+param publisher string = 'MicrosoftWindowsServer'
+
+@description('Optional. The name of the gallery Image Definition offer.')
+param offer string = 'WindowsServer'
+
+@description('Optional. The name of the gallery Image Definition SKU.')
+param sku string = '2019-Datacenter'
+
+@description('Optional. The minimum number of the CPU cores recommended for this image.')
+@minValue(1)
+@maxValue(128)
+param minRecommendedvCPUs int = 1
+
+@description('Optional. The maximum number of the CPU cores recommended for this image.')
+@minValue(1)
+@maxValue(128)
+param maxRecommendedvCPUs int = 4
+
+@description('Optional. The minimum amount of RAM in GB recommended for this image.')
+@minValue(1)
+@maxValue(4000)
+param minRecommendedMemory int = 4
+
+@description('Optional. The maximum amount of RAM in GB recommended for this image.')
+@minValue(1)
+@maxValue(4000)
+param maxRecommendedMemory int = 16
+
+var ImageDefinitionName = '${SIGname}/${imageDefinitionPropertiesName}'
+
+resource imageDefinition 'Microsoft.Compute/galleries/images@2020-09-30' = {
+ name: ImageDefinitionName
+ location: location
+ properties: {
+ osType: 'Windows'
+ osState: 'Generalized'
+ identifier: {
+ publisher: publisher
+ offer: offer
+ sku: sku
+ }
+ recommended: {
+ vCPUs: {
+ min: minRecommendedvCPUs
+ max: maxRecommendedvCPUs
+ }
+ memory: {
+ min: minRecommendedMemory
+ max: maxRecommendedMemory
+ }
+ }
+ hyperVGeneration: hyperVGeneration
+ }
+}
+
+@description('The resource group the image was deployed into')
+output resourceGroupName string = resourceGroup().name
+
+@description('The resource ID of the image')
+output resourceId string = imageDefinition.id
+
+@description('The name of the image')
+output name string = imageDefinition.name
diff --git a/carml/1.0.0/Microsoft.Compute/galleries/images/readme.md b/carml/1.0.0/Microsoft.Compute/galleries/images/readme.md
new file mode 100644
index 000000000..916fab525
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/galleries/images/readme.md
@@ -0,0 +1,92 @@
+# Shared Image Definition `[Microsoft.Compute/galleries/images]`
+
+This module deploys an Image Definition in a Shared Image Gallery.
+
+## Resource types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/roleAssignments` | 2021-04-01-preview |
+| `Microsoft.Compute/galleries/images` | 2020-09-30 |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered |
+| `endOfLife` | string | | | Optional. The end of life date of the gallery Image Definition. This property can be used for decommissioning purposes. This property is updatable. Allowed format: 2020-01-10T23:00:00.000Z |
+| `eula` | string | | | Optional. The Eula agreement for the gallery Image Definition. Has to be a valid URL. |
+| `excludedDiskTypes` | array | `[]` | | Optional. List of the excluded disk types. E.g. Standard_LRS |
+| `galleryName` | string | | | Required. Name of the Azure Shared Image Gallery |
+| `hyperVGeneration` | string | `V1` | `[V1, V2]` | Optional. The hypervisor generation of the Virtual Machine. Applicable to OS disks only. - V1 or V2 |
+| `imageDefinitionDescription` | string | | | Optional. The description of this gallery Image Definition resource. This property is updatable. |
+| `location` | string | `[resourceGroup().location]` | | Optional. Location for all resources. |
+| `maxRecommendedMemory` | int | `16` | | Optional. The maximum amount of RAM in GB recommended for this image. |
+| `maxRecommendedvCPUs` | int | `4` | | Optional. The maximum number of the CPU cores recommended for this image. |
+| `minRecommendedMemory` | int | `4` | | Optional. The minimum amount of RAM in GB recommended for this image. |
+| `minRecommendedvCPUs` | int | `1` | | Optional. The minimum number of the CPU cores recommended for this image. |
+| `name` | string | | | Required. Name of the image definition. |
+| `offer` | string | `WindowsServer` | | Optional. The name of the gallery Image Definition offer. |
+| `osState` | string | `Generalized` | `[Generalized, Specialized]` | Optional. This property allows the user to specify whether the virtual machines created under this image are 'Generalized' or 'Specialized'. |
+| `osType` | string | `Windows` | `[Windows, Linux]` | Optional. OS type of the image to be created. |
+| `planName` | string | | | Optional. The plan ID. |
+| `planPublisherName` | string | | | Optional. The publisher ID. |
+| `privacyStatementUri` | string | | | Optional. The privacy statement uri. Has to be a valid URL. |
+| `productName` | string | | | Optional. The product ID. |
+| `publisher` | string | `MicrosoftWindowsServer` | | Optional. The name of the gallery Image Definition publisher. |
+| `releaseNoteUri` | string | | | Optional. The release note uri. Has to be a valid URL. |
+| `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' |
+| `sku` | string | `2019-Datacenter` | | Optional. The name of the gallery Image Definition SKU. |
+| `tags` | object | `{object}` | | Optional. Tags for all resources. |
+
+### Parameter Usage: `roleAssignments`
+
+```json
+"roleAssignments": {
+ "value": [
+ {
+ "roleDefinitionIdOrName": "Reader",
+ "principalIds": [
+ "12345678-1234-1234-1234-123456789012", // object 1
+ "78945612-1234-1234-1234-123456789012" // object 2
+ ]
+ },
+ {
+ "roleDefinitionIdOrName": "/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11",
+ "principalIds": [
+ "12345678-1234-1234-1234-123456789012" // object 1
+ ]
+ }
+ ]
+}
+```
+
+### 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"
+ }
+}
+```
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The name of the image |
+| `resourceGroupName` | string | The resource group the image was deployed into |
+| `resourceId` | string | The resource ID of the image |
+
+## Template references
+
+- [Galleries/Images](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Compute/2020-09-30/galleries/images)
+- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/roleAssignments)
diff --git a/carml/1.0.0/Microsoft.Compute/galleries/images/version.json b/carml/1.0.0/Microsoft.Compute/galleries/images/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/galleries/images/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Compute/galleries/readme.md b/carml/1.0.0/Microsoft.Compute/galleries/readme.md
new file mode 100644
index 000000000..6086b7d95
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/galleries/readme.md
@@ -0,0 +1,79 @@
+# Azure Compute Galleries `[Microsoft.Compute/galleries]`
+
+This module deploys an Azure compute gallery (formerly known as shared image gallery).
+
+## Resource Types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/locks` | 2017-04-01 |
+| `Microsoft.Authorization/roleAssignments` | 2021-04-01-preview |
+| `Microsoft.Compute/galleries` | 2020-09-30 |
+| `Microsoft.Compute/galleries/images` | 2020-09-30 |
+
+## Parameters
+
+| Parameter Name | Type | Default Value | Possible Values | Description |
+| :-- | :-- | :-- | :-- | :-- |
+| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered |
+| `galleryDescription` | string | | | Optional. Description of the Azure Shared Image Gallery |
+| `images` | _[images](images/readme.md)_ array | `[]` | | Optional. Images to create |
+| `location` | string | `[resourceGroup().location]` | | Optional. Location for all resources. |
+| `lock` | string | `NotSpecified` | `[CanNotDelete, NotSpecified, ReadOnly]` | Optional. Specify the type of lock. |
+| `name` | string | | | Required. Name of the Azure Shared Image Gallery |
+| `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' |
+| `tags` | object | `{object}` | | Optional. Tags for all resources. |
+
+### Parameter Usage: `roleAssignments`
+
+```json
+"roleAssignments": {
+ "value": [
+ {
+ "roleDefinitionIdOrName": "Reader",
+ "principalIds": [
+ "12345678-1234-1234-1234-123456789012", // object 1
+ "78945612-1234-1234-1234-123456789012" // object 2
+ ]
+ },
+ {
+ "roleDefinitionIdOrName": "/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11",
+ "principalIds": [
+ "12345678-1234-1234-1234-123456789012" // object 1
+ ]
+ }
+ ]
+}
+```
+
+### 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"
+ }
+}
+```
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The name of the deployed image gallery |
+| `resourceGroupName` | string | The resource group of the deployed image gallery |
+| `resourceId` | string | The resource ID of the deployed image gallery |
+
+## Template references
+
+- [Galleries](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Compute/2020-09-30/galleries)
+- [Galleries/Images](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Compute/2020-09-30/galleries/images)
+- [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/roleAssignments)
diff --git a/carml/1.0.0/Microsoft.Compute/galleries/version.json b/carml/1.0.0/Microsoft.Compute/galleries/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/galleries/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Compute/images/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.Compute/images/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/images/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.Compute/images/.bicep/nested_rbac.bicep b/carml/1.0.0/Microsoft.Compute/images/.bicep/nested_rbac.bicep
new file mode 100644
index 000000000..aa3a3fa03
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/images/.bicep/nested_rbac.bicep
@@ -0,0 +1,36 @@
+param principalIds array
+param roleDefinitionIdOrName string
+param resourceId string
+
+var builtInRoleNames = {
+ 'Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')
+ 'Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')
+ 'Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')
+ 'Avere Cluster Create': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a7b1b19a-0e83-4fe5-935c-faaefbfd18c3')
+ 'Avere Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')
+ 'Azure Service Deploy Release Management Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '21d96096-b162-414a-8302-d8354f9d91b2')
+ 'CAL-Custom-Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b266cd7-0bba-4ae2-8423-90ede5e1e898')
+ 'Log Analytics Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')
+ 'Log Analytics Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')
+ 'Managed Application Contributor Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')
+ 'Managed Application Operator Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')
+ 'Managed Applications Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')
+ 'masterreader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a48d7796-14b4-4889-afef-fbb65a93e5a2')
+ 'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')
+ 'Monitoring Metrics Publisher': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')
+ 'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')
+ 'myCustomRoleAtSub': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '60cb79d9-783a-50a4-9f05-d4c579fb8ce3')
+}
+
+resource image 'Microsoft.Compute/images@2021-04-01' existing = {
+ name: last(split(resourceId, '/'))
+}
+
+resource roleAssignment 'Microsoft.Authorization/roleAssignments@2021-04-01-preview' = [for principalId in principalIds: {
+ name: guid(image.name, principalId, roleDefinitionIdOrName)
+ properties: {
+ roleDefinitionId: contains(builtInRoleNames, roleDefinitionIdOrName) ? builtInRoleNames[roleDefinitionIdOrName] : roleDefinitionIdOrName
+ principalId: principalId
+ }
+ scope: image
+}]
diff --git a/carml/1.0.0/Microsoft.Compute/images/.parameters/parameters.json b/carml/1.0.0/Microsoft.Compute/images/.parameters/parameters.json
new file mode 100644
index 000000000..85e8b306e
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/images/.parameters/parameters.json
@@ -0,0 +1,37 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-az-img-x-001"
+ },
+ "osAccountType": {
+ "value": "Premium_LRS"
+ },
+ "osType": {
+ "value": "Windows"
+ },
+ "osDiskBlobUri": {
+ "value": "https://adp<>azsax001.blob.core.windows.net/vhds/adp-<>-az-imgt-x-001.vhd"
+ },
+ "osDiskCaching": {
+ "value": "ReadWrite"
+ },
+ "zoneResilient": {
+ "value": true
+ },
+ "hyperVGeneration": {
+ "value": "V1"
+ },
+ "roleAssignments": {
+ "value": [
+ {
+ "roleDefinitionIdOrName": "Reader",
+ "principalIds": [
+ "<>"
+ ]
+ }
+ ]
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Compute/images/deploy.bicep b/carml/1.0.0/Microsoft.Compute/images/deploy.bicep
new file mode 100644
index 000000000..f17102d68
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/images/deploy.bicep
@@ -0,0 +1,74 @@
+@description('Required. The name of the image.')
+param name string
+
+@description('Optional. Location for all resources.')
+param location string = resourceGroup().location
+
+@description('Required. The Virtual Hard Disk.')
+param osDiskBlobUri string
+
+@description('Required. This property allows you to specify the type of the OS that is included in the disk if creating a VM from a custom image. - Windows or Linux')
+param osType string
+
+@description('Optional. Specifies the caching requirements. Default: None for Standard storage. ReadOnly for Premium storage. - None, ReadOnly, ReadWrite')
+param osDiskCaching string
+
+@description('Optional. Specifies the storage account type for the managed disk. NOTE: UltraSSD_LRS can only be used with data disks, it cannot be used with OS Disk. - Standard_LRS, Premium_LRS, StandardSSD_LRS, UltraSSD_LRS')
+param osAccountType string
+
+@description('Optional. Default is false. Specifies whether an image is zone resilient or not. Zone resilient images can be created only in regions that provide Zone Redundant Storage (ZRS).')
+param zoneResilient bool = false
+
+@description('Optional. Gets the HyperVGenerationType of the VirtualMachine created from the image. - V1 or V2')
+param hyperVGeneration string = 'V1'
+
+@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 resource.')
+param tags object = {}
+
+@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 image 'Microsoft.Compute/images@2021-04-01' = {
+ name: name
+ location: location
+ tags: tags
+ properties: {
+ storageProfile: {
+ osDisk: {
+ osType: osType
+ blobUri: osDiskBlobUri
+ caching: osDiskCaching
+ storageAccountType: osAccountType
+ }
+ dataDisks: []
+ zoneResilient: zoneResilient
+ }
+ hyperVGeneration: hyperVGeneration
+ }
+}
+
+module image_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: {
+ name: '${uniqueString(deployment().name, location)}-Image-Rbac-${index}'
+ params: {
+ principalIds: roleAssignment.principalIds
+ roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName
+ resourceId: image.id
+ }
+}]
+
+@description('The resource ID of the image')
+output resourceId string = image.id
+
+@description('The resource group the image was deployed into')
+output resourceGroupName string = resourceGroup().name
+
+@description('The name of the image')
+output name string = image.name
diff --git a/carml/1.0.0/Microsoft.Compute/images/readme.md b/carml/1.0.0/Microsoft.Compute/images/readme.md
new file mode 100644
index 000000000..21c3e1a47
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/images/readme.md
@@ -0,0 +1,78 @@
+# Images `[Microsoft.Compute/images]`
+
+This module deploys a compute image.
+
+## Resource types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/roleAssignments` | 2021-04-01-preview |
+| `Microsoft.Compute/images` | 2021-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 |
+| `hyperVGeneration` | string | `V1` | | Optional. Gets the HyperVGenerationType of the VirtualMachine created from the image. - V1 or V2 |
+| `location` | string | `[resourceGroup().location]` | | Optional. Location for all resources. |
+| `name` | string | | | Required. The name of the image. |
+| `osAccountType` | string | | | Optional. Specifies the storage account type for the managed disk. NOTE: UltraSSD_LRS can only be used with data disks, it cannot be used with OS Disk. - Standard_LRS, Premium_LRS, StandardSSD_LRS, UltraSSD_LRS |
+| `osDiskBlobUri` | string | | | Required. The Virtual Hard Disk. |
+| `osDiskCaching` | string | | | Optional. Specifies the caching requirements. Default: None for Standard storage. ReadOnly for Premium storage. - None, ReadOnly, ReadWrite |
+| `osType` | string | | | Required. This property allows you to specify the type of the OS that is included in the disk if creating a VM from a custom image. - Windows or Linux |
+| `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' |
+| `tags` | object | `{object}` | | Optional. Tags of the resource. |
+| `zoneResilient` | bool | | | Optional. Default is false. Specifies whether an image is zone resilient or not. Zone resilient images can be created only in regions that provide Zone Redundant Storage (ZRS). |
+
+### Parameter Usage: `roleAssignments`
+
+```json
+"roleAssignments": {
+ "value": [
+ {
+ "roleDefinitionIdOrName": "Reader",
+ "principalIds": [
+ "12345678-1234-1234-1234-123456789012", // object 1
+ "78945612-1234-1234-1234-123456789012" // object 2
+ ]
+ },
+ {
+ "roleDefinitionIdOrName": "/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11",
+ "principalIds": [
+ "12345678-1234-1234-1234-123456789012" // object 1
+ ]
+ }
+ ]
+}
+```
+
+### 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"
+ }
+}
+```
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The name of the image |
+| `resourceGroupName` | string | The resource group the image was deployed into |
+| `resourceId` | string | The resource ID of the image |
+
+## Template references
+
+- [Images](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Compute/2021-04-01/images)
+- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/roleAssignments)
diff --git a/carml/1.0.0/Microsoft.Compute/images/version.json b/carml/1.0.0/Microsoft.Compute/images/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/images/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Compute/proximityPlacementGroups/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.Compute/proximityPlacementGroups/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/proximityPlacementGroups/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.Compute/proximityPlacementGroups/.bicep/nested_rbac.bicep b/carml/1.0.0/Microsoft.Compute/proximityPlacementGroups/.bicep/nested_rbac.bicep
new file mode 100644
index 000000000..b4f7f380f
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/proximityPlacementGroups/.bicep/nested_rbac.bicep
@@ -0,0 +1,38 @@
+param principalIds array
+param roleDefinitionIdOrName string
+param resourceId string
+
+var builtInRoleNames = {
+ 'Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')
+ 'Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')
+ 'Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')
+ 'Avere Cluster Create': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a7b1b19a-0e83-4fe5-935c-faaefbfd18c3')
+ 'Avere Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')
+ 'Azure Service Deploy Release Management Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '21d96096-b162-414a-8302-d8354f9d91b2')
+ 'CAL-Custom-Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b266cd7-0bba-4ae2-8423-90ede5e1e898')
+ 'Log Analytics Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')
+ 'Log Analytics Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')
+ 'Managed Application Contributor Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')
+ 'Managed Application Operator Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')
+ 'Managed Applications Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')
+ 'masterreader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a48d7796-14b4-4889-afef-fbb65a93e5a2')
+ 'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')
+ 'Monitoring Metrics Publisher': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')
+ 'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')
+ 'Reservation Purchaser': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f7b75c60-3036-4b75-91c3-6b41c27c1689')
+ 'Resource Policy Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')
+ 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')
+}
+
+resource proximityPlacementGroup 'Microsoft.Compute/proximityPlacementGroups@2021-04-01' existing = {
+ name: last(split(resourceId, '/'))
+}
+
+resource roleAssignment 'Microsoft.Authorization/roleAssignments@2021-04-01-preview' = [for principalId in principalIds: {
+ name: guid(proximityPlacementGroup.name, principalId, roleDefinitionIdOrName)
+ properties: {
+ roleDefinitionId: contains(builtInRoleNames, roleDefinitionIdOrName) ? builtInRoleNames[roleDefinitionIdOrName] : roleDefinitionIdOrName
+ principalId: principalId
+ }
+ scope: proximityPlacementGroup
+}]
diff --git a/carml/1.0.0/Microsoft.Compute/proximityPlacementGroups/.parameters/parameters.json b/carml/1.0.0/Microsoft.Compute/proximityPlacementGroups/.parameters/parameters.json
new file mode 100644
index 000000000..71bff3e25
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/proximityPlacementGroups/.parameters/parameters.json
@@ -0,0 +1,19 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-az-ppg-x-001"
+ },
+ "roleAssignments": {
+ "value": [
+ {
+ "roleDefinitionIdOrName": "Reader",
+ "principalIds": [
+ "<>"
+ ]
+ }
+ ]
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Compute/proximityPlacementGroups/deploy.bicep b/carml/1.0.0/Microsoft.Compute/proximityPlacementGroups/deploy.bicep
new file mode 100644
index 000000000..0c215b8fd
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/proximityPlacementGroups/deploy.bicep
@@ -0,0 +1,70 @@
+@description('Required. The name of the proximity placement group that is being created.')
+param name string = ''
+
+@description('Optional. Specifies the type of the proximity placement group.')
+@allowed([
+ 'Standard'
+ 'Ultra'
+])
+param proximityPlacementGroupType string = 'Standard'
+
+@description('Optional. Resource location.')
+param location string = resourceGroup().location
+
+@allowed([
+ 'CanNotDelete'
+ 'NotSpecified'
+ 'ReadOnly'
+])
+@description('Optional. Specify the type of lock.')
+param lock string = 'NotSpecified'
+
+@description('Optional. Array of role assignment objects that contain the \'roleDefinitionIdOrName\' and \'principalId\' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'')
+param roleAssignments array = []
+
+@description('Optional. Tags of the proximity placement group resource.')
+param tags object = {}
+
+@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 proximityPlacementGroup 'Microsoft.Compute/proximityPlacementGroups@2021-04-01' = {
+ name: name
+ location: location
+ tags: tags
+ properties: {
+ proximityPlacementGroupType: proximityPlacementGroupType
+ }
+}
+
+resource proximityPlacementGroup_lock 'Microsoft.Authorization/locks@2017-04-01' = if (lock != 'NotSpecified') {
+ name: '${proximityPlacementGroup.name}-${lock}-lock'
+ properties: {
+ level: lock
+ notes: lock == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot modify the resource or child resources.'
+ }
+ scope: proximityPlacementGroup
+}
+
+module proximityPlacementGroup_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: {
+ name: '${uniqueString(deployment().name, location)}-ProxPlaceGroup-Rbac-${index}'
+ params: {
+ principalIds: roleAssignment.principalIds
+ roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName
+ resourceId: proximityPlacementGroup.id
+ }
+}]
+
+@description('The name of the proximity placement group')
+output name string = proximityPlacementGroup.name
+
+@description('The resourceId the proximity placement group')
+output resourceId string = proximityPlacementGroup.id
+
+@description('The resource group the proximity placement group was deployed into')
+output resourceGroupName string = resourceGroup().name
diff --git a/carml/1.0.0/Microsoft.Compute/proximityPlacementGroups/readme.md b/carml/1.0.0/Microsoft.Compute/proximityPlacementGroups/readme.md
new file mode 100644
index 000000000..3f4fb2086
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/proximityPlacementGroups/readme.md
@@ -0,0 +1,76 @@
+# Proximity Placement Groups `[Microsoft.Compute/proximityPlacementGroups]`
+
+This template deploys a proximity placement group.
+
+## Resource types
+
+| Resource Type | API Version |
+| :-- | :-- |
+| `Microsoft.Authorization/locks` | 2017-04-01 |
+| `Microsoft.Authorization/roleAssignments` | 2021-04-01-preview |
+| `Microsoft.Compute/proximityPlacementGroups` | 2021-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 |
+| `location` | string | `[resourceGroup().location]` | | Optional. Resource location. |
+| `lock` | string | `NotSpecified` | `[CanNotDelete, NotSpecified, ReadOnly]` | Optional. Specify the type of lock. |
+| `name` | string | | | Required. The name of the proximity placement group that is being created. |
+| `proximityPlacementGroupType` | string | `Standard` | `[Standard, Ultra]` | Optional. Specifies the type of the proximity placement 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' |
+| `tags` | object | `{object}` | | Optional. Tags of the proximity placement group resource. |
+
+### Parameter Usage: `roleAssignments`
+
+```json
+"roleAssignments": {
+ "value": [
+ {
+ "roleDefinitionIdOrName": "Reader",
+ "principalIds": [
+ "12345678-1234-1234-1234-123456789012", // object 1
+ "78945612-1234-1234-1234-123456789012" // object 2
+ ]
+ },
+ {
+ "roleDefinitionIdOrName": "/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11",
+ "principalIds": [
+ "12345678-1234-1234-1234-123456789012" // object 1
+ ]
+ }
+ ]
+}
+```
+
+### 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"
+ }
+}
+```
+
+## Outputs
+
+| Output Name | Type | Description |
+| :-- | :-- | :-- |
+| `name` | string | The name of the proximity placement group |
+| `resourceGroupName` | string | The resource group the proximity placement group was deployed into |
+| `resourceId` | string | The resourceId the proximity placement group |
+
+## Template references
+
+- [Locks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2017-04-01/locks)
+- [Proximityplacementgroups](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Compute/2021-04-01/proximityPlacementGroups)
+- [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/roleAssignments)
diff --git a/carml/1.0.0/Microsoft.Compute/proximityPlacementGroups/version.json b/carml/1.0.0/Microsoft.Compute/proximityPlacementGroups/version.json
new file mode 100644
index 000000000..56f8d9ca4
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/proximityPlacementGroups/version.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
+ "version": "0.4"
+}
diff --git a/carml/1.0.0/Microsoft.Compute/virtualMachineScaleSets/.bicep/nested_cuaId.bicep b/carml/1.0.0/Microsoft.Compute/virtualMachineScaleSets/.bicep/nested_cuaId.bicep
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/virtualMachineScaleSets/.bicep/nested_cuaId.bicep
@@ -0,0 +1 @@
+
diff --git a/carml/1.0.0/Microsoft.Compute/virtualMachineScaleSets/.bicep/nested_rbac.bicep b/carml/1.0.0/Microsoft.Compute/virtualMachineScaleSets/.bicep/nested_rbac.bicep
new file mode 100644
index 000000000..6648bea36
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/virtualMachineScaleSets/.bicep/nested_rbac.bicep
@@ -0,0 +1,39 @@
+param principalIds array
+param roleDefinitionIdOrName string
+param resourceId string
+
+var builtInRoleNames = {
+ 'Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')
+ 'Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')
+ 'Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')
+ 'Avere Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')
+ 'Avere Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')
+ 'DevTest Labs User': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')
+ 'Log Analytics Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')
+ 'Log Analytics Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')
+ 'Managed Application Contributor Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')
+ 'Managed Application Operator Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')
+ 'Managed Applications Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')
+ 'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')
+ 'Monitoring Metrics Publisher': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')
+ 'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')
+ 'Reservation Purchaser': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f7b75c60-3036-4b75-91c3-6b41c27c1689')
+ 'Resource Policy Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')
+ 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')
+ 'Virtual Machine Administrator Login': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')
+ 'Virtual Machine Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')
+ 'Virtual Machine User Login': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')
+}
+
+resource vmss 'Microsoft.Compute/virtualMachineScaleSets@2021-04-01' existing = {
+ name: last(split(resourceId, '/'))
+}
+
+resource roleAssignment 'Microsoft.Authorization/roleAssignments@2021-04-01-preview' = [for principalId in principalIds: {
+ name: guid(vmss.name, principalId, roleDefinitionIdOrName)
+ properties: {
+ roleDefinitionId: contains(builtInRoleNames, roleDefinitionIdOrName) ? builtInRoleNames[roleDefinitionIdOrName] : roleDefinitionIdOrName
+ principalId: principalId
+ }
+ scope: vmss
+}]
diff --git a/carml/1.0.0/Microsoft.Compute/virtualMachineScaleSets/.parameters/linux.min.parameters.json b/carml/1.0.0/Microsoft.Compute/virtualMachineScaleSets/.parameters/linux.min.parameters.json
new file mode 100644
index 000000000..0c3f3189b
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/virtualMachineScaleSets/.parameters/linux.min.parameters.json
@@ -0,0 +1,63 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-scaleset-linux-min-001"
+ },
+ "osDisk": {
+ "value": {
+ "createOption": "fromImage",
+ "diskSizeGB": "128",
+ "managedDisk": {
+ "storageAccountType": "Premium_LRS"
+ }
+ }
+ },
+ "osType": {
+ "value": "Linux"
+ },
+ "skuName": {
+ "value": "Standard_B2s"
+ },
+ "imageReference": {
+ "value": {
+ "publisher": "Canonical",
+ "offer": "UbuntuServer",
+ "sku": "18.04-LTS",
+ "version": "latest"
+ }
+ },
+ "adminUsername": {
+ "value": "scaleSetAdmin"
+ },
+ "disablePasswordAuthentication": {
+ "value": true
+ },
+ "publicKeys": {
+ "value": [
+ {
+ "path": "/home/scaleSetAdmin/.ssh/authorized_keys",
+ "keyData": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDdOir5eO28EBwxU0Dyra7g9h0HUXDyMNFp2z8PhaTUQgHjrimkMxjYRwEOG/lxnYL7+TqZk+HcPTfbZOunHBw0Wx2CITzILt6531vmIYZGfq5YyYXbxZa5MON7L/PVivoRlPj5Z/t4RhqMhyfR7EPcZ516LJ8lXPTo8dE/bkOCS+kFBEYHvPEEKAyLs19sRcK37SeHjpX04zdg62nqtuRr00Tp7oeiTXA1xn5K5mxeAswotmd8CU0lWUcJuPBWQedo649b+L2cm52kTncOBI6YChAeyEc1PDF0Tn9FmpdOWKtI9efh+S3f8qkcVEtSTXoTeroBd31nzjAunMrZeM8Ut6dre+XeQQIjT7I8oEm+ZkIuIyq0x2fls8JXP2YJDWDqu8v1+yLGTQ3Z9XVt2lMti/7bIgYxS0JvwOr5n5L4IzKvhb4fm13LLDGFa3o7Nsfe3fPb882APE0bLFCmfyIeiPh7go70WqZHakpgIr6LCWTyePez9CsI/rfWDb6eAM8= generated-by-azure"
+ }
+ ]
+ },
+ "nicConfigurations": {
+ "value": [
+ {
+ "nicSuffix": "-nic01",
+ "ipConfigurations": [
+ {
+ "name": "ipconfig1",
+ "properties": {
+ "subnet": {
+ "id": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/adp-<>-az-vnet-x-001/subnets/<>-az-subnet-x-002"
+ }
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Compute/virtualMachineScaleSets/.parameters/linux.parameters.json b/carml/1.0.0/Microsoft.Compute/virtualMachineScaleSets/.parameters/linux.parameters.json
new file mode 100644
index 000000000..b4d6340af
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/virtualMachineScaleSets/.parameters/linux.parameters.json
@@ -0,0 +1,186 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-scaleset-linux-001"
+ },
+ "vmNamePrefix": {
+ "value": "vmsslinvm"
+ },
+ "skuName": {
+ "value": "Standard_B2s"
+ },
+ "skuCapacity": {
+ "value": 1
+ },
+ "upgradePolicyMode": {
+ "value": "Manual"
+ },
+ "vmPriority": {
+ "value": "Regular"
+ },
+ "osDisk": {
+ "value": {
+ "createOption": "fromImage",
+ "diskSizeGB": "128",
+ "managedDisk": {
+ "storageAccountType": "Premium_LRS"
+ }
+ }
+ },
+ "availabilityZones": {
+ "value": [
+ "2"
+ ]
+ },
+ "scaleSetFaultDomain": {
+ "value": 1
+ },
+ "systemAssignedIdentity": {
+ "value": true
+ },
+ "userAssignedIdentities": {
+ "value": {
+ "/subscriptions/<>/resourcegroups/validation-rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/adp-<>-az-msi-x-001": {}
+ }
+ },
+ "bootDiagnosticStorageAccountName": {
+ "value": "adp<>azsax001"
+ },
+ "osType": {
+ "value": "Linux"
+ },
+ "encryptionAtHost": {
+ "value": false
+ },
+ "imageReference": {
+ "value": {
+ "publisher": "Canonical",
+ "offer": "UbuntuServer",
+ "sku": "18.04-LTS",
+ "version": "latest"
+ }
+ },
+ "adminUsername": {
+ "value": "scaleSetAdmin"
+ },
+ "disablePasswordAuthentication": {
+ "value": true
+ },
+ "publicKeys": {
+ "value": [
+ {
+ "path": "/home/scaleSetAdmin/.ssh/authorized_keys",
+ "keyData": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDdOir5eO28EBwxU0Dyra7g9h0HUXDyMNFp2z8PhaTUQgHjrimkMxjYRwEOG/lxnYL7+TqZk+HcPTfbZOunHBw0Wx2CITzILt6531vmIYZGfq5YyYXbxZa5MON7L/PVivoRlPj5Z/t4RhqMhyfR7EPcZ516LJ8lXPTo8dE/bkOCS+kFBEYHvPEEKAyLs19sRcK37SeHjpX04zdg62nqtuRr00Tp7oeiTXA1xn5K5mxeAswotmd8CU0lWUcJuPBWQedo649b+L2cm52kTncOBI6YChAeyEc1PDF0Tn9FmpdOWKtI9efh+S3f8qkcVEtSTXoTeroBd31nzjAunMrZeM8Ut6dre+XeQQIjT7I8oEm+ZkIuIyq0x2fls8JXP2YJDWDqu8v1+yLGTQ3Z9XVt2lMti/7bIgYxS0JvwOr5n5L4IzKvhb4fm13LLDGFa3o7Nsfe3fPb882APE0bLFCmfyIeiPh7go70WqZHakpgIr6LCWTyePez9CsI/rfWDb6eAM8= generated-by-azure"
+ }
+ ]
+ },
+ "dataDisks": {
+ "value": [
+ {
+ "caching": "ReadOnly",
+ "createOption": "Empty",
+ "diskSizeGB": "256",
+ "managedDisk": {
+ "storageAccountType": "Premium_LRS"
+ }
+ },
+ {
+ "caching": "ReadOnly",
+ "createOption": "Empty",
+ "diskSizeGB": "128",
+ "managedDisk": {
+ "storageAccountType": "Premium_LRS"
+ }
+ }
+ ]
+ },
+ "nicConfigurations": {
+ "value": [
+ {
+ "nicSuffix": "-nic01",
+ "ipConfigurations": [
+ {
+ "name": "ipconfig1",
+ "properties": {
+ "subnet": {
+ "id": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/adp-<>-az-vnet-x-001/subnets/<>-az-subnet-x-002"
+ }
+ }
+ }
+ ]
+ }
+ ]
+ },
+ "roleAssignments": {
+ "value": [
+ {
+ "roleDefinitionIdOrName": "Reader",
+ "principalIds": [
+ "<>"
+ ]
+ }
+ ]
+ },
+ "diagnosticLogsRetentionInDays": {
+ "value": 7
+ },
+ "diagnosticStorageAccountId": {
+ "value": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Storage/storageAccounts/adp<>azsax001"
+ },
+ "diagnosticWorkspaceId": {
+ "value": "/subscriptions/<>/resourcegroups/validation-rg/providers/microsoft.operationalinsights/workspaces/adp-<>-az-law-x-001"
+ },
+ "diagnosticEventHubAuthorizationRuleId": {
+ "value": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.EventHub/namespaces/adp-<>-az-evhns-x-001/AuthorizationRules/RootManageSharedAccessKey"
+ },
+ "diagnosticEventHubName": {
+ "value": "adp-<>-az-evh-x-001"
+ },
+ "extensionMonitoringAgentConfig": {
+ "value": {
+ "enabled": true
+ }
+ },
+ "extensionDependencyAgentConfig": {
+ "value": {
+ "enabled": true
+ }
+ },
+ "extensionNetworkWatcherAgentConfig": {
+ "value": {
+ "enabled": true
+ }
+ },
+ "extensionDiskEncryptionConfig": {
+ "value": {
+ "enabled": true,
+ "settings": {
+ "EncryptionOperation": "EnableEncryption",
+ "KeyVaultURL": "https://adp-<>-az-kv-x-001.vault.azure.net/",
+ "KeyVaultResourceId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.KeyVault/vaults/adp-<>-az-kv-x-001",
+ "KeyEncryptionKeyURL": "https://adp-<>-az-kv-x-001.vault.azure.net/keys/keyEncryptionKey/bc3bb46d95c64367975d722f473eeae5", // ID must be updated for new keys
+ "KekVaultResourceId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.KeyVault/vaults/adp-<>-az-kv-x-001",
+ "KeyEncryptionAlgorithm": "RSA-OAEP",
+ "VolumeType": "All",
+ "ResizeOSDisk": "false"
+ }
+ }
+ },
+ "extensionCustomScriptConfig": {
+ "value": {
+ "enabled": true,
+ "fileData": [
+ {
+ "uri": "https://adp<>azsax001.blob.core.windows.net/scripts/scriptExtensionMasterInstaller.ps1",
+ "storageAccountId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Storage/storageAccounts/adp<>azsax001"
+ }
+ ],
+ "protectedSettings": {
+ "commandToExecute": "sudo apt-get update"
+ }
+ }
+ }
+ }
+}
diff --git a/carml/1.0.0/Microsoft.Compute/virtualMachineScaleSets/.parameters/windows.min.parameters.json b/carml/1.0.0/Microsoft.Compute/virtualMachineScaleSets/.parameters/windows.min.parameters.json
new file mode 100644
index 000000000..5444ff795
--- /dev/null
+++ b/carml/1.0.0/Microsoft.Compute/virtualMachineScaleSets/.parameters/windows.min.parameters.json
@@ -0,0 +1,65 @@
+{
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+ "contentVersion": "1.0.0.0",
+ "parameters": {
+ "name": {
+ "value": "<>-scaleset-win-min-001"
+ },
+ "skuName": {
+ "value": "Standard_B2s"
+ },
+ "osDisk": {
+ "value": {
+ "createOption": "fromImage",
+ "diskSizeGB": "128",
+ "managedDisk": {
+ "storageAccountType": "Premium_LRS"
+ }
+ }
+ },
+ "osType": {
+ "value": "Windows"
+ },
+ "imageReference": {
+ "value": {
+ "publisher": "MicrosoftWindowsServer",
+ "offer": "WindowsServer",
+ "sku": "2016-Datacenter",
+ "version": "latest"
+ }
+ },
+ "adminUsername": {
+ "reference": {
+ "keyVault": {
+ "id": "/subscriptions/<