diff --git a/.ps-rule/Rule.Rule.ps1 b/.ps-rule/Rule.Rule.ps1 index aedf911c807..cbdfcc14175 100644 --- a/.ps-rule/Rule.Rule.ps1 +++ b/.ps-rule/Rule.Rule.ps1 @@ -30,7 +30,7 @@ Rule 'Rule.Release' -Type 'PSRule.Rules.Rule' { # Synopsis: Rules must be added to a rule set. Rule 'Rule.RuleSet' -Type 'PSRule.Rules.Rule' { Recommend 'Add a ruleSet the to the rule.' - $Assert.Match($TargetObject, 'Tag.ruleSet', '^(2020|2021|2022|2023|2024)_(03|06|09|12)$') + $Assert.Match($TargetObject, 'Tag.ruleSet', '^(2020|2021|2022|2023|2024|2025)_(03|06|09|12)$') } # Synopsis: Annotate rules with a valid Well-Architected Framework pillar. diff --git a/docs/CHANGELOG-v1.md b/docs/CHANGELOG-v1.md index 50e7a3830fb..aa27dc49fbc 100644 --- a/docs/CHANGELOG-v1.md +++ b/docs/CHANGELOG-v1.md @@ -31,6 +31,10 @@ See [upgrade notes][1] for helpful information when upgrading from previous vers What's changed since v1.41.4: +- New rules: + - Image Builder: + - Check that image builder build and validation scripts are pinned by @BernieWhite. + [#2903](https://github.com/Azure/PSRule.Rules.Azure/issues/2903) - General improvements: - Added a new quickstart guide for using Azure Pipelines with PSRule by @that-ar-guy. [#3220](https://github.com/Azure/PSRule.Rules.Azure/pull/3220) diff --git a/docs/en/rules/Azure.ImageBuilder.CustomizeHash.md b/docs/en/rules/Azure.ImageBuilder.CustomizeHash.md new file mode 100644 index 00000000000..43e305c9357 --- /dev/null +++ b/docs/en/rules/Azure.ImageBuilder.CustomizeHash.md @@ -0,0 +1,169 @@ +--- +reviewed: 2025-03-06 +severity: Important +pillar: Security +category: SE:02 Secured development lifecycle +resource: Image Builder +online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.ImageBuilder.CustomizeHash/ +--- + +# Image Builder customization script is not pinned + +## SYNOPSIS + +External scripts that are not pinned may be modified to execute privileged actions by an unauthorized user. + +## DESCRIPTION + +When building and developing VM images it is common to execute scripts to customize and validate the image. +Scripts that are used to customize the image can be stored in a variety of locations including a public or private URLs. + +During the process of building and validating the image scripts often have privileged access to the image. +Additionally, many of the normal operating system (OS) security features are disabled during the build process. +This can make the image vulnerable to supply chain attacks that could be latter rolled out to development and production. + +Azure Image Builder allows you to configure a SHA-256 hash for external scripts. +This hash can be used to verify the integrity of the script before it is executed. + +## RECOMMENDATION + +Consider reviewing all scripts and using a hash to ensure customization scripts have not been modified since they were last reviewed. + +## EXAMPLES + +### Configure with Bicep + +To deploy image templates that pass this rule: + +- Set the `properties.customize[*].sha256Checksum` property to a SHA-256 hash if `sourceUri` or `scriptUri` is used. + - The `sha256Checksum` should be a SHA-256 hash of the script content. + - This applies when the `type` is `Shell`, `PowerShell`, or `File`. + +For example: + +```bicep +resource imageBuilder 'Microsoft.VirtualMachineImages/imageTemplates@2024-02-01' = { + name: name + location: location + identity: { + type: 'UserAssigned' + userAssignedIdentities: { + '${identityId}': {} + } + } + properties: { + source: { + type: 'PlatformImage' + publisher: 'canonical' + offer: 'ubuntu-24_04-lts' + sku: 'server' + version: 'latest' + } + distribute: [ + { + location: location + imageId: imageId + runOutputName: outputRunName + type: 'ManagedImage' + artifactTags: { + sourceType: 'PlatformImage' + sourcePublisher: 'canonical' + sourceOffer: 'ubuntu-24_04-lts' + sourceSku: 'server' + sourceVersion: 'latest' + } + } + ] + customize: [ + { + type: 'Shell' + name: 'PowerShell installation' + scriptUri: 'https://raw.githubusercontent.com/Azure/bicep-registry-modules/5bbac220dfdf8643fb0091e23095ce875f7fe54b/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Install-LinuxPowerShell.sh' + sha256Checksum: '8d469f6864a38e1cf957cd080603026bba325793edfb4fe2e8b8e7368eb15b92' + } + ] + validate: { + inVMValidations: [ + { + type: 'PowerShell' + name: 'Run PowerShell script' + scriptUri: 'https://raw.githubusercontent.com/Azure/azure-quickstart-templates/5670db39d51799c896f1f8223f32b8ba08cc816e/demos/imagebuilder-windowsbaseline/scripts/runScript.ps1' + sha256Checksum: 'c76d82a68e57b559ea82bcb191b48f5e08a391b036ba5fa0b9c3efe795131e82' + } + ] + } + } +} +``` + +### Configure with Azure template + +To deploy image templates that pass this rule: + +- Set the `properties.customize[*].sha256Checksum` property to a SHA-256 hash if `sourceUri` or `scriptUri` is used. + - The `sha256Checksum` should be a SHA-256 hash of the script content. + - This applies when the `type` is `Shell`, `PowerShell`, or `File`. + +For example: + +```json +{ + "type": "Microsoft.VirtualMachineImages/imageTemplates", + "apiVersion": "2024-02-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "identity": { + "type": "UserAssigned", + "userAssignedIdentities": { + "[format('{0}', parameters('identityId'))]": {} + } + }, + "properties": { + "source": { + "type": "PlatformImage", + "publisher": "canonical", + "offer": "ubuntu-24_04-lts", + "sku": "server", + "version": "latest" + }, + "distribute": [ + { + "location": "[parameters('location')]", + "imageId": "[parameters('imageId')]", + "runOutputName": "[parameters('outputRunName')]", + "type": "ManagedImage", + "artifactTags": { + "sourceType": "PlatformImage", + "sourcePublisher": "canonical", + "sourceOffer": "ubuntu-24_04-lts", + "sourceSku": "server", + "sourceVersion": "latest" + } + } + ], + "customize": [ + { + "type": "Shell", + "name": "PowerShell installation", + "scriptUri": "https://raw.githubusercontent.com/Azure/bicep-registry-modules/5bbac220dfdf8643fb0091e23095ce875f7fe54b/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Install-LinuxPowerShell.sh", + "sha256Checksum": "8d469f6864a38e1cf957cd080603026bba325793edfb4fe2e8b8e7368eb15b92" + } + ], + "validate": { + "inVMValidations": [ + { + "type": "PowerShell", + "name": "Run PowerShell script", + "scriptUri": "https://raw.githubusercontent.com/Azure/azure-quickstart-templates/5670db39d51799c896f1f8223f32b8ba08cc816e/demos/imagebuilder-windowsbaseline/scripts/runScript.ps1", + "sha256Checksum": "c76d82a68e57b559ea82bcb191b48f5e08a391b036ba5fa0b9c3efe795131e82" + } + ] + } + } +} +``` + +## LINKS + +- [SE:02 Secured development lifecycle](https://learn.microsoft.com/azure/well-architected/security/secure-development-lifecycle) +- [Azure deployment reference](https://learn.microsoft.com/azure/templates/Microsoft.VirtualMachineImages/imageTemplates) diff --git a/docs/en/rules/Azure.ImageBuilder.ValidateHash.md b/docs/en/rules/Azure.ImageBuilder.ValidateHash.md new file mode 100644 index 00000000000..df76a8096ac --- /dev/null +++ b/docs/en/rules/Azure.ImageBuilder.ValidateHash.md @@ -0,0 +1,169 @@ +--- +reviewed: 2025-03-06 +severity: Important +pillar: Security +category: SE:02 Secured development lifecycle +resource: Image Builder +online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.ImageBuilder.ValidateHash/ +--- + +# Image Builder validation script is not pinned + +## SYNOPSIS + +External scripts that are not pinned may be modified to execute privileged actions by an unauthorized user. + +## DESCRIPTION + +When building and developing VM images it is common to execute scripts to customize and validate the image. +Scripts that are used to validate the image can be stored in a variety of locations including a public or private URLs. + +During the process of building and validating the image scripts often have privileged access to the image. +Additionally, many of the normal operating system (OS) security features are disabled during the build process. +This can make the image vulnerable to supply chain attacks that could be latter rolled out to development and production. + +Azure Image Builder allows you to configure a SHA-256 hash for external scripts. +This hash can be used to verify the integrity of the script before it is executed. + +## RECOMMENDATION + +Consider reviewing all scripts and using a hash to ensure validation scripts have not been modified since they were last reviewed. + +## EXAMPLES + +### Configure with Bicep + +To deploy image templates that pass this rule: + +- Set the `properties.validate.inVMValidations[*].sha256Checksum` property to a SHA-256 hash if `sourceUri` or `scriptUri` is used. + - The `sha256Checksum` should be a SHA-256 hash of the script content. + - This applies when the `type` is `Shell`, `PowerShell`, or `File`. + +For example: + +```bicep +resource imageBuilder 'Microsoft.VirtualMachineImages/imageTemplates@2024-02-01' = { + name: name + location: location + identity: { + type: 'UserAssigned' + userAssignedIdentities: { + '${identityId}': {} + } + } + properties: { + source: { + type: 'PlatformImage' + publisher: 'canonical' + offer: 'ubuntu-24_04-lts' + sku: 'server' + version: 'latest' + } + distribute: [ + { + location: location + imageId: imageId + runOutputName: outputRunName + type: 'ManagedImage' + artifactTags: { + sourceType: 'PlatformImage' + sourcePublisher: 'canonical' + sourceOffer: 'ubuntu-24_04-lts' + sourceSku: 'server' + sourceVersion: 'latest' + } + } + ] + customize: [ + { + type: 'Shell' + name: 'PowerShell installation' + scriptUri: 'https://raw.githubusercontent.com/Azure/bicep-registry-modules/5bbac220dfdf8643fb0091e23095ce875f7fe54b/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Install-LinuxPowerShell.sh' + sha256Checksum: '8d469f6864a38e1cf957cd080603026bba325793edfb4fe2e8b8e7368eb15b92' + } + ] + validate: { + inVMValidations: [ + { + type: 'PowerShell' + name: 'Run PowerShell script' + scriptUri: 'https://raw.githubusercontent.com/Azure/azure-quickstart-templates/5670db39d51799c896f1f8223f32b8ba08cc816e/demos/imagebuilder-windowsbaseline/scripts/runScript.ps1' + sha256Checksum: 'c76d82a68e57b559ea82bcb191b48f5e08a391b036ba5fa0b9c3efe795131e82' + } + ] + } + } +} +``` + +### Configure with Azure template + +To deploy image templates that pass this rule: + +- Set the `properties.validate.inVMValidations[*].sha256Checksum` property to a SHA-256 hash if `sourceUri` or `scriptUri` is used. + - The `sha256Checksum` should be a SHA-256 hash of the script content. + - This applies when the `type` is `Shell`, `PowerShell`, or `File`. + +For example: + +```json +{ + "type": "Microsoft.VirtualMachineImages/imageTemplates", + "apiVersion": "2024-02-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "identity": { + "type": "UserAssigned", + "userAssignedIdentities": { + "[format('{0}', parameters('identityId'))]": {} + } + }, + "properties": { + "source": { + "type": "PlatformImage", + "publisher": "canonical", + "offer": "ubuntu-24_04-lts", + "sku": "server", + "version": "latest" + }, + "distribute": [ + { + "location": "[parameters('location')]", + "imageId": "[parameters('imageId')]", + "runOutputName": "[parameters('outputRunName')]", + "type": "ManagedImage", + "artifactTags": { + "sourceType": "PlatformImage", + "sourcePublisher": "canonical", + "sourceOffer": "ubuntu-24_04-lts", + "sourceSku": "server", + "sourceVersion": "latest" + } + } + ], + "customize": [ + { + "type": "Shell", + "name": "PowerShell installation", + "scriptUri": "https://raw.githubusercontent.com/Azure/bicep-registry-modules/5bbac220dfdf8643fb0091e23095ce875f7fe54b/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Install-LinuxPowerShell.sh", + "sha256Checksum": "8d469f6864a38e1cf957cd080603026bba325793edfb4fe2e8b8e7368eb15b92" + } + ], + "validate": { + "inVMValidations": [ + { + "type": "PowerShell", + "name": "Run PowerShell script", + "scriptUri": "https://raw.githubusercontent.com/Azure/azure-quickstart-templates/5670db39d51799c896f1f8223f32b8ba08cc816e/demos/imagebuilder-windowsbaseline/scripts/runScript.ps1", + "sha256Checksum": "c76d82a68e57b559ea82bcb191b48f5e08a391b036ba5fa0b9c3efe795131e82" + } + ] + } + } +} +``` + +## LINKS + +- [SE:02 Secured development lifecycle](https://learn.microsoft.com/azure/well-architected/security/secure-development-lifecycle) +- [Azure deployment reference](https://learn.microsoft.com/azure/templates/Microsoft.VirtualMachineImages/imageTemplates) diff --git a/docs/examples/resources/image-builder.bicep b/docs/examples/resources/image-builder.bicep new file mode 100644 index 00000000000..a6e9924eb81 --- /dev/null +++ b/docs/examples/resources/image-builder.bicep @@ -0,0 +1,73 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +// Bicep documentation examples + +@description('The name of the resource.') +param name string + +@description('The location resources will be deployed.') +param location string = resourceGroup().location + +@description('The image ID to distribute the image to.') +param imageId string + +@description('The name of the output run to distribute the image to.') +param outputRunName string + +@description('The managed identity used to create Azure resources.') +param identityId string + +// An example of a resource that creates an image builder using external scripts and hashes. +resource imageBuilder 'Microsoft.VirtualMachineImages/imageTemplates@2024-02-01' = { + name: name + location: location + identity: { + type: 'UserAssigned' + userAssignedIdentities: { + '${identityId}': {} + } + } + properties: { + source: { + type: 'PlatformImage' + publisher: 'canonical' + offer: 'ubuntu-24_04-lts' + sku: 'server' + version: 'latest' + } + distribute: [ + { + location: location + imageId: imageId + runOutputName: outputRunName + type: 'ManagedImage' + artifactTags: { + sourceType: 'PlatformImage' + sourcePublisher: 'canonical' + sourceOffer: 'ubuntu-24_04-lts' + sourceSku: 'server' + sourceVersion: 'latest' + } + } + ] + customize: [ + { + type: 'Shell' + name: 'PowerShell installation' + scriptUri: 'https://raw.githubusercontent.com/Azure/bicep-registry-modules/5bbac220dfdf8643fb0091e23095ce875f7fe54b/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Install-LinuxPowerShell.sh' + sha256Checksum: '8d469f6864a38e1cf957cd080603026bba325793edfb4fe2e8b8e7368eb15b92' + } + ] + validate: { + inVMValidations: [ + { + type: 'PowerShell' + name: 'Run PowerShell script' + scriptUri: 'https://raw.githubusercontent.com/Azure/azure-quickstart-templates/5670db39d51799c896f1f8223f32b8ba08cc816e/demos/imagebuilder-windowsbaseline/scripts/runScript.ps1' + sha256Checksum: 'c76d82a68e57b559ea82bcb191b48f5e08a391b036ba5fa0b9c3efe795131e82' + } + ] + } + } +} diff --git a/docs/examples/resources/image-builder.json b/docs/examples/resources/image-builder.json new file mode 100644 index 00000000000..90c636d286d --- /dev/null +++ b/docs/examples/resources/image-builder.json @@ -0,0 +1,100 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.33.93.31351", + "templateHash": "6607772561245464948" + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the resource." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "The location resources will be deployed." + } + }, + "imageId": { + "type": "string", + "metadata": { + "description": "The image ID to distribute the image to." + } + }, + "outputRunName": { + "type": "string", + "metadata": { + "description": "The name of the output run to distribute the image to." + } + }, + "identityId": { + "type": "string", + "metadata": { + "description": "The managed identity used to create Azure resources." + } + } + }, + "resources": [ + { + "type": "Microsoft.VirtualMachineImages/imageTemplates", + "apiVersion": "2024-02-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "identity": { + "type": "UserAssigned", + "userAssignedIdentities": { + "[format('{0}', parameters('identityId'))]": {} + } + }, + "properties": { + "source": { + "type": "PlatformImage", + "publisher": "canonical", + "offer": "ubuntu-24_04-lts", + "sku": "server", + "version": "latest" + }, + "distribute": [ + { + "location": "[parameters('location')]", + "imageId": "[parameters('imageId')]", + "runOutputName": "[parameters('outputRunName')]", + "type": "ManagedImage", + "artifactTags": { + "sourceType": "PlatformImage", + "sourcePublisher": "canonical", + "sourceOffer": "ubuntu-24_04-lts", + "sourceSku": "server", + "sourceVersion": "latest" + } + } + ], + "customize": [ + { + "type": "Shell", + "name": "PowerShell installation", + "scriptUri": "https://raw.githubusercontent.com/Azure/bicep-registry-modules/5bbac220dfdf8643fb0091e23095ce875f7fe54b/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Install-LinuxPowerShell.sh", + "sha256Checksum": "8d469f6864a38e1cf957cd080603026bba325793edfb4fe2e8b8e7368eb15b92" + } + ], + "validate": { + "inVMValidations": [ + { + "type": "PowerShell", + "name": "Run PowerShell script", + "scriptUri": "https://raw.githubusercontent.com/Azure/azure-quickstart-templates/5670db39d51799c896f1f8223f32b8ba08cc816e/demos/imagebuilder-windowsbaseline/scripts/runScript.ps1", + "sha256Checksum": "c76d82a68e57b559ea82bcb191b48f5e08a391b036ba5fa0b9c3efe795131e82" + } + ] + } + } + } + ] +} \ No newline at end of file diff --git a/src/PSRule.Rules.Azure/rules/Azure.ImageBuilder.Rule.yaml b/src/PSRule.Rules.Azure/rules/Azure.ImageBuilder.Rule.yaml new file mode 100644 index 00000000000..b56a5af76d5 --- /dev/null +++ b/src/PSRule.Rules.Azure/rules/Azure.ImageBuilder.Rule.yaml @@ -0,0 +1,80 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +# +# Validation rules for Azure Image Builder +# + +--- +# Synopsis: External scripts that are not pinned may be modified to execute privileged actions by an unauthorized user. +apiVersion: github.com/microsoft/PSRule/v1 +kind: Rule +metadata: + name: Azure.ImageBuilder.CustomizeHash + ref: AZR-000453 + tags: + release: GA + ruleSet: 2025_03 + Azure.WAF/pillar: Security +spec: + type: + - Microsoft.VirtualMachineImages/imageTemplates + condition: + anyOf: + - field: properties.customize + hasValue: false + - field: properties.customize + where: + anyOf: + - allOf: + - field: type + equals: File + - field: sourceUri + hasValue: true + - allOf: + - field: type + in: + - PowerShell + - Shell + - field: scriptUri + hasValue: true + allOf: + - field: sha256Checksum + hasValue: true + +--- +# Synopsis: External scripts that are not pinned may be modified to execute privileged actions by an unauthorized user. +apiVersion: github.com/microsoft/PSRule/v1 +kind: Rule +metadata: + name: Azure.ImageBuilder.ValidateHash + ref: AZR-000454 + tags: + release: GA + ruleSet: 2025_03 + Azure.WAF/pillar: Security +spec: + type: + - Microsoft.VirtualMachineImages/imageTemplates + condition: + anyOf: + - field: properties.validate.inVMValidations + hasValue: false + - field: properties.validate.inVMValidations + where: + anyOf: + - allOf: + - field: type + equals: File + - field: sourceUri + hasValue: true + - allOf: + - field: type + in: + - PowerShell + - Shell + - field: scriptUri + hasValue: true + allOf: + - field: sha256Checksum + hasValue: true diff --git a/tests/PSRule.Rules.Azure.Tests/Azure.ImageBuilder.Tests.ps1 b/tests/PSRule.Rules.Azure.Tests/Azure.ImageBuilder.Tests.ps1 new file mode 100644 index 00000000000..2231ce1ca1c --- /dev/null +++ b/tests/PSRule.Rules.Azure.Tests/Azure.ImageBuilder.Tests.ps1 @@ -0,0 +1,71 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +# +# Unit tests for User Assigned Managed Identity rules +# + +[CmdletBinding()] +param () + +BeforeAll { + # Setup error handling + $ErrorActionPreference = 'Stop'; + Set-StrictMode -Version latest; + + if ($Env:SYSTEM_DEBUG -eq 'true') { + $VerbosePreference = 'Continue'; + } + + # Setup tests paths + $rootPath = $PWD; + Import-Module (Join-Path -Path $rootPath -ChildPath out/modules/PSRule.Rules.Azure) -Force; + $here = (Resolve-Path $PSScriptRoot).Path; +} + +Describe 'Azure.ImageBuilder' -Tag 'AIB', 'ImageBuilder', 'ImageTemplate' { + Context 'Conditions' { + BeforeAll { + $invokeParams = @{ + Baseline = 'Azure.All' + Module = 'PSRule.Rules.Azure' + WarningAction = 'Ignore' + ErrorAction = 'Stop' + } + $dataPath = Join-Path -Path $here -ChildPath 'Resources.ImageBuilder.Source.json'; + $result = Invoke-PSRule @invokeParams -InputPath $dataPath -Outcome All; + } + + It 'Azure.ImageBuilder.CustomizeHash' { + $filteredResult = $result | Where-Object { $_.RuleName -eq 'Azure.ImageBuilder.CustomizeHash' }; + + # Fail + $ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' }); + $ruleResult | Should -Not -BeNullOrEmpty; + $ruleResult.TargetName | Should -BeIn 'image-001-0'; + $ruleResult.Length | Should -Be 1; + + # Pass + $ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' }); + $ruleResult | Should -Not -BeNullOrEmpty; + $ruleResult.TargetName | Should -BeIn 'image-002-0', 'image-003-0'; + $ruleResult.Length | Should -Be 2; + } + + It 'Azure.ImageBuilder.ValidateHash' { + $filteredResult = $result | Where-Object { $_.RuleName -eq 'Azure.ImageBuilder.ValidateHash' }; + + # Fail + $ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' }); + $ruleResult | Should -Not -BeNullOrEmpty; + $ruleResult.TargetName | Should -BeIn 'image-001-0'; + $ruleResult.Length | Should -Be 1; + + # Pass + $ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' }); + $ruleResult | Should -Not -BeNullOrEmpty; + $ruleResult.TargetName | Should -BeIn 'image-002-0', 'image-003-0'; + $ruleResult.Length | Should -Be 2; + } + } +} diff --git a/tests/PSRule.Rules.Azure.Tests/Resources.ImageBuilder.Source.bicep b/tests/PSRule.Rules.Azure.Tests/Resources.ImageBuilder.Source.bicep new file mode 100644 index 00000000000..5792baafef5 --- /dev/null +++ b/tests/PSRule.Rules.Azure.Tests/Resources.ImageBuilder.Source.bicep @@ -0,0 +1,108 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +// An example if a failing image template with source hashes. +module image_001 'br/public:avm/res/virtual-machine-images/image-template:0.5.0' = { + params: { + name: 'image-001' + baseTime: '0' + distributions: [ + { + type: 'ManagedImage' + imageName: 'image-001' + } + ] + imageSource: { + type: 'PlatformImage' + publisher: 'canonical' + offer: 'ubuntu-24_04-lts' + sku: 'server' + version: 'latest' + } + managedIdentities: {} + customizationSteps: [ + { + type: 'Shell' + name: 'PowerShell installation' + scriptUri: 'https://raw.githubusercontent.com/Azure/bicep-registry-modules/refs/heads/main/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Install-LinuxPowerShell.sh' + } + ] + validationProcess: { + inVMValidations: [ + { + type: 'Shell' + name: 'Validate PowerShell' + scriptUri: 'https://raw.githubusercontent.com/Azure/bicep-registry-modules/refs/heads/main/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Install-LinuxPowerShell.sh' + } + ] + } + buildTimeoutInMinutes: 60 + vmSize: 'Standard_D2s_v3' + } +} + +// An example if a passing image template with source hashes. +module image_002 'br/public:avm/res/virtual-machine-images/image-template:0.5.0' = { + params: { + name: 'image-002' + baseTime: '0' + distributions: [ + { + type: 'ManagedImage' + imageName: 'image-002' + } + ] + imageSource: { + type: 'PlatformImage' + publisher: 'canonical' + offer: 'ubuntu-24_04-lts' + sku: 'server' + version: 'latest' + } + managedIdentities: {} + customizationSteps: [ + { + type: 'Shell' + name: 'PowerShell installation' + scriptUri: 'https://raw.githubusercontent.com/Azure/bicep-registry-modules/refs/heads/main/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Install-LinuxPowerShell.sh' + sha256Checksum: '8d469f6864a38e1cf957cd080603026bba325793edfb4fe2e8b8e7368eb15b92' + } + ] + validationProcess: { + inVMValidations: [ + { + type: 'Shell' + name: 'Validate PowerShell' + scriptUri: 'https://raw.githubusercontent.com/Azure/bicep-registry-modules/refs/heads/main/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Install-LinuxPowerShell.sh' + sha256Checksum: '8d469f6864a38e1cf957cd080603026bba325793edfb4fe2e8b8e7368eb15b92' + } + ] + } + buildTimeoutInMinutes: 60 + vmSize: 'Standard_D2s_v3' + } +} + +// A basic example that doesn't use any external scripts. +module image_003 'br/public:avm/res/virtual-machine-images/image-template:0.5.0' = { + params: { + name: 'image-003' + baseTime: '0' + distributions: [ + { + type: 'ManagedImage' + imageName: 'image-003' + } + ] + imageSource: { + type: 'PlatformImage' + publisher: 'canonical' + offer: 'ubuntu-24_04-lts' + sku: 'server' + version: 'latest' + } + managedIdentities: {} + buildTimeoutInMinutes: 60 + vmSize: 'Standard_D2s_v3' + } +} diff --git a/tests/PSRule.Rules.Azure.Tests/Resources.ImageBuilder.Source.json b/tests/PSRule.Rules.Azure.Tests/Resources.ImageBuilder.Source.json new file mode 100644 index 00000000000..69784ff3335 --- /dev/null +++ b/tests/PSRule.Rules.Azure.Tests/Resources.ImageBuilder.Source.json @@ -0,0 +1 @@ +[{"ResourceName":"tests\\PSRule.Rules.Azure.Tests\\Resources.ImageBuilder.Source.bicep","name":"helper","properties":{"template":{"$schema":"https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#","languageVersion":"2.0","contentVersion":"1.0.0.0","metadata":{"_generator":{"name":"bicep","version":"0.33.93.31351","templateHash":"8291788442761701655"}},"resources":{"image_001":{"type":"Microsoft.Resources/deployments","apiVersion":"2022-09-01","name":"[format('image_001-{0}', uniqueString('image_001', deployment().name))]","properties":{"expressionEvaluationOptions":{"scope":"inner"},"mode":"Incremental","parameters":{"name":{"value":"image-001"},"baseTime":{"value":"0"},"distributions":{"value":[{"type":"ManagedImage","imageName":"image-001"}]},"imageSource":{"value":{"type":"PlatformImage","publisher":"canonical","offer":"ubuntu-24_04-lts","sku":"server","version":"latest"}},"managedIdentities":{"value":{}},"customizationSteps":{"value":[{"type":"Shell","name":"PowerShell installation","scriptUri":"https://raw.githubusercontent.com/Azure/bicep-registry-modules/refs/heads/main/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Install-LinuxPowerShell.sh"}]},"validationProcess":{"value":{"inVMValidations":[{"type":"Shell","name":"Validate PowerShell","scriptUri":"https://raw.githubusercontent.com/Azure/bicep-registry-modules/refs/heads/main/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Install-LinuxPowerShell.sh"}]}},"buildTimeoutInMinutes":{"value":60},"vmSize":{"value":"Standard_D2s_v3"}},"template":{"$schema":"https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#","languageVersion":"2.0","contentVersion":"1.0.0.0","metadata":{"_generator":{"name":"bicep","version":"0.33.93.31351","templateHash":"17156102195331830052"},"name":"Virtual Machine Image Templates","description":"This module deploys a Virtual Machine Image Template that can be consumed by Azure Image Builder (AIB)."},"definitions":{"distributionType":{"type":"object","discriminator":{"propertyName":"type","mapping":{"SharedImage":{"$ref":"#/definitions/sharedImageDistributionType"},"ManagedImage":{"$ref":"#/definitions/managedImageDistributionType"},"VHD":{"$ref":"#/definitions/unManagedDistributionType"}}},"metadata":{"__bicep_export!":true}},"sharedImageDistributionType":{"type":"object","properties":{"runOutputName":{"type":"string","nullable":true,"metadata":{"description":"Optional. The name to be used for the associated RunOutput. If not provided, a name will be calculated."}},"artifactTags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags that will be applied to the artifact once it has been created/updated by the distributor. If not provided will set tags based on the provided image source."}},"type":{"type":"string","allowedValues":["SharedImage"],"metadata":{"description":"Required. The type of distribution."}},"sharedImageGalleryImageDefinitionResourceId":{"type":"string","metadata":{"description":"Conditional. Resource ID of Compute Gallery Image Definition to distribute image to, e.g.: /subscriptions//resourceGroups//providers/Microsoft.Compute/galleries//images/."}},"sharedImageGalleryImageDefinitionTargetVersion":{"type":"string","nullable":true,"metadata":{"description":"Optional. Version of the Compute Gallery Image. Supports the following Version Syntax: Major.Minor.Build (i.e., '1.1.1' or '10.1.2'). If not provided, a version will be calculated."}},"excludeFromLatest":{"type":"bool","nullable":true,"metadata":{"description":"Optional. The exclude from latest flag of the image. Defaults to [false]."}},"replicationRegions":{"type":"array","items":{"type":"string"},"nullable":true,"metadata":{"description":"Optional. The replication regions of the image. Defaults to the value of the 'location' parameter."}},"storageAccountType":{"type":"string","allowedValues":["Standard_LRS","Standard_ZRS"],"nullable":true,"metadata":{"description":"Optional. The storage account type of the image. Defaults to [Standard_LRS]."}}},"metadata":{"__bicep_export!":true}},"unManagedDistributionType":{"type":"object","properties":{"type":{"type":"string","allowedValues":["VHD"],"metadata":{"description":"Required. The type of distribution."}},"runOutputName":{"type":"string","nullable":true,"metadata":{"description":"Optional. The name to be used for the associated RunOutput. If not provided, a name will be calculated."}},"artifactTags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags that will be applied to the artifact once it has been created/updated by the distributor. If not provided will set tags based on the provided image source."}},"imageName":{"type":"string","metadata":{"description":"Conditional. Name of the managed or unmanaged image that will be created."}}},"metadata":{"__bicep_export!":true}},"managedImageDistributionType":{"type":"object","properties":{"type":{"type":"string","allowedValues":["ManagedImage"],"metadata":{"description":"Required. The type of distribution."}},"runOutputName":{"type":"string","nullable":true,"metadata":{"description":"Optional. The name to be used for the associated RunOutput. If not provided, a name will be calculated."}},"artifactTags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags that will be applied to the artifact once it has been created/updated by the distributor. If not provided will set tags based on the provided image source."}},"location":{"type":"string","nullable":true,"metadata":{"description":"Optional. Azure location for the image, should match if image already exists. Defaults to the value of the 'location' parameter."}},"imageResourceId":{"type":"string","nullable":true,"metadata":{"description":"Required. The resource ID of the managed image. Defaults to a compute image with name 'imageName-baseTime' in the current resource group."}},"imageName":{"type":"string","metadata":{"description":"Conditional. Name of the managed or unmanaged image that will be created."}}},"metadata":{"__bicep_export!":true}},"validationProcessType":{"type":"object","properties":{"continueDistributeOnFailure":{"type":"bool","nullable":true,"metadata":{"description":"Optional. If validation fails and this field is set to false, output image(s) will not be distributed. This is the default behavior. If validation fails and this field is set to true, output image(s) will still be distributed. Please use this option with caution as it may result in bad images being distributed for use. In either case (true or false), the end to end image run will be reported as having failed in case of a validation failure. [Note: This field has no effect if validation succeeds.]."}},"inVMValidations":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","allowedValues":["File","PowerShell","Shell"],"metadata":{"description":"Required. The type of validation."}},"name":{"type":"string","nullable":true,"metadata":{"description":"Optional. Friendly Name to provide context on what this validation step does."}},"scriptUri":{"type":"string","nullable":true,"metadata":{"description":"Optional. URI of the PowerShell script to be run for validation. It can be a github link, Azure Storage URI, etc."}},"inline":{"type":"array","items":{"type":"string"},"nullable":true,"metadata":{"description":"Optional. Array of commands to be run, separated by commas."}},"validExitCodes":{"type":"array","items":{"type":"int"},"nullable":true,"metadata":{"description":"Optional. Valid codes that can be returned from the script/inline command, this avoids reported failure of the script/inline command."}},"sha256Checksum":{"type":"string","nullable":true,"metadata":{"description":"Optional. Value of sha256 checksum of the file, you generate this locally, and then Image Builder will checksum and validate."}},"sourceUri":{"type":"string","nullable":true,"metadata":{"description":"Optional. The source URI of the file."}},"destination":{"type":"string","nullable":true,"metadata":{"description":"Optional. Destination of the file."}},"runAsSystem":{"type":"bool","nullable":true,"metadata":{"description":"Optional. If specified, the PowerShell script will be run with elevated privileges using the Local System user. Can only be true when the runElevated field above is set to true."}},"runElevated":{"type":"bool","nullable":true,"metadata":{"description":"Optional. If specified, the PowerShell script will be run with elevated privileges."}}}},"nullable":true,"metadata":{"description":"Optional. A list of validators that will be performed on the image. Azure Image Builder supports File, PowerShell and Shell validators."}},"sourceValidationOnly":{"type":"bool","nullable":true,"metadata":{"description":"Optional. If this field is set to true, the image specified in the 'source' section will directly be validated. No separate build will be run to generate and then validate a customized image. Not supported when performing customizations, validations or distributions on the image."}}},"metadata":{"__bicep_export!":true}},"lockType":{"type":"object","properties":{"name":{"type":"string","nullable":true,"metadata":{"description":"Optional. Specify the name of lock."}},"kind":{"type":"string","allowedValues":["CanNotDelete","None","ReadOnly"],"nullable":true,"metadata":{"description":"Optional. Specify the type of lock."}}},"metadata":{"description":"An AVM-aligned type for a lock.","__bicep_imported_from!":{"sourceTemplate":"br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"}}},"managedIdentityOnlyUserAssignedType":{"type":"object","properties":{"userAssignedResourceIds":{"type":"array","items":{"type":"string"},"nullable":true,"metadata":{"description":"Optional. The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption."}}},"metadata":{"description":"An AVM-aligned type for a managed identity configuration. To be used if only user-assigned identities are supported by the resource provider.","__bicep_imported_from!":{"sourceTemplate":"br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"}}},"roleAssignmentType":{"type":"object","properties":{"name":{"type":"string","nullable":true,"metadata":{"description":"Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated."}},"roleDefinitionIdOrName":{"type":"string","metadata":{"description":"Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'."}},"principalId":{"type":"string","metadata":{"description":"Required. The principal ID of the principal (user/group/identity) to assign the role to."}},"principalType":{"type":"string","allowedValues":["Device","ForeignGroup","Group","ServicePrincipal","User"],"nullable":true,"metadata":{"description":"Optional. The principal type of the assigned principal ID."}},"description":{"type":"string","nullable":true,"metadata":{"description":"Optional. The description of the role assignment."}},"condition":{"type":"string","nullable":true,"metadata":{"description":"Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"."}},"conditionVersion":{"type":"string","allowedValues":["2.0"],"nullable":true,"metadata":{"description":"Optional. Version of the condition."}},"delegatedManagedIdentityResourceId":{"type":"string","nullable":true,"metadata":{"description":"Optional. The Resource Id of the delegated managed identity resource."}}},"metadata":{"description":"An AVM-aligned type for a role assignment.","__bicep_imported_from!":{"sourceTemplate":"br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"}}}},"parameters":{"name":{"type":"string","metadata":{"description":"Required. The name prefix of the Image Template to be built by the Azure Image Builder service."}},"location":{"type":"string","defaultValue":"[resourceGroup().location]","metadata":{"description":"Optional. Location for all resources."}},"buildTimeoutInMinutes":{"type":"int","defaultValue":0,"minValue":0,"maxValue":960,"metadata":{"description":"Optional. The image build timeout in minutes. 0 means the default 240 minutes."}},"vmSize":{"type":"string","defaultValue":"Standard_D2s_v3","metadata":{"description":"Optional. Specifies the size for the VM."}},"osDiskSizeGB":{"type":"int","defaultValue":128,"metadata":{"description":"Optional. Specifies the size of OS disk."}},"subnetResourceId":{"type":"string","nullable":true,"metadata":{"description":"Optional. Resource ID of an already existing subnet, e.g.: /subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/.

If no value is provided, a new temporary VNET and subnet will be created in the staging resource group and will be deleted along with the remaining temporary resources."}},"imageSource":{"type":"object","metadata":{"description":"Required. Image source definition in object format."}},"customizationSteps":{"type":"array","nullable":true,"metadata":{"description":"Optional. Customization steps to be run when building the VM image."}},"stagingResourceGroupResourceId":{"type":"string","nullable":true,"metadata":{"description":"Optional. Resource ID of the staging resource group in the same subscription and location as the image template that will be used to build the image.

If this field is empty, a resource group with a random name will be created.

If the resource group specified in this field doesn't exist, it will be created with the same name.

If the resource group specified exists, it must be empty and in the same region as the image template.

The resource group created will be deleted during template deletion if this field is empty or the resource group specified doesn't exist,

but if the resource group specified exists the resources created in the resource group will be deleted during template deletion and the resource group itself will remain."}},"lock":{"$ref":"#/definitions/lockType","nullable":true,"metadata":{"description":"Optional. The lock settings of the service."}},"tags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags of the resource."}},"baseTime":{"type":"string","defaultValue":"[utcNow('yyyy-MM-dd-HH-mm-ss')]","metadata":{"description":"Generated. Do not provide a value! This date is used to generate a unique image template name."}},"enableTelemetry":{"type":"bool","defaultValue":true,"metadata":{"description":"Optional. Enable/Disable usage telemetry for module."}},"roleAssignments":{"type":"array","items":{"$ref":"#/definitions/roleAssignmentType"},"nullable":true,"metadata":{"description":"Optional. Array of role assignments to create."}},"distributions":{"type":"array","items":{"$ref":"#/definitions/distributionType"},"metadata":{"description":"Required. The distribution targets where the image output needs to go to."}},"vmUserAssignedIdentities":{"type":"array","defaultValue":[],"metadata":{"description":"Optional. List of User-Assigned Identities associated to the Build VM for accessing Azure resources such as Key Vaults from your customizer scripts. Be aware, the user assigned identities specified in the 'managedIdentities' parameter must have the 'Managed Identity Operator' role assignment on all the user assigned identities specified in this parameter for Azure Image Builder to be able to associate them to the build VM."}},"managedIdentities":{"$ref":"#/definitions/managedIdentityOnlyUserAssignedType","metadata":{"description":"Required. The managed identity definition for this resource."}},"validationProcess":{"$ref":"#/definitions/validationProcessType","nullable":true,"metadata":{"description":"Optional. Configuration options and list of validations to be performed on the resulting image."}},"optimizeVmBoot":{"type":"string","nullable":true,"allowedValues":["Enabled","Disabled"],"metadata":{"description":"Optional. The optimize property can be enabled while creating a VM image and allows VM optimization to improve image creation time."}},"autoRunState":{"type":"string","defaultValue":"Disabled","allowedValues":["Enabled","Disabled"],"metadata":{"description":"Optional. Indicates whether or not to automatically run the image template build on template creation or update."}},"errorHandlingOnCustomizerError":{"type":"string","defaultValue":"cleanup","allowedValues":["cleanup","abort"],"metadata":{"description":"Optional. If there is a customizer error and this field is set to 'cleanup', the build VM and associated network resources will be cleaned up. This is the default behavior. If there is a customizer error and this field is set to 'abort', the build VM will be preserved."}},"errorHandlingOnValidationError":{"type":"string","defaultValue":"cleanup","allowedValues":["cleanup","abort"],"metadata":{"description":"Optional. If there is a validation error and this field is set to 'cleanup', the build VM and associated network resources will be cleaned up. If there is a validation error and this field is set to 'abort', the build VM will be preserved. This is the default behavior."}},"managedResourceTags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags that will be applied to the resource group and/or resources created by the service."}}},"variables":{"copy":[{"name":"formattedRoleAssignments","count":"[length(coalesce(parameters('roleAssignments'), createArray()))]","input":"[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]"}],"identity":{"type":"UserAssigned","userAssignedIdentities":"[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]"},"builtInRoleNames":{"Contributor":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]","Owner":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]","Reader":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]","Role Based Access Control Administrator":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]","User Access Administrator":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]"}},"resources":{"avmTelemetry":{"condition":"[parameters('enableTelemetry')]","type":"Microsoft.Resources/deployments","apiVersion":"2024-03-01","name":"[format('46d3xbcp.res.virtualmachineimages-imagetemplate.{0}.{1}', replace('0.5.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]","properties":{"mode":"Incremental","template":{"$schema":"https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#","contentVersion":"1.0.0.0","resources":[],"outputs":{"telemetry":{"type":"String","value":"For more information, see https://aka.ms/avm/TelemetryInfo"}}}}},"imageTemplate":{"type":"Microsoft.VirtualMachineImages/imageTemplates","apiVersion":"2024-02-01","name":"[format('{0}-{1}', parameters('name'), parameters('baseTime'))]","location":"[parameters('location')]","tags":"[parameters('tags')]","identity":"[variables('identity')]","properties":"[shallowMerge(createArray(createObject('buildTimeoutInMinutes', parameters('buildTimeoutInMinutes'), 'vmProfile', createObject('vmSize', parameters('vmSize'), 'osDiskSizeGB', parameters('osDiskSizeGB'), 'userAssignedIdentities', parameters('vmUserAssignedIdentities'), 'vnetConfig', if(not(empty(parameters('subnetResourceId'))), createObject('subnetId', parameters('subnetResourceId')), null())), 'source', parameters('imageSource')), if(not(empty(parameters('customizationSteps'))), createObject('customize', parameters('customizationSteps')), createObject()), createObject('stagingResourceGroup', parameters('stagingResourceGroupResourceId'), 'distribute', map(parameters('distributions'), lambda('distribution', shallowMerge(createArray(createObject('type', lambdaVariables('distribution').type, 'artifactTags', coalesce(tryGet(lambdaVariables('distribution'), 'artifactTags'), createObject('sourceType', parameters('imageSource').type, 'sourcePublisher', tryGet(parameters('imageSource'), 'publisher'), 'sourceOffer', tryGet(parameters('imageSource'), 'offer'), 'sourceSku', tryGet(parameters('imageSource'), 'sku'), 'sourceVersion', tryGet(parameters('imageSource'), 'version'), 'sourceImageId', tryGet(parameters('imageSource'), 'imageId'), 'sourceImageVersionID', tryGet(parameters('imageSource'), 'imageVersionID'), 'creationTime', parameters('baseTime')))), if(equals(lambdaVariables('distribution').type, 'ManagedImage'), createObject('runOutputName', coalesce(tryGet(lambdaVariables('distribution'), 'runOutputName'), format('{0}-{1}-ManagedImage', lambdaVariables('distribution').imageName, parameters('baseTime'))), 'location', coalesce(tryGet(lambdaVariables('distribution'), 'location'), parameters('location')), 'imageId', coalesce(tryGet(lambdaVariables('distribution'), 'imageResourceId'), format('{0}/resourceGroups/{1}/providers/Microsoft.Compute/images/{2}-{3}', subscription().id, resourceGroup().name, lambdaVariables('distribution').imageName, parameters('baseTime')))), createObject()), if(equals(lambdaVariables('distribution').type, 'SharedImage'), createObject('runOutputName', coalesce(tryGet(lambdaVariables('distribution'), 'runOutputName'), if(not(empty(tryGet(lambdaVariables('distribution'), 'sharedImageGalleryImageDefinitionResourceId'))), format('{0}-SharedImage', last(split(coalesce(lambdaVariables('distribution').sharedImageGalleryImageDefinitionResourceId, '/'), '/'))), 'SharedImage')), 'galleryImageId', if(not(empty(tryGet(lambdaVariables('distribution'), 'sharedImageGalleryImageDefinitionTargetVersion'))), format('{0}/versions/{1}', lambdaVariables('distribution').sharedImageGalleryImageDefinitionResourceId, lambdaVariables('distribution').sharedImageGalleryImageDefinitionTargetVersion), lambdaVariables('distribution').sharedImageGalleryImageDefinitionResourceId), 'excludeFromLatest', coalesce(tryGet(lambdaVariables('distribution'), 'excludeFromLatest'), false()), 'replicationRegions', coalesce(tryGet(lambdaVariables('distribution'), 'replicationRegions'), createArray(parameters('location'))), 'storageAccountType', coalesce(tryGet(lambdaVariables('distribution'), 'storageAccountType'), 'Standard_LRS')), createObject()), if(equals(lambdaVariables('distribution').type, 'VHD'), createObject('runOutputName', coalesce(tryGet(lambdaVariables('distribution'), 'runOutputName'), format('{0}-VHD', lambdaVariables('distribution').imageName))), createObject()))))), 'validate', parameters('validationProcess'), 'optimize', if(not(equals(parameters('optimizeVmBoot'), null())), createObject('vmBoot', createObject('state', parameters('optimizeVmBoot'))), null()), 'autoRun', createObject('state', parameters('autoRunState')), 'errorHandling', createObject('onCustomizerError', parameters('errorHandlingOnCustomizerError'), 'onValidationError', parameters('errorHandlingOnValidationError')), 'managedResourceTags', parameters('managedResourceTags'))))]"},"imageTemplate_lock":{"condition":"[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]","type":"Microsoft.Authorization/locks","apiVersion":"2020-05-01","scope":"[format('Microsoft.VirtualMachineImages/imageTemplates/{0}', format('{0}-{1}', parameters('name'), parameters('baseTime')))]","name":"[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]","properties":{"level":"[coalesce(tryGet(parameters('lock'), 'kind'), '')]","notes":"[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]"},"dependsOn":["imageTemplate"]},"imageTemplate_roleAssignments":{"copy":{"name":"imageTemplate_roleAssignments","count":"[length(coalesce(variables('formattedRoleAssignments'), createArray()))]"},"type":"Microsoft.Authorization/roleAssignments","apiVersion":"2022-04-01","scope":"[format('Microsoft.VirtualMachineImages/imageTemplates/{0}', format('{0}-{1}', parameters('name'), parameters('baseTime')))]","name":"[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.VirtualMachineImages/imageTemplates', format('{0}-{1}', parameters('name'), parameters('baseTime'))), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]","properties":{"roleDefinitionId":"[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]","principalId":"[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]","description":"[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]","principalType":"[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]","condition":"[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]","conditionVersion":"[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]","delegatedManagedIdentityResourceId":"[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]"},"dependsOn":["imageTemplate"]}},"outputs":{"resourceId":{"type":"string","metadata":{"description":"The resource ID of the image template."},"value":"[resourceId('Microsoft.VirtualMachineImages/imageTemplates', format('{0}-{1}', parameters('name'), parameters('baseTime')))]"},"resourceGroupName":{"type":"string","metadata":{"description":"The resource group the image template was deployed into."},"value":"[resourceGroup().name]"},"name":{"type":"string","metadata":{"description":"The full name of the deployed image template."},"value":"[format('{0}-{1}', parameters('name'), parameters('baseTime'))]"},"namePrefix":{"type":"string","metadata":{"description":"The prefix of the image template name provided as input."},"value":"[parameters('name')]"},"runThisCommand":{"type":"string","metadata":{"description":"The command to run in order to trigger the image build."},"value":"[format('Invoke-AzResourceAction -ResourceName {0} -ResourceGroupName {1} -ResourceType Microsoft.VirtualMachineImages/imageTemplates -Action Run -Force', format('{0}-{1}', parameters('name'), parameters('baseTime')), resourceGroup().name)]"},"location":{"type":"string","metadata":{"description":"The location the resource was deployed into."},"value":"[reference('imageTemplate', '2024-02-01', 'full').location]"}}}}},"image_002":{"type":"Microsoft.Resources/deployments","apiVersion":"2022-09-01","name":"[format('image_002-{0}', uniqueString('image_002', deployment().name))]","properties":{"expressionEvaluationOptions":{"scope":"inner"},"mode":"Incremental","parameters":{"name":{"value":"image-002"},"baseTime":{"value":"0"},"distributions":{"value":[{"type":"ManagedImage","imageName":"image-002"}]},"imageSource":{"value":{"type":"PlatformImage","publisher":"canonical","offer":"ubuntu-24_04-lts","sku":"server","version":"latest"}},"managedIdentities":{"value":{}},"customizationSteps":{"value":[{"type":"Shell","name":"PowerShell installation","scriptUri":"https://raw.githubusercontent.com/Azure/bicep-registry-modules/refs/heads/main/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Install-LinuxPowerShell.sh","sha256Checksum":"8d469f6864a38e1cf957cd080603026bba325793edfb4fe2e8b8e7368eb15b92"}]},"validationProcess":{"value":{"inVMValidations":[{"type":"Shell","name":"Validate PowerShell","scriptUri":"https://raw.githubusercontent.com/Azure/bicep-registry-modules/refs/heads/main/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Install-LinuxPowerShell.sh","sha256Checksum":"8d469f6864a38e1cf957cd080603026bba325793edfb4fe2e8b8e7368eb15b92"}]}},"buildTimeoutInMinutes":{"value":60},"vmSize":{"value":"Standard_D2s_v3"}},"template":{"$schema":"https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#","languageVersion":"2.0","contentVersion":"1.0.0.0","metadata":{"_generator":{"name":"bicep","version":"0.33.93.31351","templateHash":"17156102195331830052"},"name":"Virtual Machine Image Templates","description":"This module deploys a Virtual Machine Image Template that can be consumed by Azure Image Builder (AIB)."},"definitions":{"distributionType":{"type":"object","discriminator":{"propertyName":"type","mapping":{"SharedImage":{"$ref":"#/definitions/sharedImageDistributionType"},"ManagedImage":{"$ref":"#/definitions/managedImageDistributionType"},"VHD":{"$ref":"#/definitions/unManagedDistributionType"}}},"metadata":{"__bicep_export!":true}},"sharedImageDistributionType":{"type":"object","properties":{"runOutputName":{"type":"string","nullable":true,"metadata":{"description":"Optional. The name to be used for the associated RunOutput. If not provided, a name will be calculated."}},"artifactTags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags that will be applied to the artifact once it has been created/updated by the distributor. If not provided will set tags based on the provided image source."}},"type":{"type":"string","allowedValues":["SharedImage"],"metadata":{"description":"Required. The type of distribution."}},"sharedImageGalleryImageDefinitionResourceId":{"type":"string","metadata":{"description":"Conditional. Resource ID of Compute Gallery Image Definition to distribute image to, e.g.: /subscriptions//resourceGroups//providers/Microsoft.Compute/galleries//images/."}},"sharedImageGalleryImageDefinitionTargetVersion":{"type":"string","nullable":true,"metadata":{"description":"Optional. Version of the Compute Gallery Image. Supports the following Version Syntax: Major.Minor.Build (i.e., '1.1.1' or '10.1.2'). If not provided, a version will be calculated."}},"excludeFromLatest":{"type":"bool","nullable":true,"metadata":{"description":"Optional. The exclude from latest flag of the image. Defaults to [false]."}},"replicationRegions":{"type":"array","items":{"type":"string"},"nullable":true,"metadata":{"description":"Optional. The replication regions of the image. Defaults to the value of the 'location' parameter."}},"storageAccountType":{"type":"string","allowedValues":["Standard_LRS","Standard_ZRS"],"nullable":true,"metadata":{"description":"Optional. The storage account type of the image. Defaults to [Standard_LRS]."}}},"metadata":{"__bicep_export!":true}},"unManagedDistributionType":{"type":"object","properties":{"type":{"type":"string","allowedValues":["VHD"],"metadata":{"description":"Required. The type of distribution."}},"runOutputName":{"type":"string","nullable":true,"metadata":{"description":"Optional. The name to be used for the associated RunOutput. If not provided, a name will be calculated."}},"artifactTags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags that will be applied to the artifact once it has been created/updated by the distributor. If not provided will set tags based on the provided image source."}},"imageName":{"type":"string","metadata":{"description":"Conditional. Name of the managed or unmanaged image that will be created."}}},"metadata":{"__bicep_export!":true}},"managedImageDistributionType":{"type":"object","properties":{"type":{"type":"string","allowedValues":["ManagedImage"],"metadata":{"description":"Required. The type of distribution."}},"runOutputName":{"type":"string","nullable":true,"metadata":{"description":"Optional. The name to be used for the associated RunOutput. If not provided, a name will be calculated."}},"artifactTags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags that will be applied to the artifact once it has been created/updated by the distributor. If not provided will set tags based on the provided image source."}},"location":{"type":"string","nullable":true,"metadata":{"description":"Optional. Azure location for the image, should match if image already exists. Defaults to the value of the 'location' parameter."}},"imageResourceId":{"type":"string","nullable":true,"metadata":{"description":"Required. The resource ID of the managed image. Defaults to a compute image with name 'imageName-baseTime' in the current resource group."}},"imageName":{"type":"string","metadata":{"description":"Conditional. Name of the managed or unmanaged image that will be created."}}},"metadata":{"__bicep_export!":true}},"validationProcessType":{"type":"object","properties":{"continueDistributeOnFailure":{"type":"bool","nullable":true,"metadata":{"description":"Optional. If validation fails and this field is set to false, output image(s) will not be distributed. This is the default behavior. If validation fails and this field is set to true, output image(s) will still be distributed. Please use this option with caution as it may result in bad images being distributed for use. In either case (true or false), the end to end image run will be reported as having failed in case of a validation failure. [Note: This field has no effect if validation succeeds.]."}},"inVMValidations":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","allowedValues":["File","PowerShell","Shell"],"metadata":{"description":"Required. The type of validation."}},"name":{"type":"string","nullable":true,"metadata":{"description":"Optional. Friendly Name to provide context on what this validation step does."}},"scriptUri":{"type":"string","nullable":true,"metadata":{"description":"Optional. URI of the PowerShell script to be run for validation. It can be a github link, Azure Storage URI, etc."}},"inline":{"type":"array","items":{"type":"string"},"nullable":true,"metadata":{"description":"Optional. Array of commands to be run, separated by commas."}},"validExitCodes":{"type":"array","items":{"type":"int"},"nullable":true,"metadata":{"description":"Optional. Valid codes that can be returned from the script/inline command, this avoids reported failure of the script/inline command."}},"sha256Checksum":{"type":"string","nullable":true,"metadata":{"description":"Optional. Value of sha256 checksum of the file, you generate this locally, and then Image Builder will checksum and validate."}},"sourceUri":{"type":"string","nullable":true,"metadata":{"description":"Optional. The source URI of the file."}},"destination":{"type":"string","nullable":true,"metadata":{"description":"Optional. Destination of the file."}},"runAsSystem":{"type":"bool","nullable":true,"metadata":{"description":"Optional. If specified, the PowerShell script will be run with elevated privileges using the Local System user. Can only be true when the runElevated field above is set to true."}},"runElevated":{"type":"bool","nullable":true,"metadata":{"description":"Optional. If specified, the PowerShell script will be run with elevated privileges."}}}},"nullable":true,"metadata":{"description":"Optional. A list of validators that will be performed on the image. Azure Image Builder supports File, PowerShell and Shell validators."}},"sourceValidationOnly":{"type":"bool","nullable":true,"metadata":{"description":"Optional. If this field is set to true, the image specified in the 'source' section will directly be validated. No separate build will be run to generate and then validate a customized image. Not supported when performing customizations, validations or distributions on the image."}}},"metadata":{"__bicep_export!":true}},"lockType":{"type":"object","properties":{"name":{"type":"string","nullable":true,"metadata":{"description":"Optional. Specify the name of lock."}},"kind":{"type":"string","allowedValues":["CanNotDelete","None","ReadOnly"],"nullable":true,"metadata":{"description":"Optional. Specify the type of lock."}}},"metadata":{"description":"An AVM-aligned type for a lock.","__bicep_imported_from!":{"sourceTemplate":"br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"}}},"managedIdentityOnlyUserAssignedType":{"type":"object","properties":{"userAssignedResourceIds":{"type":"array","items":{"type":"string"},"nullable":true,"metadata":{"description":"Optional. The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption."}}},"metadata":{"description":"An AVM-aligned type for a managed identity configuration. To be used if only user-assigned identities are supported by the resource provider.","__bicep_imported_from!":{"sourceTemplate":"br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"}}},"roleAssignmentType":{"type":"object","properties":{"name":{"type":"string","nullable":true,"metadata":{"description":"Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated."}},"roleDefinitionIdOrName":{"type":"string","metadata":{"description":"Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'."}},"principalId":{"type":"string","metadata":{"description":"Required. The principal ID of the principal (user/group/identity) to assign the role to."}},"principalType":{"type":"string","allowedValues":["Device","ForeignGroup","Group","ServicePrincipal","User"],"nullable":true,"metadata":{"description":"Optional. The principal type of the assigned principal ID."}},"description":{"type":"string","nullable":true,"metadata":{"description":"Optional. The description of the role assignment."}},"condition":{"type":"string","nullable":true,"metadata":{"description":"Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"."}},"conditionVersion":{"type":"string","allowedValues":["2.0"],"nullable":true,"metadata":{"description":"Optional. Version of the condition."}},"delegatedManagedIdentityResourceId":{"type":"string","nullable":true,"metadata":{"description":"Optional. The Resource Id of the delegated managed identity resource."}}},"metadata":{"description":"An AVM-aligned type for a role assignment.","__bicep_imported_from!":{"sourceTemplate":"br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"}}}},"parameters":{"name":{"type":"string","metadata":{"description":"Required. The name prefix of the Image Template to be built by the Azure Image Builder service."}},"location":{"type":"string","defaultValue":"[resourceGroup().location]","metadata":{"description":"Optional. Location for all resources."}},"buildTimeoutInMinutes":{"type":"int","defaultValue":0,"minValue":0,"maxValue":960,"metadata":{"description":"Optional. The image build timeout in minutes. 0 means the default 240 minutes."}},"vmSize":{"type":"string","defaultValue":"Standard_D2s_v3","metadata":{"description":"Optional. Specifies the size for the VM."}},"osDiskSizeGB":{"type":"int","defaultValue":128,"metadata":{"description":"Optional. Specifies the size of OS disk."}},"subnetResourceId":{"type":"string","nullable":true,"metadata":{"description":"Optional. Resource ID of an already existing subnet, e.g.: /subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/.

If no value is provided, a new temporary VNET and subnet will be created in the staging resource group and will be deleted along with the remaining temporary resources."}},"imageSource":{"type":"object","metadata":{"description":"Required. Image source definition in object format."}},"customizationSteps":{"type":"array","nullable":true,"metadata":{"description":"Optional. Customization steps to be run when building the VM image."}},"stagingResourceGroupResourceId":{"type":"string","nullable":true,"metadata":{"description":"Optional. Resource ID of the staging resource group in the same subscription and location as the image template that will be used to build the image.

If this field is empty, a resource group with a random name will be created.

If the resource group specified in this field doesn't exist, it will be created with the same name.

If the resource group specified exists, it must be empty and in the same region as the image template.

The resource group created will be deleted during template deletion if this field is empty or the resource group specified doesn't exist,

but if the resource group specified exists the resources created in the resource group will be deleted during template deletion and the resource group itself will remain."}},"lock":{"$ref":"#/definitions/lockType","nullable":true,"metadata":{"description":"Optional. The lock settings of the service."}},"tags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags of the resource."}},"baseTime":{"type":"string","defaultValue":"[utcNow('yyyy-MM-dd-HH-mm-ss')]","metadata":{"description":"Generated. Do not provide a value! This date is used to generate a unique image template name."}},"enableTelemetry":{"type":"bool","defaultValue":true,"metadata":{"description":"Optional. Enable/Disable usage telemetry for module."}},"roleAssignments":{"type":"array","items":{"$ref":"#/definitions/roleAssignmentType"},"nullable":true,"metadata":{"description":"Optional. Array of role assignments to create."}},"distributions":{"type":"array","items":{"$ref":"#/definitions/distributionType"},"metadata":{"description":"Required. The distribution targets where the image output needs to go to."}},"vmUserAssignedIdentities":{"type":"array","defaultValue":[],"metadata":{"description":"Optional. List of User-Assigned Identities associated to the Build VM for accessing Azure resources such as Key Vaults from your customizer scripts. Be aware, the user assigned identities specified in the 'managedIdentities' parameter must have the 'Managed Identity Operator' role assignment on all the user assigned identities specified in this parameter for Azure Image Builder to be able to associate them to the build VM."}},"managedIdentities":{"$ref":"#/definitions/managedIdentityOnlyUserAssignedType","metadata":{"description":"Required. The managed identity definition for this resource."}},"validationProcess":{"$ref":"#/definitions/validationProcessType","nullable":true,"metadata":{"description":"Optional. Configuration options and list of validations to be performed on the resulting image."}},"optimizeVmBoot":{"type":"string","nullable":true,"allowedValues":["Enabled","Disabled"],"metadata":{"description":"Optional. The optimize property can be enabled while creating a VM image and allows VM optimization to improve image creation time."}},"autoRunState":{"type":"string","defaultValue":"Disabled","allowedValues":["Enabled","Disabled"],"metadata":{"description":"Optional. Indicates whether or not to automatically run the image template build on template creation or update."}},"errorHandlingOnCustomizerError":{"type":"string","defaultValue":"cleanup","allowedValues":["cleanup","abort"],"metadata":{"description":"Optional. If there is a customizer error and this field is set to 'cleanup', the build VM and associated network resources will be cleaned up. This is the default behavior. If there is a customizer error and this field is set to 'abort', the build VM will be preserved."}},"errorHandlingOnValidationError":{"type":"string","defaultValue":"cleanup","allowedValues":["cleanup","abort"],"metadata":{"description":"Optional. If there is a validation error and this field is set to 'cleanup', the build VM and associated network resources will be cleaned up. If there is a validation error and this field is set to 'abort', the build VM will be preserved. This is the default behavior."}},"managedResourceTags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags that will be applied to the resource group and/or resources created by the service."}}},"variables":{"copy":[{"name":"formattedRoleAssignments","count":"[length(coalesce(parameters('roleAssignments'), createArray()))]","input":"[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]"}],"identity":{"type":"UserAssigned","userAssignedIdentities":"[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]"},"builtInRoleNames":{"Contributor":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]","Owner":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]","Reader":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]","Role Based Access Control Administrator":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]","User Access Administrator":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]"}},"resources":{"avmTelemetry":{"condition":"[parameters('enableTelemetry')]","type":"Microsoft.Resources/deployments","apiVersion":"2024-03-01","name":"[format('46d3xbcp.res.virtualmachineimages-imagetemplate.{0}.{1}', replace('0.5.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]","properties":{"mode":"Incremental","template":{"$schema":"https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#","contentVersion":"1.0.0.0","resources":[],"outputs":{"telemetry":{"type":"String","value":"For more information, see https://aka.ms/avm/TelemetryInfo"}}}}},"imageTemplate":{"type":"Microsoft.VirtualMachineImages/imageTemplates","apiVersion":"2024-02-01","name":"[format('{0}-{1}', parameters('name'), parameters('baseTime'))]","location":"[parameters('location')]","tags":"[parameters('tags')]","identity":"[variables('identity')]","properties":"[shallowMerge(createArray(createObject('buildTimeoutInMinutes', parameters('buildTimeoutInMinutes'), 'vmProfile', createObject('vmSize', parameters('vmSize'), 'osDiskSizeGB', parameters('osDiskSizeGB'), 'userAssignedIdentities', parameters('vmUserAssignedIdentities'), 'vnetConfig', if(not(empty(parameters('subnetResourceId'))), createObject('subnetId', parameters('subnetResourceId')), null())), 'source', parameters('imageSource')), if(not(empty(parameters('customizationSteps'))), createObject('customize', parameters('customizationSteps')), createObject()), createObject('stagingResourceGroup', parameters('stagingResourceGroupResourceId'), 'distribute', map(parameters('distributions'), lambda('distribution', shallowMerge(createArray(createObject('type', lambdaVariables('distribution').type, 'artifactTags', coalesce(tryGet(lambdaVariables('distribution'), 'artifactTags'), createObject('sourceType', parameters('imageSource').type, 'sourcePublisher', tryGet(parameters('imageSource'), 'publisher'), 'sourceOffer', tryGet(parameters('imageSource'), 'offer'), 'sourceSku', tryGet(parameters('imageSource'), 'sku'), 'sourceVersion', tryGet(parameters('imageSource'), 'version'), 'sourceImageId', tryGet(parameters('imageSource'), 'imageId'), 'sourceImageVersionID', tryGet(parameters('imageSource'), 'imageVersionID'), 'creationTime', parameters('baseTime')))), if(equals(lambdaVariables('distribution').type, 'ManagedImage'), createObject('runOutputName', coalesce(tryGet(lambdaVariables('distribution'), 'runOutputName'), format('{0}-{1}-ManagedImage', lambdaVariables('distribution').imageName, parameters('baseTime'))), 'location', coalesce(tryGet(lambdaVariables('distribution'), 'location'), parameters('location')), 'imageId', coalesce(tryGet(lambdaVariables('distribution'), 'imageResourceId'), format('{0}/resourceGroups/{1}/providers/Microsoft.Compute/images/{2}-{3}', subscription().id, resourceGroup().name, lambdaVariables('distribution').imageName, parameters('baseTime')))), createObject()), if(equals(lambdaVariables('distribution').type, 'SharedImage'), createObject('runOutputName', coalesce(tryGet(lambdaVariables('distribution'), 'runOutputName'), if(not(empty(tryGet(lambdaVariables('distribution'), 'sharedImageGalleryImageDefinitionResourceId'))), format('{0}-SharedImage', last(split(coalesce(lambdaVariables('distribution').sharedImageGalleryImageDefinitionResourceId, '/'), '/'))), 'SharedImage')), 'galleryImageId', if(not(empty(tryGet(lambdaVariables('distribution'), 'sharedImageGalleryImageDefinitionTargetVersion'))), format('{0}/versions/{1}', lambdaVariables('distribution').sharedImageGalleryImageDefinitionResourceId, lambdaVariables('distribution').sharedImageGalleryImageDefinitionTargetVersion), lambdaVariables('distribution').sharedImageGalleryImageDefinitionResourceId), 'excludeFromLatest', coalesce(tryGet(lambdaVariables('distribution'), 'excludeFromLatest'), false()), 'replicationRegions', coalesce(tryGet(lambdaVariables('distribution'), 'replicationRegions'), createArray(parameters('location'))), 'storageAccountType', coalesce(tryGet(lambdaVariables('distribution'), 'storageAccountType'), 'Standard_LRS')), createObject()), if(equals(lambdaVariables('distribution').type, 'VHD'), createObject('runOutputName', coalesce(tryGet(lambdaVariables('distribution'), 'runOutputName'), format('{0}-VHD', lambdaVariables('distribution').imageName))), createObject()))))), 'validate', parameters('validationProcess'), 'optimize', if(not(equals(parameters('optimizeVmBoot'), null())), createObject('vmBoot', createObject('state', parameters('optimizeVmBoot'))), null()), 'autoRun', createObject('state', parameters('autoRunState')), 'errorHandling', createObject('onCustomizerError', parameters('errorHandlingOnCustomizerError'), 'onValidationError', parameters('errorHandlingOnValidationError')), 'managedResourceTags', parameters('managedResourceTags'))))]"},"imageTemplate_lock":{"condition":"[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]","type":"Microsoft.Authorization/locks","apiVersion":"2020-05-01","scope":"[format('Microsoft.VirtualMachineImages/imageTemplates/{0}', format('{0}-{1}', parameters('name'), parameters('baseTime')))]","name":"[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]","properties":{"level":"[coalesce(tryGet(parameters('lock'), 'kind'), '')]","notes":"[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]"},"dependsOn":["imageTemplate"]},"imageTemplate_roleAssignments":{"copy":{"name":"imageTemplate_roleAssignments","count":"[length(coalesce(variables('formattedRoleAssignments'), createArray()))]"},"type":"Microsoft.Authorization/roleAssignments","apiVersion":"2022-04-01","scope":"[format('Microsoft.VirtualMachineImages/imageTemplates/{0}', format('{0}-{1}', parameters('name'), parameters('baseTime')))]","name":"[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.VirtualMachineImages/imageTemplates', format('{0}-{1}', parameters('name'), parameters('baseTime'))), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]","properties":{"roleDefinitionId":"[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]","principalId":"[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]","description":"[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]","principalType":"[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]","condition":"[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]","conditionVersion":"[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]","delegatedManagedIdentityResourceId":"[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]"},"dependsOn":["imageTemplate"]}},"outputs":{"resourceId":{"type":"string","metadata":{"description":"The resource ID of the image template."},"value":"[resourceId('Microsoft.VirtualMachineImages/imageTemplates', format('{0}-{1}', parameters('name'), parameters('baseTime')))]"},"resourceGroupName":{"type":"string","metadata":{"description":"The resource group the image template was deployed into."},"value":"[resourceGroup().name]"},"name":{"type":"string","metadata":{"description":"The full name of the deployed image template."},"value":"[format('{0}-{1}', parameters('name'), parameters('baseTime'))]"},"namePrefix":{"type":"string","metadata":{"description":"The prefix of the image template name provided as input."},"value":"[parameters('name')]"},"runThisCommand":{"type":"string","metadata":{"description":"The command to run in order to trigger the image build."},"value":"[format('Invoke-AzResourceAction -ResourceName {0} -ResourceGroupName {1} -ResourceType Microsoft.VirtualMachineImages/imageTemplates -Action Run -Force', format('{0}-{1}', parameters('name'), parameters('baseTime')), resourceGroup().name)]"},"location":{"type":"string","metadata":{"description":"The location the resource was deployed into."},"value":"[reference('imageTemplate', '2024-02-01', 'full').location]"}}}}},"image_003":{"type":"Microsoft.Resources/deployments","apiVersion":"2022-09-01","name":"[format('image_003-{0}', uniqueString('image_003', deployment().name))]","properties":{"expressionEvaluationOptions":{"scope":"inner"},"mode":"Incremental","parameters":{"name":{"value":"image-003"},"baseTime":{"value":"0"},"distributions":{"value":[{"type":"ManagedImage","imageName":"image-003"}]},"imageSource":{"value":{"type":"PlatformImage","publisher":"canonical","offer":"ubuntu-24_04-lts","sku":"server","version":"latest"}},"managedIdentities":{"value":{}},"buildTimeoutInMinutes":{"value":60},"vmSize":{"value":"Standard_D2s_v3"}},"template":{"$schema":"https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#","languageVersion":"2.0","contentVersion":"1.0.0.0","metadata":{"_generator":{"name":"bicep","version":"0.33.93.31351","templateHash":"17156102195331830052"},"name":"Virtual Machine Image Templates","description":"This module deploys a Virtual Machine Image Template that can be consumed by Azure Image Builder (AIB)."},"definitions":{"distributionType":{"type":"object","discriminator":{"propertyName":"type","mapping":{"SharedImage":{"$ref":"#/definitions/sharedImageDistributionType"},"ManagedImage":{"$ref":"#/definitions/managedImageDistributionType"},"VHD":{"$ref":"#/definitions/unManagedDistributionType"}}},"metadata":{"__bicep_export!":true}},"sharedImageDistributionType":{"type":"object","properties":{"runOutputName":{"type":"string","nullable":true,"metadata":{"description":"Optional. The name to be used for the associated RunOutput. If not provided, a name will be calculated."}},"artifactTags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags that will be applied to the artifact once it has been created/updated by the distributor. If not provided will set tags based on the provided image source."}},"type":{"type":"string","allowedValues":["SharedImage"],"metadata":{"description":"Required. The type of distribution."}},"sharedImageGalleryImageDefinitionResourceId":{"type":"string","metadata":{"description":"Conditional. Resource ID of Compute Gallery Image Definition to distribute image to, e.g.: /subscriptions//resourceGroups//providers/Microsoft.Compute/galleries//images/."}},"sharedImageGalleryImageDefinitionTargetVersion":{"type":"string","nullable":true,"metadata":{"description":"Optional. Version of the Compute Gallery Image. Supports the following Version Syntax: Major.Minor.Build (i.e., '1.1.1' or '10.1.2'). If not provided, a version will be calculated."}},"excludeFromLatest":{"type":"bool","nullable":true,"metadata":{"description":"Optional. The exclude from latest flag of the image. Defaults to [false]."}},"replicationRegions":{"type":"array","items":{"type":"string"},"nullable":true,"metadata":{"description":"Optional. The replication regions of the image. Defaults to the value of the 'location' parameter."}},"storageAccountType":{"type":"string","allowedValues":["Standard_LRS","Standard_ZRS"],"nullable":true,"metadata":{"description":"Optional. The storage account type of the image. Defaults to [Standard_LRS]."}}},"metadata":{"__bicep_export!":true}},"unManagedDistributionType":{"type":"object","properties":{"type":{"type":"string","allowedValues":["VHD"],"metadata":{"description":"Required. The type of distribution."}},"runOutputName":{"type":"string","nullable":true,"metadata":{"description":"Optional. The name to be used for the associated RunOutput. If not provided, a name will be calculated."}},"artifactTags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags that will be applied to the artifact once it has been created/updated by the distributor. If not provided will set tags based on the provided image source."}},"imageName":{"type":"string","metadata":{"description":"Conditional. Name of the managed or unmanaged image that will be created."}}},"metadata":{"__bicep_export!":true}},"managedImageDistributionType":{"type":"object","properties":{"type":{"type":"string","allowedValues":["ManagedImage"],"metadata":{"description":"Required. The type of distribution."}},"runOutputName":{"type":"string","nullable":true,"metadata":{"description":"Optional. The name to be used for the associated RunOutput. If not provided, a name will be calculated."}},"artifactTags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags that will be applied to the artifact once it has been created/updated by the distributor. If not provided will set tags based on the provided image source."}},"location":{"type":"string","nullable":true,"metadata":{"description":"Optional. Azure location for the image, should match if image already exists. Defaults to the value of the 'location' parameter."}},"imageResourceId":{"type":"string","nullable":true,"metadata":{"description":"Required. The resource ID of the managed image. Defaults to a compute image with name 'imageName-baseTime' in the current resource group."}},"imageName":{"type":"string","metadata":{"description":"Conditional. Name of the managed or unmanaged image that will be created."}}},"metadata":{"__bicep_export!":true}},"validationProcessType":{"type":"object","properties":{"continueDistributeOnFailure":{"type":"bool","nullable":true,"metadata":{"description":"Optional. If validation fails and this field is set to false, output image(s) will not be distributed. This is the default behavior. If validation fails and this field is set to true, output image(s) will still be distributed. Please use this option with caution as it may result in bad images being distributed for use. In either case (true or false), the end to end image run will be reported as having failed in case of a validation failure. [Note: This field has no effect if validation succeeds.]."}},"inVMValidations":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","allowedValues":["File","PowerShell","Shell"],"metadata":{"description":"Required. The type of validation."}},"name":{"type":"string","nullable":true,"metadata":{"description":"Optional. Friendly Name to provide context on what this validation step does."}},"scriptUri":{"type":"string","nullable":true,"metadata":{"description":"Optional. URI of the PowerShell script to be run for validation. It can be a github link, Azure Storage URI, etc."}},"inline":{"type":"array","items":{"type":"string"},"nullable":true,"metadata":{"description":"Optional. Array of commands to be run, separated by commas."}},"validExitCodes":{"type":"array","items":{"type":"int"},"nullable":true,"metadata":{"description":"Optional. Valid codes that can be returned from the script/inline command, this avoids reported failure of the script/inline command."}},"sha256Checksum":{"type":"string","nullable":true,"metadata":{"description":"Optional. Value of sha256 checksum of the file, you generate this locally, and then Image Builder will checksum and validate."}},"sourceUri":{"type":"string","nullable":true,"metadata":{"description":"Optional. The source URI of the file."}},"destination":{"type":"string","nullable":true,"metadata":{"description":"Optional. Destination of the file."}},"runAsSystem":{"type":"bool","nullable":true,"metadata":{"description":"Optional. If specified, the PowerShell script will be run with elevated privileges using the Local System user. Can only be true when the runElevated field above is set to true."}},"runElevated":{"type":"bool","nullable":true,"metadata":{"description":"Optional. If specified, the PowerShell script will be run with elevated privileges."}}}},"nullable":true,"metadata":{"description":"Optional. A list of validators that will be performed on the image. Azure Image Builder supports File, PowerShell and Shell validators."}},"sourceValidationOnly":{"type":"bool","nullable":true,"metadata":{"description":"Optional. If this field is set to true, the image specified in the 'source' section will directly be validated. No separate build will be run to generate and then validate a customized image. Not supported when performing customizations, validations or distributions on the image."}}},"metadata":{"__bicep_export!":true}},"lockType":{"type":"object","properties":{"name":{"type":"string","nullable":true,"metadata":{"description":"Optional. Specify the name of lock."}},"kind":{"type":"string","allowedValues":["CanNotDelete","None","ReadOnly"],"nullable":true,"metadata":{"description":"Optional. Specify the type of lock."}}},"metadata":{"description":"An AVM-aligned type for a lock.","__bicep_imported_from!":{"sourceTemplate":"br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"}}},"managedIdentityOnlyUserAssignedType":{"type":"object","properties":{"userAssignedResourceIds":{"type":"array","items":{"type":"string"},"nullable":true,"metadata":{"description":"Optional. The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption."}}},"metadata":{"description":"An AVM-aligned type for a managed identity configuration. To be used if only user-assigned identities are supported by the resource provider.","__bicep_imported_from!":{"sourceTemplate":"br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"}}},"roleAssignmentType":{"type":"object","properties":{"name":{"type":"string","nullable":true,"metadata":{"description":"Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated."}},"roleDefinitionIdOrName":{"type":"string","metadata":{"description":"Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'."}},"principalId":{"type":"string","metadata":{"description":"Required. The principal ID of the principal (user/group/identity) to assign the role to."}},"principalType":{"type":"string","allowedValues":["Device","ForeignGroup","Group","ServicePrincipal","User"],"nullable":true,"metadata":{"description":"Optional. The principal type of the assigned principal ID."}},"description":{"type":"string","nullable":true,"metadata":{"description":"Optional. The description of the role assignment."}},"condition":{"type":"string","nullable":true,"metadata":{"description":"Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"."}},"conditionVersion":{"type":"string","allowedValues":["2.0"],"nullable":true,"metadata":{"description":"Optional. Version of the condition."}},"delegatedManagedIdentityResourceId":{"type":"string","nullable":true,"metadata":{"description":"Optional. The Resource Id of the delegated managed identity resource."}}},"metadata":{"description":"An AVM-aligned type for a role assignment.","__bicep_imported_from!":{"sourceTemplate":"br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"}}}},"parameters":{"name":{"type":"string","metadata":{"description":"Required. The name prefix of the Image Template to be built by the Azure Image Builder service."}},"location":{"type":"string","defaultValue":"[resourceGroup().location]","metadata":{"description":"Optional. Location for all resources."}},"buildTimeoutInMinutes":{"type":"int","defaultValue":0,"minValue":0,"maxValue":960,"metadata":{"description":"Optional. The image build timeout in minutes. 0 means the default 240 minutes."}},"vmSize":{"type":"string","defaultValue":"Standard_D2s_v3","metadata":{"description":"Optional. Specifies the size for the VM."}},"osDiskSizeGB":{"type":"int","defaultValue":128,"metadata":{"description":"Optional. Specifies the size of OS disk."}},"subnetResourceId":{"type":"string","nullable":true,"metadata":{"description":"Optional. Resource ID of an already existing subnet, e.g.: /subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/.

If no value is provided, a new temporary VNET and subnet will be created in the staging resource group and will be deleted along with the remaining temporary resources."}},"imageSource":{"type":"object","metadata":{"description":"Required. Image source definition in object format."}},"customizationSteps":{"type":"array","nullable":true,"metadata":{"description":"Optional. Customization steps to be run when building the VM image."}},"stagingResourceGroupResourceId":{"type":"string","nullable":true,"metadata":{"description":"Optional. Resource ID of the staging resource group in the same subscription and location as the image template that will be used to build the image.

If this field is empty, a resource group with a random name will be created.

If the resource group specified in this field doesn't exist, it will be created with the same name.

If the resource group specified exists, it must be empty and in the same region as the image template.

The resource group created will be deleted during template deletion if this field is empty or the resource group specified doesn't exist,

but if the resource group specified exists the resources created in the resource group will be deleted during template deletion and the resource group itself will remain."}},"lock":{"$ref":"#/definitions/lockType","nullable":true,"metadata":{"description":"Optional. The lock settings of the service."}},"tags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags of the resource."}},"baseTime":{"type":"string","defaultValue":"[utcNow('yyyy-MM-dd-HH-mm-ss')]","metadata":{"description":"Generated. Do not provide a value! This date is used to generate a unique image template name."}},"enableTelemetry":{"type":"bool","defaultValue":true,"metadata":{"description":"Optional. Enable/Disable usage telemetry for module."}},"roleAssignments":{"type":"array","items":{"$ref":"#/definitions/roleAssignmentType"},"nullable":true,"metadata":{"description":"Optional. Array of role assignments to create."}},"distributions":{"type":"array","items":{"$ref":"#/definitions/distributionType"},"metadata":{"description":"Required. The distribution targets where the image output needs to go to."}},"vmUserAssignedIdentities":{"type":"array","defaultValue":[],"metadata":{"description":"Optional. List of User-Assigned Identities associated to the Build VM for accessing Azure resources such as Key Vaults from your customizer scripts. Be aware, the user assigned identities specified in the 'managedIdentities' parameter must have the 'Managed Identity Operator' role assignment on all the user assigned identities specified in this parameter for Azure Image Builder to be able to associate them to the build VM."}},"managedIdentities":{"$ref":"#/definitions/managedIdentityOnlyUserAssignedType","metadata":{"description":"Required. The managed identity definition for this resource."}},"validationProcess":{"$ref":"#/definitions/validationProcessType","nullable":true,"metadata":{"description":"Optional. Configuration options and list of validations to be performed on the resulting image."}},"optimizeVmBoot":{"type":"string","nullable":true,"allowedValues":["Enabled","Disabled"],"metadata":{"description":"Optional. The optimize property can be enabled while creating a VM image and allows VM optimization to improve image creation time."}},"autoRunState":{"type":"string","defaultValue":"Disabled","allowedValues":["Enabled","Disabled"],"metadata":{"description":"Optional. Indicates whether or not to automatically run the image template build on template creation or update."}},"errorHandlingOnCustomizerError":{"type":"string","defaultValue":"cleanup","allowedValues":["cleanup","abort"],"metadata":{"description":"Optional. If there is a customizer error and this field is set to 'cleanup', the build VM and associated network resources will be cleaned up. This is the default behavior. If there is a customizer error and this field is set to 'abort', the build VM will be preserved."}},"errorHandlingOnValidationError":{"type":"string","defaultValue":"cleanup","allowedValues":["cleanup","abort"],"metadata":{"description":"Optional. If there is a validation error and this field is set to 'cleanup', the build VM and associated network resources will be cleaned up. If there is a validation error and this field is set to 'abort', the build VM will be preserved. This is the default behavior."}},"managedResourceTags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags that will be applied to the resource group and/or resources created by the service."}}},"variables":{"copy":[{"name":"formattedRoleAssignments","count":"[length(coalesce(parameters('roleAssignments'), createArray()))]","input":"[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]"}],"identity":{"type":"UserAssigned","userAssignedIdentities":"[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]"},"builtInRoleNames":{"Contributor":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]","Owner":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]","Reader":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]","Role Based Access Control Administrator":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]","User Access Administrator":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]"}},"resources":{"avmTelemetry":{"condition":"[parameters('enableTelemetry')]","type":"Microsoft.Resources/deployments","apiVersion":"2024-03-01","name":"[format('46d3xbcp.res.virtualmachineimages-imagetemplate.{0}.{1}', replace('0.5.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]","properties":{"mode":"Incremental","template":{"$schema":"https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#","contentVersion":"1.0.0.0","resources":[],"outputs":{"telemetry":{"type":"String","value":"For more information, see https://aka.ms/avm/TelemetryInfo"}}}}},"imageTemplate":{"type":"Microsoft.VirtualMachineImages/imageTemplates","apiVersion":"2024-02-01","name":"[format('{0}-{1}', parameters('name'), parameters('baseTime'))]","location":"[parameters('location')]","tags":"[parameters('tags')]","identity":"[variables('identity')]","properties":"[shallowMerge(createArray(createObject('buildTimeoutInMinutes', parameters('buildTimeoutInMinutes'), 'vmProfile', createObject('vmSize', parameters('vmSize'), 'osDiskSizeGB', parameters('osDiskSizeGB'), 'userAssignedIdentities', parameters('vmUserAssignedIdentities'), 'vnetConfig', if(not(empty(parameters('subnetResourceId'))), createObject('subnetId', parameters('subnetResourceId')), null())), 'source', parameters('imageSource')), if(not(empty(parameters('customizationSteps'))), createObject('customize', parameters('customizationSteps')), createObject()), createObject('stagingResourceGroup', parameters('stagingResourceGroupResourceId'), 'distribute', map(parameters('distributions'), lambda('distribution', shallowMerge(createArray(createObject('type', lambdaVariables('distribution').type, 'artifactTags', coalesce(tryGet(lambdaVariables('distribution'), 'artifactTags'), createObject('sourceType', parameters('imageSource').type, 'sourcePublisher', tryGet(parameters('imageSource'), 'publisher'), 'sourceOffer', tryGet(parameters('imageSource'), 'offer'), 'sourceSku', tryGet(parameters('imageSource'), 'sku'), 'sourceVersion', tryGet(parameters('imageSource'), 'version'), 'sourceImageId', tryGet(parameters('imageSource'), 'imageId'), 'sourceImageVersionID', tryGet(parameters('imageSource'), 'imageVersionID'), 'creationTime', parameters('baseTime')))), if(equals(lambdaVariables('distribution').type, 'ManagedImage'), createObject('runOutputName', coalesce(tryGet(lambdaVariables('distribution'), 'runOutputName'), format('{0}-{1}-ManagedImage', lambdaVariables('distribution').imageName, parameters('baseTime'))), 'location', coalesce(tryGet(lambdaVariables('distribution'), 'location'), parameters('location')), 'imageId', coalesce(tryGet(lambdaVariables('distribution'), 'imageResourceId'), format('{0}/resourceGroups/{1}/providers/Microsoft.Compute/images/{2}-{3}', subscription().id, resourceGroup().name, lambdaVariables('distribution').imageName, parameters('baseTime')))), createObject()), if(equals(lambdaVariables('distribution').type, 'SharedImage'), createObject('runOutputName', coalesce(tryGet(lambdaVariables('distribution'), 'runOutputName'), if(not(empty(tryGet(lambdaVariables('distribution'), 'sharedImageGalleryImageDefinitionResourceId'))), format('{0}-SharedImage', last(split(coalesce(lambdaVariables('distribution').sharedImageGalleryImageDefinitionResourceId, '/'), '/'))), 'SharedImage')), 'galleryImageId', if(not(empty(tryGet(lambdaVariables('distribution'), 'sharedImageGalleryImageDefinitionTargetVersion'))), format('{0}/versions/{1}', lambdaVariables('distribution').sharedImageGalleryImageDefinitionResourceId, lambdaVariables('distribution').sharedImageGalleryImageDefinitionTargetVersion), lambdaVariables('distribution').sharedImageGalleryImageDefinitionResourceId), 'excludeFromLatest', coalesce(tryGet(lambdaVariables('distribution'), 'excludeFromLatest'), false()), 'replicationRegions', coalesce(tryGet(lambdaVariables('distribution'), 'replicationRegions'), createArray(parameters('location'))), 'storageAccountType', coalesce(tryGet(lambdaVariables('distribution'), 'storageAccountType'), 'Standard_LRS')), createObject()), if(equals(lambdaVariables('distribution').type, 'VHD'), createObject('runOutputName', coalesce(tryGet(lambdaVariables('distribution'), 'runOutputName'), format('{0}-VHD', lambdaVariables('distribution').imageName))), createObject()))))), 'validate', parameters('validationProcess'), 'optimize', if(not(equals(parameters('optimizeVmBoot'), null())), createObject('vmBoot', createObject('state', parameters('optimizeVmBoot'))), null()), 'autoRun', createObject('state', parameters('autoRunState')), 'errorHandling', createObject('onCustomizerError', parameters('errorHandlingOnCustomizerError'), 'onValidationError', parameters('errorHandlingOnValidationError')), 'managedResourceTags', parameters('managedResourceTags'))))]"},"imageTemplate_lock":{"condition":"[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]","type":"Microsoft.Authorization/locks","apiVersion":"2020-05-01","scope":"[format('Microsoft.VirtualMachineImages/imageTemplates/{0}', format('{0}-{1}', parameters('name'), parameters('baseTime')))]","name":"[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]","properties":{"level":"[coalesce(tryGet(parameters('lock'), 'kind'), '')]","notes":"[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]"},"dependsOn":["imageTemplate"]},"imageTemplate_roleAssignments":{"copy":{"name":"imageTemplate_roleAssignments","count":"[length(coalesce(variables('formattedRoleAssignments'), createArray()))]"},"type":"Microsoft.Authorization/roleAssignments","apiVersion":"2022-04-01","scope":"[format('Microsoft.VirtualMachineImages/imageTemplates/{0}', format('{0}-{1}', parameters('name'), parameters('baseTime')))]","name":"[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.VirtualMachineImages/imageTemplates', format('{0}-{1}', parameters('name'), parameters('baseTime'))), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]","properties":{"roleDefinitionId":"[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]","principalId":"[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]","description":"[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]","principalType":"[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]","condition":"[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]","conditionVersion":"[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]","delegatedManagedIdentityResourceId":"[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]"},"dependsOn":["imageTemplate"]}},"outputs":{"resourceId":{"type":"string","metadata":{"description":"The resource ID of the image template."},"value":"[resourceId('Microsoft.VirtualMachineImages/imageTemplates', format('{0}-{1}', parameters('name'), parameters('baseTime')))]"},"resourceGroupName":{"type":"string","metadata":{"description":"The resource group the image template was deployed into."},"value":"[resourceGroup().name]"},"name":{"type":"string","metadata":{"description":"The full name of the deployed image template."},"value":"[format('{0}-{1}', parameters('name'), parameters('baseTime'))]"},"namePrefix":{"type":"string","metadata":{"description":"The prefix of the image template name provided as input."},"value":"[parameters('name')]"},"runThisCommand":{"type":"string","metadata":{"description":"The command to run in order to trigger the image build."},"value":"[format('Invoke-AzResourceAction -ResourceName {0} -ResourceGroupName {1} -ResourceType Microsoft.VirtualMachineImages/imageTemplates -Action Run -Force', format('{0}-{1}', parameters('name'), parameters('baseTime')), resourceGroup().name)]"},"location":{"type":"string","metadata":{"description":"The location the resource was deployed into."},"value":"[reference('imageTemplate', '2024-02-01', 'full').location]"}}}}}}},"templateLink":{"id":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg","uri":"https://deployment-uri"},"parameters":null,"mode":"Incremental","provisioningState":"Accepted","templateHash":"8015957","outputs":{}},"location":"eastus","type":"Microsoft.Resources/deployments","metadata":{"_generator":{"name":"bicep","version":"0.33.93.31351","templateHash":"8291788442761701655"}},"id":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg/providers/Microsoft.Resources/deployments/helper","scope":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg","rootDeployment":true,"_PSRule":{"path":"","source":[{"file":"tests\\PSRule.Rules.Azure.Tests\\Resources.ImageBuilder.Source.bicep","type":"Template"}]}},{"ResourceName":"image_001-6779b22524d1f","name":"image_001-6779b22524d1f","properties":{"template":{"$schema":"https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#","languageVersion":"2.0","contentVersion":"1.0.0.0","metadata":{"_generator":{"name":"bicep","version":"0.33.93.31351","templateHash":"17156102195331830052"},"name":"Virtual Machine Image Templates","description":"This module deploys a Virtual Machine Image Template that can be consumed by Azure Image Builder (AIB)."},"definitions":{"distributionType":{"type":"object","discriminator":{"propertyName":"type","mapping":{"SharedImage":{"$ref":"#/definitions/sharedImageDistributionType"},"ManagedImage":{"$ref":"#/definitions/managedImageDistributionType"},"VHD":{"$ref":"#/definitions/unManagedDistributionType"}}},"metadata":{"__bicep_export!":true}},"sharedImageDistributionType":{"type":"object","properties":{"runOutputName":{"type":"string","nullable":true,"metadata":{"description":"Optional. The name to be used for the associated RunOutput. If not provided, a name will be calculated."}},"artifactTags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags that will be applied to the artifact once it has been created/updated by the distributor. If not provided will set tags based on the provided image source."}},"type":{"type":"string","allowedValues":["SharedImage"],"metadata":{"description":"Required. The type of distribution."}},"sharedImageGalleryImageDefinitionResourceId":{"type":"string","metadata":{"description":"Conditional. Resource ID of Compute Gallery Image Definition to distribute image to, e.g.: /subscriptions//resourceGroups//providers/Microsoft.Compute/galleries//images/."}},"sharedImageGalleryImageDefinitionTargetVersion":{"type":"string","nullable":true,"metadata":{"description":"Optional. Version of the Compute Gallery Image. Supports the following Version Syntax: Major.Minor.Build (i.e., '1.1.1' or '10.1.2'). If not provided, a version will be calculated."}},"excludeFromLatest":{"type":"bool","nullable":true,"metadata":{"description":"Optional. The exclude from latest flag of the image. Defaults to [false]."}},"replicationRegions":{"type":"array","items":{"type":"string"},"nullable":true,"metadata":{"description":"Optional. The replication regions of the image. Defaults to the value of the 'location' parameter."}},"storageAccountType":{"type":"string","allowedValues":["Standard_LRS","Standard_ZRS"],"nullable":true,"metadata":{"description":"Optional. The storage account type of the image. Defaults to [Standard_LRS]."}}},"metadata":{"__bicep_export!":true}},"unManagedDistributionType":{"type":"object","properties":{"type":{"type":"string","allowedValues":["VHD"],"metadata":{"description":"Required. The type of distribution."}},"runOutputName":{"type":"string","nullable":true,"metadata":{"description":"Optional. The name to be used for the associated RunOutput. If not provided, a name will be calculated."}},"artifactTags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags that will be applied to the artifact once it has been created/updated by the distributor. If not provided will set tags based on the provided image source."}},"imageName":{"type":"string","metadata":{"description":"Conditional. Name of the managed or unmanaged image that will be created."}}},"metadata":{"__bicep_export!":true}},"managedImageDistributionType":{"type":"object","properties":{"type":{"type":"string","allowedValues":["ManagedImage"],"metadata":{"description":"Required. The type of distribution."}},"runOutputName":{"type":"string","nullable":true,"metadata":{"description":"Optional. The name to be used for the associated RunOutput. If not provided, a name will be calculated."}},"artifactTags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags that will be applied to the artifact once it has been created/updated by the distributor. If not provided will set tags based on the provided image source."}},"location":{"type":"string","nullable":true,"metadata":{"description":"Optional. Azure location for the image, should match if image already exists. Defaults to the value of the 'location' parameter."}},"imageResourceId":{"type":"string","nullable":true,"metadata":{"description":"Required. The resource ID of the managed image. Defaults to a compute image with name 'imageName-baseTime' in the current resource group."}},"imageName":{"type":"string","metadata":{"description":"Conditional. Name of the managed or unmanaged image that will be created."}}},"metadata":{"__bicep_export!":true}},"validationProcessType":{"type":"object","properties":{"continueDistributeOnFailure":{"type":"bool","nullable":true,"metadata":{"description":"Optional. If validation fails and this field is set to false, output image(s) will not be distributed. This is the default behavior. If validation fails and this field is set to true, output image(s) will still be distributed. Please use this option with caution as it may result in bad images being distributed for use. In either case (true or false), the end to end image run will be reported as having failed in case of a validation failure. [Note: This field has no effect if validation succeeds.]."}},"inVMValidations":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","allowedValues":["File","PowerShell","Shell"],"metadata":{"description":"Required. The type of validation."}},"name":{"type":"string","nullable":true,"metadata":{"description":"Optional. Friendly Name to provide context on what this validation step does."}},"scriptUri":{"type":"string","nullable":true,"metadata":{"description":"Optional. URI of the PowerShell script to be run for validation. It can be a github link, Azure Storage URI, etc."}},"inline":{"type":"array","items":{"type":"string"},"nullable":true,"metadata":{"description":"Optional. Array of commands to be run, separated by commas."}},"validExitCodes":{"type":"array","items":{"type":"int"},"nullable":true,"metadata":{"description":"Optional. Valid codes that can be returned from the script/inline command, this avoids reported failure of the script/inline command."}},"sha256Checksum":{"type":"string","nullable":true,"metadata":{"description":"Optional. Value of sha256 checksum of the file, you generate this locally, and then Image Builder will checksum and validate."}},"sourceUri":{"type":"string","nullable":true,"metadata":{"description":"Optional. The source URI of the file."}},"destination":{"type":"string","nullable":true,"metadata":{"description":"Optional. Destination of the file."}},"runAsSystem":{"type":"bool","nullable":true,"metadata":{"description":"Optional. If specified, the PowerShell script will be run with elevated privileges using the Local System user. Can only be true when the runElevated field above is set to true."}},"runElevated":{"type":"bool","nullable":true,"metadata":{"description":"Optional. If specified, the PowerShell script will be run with elevated privileges."}}}},"nullable":true,"metadata":{"description":"Optional. A list of validators that will be performed on the image. Azure Image Builder supports File, PowerShell and Shell validators."}},"sourceValidationOnly":{"type":"bool","nullable":true,"metadata":{"description":"Optional. If this field is set to true, the image specified in the 'source' section will directly be validated. No separate build will be run to generate and then validate a customized image. Not supported when performing customizations, validations or distributions on the image."}}},"metadata":{"__bicep_export!":true}},"lockType":{"type":"object","properties":{"name":{"type":"string","nullable":true,"metadata":{"description":"Optional. Specify the name of lock."}},"kind":{"type":"string","allowedValues":["CanNotDelete","None","ReadOnly"],"nullable":true,"metadata":{"description":"Optional. Specify the type of lock."}}},"metadata":{"description":"An AVM-aligned type for a lock.","__bicep_imported_from!":{"sourceTemplate":"br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"}}},"managedIdentityOnlyUserAssignedType":{"type":"object","properties":{"userAssignedResourceIds":{"type":"array","items":{"type":"string"},"nullable":true,"metadata":{"description":"Optional. The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption."}}},"metadata":{"description":"An AVM-aligned type for a managed identity configuration. To be used if only user-assigned identities are supported by the resource provider.","__bicep_imported_from!":{"sourceTemplate":"br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"}}},"roleAssignmentType":{"type":"object","properties":{"name":{"type":"string","nullable":true,"metadata":{"description":"Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated."}},"roleDefinitionIdOrName":{"type":"string","metadata":{"description":"Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'."}},"principalId":{"type":"string","metadata":{"description":"Required. The principal ID of the principal (user/group/identity) to assign the role to."}},"principalType":{"type":"string","allowedValues":["Device","ForeignGroup","Group","ServicePrincipal","User"],"nullable":true,"metadata":{"description":"Optional. The principal type of the assigned principal ID."}},"description":{"type":"string","nullable":true,"metadata":{"description":"Optional. The description of the role assignment."}},"condition":{"type":"string","nullable":true,"metadata":{"description":"Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"."}},"conditionVersion":{"type":"string","allowedValues":["2.0"],"nullable":true,"metadata":{"description":"Optional. Version of the condition."}},"delegatedManagedIdentityResourceId":{"type":"string","nullable":true,"metadata":{"description":"Optional. The Resource Id of the delegated managed identity resource."}}},"metadata":{"description":"An AVM-aligned type for a role assignment.","__bicep_imported_from!":{"sourceTemplate":"br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"}}}},"parameters":{"name":{"type":"string","metadata":{"description":"Required. The name prefix of the Image Template to be built by the Azure Image Builder service."}},"location":{"type":"string","defaultValue":"[resourceGroup().location]","metadata":{"description":"Optional. Location for all resources."}},"buildTimeoutInMinutes":{"type":"int","defaultValue":0,"minValue":0,"maxValue":960,"metadata":{"description":"Optional. The image build timeout in minutes. 0 means the default 240 minutes."}},"vmSize":{"type":"string","defaultValue":"Standard_D2s_v3","metadata":{"description":"Optional. Specifies the size for the VM."}},"osDiskSizeGB":{"type":"int","defaultValue":128,"metadata":{"description":"Optional. Specifies the size of OS disk."}},"subnetResourceId":{"type":"string","nullable":true,"metadata":{"description":"Optional. Resource ID of an already existing subnet, e.g.: /subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/.

If no value is provided, a new temporary VNET and subnet will be created in the staging resource group and will be deleted along with the remaining temporary resources."}},"imageSource":{"type":"object","metadata":{"description":"Required. Image source definition in object format."}},"customizationSteps":{"type":"array","nullable":true,"metadata":{"description":"Optional. Customization steps to be run when building the VM image."}},"stagingResourceGroupResourceId":{"type":"string","nullable":true,"metadata":{"description":"Optional. Resource ID of the staging resource group in the same subscription and location as the image template that will be used to build the image.

If this field is empty, a resource group with a random name will be created.

If the resource group specified in this field doesn't exist, it will be created with the same name.

If the resource group specified exists, it must be empty and in the same region as the image template.

The resource group created will be deleted during template deletion if this field is empty or the resource group specified doesn't exist,

but if the resource group specified exists the resources created in the resource group will be deleted during template deletion and the resource group itself will remain."}},"lock":{"$ref":"#/definitions/lockType","nullable":true,"metadata":{"description":"Optional. The lock settings of the service."}},"tags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags of the resource."}},"baseTime":{"type":"string","defaultValue":"[utcNow('yyyy-MM-dd-HH-mm-ss')]","metadata":{"description":"Generated. Do not provide a value! This date is used to generate a unique image template name."}},"enableTelemetry":{"type":"bool","defaultValue":true,"metadata":{"description":"Optional. Enable/Disable usage telemetry for module."}},"roleAssignments":{"type":"array","items":{"$ref":"#/definitions/roleAssignmentType"},"nullable":true,"metadata":{"description":"Optional. Array of role assignments to create."}},"distributions":{"type":"array","items":{"$ref":"#/definitions/distributionType"},"metadata":{"description":"Required. The distribution targets where the image output needs to go to."}},"vmUserAssignedIdentities":{"type":"array","defaultValue":[],"metadata":{"description":"Optional. List of User-Assigned Identities associated to the Build VM for accessing Azure resources such as Key Vaults from your customizer scripts. Be aware, the user assigned identities specified in the 'managedIdentities' parameter must have the 'Managed Identity Operator' role assignment on all the user assigned identities specified in this parameter for Azure Image Builder to be able to associate them to the build VM."}},"managedIdentities":{"$ref":"#/definitions/managedIdentityOnlyUserAssignedType","metadata":{"description":"Required. The managed identity definition for this resource."}},"validationProcess":{"$ref":"#/definitions/validationProcessType","nullable":true,"metadata":{"description":"Optional. Configuration options and list of validations to be performed on the resulting image."}},"optimizeVmBoot":{"type":"string","nullable":true,"allowedValues":["Enabled","Disabled"],"metadata":{"description":"Optional. The optimize property can be enabled while creating a VM image and allows VM optimization to improve image creation time."}},"autoRunState":{"type":"string","defaultValue":"Disabled","allowedValues":["Enabled","Disabled"],"metadata":{"description":"Optional. Indicates whether or not to automatically run the image template build on template creation or update."}},"errorHandlingOnCustomizerError":{"type":"string","defaultValue":"cleanup","allowedValues":["cleanup","abort"],"metadata":{"description":"Optional. If there is a customizer error and this field is set to 'cleanup', the build VM and associated network resources will be cleaned up. This is the default behavior. If there is a customizer error and this field is set to 'abort', the build VM will be preserved."}},"errorHandlingOnValidationError":{"type":"string","defaultValue":"cleanup","allowedValues":["cleanup","abort"],"metadata":{"description":"Optional. If there is a validation error and this field is set to 'cleanup', the build VM and associated network resources will be cleaned up. If there is a validation error and this field is set to 'abort', the build VM will be preserved. This is the default behavior."}},"managedResourceTags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags that will be applied to the resource group and/or resources created by the service."}}},"variables":{"copy":[{"name":"formattedRoleAssignments","count":"[length(coalesce(parameters('roleAssignments'), createArray()))]","input":"[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]"}],"identity":{"type":"UserAssigned","userAssignedIdentities":"[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]"},"builtInRoleNames":{"Contributor":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]","Owner":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]","Reader":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]","Role Based Access Control Administrator":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]","User Access Administrator":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]"}},"resources":{"avmTelemetry":{"condition":"[parameters('enableTelemetry')]","type":"Microsoft.Resources/deployments","apiVersion":"2024-03-01","name":"[format('46d3xbcp.res.virtualmachineimages-imagetemplate.{0}.{1}', replace('0.5.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]","properties":{"mode":"Incremental","template":{"$schema":"https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#","contentVersion":"1.0.0.0","resources":[],"outputs":{"telemetry":{"type":"String","value":"For more information, see https://aka.ms/avm/TelemetryInfo"}}}}},"imageTemplate":{"type":"Microsoft.VirtualMachineImages/imageTemplates","apiVersion":"2024-02-01","name":"[format('{0}-{1}', parameters('name'), parameters('baseTime'))]","location":"[parameters('location')]","tags":"[parameters('tags')]","identity":"[variables('identity')]","properties":"[shallowMerge(createArray(createObject('buildTimeoutInMinutes', parameters('buildTimeoutInMinutes'), 'vmProfile', createObject('vmSize', parameters('vmSize'), 'osDiskSizeGB', parameters('osDiskSizeGB'), 'userAssignedIdentities', parameters('vmUserAssignedIdentities'), 'vnetConfig', if(not(empty(parameters('subnetResourceId'))), createObject('subnetId', parameters('subnetResourceId')), null())), 'source', parameters('imageSource')), if(not(empty(parameters('customizationSteps'))), createObject('customize', parameters('customizationSteps')), createObject()), createObject('stagingResourceGroup', parameters('stagingResourceGroupResourceId'), 'distribute', map(parameters('distributions'), lambda('distribution', shallowMerge(createArray(createObject('type', lambdaVariables('distribution').type, 'artifactTags', coalesce(tryGet(lambdaVariables('distribution'), 'artifactTags'), createObject('sourceType', parameters('imageSource').type, 'sourcePublisher', tryGet(parameters('imageSource'), 'publisher'), 'sourceOffer', tryGet(parameters('imageSource'), 'offer'), 'sourceSku', tryGet(parameters('imageSource'), 'sku'), 'sourceVersion', tryGet(parameters('imageSource'), 'version'), 'sourceImageId', tryGet(parameters('imageSource'), 'imageId'), 'sourceImageVersionID', tryGet(parameters('imageSource'), 'imageVersionID'), 'creationTime', parameters('baseTime')))), if(equals(lambdaVariables('distribution').type, 'ManagedImage'), createObject('runOutputName', coalesce(tryGet(lambdaVariables('distribution'), 'runOutputName'), format('{0}-{1}-ManagedImage', lambdaVariables('distribution').imageName, parameters('baseTime'))), 'location', coalesce(tryGet(lambdaVariables('distribution'), 'location'), parameters('location')), 'imageId', coalesce(tryGet(lambdaVariables('distribution'), 'imageResourceId'), format('{0}/resourceGroups/{1}/providers/Microsoft.Compute/images/{2}-{3}', subscription().id, resourceGroup().name, lambdaVariables('distribution').imageName, parameters('baseTime')))), createObject()), if(equals(lambdaVariables('distribution').type, 'SharedImage'), createObject('runOutputName', coalesce(tryGet(lambdaVariables('distribution'), 'runOutputName'), if(not(empty(tryGet(lambdaVariables('distribution'), 'sharedImageGalleryImageDefinitionResourceId'))), format('{0}-SharedImage', last(split(coalesce(lambdaVariables('distribution').sharedImageGalleryImageDefinitionResourceId, '/'), '/'))), 'SharedImage')), 'galleryImageId', if(not(empty(tryGet(lambdaVariables('distribution'), 'sharedImageGalleryImageDefinitionTargetVersion'))), format('{0}/versions/{1}', lambdaVariables('distribution').sharedImageGalleryImageDefinitionResourceId, lambdaVariables('distribution').sharedImageGalleryImageDefinitionTargetVersion), lambdaVariables('distribution').sharedImageGalleryImageDefinitionResourceId), 'excludeFromLatest', coalesce(tryGet(lambdaVariables('distribution'), 'excludeFromLatest'), false()), 'replicationRegions', coalesce(tryGet(lambdaVariables('distribution'), 'replicationRegions'), createArray(parameters('location'))), 'storageAccountType', coalesce(tryGet(lambdaVariables('distribution'), 'storageAccountType'), 'Standard_LRS')), createObject()), if(equals(lambdaVariables('distribution').type, 'VHD'), createObject('runOutputName', coalesce(tryGet(lambdaVariables('distribution'), 'runOutputName'), format('{0}-VHD', lambdaVariables('distribution').imageName))), createObject()))))), 'validate', parameters('validationProcess'), 'optimize', if(not(equals(parameters('optimizeVmBoot'), null())), createObject('vmBoot', createObject('state', parameters('optimizeVmBoot'))), null()), 'autoRun', createObject('state', parameters('autoRunState')), 'errorHandling', createObject('onCustomizerError', parameters('errorHandlingOnCustomizerError'), 'onValidationError', parameters('errorHandlingOnValidationError')), 'managedResourceTags', parameters('managedResourceTags'))))]"},"imageTemplate_lock":{"condition":"[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]","type":"Microsoft.Authorization/locks","apiVersion":"2020-05-01","scope":"[format('Microsoft.VirtualMachineImages/imageTemplates/{0}', format('{0}-{1}', parameters('name'), parameters('baseTime')))]","name":"[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]","properties":{"level":"[coalesce(tryGet(parameters('lock'), 'kind'), '')]","notes":"[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]"},"dependsOn":["imageTemplate"]},"imageTemplate_roleAssignments":{"copy":{"name":"imageTemplate_roleAssignments","count":"[length(coalesce(variables('formattedRoleAssignments'), createArray()))]"},"type":"Microsoft.Authorization/roleAssignments","apiVersion":"2022-04-01","scope":"[format('Microsoft.VirtualMachineImages/imageTemplates/{0}', format('{0}-{1}', parameters('name'), parameters('baseTime')))]","name":"[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.VirtualMachineImages/imageTemplates', format('{0}-{1}', parameters('name'), parameters('baseTime'))), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]","properties":{"roleDefinitionId":"[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]","principalId":"[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]","description":"[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]","principalType":"[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]","condition":"[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]","conditionVersion":"[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]","delegatedManagedIdentityResourceId":"[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]"},"dependsOn":["imageTemplate"]}},"outputs":{"resourceId":{"type":"string","metadata":{"description":"The resource ID of the image template."},"value":"[resourceId('Microsoft.VirtualMachineImages/imageTemplates', format('{0}-{1}', parameters('name'), parameters('baseTime')))]"},"resourceGroupName":{"type":"string","metadata":{"description":"The resource group the image template was deployed into."},"value":"[resourceGroup().name]"},"name":{"type":"string","metadata":{"description":"The full name of the deployed image template."},"value":"[format('{0}-{1}', parameters('name'), parameters('baseTime'))]"},"namePrefix":{"type":"string","metadata":{"description":"The prefix of the image template name provided as input."},"value":"[parameters('name')]"},"runThisCommand":{"type":"string","metadata":{"description":"The command to run in order to trigger the image build."},"value":"[format('Invoke-AzResourceAction -ResourceName {0} -ResourceGroupName {1} -ResourceType Microsoft.VirtualMachineImages/imageTemplates -Action Run -Force', format('{0}-{1}', parameters('name'), parameters('baseTime')), resourceGroup().name)]"},"location":{"type":"string","metadata":{"description":"The location the resource was deployed into."},"value":"[reference('imageTemplate', '2024-02-01', 'full').location]"}}},"templateLink":{"id":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg","uri":"https://deployment-uri"},"parameters":{"name":{"value":"image-001"},"baseTime":{"value":"0"},"distributions":{"value":[{"type":"ManagedImage","imageName":"image-001"}]},"imageSource":{"value":{"type":"PlatformImage","publisher":"canonical","offer":"ubuntu-24_04-lts","sku":"server","version":"latest"}},"managedIdentities":{"value":{}},"customizationSteps":{"value":[{"type":"Shell","name":"PowerShell installation","scriptUri":"https://raw.githubusercontent.com/Azure/bicep-registry-modules/refs/heads/main/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Install-LinuxPowerShell.sh"}]},"validationProcess":{"value":{"inVMValidations":[{"type":"Shell","name":"Validate PowerShell","scriptUri":"https://raw.githubusercontent.com/Azure/bicep-registry-modules/refs/heads/main/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Install-LinuxPowerShell.sh"}]}},"buildTimeoutInMinutes":{"value":60},"vmSize":{"value":"Standard_D2s_v3"}},"mode":"Incremental","provisioningState":"Accepted","templateHash":"45312816","outputs":{}},"location":"eastus","type":"Microsoft.Resources/deployments","metadata":{"_generator":{"name":"bicep","version":"0.33.93.31351","templateHash":"17156102195331830052"},"name":"Virtual Machine Image Templates","description":"This module deploys a Virtual Machine Image Template that can be consumed by Azure Image Builder (AIB)."},"id":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg/providers/Microsoft.Resources/deployments/image_001-6779b22524d1f","scope":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg","rootDeployment":false,"_PSRule":{"path":"resources.image_001","source":[{"file":"tests\\PSRule.Rules.Azure.Tests\\Resources.ImageBuilder.Source.bicep","type":"Template"}]}},{"ResourceName":"46d3xbcp.res.virtualmachineimages-imagetemplate.0-5-0.bcf5","name":"46d3xbcp.res.virtualmachineimages-imagetemplate.0-5-0.bcf5","properties":{"template":{"$schema":"https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#","contentVersion":"1.0.0.0","resources":[],"outputs":{"telemetry":{"type":"String","value":"For more information, see https://aka.ms/avm/TelemetryInfo"}}},"templateLink":{"id":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg","uri":"https://deployment-uri"},"parameters":{"name":{"value":"image-001"},"baseTime":{"value":"0"},"distributions":{"value":[{"type":"ManagedImage","imageName":"image-001"}]},"imageSource":{"value":{"type":"PlatformImage","publisher":"canonical","offer":"ubuntu-24_04-lts","sku":"server","version":"latest"}},"managedIdentities":{"value":{}},"customizationSteps":{"value":[{"type":"Shell","name":"PowerShell installation","scriptUri":"https://raw.githubusercontent.com/Azure/bicep-registry-modules/refs/heads/main/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Install-LinuxPowerShell.sh"}]},"validationProcess":{"value":{"inVMValidations":[{"type":"Shell","name":"Validate PowerShell","scriptUri":"https://raw.githubusercontent.com/Azure/bicep-registry-modules/refs/heads/main/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Install-LinuxPowerShell.sh"}]}},"buildTimeoutInMinutes":{"value":60},"vmSize":{"value":"Standard_D2s_v3"}},"mode":"Incremental","provisioningState":"Accepted","templateHash":"46459517","outputs":{}},"location":"eastus","type":"Microsoft.Resources/deployments","metadata":null,"id":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg/providers/Microsoft.Resources/deployments/46d3xbcp.res.virtualmachineimages-imagetemplate.0-5-0.bcf5","scope":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg","rootDeployment":false,"_PSRule":{"path":"properties.template.resources.avmTelemetry","source":[{"file":"tests\\PSRule.Rules.Azure.Tests\\Resources.ImageBuilder.Source.bicep","type":"Template"}]}},{"type":"Microsoft.VirtualMachineImages/imageTemplates","apiVersion":"2024-02-01","name":"image-001-0","location":"eastus","identity":{"type":"UserAssigned","userAssignedIdentities":{}},"properties":{"buildTimeoutInMinutes":60,"vmProfile":{"vmSize":"Standard_D2s_v3","osDiskSizeGB":128,"userAssignedIdentities":[]},"source":{"type":"PlatformImage","publisher":"canonical","offer":"ubuntu-24_04-lts","sku":"server","version":"latest"},"customize":[{"type":"Shell","name":"PowerShell installation","scriptUri":"https://raw.githubusercontent.com/Azure/bicep-registry-modules/refs/heads/main/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Install-LinuxPowerShell.sh"}],"distribute":[{"type":"ManagedImage","artifactTags":{"sourceType":"PlatformImage","sourcePublisher":"canonical","sourceOffer":"ubuntu-24_04-lts","sourceSku":"server","sourceVersion":"latest","creationTime":"0"},"runOutputName":"image-001-0-ManagedImage","location":"eastus","imageId":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg/providers/Microsoft.Compute/images/image-001-0"}],"validate":{"inVMValidations":[{"type":"Shell","name":"Validate PowerShell","scriptUri":"https://raw.githubusercontent.com/Azure/bicep-registry-modules/refs/heads/main/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Install-LinuxPowerShell.sh"}]},"autoRun":{"state":"Disabled"},"errorHandling":{"onCustomizerError":"cleanup","onValidationError":"cleanup"}},"scope":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg","id":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg/providers/Microsoft.VirtualMachineImages/imageTemplates/image-001-0","_PSRule":{"path":"properties.template.resources.imageTemplate","source":[{"file":"tests\\PSRule.Rules.Azure.Tests\\Resources.ImageBuilder.Source.bicep","type":"Template","line":735,"position":30}]}},{"ResourceName":"image_002-84b314832a63d","name":"image_002-84b314832a63d","properties":{"template":{"$schema":"https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#","languageVersion":"2.0","contentVersion":"1.0.0.0","metadata":{"_generator":{"name":"bicep","version":"0.33.93.31351","templateHash":"17156102195331830052"},"name":"Virtual Machine Image Templates","description":"This module deploys a Virtual Machine Image Template that can be consumed by Azure Image Builder (AIB)."},"definitions":{"distributionType":{"type":"object","discriminator":{"propertyName":"type","mapping":{"SharedImage":{"$ref":"#/definitions/sharedImageDistributionType"},"ManagedImage":{"$ref":"#/definitions/managedImageDistributionType"},"VHD":{"$ref":"#/definitions/unManagedDistributionType"}}},"metadata":{"__bicep_export!":true}},"sharedImageDistributionType":{"type":"object","properties":{"runOutputName":{"type":"string","nullable":true,"metadata":{"description":"Optional. The name to be used for the associated RunOutput. If not provided, a name will be calculated."}},"artifactTags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags that will be applied to the artifact once it has been created/updated by the distributor. If not provided will set tags based on the provided image source."}},"type":{"type":"string","allowedValues":["SharedImage"],"metadata":{"description":"Required. The type of distribution."}},"sharedImageGalleryImageDefinitionResourceId":{"type":"string","metadata":{"description":"Conditional. Resource ID of Compute Gallery Image Definition to distribute image to, e.g.: /subscriptions//resourceGroups//providers/Microsoft.Compute/galleries//images/."}},"sharedImageGalleryImageDefinitionTargetVersion":{"type":"string","nullable":true,"metadata":{"description":"Optional. Version of the Compute Gallery Image. Supports the following Version Syntax: Major.Minor.Build (i.e., '1.1.1' or '10.1.2'). If not provided, a version will be calculated."}},"excludeFromLatest":{"type":"bool","nullable":true,"metadata":{"description":"Optional. The exclude from latest flag of the image. Defaults to [false]."}},"replicationRegions":{"type":"array","items":{"type":"string"},"nullable":true,"metadata":{"description":"Optional. The replication regions of the image. Defaults to the value of the 'location' parameter."}},"storageAccountType":{"type":"string","allowedValues":["Standard_LRS","Standard_ZRS"],"nullable":true,"metadata":{"description":"Optional. The storage account type of the image. Defaults to [Standard_LRS]."}}},"metadata":{"__bicep_export!":true}},"unManagedDistributionType":{"type":"object","properties":{"type":{"type":"string","allowedValues":["VHD"],"metadata":{"description":"Required. The type of distribution."}},"runOutputName":{"type":"string","nullable":true,"metadata":{"description":"Optional. The name to be used for the associated RunOutput. If not provided, a name will be calculated."}},"artifactTags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags that will be applied to the artifact once it has been created/updated by the distributor. If not provided will set tags based on the provided image source."}},"imageName":{"type":"string","metadata":{"description":"Conditional. Name of the managed or unmanaged image that will be created."}}},"metadata":{"__bicep_export!":true}},"managedImageDistributionType":{"type":"object","properties":{"type":{"type":"string","allowedValues":["ManagedImage"],"metadata":{"description":"Required. The type of distribution."}},"runOutputName":{"type":"string","nullable":true,"metadata":{"description":"Optional. The name to be used for the associated RunOutput. If not provided, a name will be calculated."}},"artifactTags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags that will be applied to the artifact once it has been created/updated by the distributor. If not provided will set tags based on the provided image source."}},"location":{"type":"string","nullable":true,"metadata":{"description":"Optional. Azure location for the image, should match if image already exists. Defaults to the value of the 'location' parameter."}},"imageResourceId":{"type":"string","nullable":true,"metadata":{"description":"Required. The resource ID of the managed image. Defaults to a compute image with name 'imageName-baseTime' in the current resource group."}},"imageName":{"type":"string","metadata":{"description":"Conditional. Name of the managed or unmanaged image that will be created."}}},"metadata":{"__bicep_export!":true}},"validationProcessType":{"type":"object","properties":{"continueDistributeOnFailure":{"type":"bool","nullable":true,"metadata":{"description":"Optional. If validation fails and this field is set to false, output image(s) will not be distributed. This is the default behavior. If validation fails and this field is set to true, output image(s) will still be distributed. Please use this option with caution as it may result in bad images being distributed for use. In either case (true or false), the end to end image run will be reported as having failed in case of a validation failure. [Note: This field has no effect if validation succeeds.]."}},"inVMValidations":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","allowedValues":["File","PowerShell","Shell"],"metadata":{"description":"Required. The type of validation."}},"name":{"type":"string","nullable":true,"metadata":{"description":"Optional. Friendly Name to provide context on what this validation step does."}},"scriptUri":{"type":"string","nullable":true,"metadata":{"description":"Optional. URI of the PowerShell script to be run for validation. It can be a github link, Azure Storage URI, etc."}},"inline":{"type":"array","items":{"type":"string"},"nullable":true,"metadata":{"description":"Optional. Array of commands to be run, separated by commas."}},"validExitCodes":{"type":"array","items":{"type":"int"},"nullable":true,"metadata":{"description":"Optional. Valid codes that can be returned from the script/inline command, this avoids reported failure of the script/inline command."}},"sha256Checksum":{"type":"string","nullable":true,"metadata":{"description":"Optional. Value of sha256 checksum of the file, you generate this locally, and then Image Builder will checksum and validate."}},"sourceUri":{"type":"string","nullable":true,"metadata":{"description":"Optional. The source URI of the file."}},"destination":{"type":"string","nullable":true,"metadata":{"description":"Optional. Destination of the file."}},"runAsSystem":{"type":"bool","nullable":true,"metadata":{"description":"Optional. If specified, the PowerShell script will be run with elevated privileges using the Local System user. Can only be true when the runElevated field above is set to true."}},"runElevated":{"type":"bool","nullable":true,"metadata":{"description":"Optional. If specified, the PowerShell script will be run with elevated privileges."}}}},"nullable":true,"metadata":{"description":"Optional. A list of validators that will be performed on the image. Azure Image Builder supports File, PowerShell and Shell validators."}},"sourceValidationOnly":{"type":"bool","nullable":true,"metadata":{"description":"Optional. If this field is set to true, the image specified in the 'source' section will directly be validated. No separate build will be run to generate and then validate a customized image. Not supported when performing customizations, validations or distributions on the image."}}},"metadata":{"__bicep_export!":true}},"lockType":{"type":"object","properties":{"name":{"type":"string","nullable":true,"metadata":{"description":"Optional. Specify the name of lock."}},"kind":{"type":"string","allowedValues":["CanNotDelete","None","ReadOnly"],"nullable":true,"metadata":{"description":"Optional. Specify the type of lock."}}},"metadata":{"description":"An AVM-aligned type for a lock.","__bicep_imported_from!":{"sourceTemplate":"br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"}}},"managedIdentityOnlyUserAssignedType":{"type":"object","properties":{"userAssignedResourceIds":{"type":"array","items":{"type":"string"},"nullable":true,"metadata":{"description":"Optional. The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption."}}},"metadata":{"description":"An AVM-aligned type for a managed identity configuration. To be used if only user-assigned identities are supported by the resource provider.","__bicep_imported_from!":{"sourceTemplate":"br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"}}},"roleAssignmentType":{"type":"object","properties":{"name":{"type":"string","nullable":true,"metadata":{"description":"Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated."}},"roleDefinitionIdOrName":{"type":"string","metadata":{"description":"Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'."}},"principalId":{"type":"string","metadata":{"description":"Required. The principal ID of the principal (user/group/identity) to assign the role to."}},"principalType":{"type":"string","allowedValues":["Device","ForeignGroup","Group","ServicePrincipal","User"],"nullable":true,"metadata":{"description":"Optional. The principal type of the assigned principal ID."}},"description":{"type":"string","nullable":true,"metadata":{"description":"Optional. The description of the role assignment."}},"condition":{"type":"string","nullable":true,"metadata":{"description":"Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"."}},"conditionVersion":{"type":"string","allowedValues":["2.0"],"nullable":true,"metadata":{"description":"Optional. Version of the condition."}},"delegatedManagedIdentityResourceId":{"type":"string","nullable":true,"metadata":{"description":"Optional. The Resource Id of the delegated managed identity resource."}}},"metadata":{"description":"An AVM-aligned type for a role assignment.","__bicep_imported_from!":{"sourceTemplate":"br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"}}}},"parameters":{"name":{"type":"string","metadata":{"description":"Required. The name prefix of the Image Template to be built by the Azure Image Builder service."}},"location":{"type":"string","defaultValue":"[resourceGroup().location]","metadata":{"description":"Optional. Location for all resources."}},"buildTimeoutInMinutes":{"type":"int","defaultValue":0,"minValue":0,"maxValue":960,"metadata":{"description":"Optional. The image build timeout in minutes. 0 means the default 240 minutes."}},"vmSize":{"type":"string","defaultValue":"Standard_D2s_v3","metadata":{"description":"Optional. Specifies the size for the VM."}},"osDiskSizeGB":{"type":"int","defaultValue":128,"metadata":{"description":"Optional. Specifies the size of OS disk."}},"subnetResourceId":{"type":"string","nullable":true,"metadata":{"description":"Optional. Resource ID of an already existing subnet, e.g.: /subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/.

If no value is provided, a new temporary VNET and subnet will be created in the staging resource group and will be deleted along with the remaining temporary resources."}},"imageSource":{"type":"object","metadata":{"description":"Required. Image source definition in object format."}},"customizationSteps":{"type":"array","nullable":true,"metadata":{"description":"Optional. Customization steps to be run when building the VM image."}},"stagingResourceGroupResourceId":{"type":"string","nullable":true,"metadata":{"description":"Optional. Resource ID of the staging resource group in the same subscription and location as the image template that will be used to build the image.

If this field is empty, a resource group with a random name will be created.

If the resource group specified in this field doesn't exist, it will be created with the same name.

If the resource group specified exists, it must be empty and in the same region as the image template.

The resource group created will be deleted during template deletion if this field is empty or the resource group specified doesn't exist,

but if the resource group specified exists the resources created in the resource group will be deleted during template deletion and the resource group itself will remain."}},"lock":{"$ref":"#/definitions/lockType","nullable":true,"metadata":{"description":"Optional. The lock settings of the service."}},"tags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags of the resource."}},"baseTime":{"type":"string","defaultValue":"[utcNow('yyyy-MM-dd-HH-mm-ss')]","metadata":{"description":"Generated. Do not provide a value! This date is used to generate a unique image template name."}},"enableTelemetry":{"type":"bool","defaultValue":true,"metadata":{"description":"Optional. Enable/Disable usage telemetry for module."}},"roleAssignments":{"type":"array","items":{"$ref":"#/definitions/roleAssignmentType"},"nullable":true,"metadata":{"description":"Optional. Array of role assignments to create."}},"distributions":{"type":"array","items":{"$ref":"#/definitions/distributionType"},"metadata":{"description":"Required. The distribution targets where the image output needs to go to."}},"vmUserAssignedIdentities":{"type":"array","defaultValue":[],"metadata":{"description":"Optional. List of User-Assigned Identities associated to the Build VM for accessing Azure resources such as Key Vaults from your customizer scripts. Be aware, the user assigned identities specified in the 'managedIdentities' parameter must have the 'Managed Identity Operator' role assignment on all the user assigned identities specified in this parameter for Azure Image Builder to be able to associate them to the build VM."}},"managedIdentities":{"$ref":"#/definitions/managedIdentityOnlyUserAssignedType","metadata":{"description":"Required. The managed identity definition for this resource."}},"validationProcess":{"$ref":"#/definitions/validationProcessType","nullable":true,"metadata":{"description":"Optional. Configuration options and list of validations to be performed on the resulting image."}},"optimizeVmBoot":{"type":"string","nullable":true,"allowedValues":["Enabled","Disabled"],"metadata":{"description":"Optional. The optimize property can be enabled while creating a VM image and allows VM optimization to improve image creation time."}},"autoRunState":{"type":"string","defaultValue":"Disabled","allowedValues":["Enabled","Disabled"],"metadata":{"description":"Optional. Indicates whether or not to automatically run the image template build on template creation or update."}},"errorHandlingOnCustomizerError":{"type":"string","defaultValue":"cleanup","allowedValues":["cleanup","abort"],"metadata":{"description":"Optional. If there is a customizer error and this field is set to 'cleanup', the build VM and associated network resources will be cleaned up. This is the default behavior. If there is a customizer error and this field is set to 'abort', the build VM will be preserved."}},"errorHandlingOnValidationError":{"type":"string","defaultValue":"cleanup","allowedValues":["cleanup","abort"],"metadata":{"description":"Optional. If there is a validation error and this field is set to 'cleanup', the build VM and associated network resources will be cleaned up. If there is a validation error and this field is set to 'abort', the build VM will be preserved. This is the default behavior."}},"managedResourceTags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags that will be applied to the resource group and/or resources created by the service."}}},"variables":{"copy":[{"name":"formattedRoleAssignments","count":"[length(coalesce(parameters('roleAssignments'), createArray()))]","input":"[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]"}],"identity":{"type":"UserAssigned","userAssignedIdentities":"[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]"},"builtInRoleNames":{"Contributor":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]","Owner":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]","Reader":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]","Role Based Access Control Administrator":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]","User Access Administrator":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]"}},"resources":{"avmTelemetry":{"condition":"[parameters('enableTelemetry')]","type":"Microsoft.Resources/deployments","apiVersion":"2024-03-01","name":"[format('46d3xbcp.res.virtualmachineimages-imagetemplate.{0}.{1}', replace('0.5.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]","properties":{"mode":"Incremental","template":{"$schema":"https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#","contentVersion":"1.0.0.0","resources":[],"outputs":{"telemetry":{"type":"String","value":"For more information, see https://aka.ms/avm/TelemetryInfo"}}}}},"imageTemplate":{"type":"Microsoft.VirtualMachineImages/imageTemplates","apiVersion":"2024-02-01","name":"[format('{0}-{1}', parameters('name'), parameters('baseTime'))]","location":"[parameters('location')]","tags":"[parameters('tags')]","identity":"[variables('identity')]","properties":"[shallowMerge(createArray(createObject('buildTimeoutInMinutes', parameters('buildTimeoutInMinutes'), 'vmProfile', createObject('vmSize', parameters('vmSize'), 'osDiskSizeGB', parameters('osDiskSizeGB'), 'userAssignedIdentities', parameters('vmUserAssignedIdentities'), 'vnetConfig', if(not(empty(parameters('subnetResourceId'))), createObject('subnetId', parameters('subnetResourceId')), null())), 'source', parameters('imageSource')), if(not(empty(parameters('customizationSteps'))), createObject('customize', parameters('customizationSteps')), createObject()), createObject('stagingResourceGroup', parameters('stagingResourceGroupResourceId'), 'distribute', map(parameters('distributions'), lambda('distribution', shallowMerge(createArray(createObject('type', lambdaVariables('distribution').type, 'artifactTags', coalesce(tryGet(lambdaVariables('distribution'), 'artifactTags'), createObject('sourceType', parameters('imageSource').type, 'sourcePublisher', tryGet(parameters('imageSource'), 'publisher'), 'sourceOffer', tryGet(parameters('imageSource'), 'offer'), 'sourceSku', tryGet(parameters('imageSource'), 'sku'), 'sourceVersion', tryGet(parameters('imageSource'), 'version'), 'sourceImageId', tryGet(parameters('imageSource'), 'imageId'), 'sourceImageVersionID', tryGet(parameters('imageSource'), 'imageVersionID'), 'creationTime', parameters('baseTime')))), if(equals(lambdaVariables('distribution').type, 'ManagedImage'), createObject('runOutputName', coalesce(tryGet(lambdaVariables('distribution'), 'runOutputName'), format('{0}-{1}-ManagedImage', lambdaVariables('distribution').imageName, parameters('baseTime'))), 'location', coalesce(tryGet(lambdaVariables('distribution'), 'location'), parameters('location')), 'imageId', coalesce(tryGet(lambdaVariables('distribution'), 'imageResourceId'), format('{0}/resourceGroups/{1}/providers/Microsoft.Compute/images/{2}-{3}', subscription().id, resourceGroup().name, lambdaVariables('distribution').imageName, parameters('baseTime')))), createObject()), if(equals(lambdaVariables('distribution').type, 'SharedImage'), createObject('runOutputName', coalesce(tryGet(lambdaVariables('distribution'), 'runOutputName'), if(not(empty(tryGet(lambdaVariables('distribution'), 'sharedImageGalleryImageDefinitionResourceId'))), format('{0}-SharedImage', last(split(coalesce(lambdaVariables('distribution').sharedImageGalleryImageDefinitionResourceId, '/'), '/'))), 'SharedImage')), 'galleryImageId', if(not(empty(tryGet(lambdaVariables('distribution'), 'sharedImageGalleryImageDefinitionTargetVersion'))), format('{0}/versions/{1}', lambdaVariables('distribution').sharedImageGalleryImageDefinitionResourceId, lambdaVariables('distribution').sharedImageGalleryImageDefinitionTargetVersion), lambdaVariables('distribution').sharedImageGalleryImageDefinitionResourceId), 'excludeFromLatest', coalesce(tryGet(lambdaVariables('distribution'), 'excludeFromLatest'), false()), 'replicationRegions', coalesce(tryGet(lambdaVariables('distribution'), 'replicationRegions'), createArray(parameters('location'))), 'storageAccountType', coalesce(tryGet(lambdaVariables('distribution'), 'storageAccountType'), 'Standard_LRS')), createObject()), if(equals(lambdaVariables('distribution').type, 'VHD'), createObject('runOutputName', coalesce(tryGet(lambdaVariables('distribution'), 'runOutputName'), format('{0}-VHD', lambdaVariables('distribution').imageName))), createObject()))))), 'validate', parameters('validationProcess'), 'optimize', if(not(equals(parameters('optimizeVmBoot'), null())), createObject('vmBoot', createObject('state', parameters('optimizeVmBoot'))), null()), 'autoRun', createObject('state', parameters('autoRunState')), 'errorHandling', createObject('onCustomizerError', parameters('errorHandlingOnCustomizerError'), 'onValidationError', parameters('errorHandlingOnValidationError')), 'managedResourceTags', parameters('managedResourceTags'))))]"},"imageTemplate_lock":{"condition":"[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]","type":"Microsoft.Authorization/locks","apiVersion":"2020-05-01","scope":"[format('Microsoft.VirtualMachineImages/imageTemplates/{0}', format('{0}-{1}', parameters('name'), parameters('baseTime')))]","name":"[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]","properties":{"level":"[coalesce(tryGet(parameters('lock'), 'kind'), '')]","notes":"[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]"},"dependsOn":["imageTemplate"]},"imageTemplate_roleAssignments":{"copy":{"name":"imageTemplate_roleAssignments","count":"[length(coalesce(variables('formattedRoleAssignments'), createArray()))]"},"type":"Microsoft.Authorization/roleAssignments","apiVersion":"2022-04-01","scope":"[format('Microsoft.VirtualMachineImages/imageTemplates/{0}', format('{0}-{1}', parameters('name'), parameters('baseTime')))]","name":"[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.VirtualMachineImages/imageTemplates', format('{0}-{1}', parameters('name'), parameters('baseTime'))), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]","properties":{"roleDefinitionId":"[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]","principalId":"[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]","description":"[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]","principalType":"[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]","condition":"[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]","conditionVersion":"[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]","delegatedManagedIdentityResourceId":"[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]"},"dependsOn":["imageTemplate"]}},"outputs":{"resourceId":{"type":"string","metadata":{"description":"The resource ID of the image template."},"value":"[resourceId('Microsoft.VirtualMachineImages/imageTemplates', format('{0}-{1}', parameters('name'), parameters('baseTime')))]"},"resourceGroupName":{"type":"string","metadata":{"description":"The resource group the image template was deployed into."},"value":"[resourceGroup().name]"},"name":{"type":"string","metadata":{"description":"The full name of the deployed image template."},"value":"[format('{0}-{1}', parameters('name'), parameters('baseTime'))]"},"namePrefix":{"type":"string","metadata":{"description":"The prefix of the image template name provided as input."},"value":"[parameters('name')]"},"runThisCommand":{"type":"string","metadata":{"description":"The command to run in order to trigger the image build."},"value":"[format('Invoke-AzResourceAction -ResourceName {0} -ResourceGroupName {1} -ResourceType Microsoft.VirtualMachineImages/imageTemplates -Action Run -Force', format('{0}-{1}', parameters('name'), parameters('baseTime')), resourceGroup().name)]"},"location":{"type":"string","metadata":{"description":"The location the resource was deployed into."},"value":"[reference('imageTemplate', '2024-02-01', 'full').location]"}}},"templateLink":{"id":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg","uri":"https://deployment-uri"},"parameters":{"name":{"value":"image-002"},"baseTime":{"value":"0"},"distributions":{"value":[{"type":"ManagedImage","imageName":"image-002"}]},"imageSource":{"value":{"type":"PlatformImage","publisher":"canonical","offer":"ubuntu-24_04-lts","sku":"server","version":"latest"}},"managedIdentities":{"value":{}},"customizationSteps":{"value":[{"type":"Shell","name":"PowerShell installation","scriptUri":"https://raw.githubusercontent.com/Azure/bicep-registry-modules/refs/heads/main/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Install-LinuxPowerShell.sh","sha256Checksum":"8d469f6864a38e1cf957cd080603026bba325793edfb4fe2e8b8e7368eb15b92"}]},"validationProcess":{"value":{"inVMValidations":[{"type":"Shell","name":"Validate PowerShell","scriptUri":"https://raw.githubusercontent.com/Azure/bicep-registry-modules/refs/heads/main/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Install-LinuxPowerShell.sh","sha256Checksum":"8d469f6864a38e1cf957cd080603026bba325793edfb4fe2e8b8e7368eb15b92"}]}},"buildTimeoutInMinutes":{"value":60},"vmSize":{"value":"Standard_D2s_v3"}},"mode":"Incremental","provisioningState":"Accepted","templateHash":"5124510","outputs":{}},"location":"eastus","type":"Microsoft.Resources/deployments","metadata":{"_generator":{"name":"bicep","version":"0.33.93.31351","templateHash":"17156102195331830052"},"name":"Virtual Machine Image Templates","description":"This module deploys a Virtual Machine Image Template that can be consumed by Azure Image Builder (AIB)."},"id":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg/providers/Microsoft.Resources/deployments/image_002-84b314832a63d","scope":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg","rootDeployment":false,"_PSRule":{"path":"resources.image_002","source":[{"file":"tests\\PSRule.Rules.Azure.Tests\\Resources.ImageBuilder.Source.bicep","type":"Template"}]}},{"ResourceName":"46d3xbcp.res.virtualmachineimages-imagetemplate.0-5-0.9a22","name":"46d3xbcp.res.virtualmachineimages-imagetemplate.0-5-0.9a22","properties":{"template":{"$schema":"https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#","contentVersion":"1.0.0.0","resources":[],"outputs":{"telemetry":{"type":"String","value":"For more information, see https://aka.ms/avm/TelemetryInfo"}}},"templateLink":{"id":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg","uri":"https://deployment-uri"},"parameters":{"name":{"value":"image-002"},"baseTime":{"value":"0"},"distributions":{"value":[{"type":"ManagedImage","imageName":"image-002"}]},"imageSource":{"value":{"type":"PlatformImage","publisher":"canonical","offer":"ubuntu-24_04-lts","sku":"server","version":"latest"}},"managedIdentities":{"value":{}},"customizationSteps":{"value":[{"type":"Shell","name":"PowerShell installation","scriptUri":"https://raw.githubusercontent.com/Azure/bicep-registry-modules/refs/heads/main/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Install-LinuxPowerShell.sh","sha256Checksum":"8d469f6864a38e1cf957cd080603026bba325793edfb4fe2e8b8e7368eb15b92"}]},"validationProcess":{"value":{"inVMValidations":[{"type":"Shell","name":"Validate PowerShell","scriptUri":"https://raw.githubusercontent.com/Azure/bicep-registry-modules/refs/heads/main/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Install-LinuxPowerShell.sh","sha256Checksum":"8d469f6864a38e1cf957cd080603026bba325793edfb4fe2e8b8e7368eb15b92"}]}},"buildTimeoutInMinutes":{"value":60},"vmSize":{"value":"Standard_D2s_v3"}},"mode":"Incremental","provisioningState":"Accepted","templateHash":"12432185","outputs":{}},"location":"eastus","type":"Microsoft.Resources/deployments","metadata":null,"id":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg/providers/Microsoft.Resources/deployments/46d3xbcp.res.virtualmachineimages-imagetemplate.0-5-0.9a22","scope":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg","rootDeployment":false,"_PSRule":{"path":"properties.template.resources.avmTelemetry","source":[{"file":"tests\\PSRule.Rules.Azure.Tests\\Resources.ImageBuilder.Source.bicep","type":"Template"}]}},{"type":"Microsoft.VirtualMachineImages/imageTemplates","apiVersion":"2024-02-01","name":"image-002-0","location":"eastus","identity":{"type":"UserAssigned","userAssignedIdentities":{}},"properties":{"buildTimeoutInMinutes":60,"vmProfile":{"vmSize":"Standard_D2s_v3","osDiskSizeGB":128,"userAssignedIdentities":[]},"source":{"type":"PlatformImage","publisher":"canonical","offer":"ubuntu-24_04-lts","sku":"server","version":"latest"},"customize":[{"type":"Shell","name":"PowerShell installation","scriptUri":"https://raw.githubusercontent.com/Azure/bicep-registry-modules/refs/heads/main/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Install-LinuxPowerShell.sh","sha256Checksum":"8d469f6864a38e1cf957cd080603026bba325793edfb4fe2e8b8e7368eb15b92"}],"distribute":[{"type":"ManagedImage","artifactTags":{"sourceType":"PlatformImage","sourcePublisher":"canonical","sourceOffer":"ubuntu-24_04-lts","sourceSku":"server","sourceVersion":"latest","creationTime":"0"},"runOutputName":"image-002-0-ManagedImage","location":"eastus","imageId":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg/providers/Microsoft.Compute/images/image-002-0"}],"validate":{"inVMValidations":[{"type":"Shell","name":"Validate PowerShell","scriptUri":"https://raw.githubusercontent.com/Azure/bicep-registry-modules/refs/heads/main/avm/res/virtual-machine-images/image-template/tests/e2e/max/src/Install-LinuxPowerShell.sh","sha256Checksum":"8d469f6864a38e1cf957cd080603026bba325793edfb4fe2e8b8e7368eb15b92"}]},"autoRun":{"state":"Disabled"},"errorHandling":{"onCustomizerError":"cleanup","onValidationError":"cleanup"}},"scope":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg","id":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg/providers/Microsoft.VirtualMachineImages/imageTemplates/image-002-0","_PSRule":{"path":"properties.template.resources.imageTemplate","source":[{"file":"tests\\PSRule.Rules.Azure.Tests\\Resources.ImageBuilder.Source.bicep","type":"Template","line":1552,"position":30}]}},{"ResourceName":"image_003-4cf31b4a1881c","name":"image_003-4cf31b4a1881c","properties":{"template":{"$schema":"https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#","languageVersion":"2.0","contentVersion":"1.0.0.0","metadata":{"_generator":{"name":"bicep","version":"0.33.93.31351","templateHash":"17156102195331830052"},"name":"Virtual Machine Image Templates","description":"This module deploys a Virtual Machine Image Template that can be consumed by Azure Image Builder (AIB)."},"definitions":{"distributionType":{"type":"object","discriminator":{"propertyName":"type","mapping":{"SharedImage":{"$ref":"#/definitions/sharedImageDistributionType"},"ManagedImage":{"$ref":"#/definitions/managedImageDistributionType"},"VHD":{"$ref":"#/definitions/unManagedDistributionType"}}},"metadata":{"__bicep_export!":true}},"sharedImageDistributionType":{"type":"object","properties":{"runOutputName":{"type":"string","nullable":true,"metadata":{"description":"Optional. The name to be used for the associated RunOutput. If not provided, a name will be calculated."}},"artifactTags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags that will be applied to the artifact once it has been created/updated by the distributor. If not provided will set tags based on the provided image source."}},"type":{"type":"string","allowedValues":["SharedImage"],"metadata":{"description":"Required. The type of distribution."}},"sharedImageGalleryImageDefinitionResourceId":{"type":"string","metadata":{"description":"Conditional. Resource ID of Compute Gallery Image Definition to distribute image to, e.g.: /subscriptions//resourceGroups//providers/Microsoft.Compute/galleries//images/."}},"sharedImageGalleryImageDefinitionTargetVersion":{"type":"string","nullable":true,"metadata":{"description":"Optional. Version of the Compute Gallery Image. Supports the following Version Syntax: Major.Minor.Build (i.e., '1.1.1' or '10.1.2'). If not provided, a version will be calculated."}},"excludeFromLatest":{"type":"bool","nullable":true,"metadata":{"description":"Optional. The exclude from latest flag of the image. Defaults to [false]."}},"replicationRegions":{"type":"array","items":{"type":"string"},"nullable":true,"metadata":{"description":"Optional. The replication regions of the image. Defaults to the value of the 'location' parameter."}},"storageAccountType":{"type":"string","allowedValues":["Standard_LRS","Standard_ZRS"],"nullable":true,"metadata":{"description":"Optional. The storage account type of the image. Defaults to [Standard_LRS]."}}},"metadata":{"__bicep_export!":true}},"unManagedDistributionType":{"type":"object","properties":{"type":{"type":"string","allowedValues":["VHD"],"metadata":{"description":"Required. The type of distribution."}},"runOutputName":{"type":"string","nullable":true,"metadata":{"description":"Optional. The name to be used for the associated RunOutput. If not provided, a name will be calculated."}},"artifactTags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags that will be applied to the artifact once it has been created/updated by the distributor. If not provided will set tags based on the provided image source."}},"imageName":{"type":"string","metadata":{"description":"Conditional. Name of the managed or unmanaged image that will be created."}}},"metadata":{"__bicep_export!":true}},"managedImageDistributionType":{"type":"object","properties":{"type":{"type":"string","allowedValues":["ManagedImage"],"metadata":{"description":"Required. The type of distribution."}},"runOutputName":{"type":"string","nullable":true,"metadata":{"description":"Optional. The name to be used for the associated RunOutput. If not provided, a name will be calculated."}},"artifactTags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags that will be applied to the artifact once it has been created/updated by the distributor. If not provided will set tags based on the provided image source."}},"location":{"type":"string","nullable":true,"metadata":{"description":"Optional. Azure location for the image, should match if image already exists. Defaults to the value of the 'location' parameter."}},"imageResourceId":{"type":"string","nullable":true,"metadata":{"description":"Required. The resource ID of the managed image. Defaults to a compute image with name 'imageName-baseTime' in the current resource group."}},"imageName":{"type":"string","metadata":{"description":"Conditional. Name of the managed or unmanaged image that will be created."}}},"metadata":{"__bicep_export!":true}},"validationProcessType":{"type":"object","properties":{"continueDistributeOnFailure":{"type":"bool","nullable":true,"metadata":{"description":"Optional. If validation fails and this field is set to false, output image(s) will not be distributed. This is the default behavior. If validation fails and this field is set to true, output image(s) will still be distributed. Please use this option with caution as it may result in bad images being distributed for use. In either case (true or false), the end to end image run will be reported as having failed in case of a validation failure. [Note: This field has no effect if validation succeeds.]."}},"inVMValidations":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","allowedValues":["File","PowerShell","Shell"],"metadata":{"description":"Required. The type of validation."}},"name":{"type":"string","nullable":true,"metadata":{"description":"Optional. Friendly Name to provide context on what this validation step does."}},"scriptUri":{"type":"string","nullable":true,"metadata":{"description":"Optional. URI of the PowerShell script to be run for validation. It can be a github link, Azure Storage URI, etc."}},"inline":{"type":"array","items":{"type":"string"},"nullable":true,"metadata":{"description":"Optional. Array of commands to be run, separated by commas."}},"validExitCodes":{"type":"array","items":{"type":"int"},"nullable":true,"metadata":{"description":"Optional. Valid codes that can be returned from the script/inline command, this avoids reported failure of the script/inline command."}},"sha256Checksum":{"type":"string","nullable":true,"metadata":{"description":"Optional. Value of sha256 checksum of the file, you generate this locally, and then Image Builder will checksum and validate."}},"sourceUri":{"type":"string","nullable":true,"metadata":{"description":"Optional. The source URI of the file."}},"destination":{"type":"string","nullable":true,"metadata":{"description":"Optional. Destination of the file."}},"runAsSystem":{"type":"bool","nullable":true,"metadata":{"description":"Optional. If specified, the PowerShell script will be run with elevated privileges using the Local System user. Can only be true when the runElevated field above is set to true."}},"runElevated":{"type":"bool","nullable":true,"metadata":{"description":"Optional. If specified, the PowerShell script will be run with elevated privileges."}}}},"nullable":true,"metadata":{"description":"Optional. A list of validators that will be performed on the image. Azure Image Builder supports File, PowerShell and Shell validators."}},"sourceValidationOnly":{"type":"bool","nullable":true,"metadata":{"description":"Optional. If this field is set to true, the image specified in the 'source' section will directly be validated. No separate build will be run to generate and then validate a customized image. Not supported when performing customizations, validations or distributions on the image."}}},"metadata":{"__bicep_export!":true}},"lockType":{"type":"object","properties":{"name":{"type":"string","nullable":true,"metadata":{"description":"Optional. Specify the name of lock."}},"kind":{"type":"string","allowedValues":["CanNotDelete","None","ReadOnly"],"nullable":true,"metadata":{"description":"Optional. Specify the type of lock."}}},"metadata":{"description":"An AVM-aligned type for a lock.","__bicep_imported_from!":{"sourceTemplate":"br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"}}},"managedIdentityOnlyUserAssignedType":{"type":"object","properties":{"userAssignedResourceIds":{"type":"array","items":{"type":"string"},"nullable":true,"metadata":{"description":"Optional. The resource ID(s) to assign to the resource. Required if a user assigned identity is used for encryption."}}},"metadata":{"description":"An AVM-aligned type for a managed identity configuration. To be used if only user-assigned identities are supported by the resource provider.","__bicep_imported_from!":{"sourceTemplate":"br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"}}},"roleAssignmentType":{"type":"object","properties":{"name":{"type":"string","nullable":true,"metadata":{"description":"Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated."}},"roleDefinitionIdOrName":{"type":"string","metadata":{"description":"Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'."}},"principalId":{"type":"string","metadata":{"description":"Required. The principal ID of the principal (user/group/identity) to assign the role to."}},"principalType":{"type":"string","allowedValues":["Device","ForeignGroup","Group","ServicePrincipal","User"],"nullable":true,"metadata":{"description":"Optional. The principal type of the assigned principal ID."}},"description":{"type":"string","nullable":true,"metadata":{"description":"Optional. The description of the role assignment."}},"condition":{"type":"string","nullable":true,"metadata":{"description":"Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"."}},"conditionVersion":{"type":"string","allowedValues":["2.0"],"nullable":true,"metadata":{"description":"Optional. Version of the condition."}},"delegatedManagedIdentityResourceId":{"type":"string","nullable":true,"metadata":{"description":"Optional. The Resource Id of the delegated managed identity resource."}}},"metadata":{"description":"An AVM-aligned type for a role assignment.","__bicep_imported_from!":{"sourceTemplate":"br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"}}}},"parameters":{"name":{"type":"string","metadata":{"description":"Required. The name prefix of the Image Template to be built by the Azure Image Builder service."}},"location":{"type":"string","defaultValue":"[resourceGroup().location]","metadata":{"description":"Optional. Location for all resources."}},"buildTimeoutInMinutes":{"type":"int","defaultValue":0,"minValue":0,"maxValue":960,"metadata":{"description":"Optional. The image build timeout in minutes. 0 means the default 240 minutes."}},"vmSize":{"type":"string","defaultValue":"Standard_D2s_v3","metadata":{"description":"Optional. Specifies the size for the VM."}},"osDiskSizeGB":{"type":"int","defaultValue":128,"metadata":{"description":"Optional. Specifies the size of OS disk."}},"subnetResourceId":{"type":"string","nullable":true,"metadata":{"description":"Optional. Resource ID of an already existing subnet, e.g.: /subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/.

If no value is provided, a new temporary VNET and subnet will be created in the staging resource group and will be deleted along with the remaining temporary resources."}},"imageSource":{"type":"object","metadata":{"description":"Required. Image source definition in object format."}},"customizationSteps":{"type":"array","nullable":true,"metadata":{"description":"Optional. Customization steps to be run when building the VM image."}},"stagingResourceGroupResourceId":{"type":"string","nullable":true,"metadata":{"description":"Optional. Resource ID of the staging resource group in the same subscription and location as the image template that will be used to build the image.

If this field is empty, a resource group with a random name will be created.

If the resource group specified in this field doesn't exist, it will be created with the same name.

If the resource group specified exists, it must be empty and in the same region as the image template.

The resource group created will be deleted during template deletion if this field is empty or the resource group specified doesn't exist,

but if the resource group specified exists the resources created in the resource group will be deleted during template deletion and the resource group itself will remain."}},"lock":{"$ref":"#/definitions/lockType","nullable":true,"metadata":{"description":"Optional. The lock settings of the service."}},"tags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags of the resource."}},"baseTime":{"type":"string","defaultValue":"[utcNow('yyyy-MM-dd-HH-mm-ss')]","metadata":{"description":"Generated. Do not provide a value! This date is used to generate a unique image template name."}},"enableTelemetry":{"type":"bool","defaultValue":true,"metadata":{"description":"Optional. Enable/Disable usage telemetry for module."}},"roleAssignments":{"type":"array","items":{"$ref":"#/definitions/roleAssignmentType"},"nullable":true,"metadata":{"description":"Optional. Array of role assignments to create."}},"distributions":{"type":"array","items":{"$ref":"#/definitions/distributionType"},"metadata":{"description":"Required. The distribution targets where the image output needs to go to."}},"vmUserAssignedIdentities":{"type":"array","defaultValue":[],"metadata":{"description":"Optional. List of User-Assigned Identities associated to the Build VM for accessing Azure resources such as Key Vaults from your customizer scripts. Be aware, the user assigned identities specified in the 'managedIdentities' parameter must have the 'Managed Identity Operator' role assignment on all the user assigned identities specified in this parameter for Azure Image Builder to be able to associate them to the build VM."}},"managedIdentities":{"$ref":"#/definitions/managedIdentityOnlyUserAssignedType","metadata":{"description":"Required. The managed identity definition for this resource."}},"validationProcess":{"$ref":"#/definitions/validationProcessType","nullable":true,"metadata":{"description":"Optional. Configuration options and list of validations to be performed on the resulting image."}},"optimizeVmBoot":{"type":"string","nullable":true,"allowedValues":["Enabled","Disabled"],"metadata":{"description":"Optional. The optimize property can be enabled while creating a VM image and allows VM optimization to improve image creation time."}},"autoRunState":{"type":"string","defaultValue":"Disabled","allowedValues":["Enabled","Disabled"],"metadata":{"description":"Optional. Indicates whether or not to automatically run the image template build on template creation or update."}},"errorHandlingOnCustomizerError":{"type":"string","defaultValue":"cleanup","allowedValues":["cleanup","abort"],"metadata":{"description":"Optional. If there is a customizer error and this field is set to 'cleanup', the build VM and associated network resources will be cleaned up. This is the default behavior. If there is a customizer error and this field is set to 'abort', the build VM will be preserved."}},"errorHandlingOnValidationError":{"type":"string","defaultValue":"cleanup","allowedValues":["cleanup","abort"],"metadata":{"description":"Optional. If there is a validation error and this field is set to 'cleanup', the build VM and associated network resources will be cleaned up. If there is a validation error and this field is set to 'abort', the build VM will be preserved. This is the default behavior."}},"managedResourceTags":{"type":"object","nullable":true,"metadata":{"description":"Optional. Tags that will be applied to the resource group and/or resources created by the service."}}},"variables":{"copy":[{"name":"formattedRoleAssignments","count":"[length(coalesce(parameters('roleAssignments'), createArray()))]","input":"[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]"}],"identity":{"type":"UserAssigned","userAssignedIdentities":"[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]"},"builtInRoleNames":{"Contributor":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]","Owner":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]","Reader":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]","Role Based Access Control Administrator":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]","User Access Administrator":"[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]"}},"resources":{"avmTelemetry":{"condition":"[parameters('enableTelemetry')]","type":"Microsoft.Resources/deployments","apiVersion":"2024-03-01","name":"[format('46d3xbcp.res.virtualmachineimages-imagetemplate.{0}.{1}', replace('0.5.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]","properties":{"mode":"Incremental","template":{"$schema":"https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#","contentVersion":"1.0.0.0","resources":[],"outputs":{"telemetry":{"type":"String","value":"For more information, see https://aka.ms/avm/TelemetryInfo"}}}}},"imageTemplate":{"type":"Microsoft.VirtualMachineImages/imageTemplates","apiVersion":"2024-02-01","name":"[format('{0}-{1}', parameters('name'), parameters('baseTime'))]","location":"[parameters('location')]","tags":"[parameters('tags')]","identity":"[variables('identity')]","properties":"[shallowMerge(createArray(createObject('buildTimeoutInMinutes', parameters('buildTimeoutInMinutes'), 'vmProfile', createObject('vmSize', parameters('vmSize'), 'osDiskSizeGB', parameters('osDiskSizeGB'), 'userAssignedIdentities', parameters('vmUserAssignedIdentities'), 'vnetConfig', if(not(empty(parameters('subnetResourceId'))), createObject('subnetId', parameters('subnetResourceId')), null())), 'source', parameters('imageSource')), if(not(empty(parameters('customizationSteps'))), createObject('customize', parameters('customizationSteps')), createObject()), createObject('stagingResourceGroup', parameters('stagingResourceGroupResourceId'), 'distribute', map(parameters('distributions'), lambda('distribution', shallowMerge(createArray(createObject('type', lambdaVariables('distribution').type, 'artifactTags', coalesce(tryGet(lambdaVariables('distribution'), 'artifactTags'), createObject('sourceType', parameters('imageSource').type, 'sourcePublisher', tryGet(parameters('imageSource'), 'publisher'), 'sourceOffer', tryGet(parameters('imageSource'), 'offer'), 'sourceSku', tryGet(parameters('imageSource'), 'sku'), 'sourceVersion', tryGet(parameters('imageSource'), 'version'), 'sourceImageId', tryGet(parameters('imageSource'), 'imageId'), 'sourceImageVersionID', tryGet(parameters('imageSource'), 'imageVersionID'), 'creationTime', parameters('baseTime')))), if(equals(lambdaVariables('distribution').type, 'ManagedImage'), createObject('runOutputName', coalesce(tryGet(lambdaVariables('distribution'), 'runOutputName'), format('{0}-{1}-ManagedImage', lambdaVariables('distribution').imageName, parameters('baseTime'))), 'location', coalesce(tryGet(lambdaVariables('distribution'), 'location'), parameters('location')), 'imageId', coalesce(tryGet(lambdaVariables('distribution'), 'imageResourceId'), format('{0}/resourceGroups/{1}/providers/Microsoft.Compute/images/{2}-{3}', subscription().id, resourceGroup().name, lambdaVariables('distribution').imageName, parameters('baseTime')))), createObject()), if(equals(lambdaVariables('distribution').type, 'SharedImage'), createObject('runOutputName', coalesce(tryGet(lambdaVariables('distribution'), 'runOutputName'), if(not(empty(tryGet(lambdaVariables('distribution'), 'sharedImageGalleryImageDefinitionResourceId'))), format('{0}-SharedImage', last(split(coalesce(lambdaVariables('distribution').sharedImageGalleryImageDefinitionResourceId, '/'), '/'))), 'SharedImage')), 'galleryImageId', if(not(empty(tryGet(lambdaVariables('distribution'), 'sharedImageGalleryImageDefinitionTargetVersion'))), format('{0}/versions/{1}', lambdaVariables('distribution').sharedImageGalleryImageDefinitionResourceId, lambdaVariables('distribution').sharedImageGalleryImageDefinitionTargetVersion), lambdaVariables('distribution').sharedImageGalleryImageDefinitionResourceId), 'excludeFromLatest', coalesce(tryGet(lambdaVariables('distribution'), 'excludeFromLatest'), false()), 'replicationRegions', coalesce(tryGet(lambdaVariables('distribution'), 'replicationRegions'), createArray(parameters('location'))), 'storageAccountType', coalesce(tryGet(lambdaVariables('distribution'), 'storageAccountType'), 'Standard_LRS')), createObject()), if(equals(lambdaVariables('distribution').type, 'VHD'), createObject('runOutputName', coalesce(tryGet(lambdaVariables('distribution'), 'runOutputName'), format('{0}-VHD', lambdaVariables('distribution').imageName))), createObject()))))), 'validate', parameters('validationProcess'), 'optimize', if(not(equals(parameters('optimizeVmBoot'), null())), createObject('vmBoot', createObject('state', parameters('optimizeVmBoot'))), null()), 'autoRun', createObject('state', parameters('autoRunState')), 'errorHandling', createObject('onCustomizerError', parameters('errorHandlingOnCustomizerError'), 'onValidationError', parameters('errorHandlingOnValidationError')), 'managedResourceTags', parameters('managedResourceTags'))))]"},"imageTemplate_lock":{"condition":"[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]","type":"Microsoft.Authorization/locks","apiVersion":"2020-05-01","scope":"[format('Microsoft.VirtualMachineImages/imageTemplates/{0}', format('{0}-{1}', parameters('name'), parameters('baseTime')))]","name":"[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]","properties":{"level":"[coalesce(tryGet(parameters('lock'), 'kind'), '')]","notes":"[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]"},"dependsOn":["imageTemplate"]},"imageTemplate_roleAssignments":{"copy":{"name":"imageTemplate_roleAssignments","count":"[length(coalesce(variables('formattedRoleAssignments'), createArray()))]"},"type":"Microsoft.Authorization/roleAssignments","apiVersion":"2022-04-01","scope":"[format('Microsoft.VirtualMachineImages/imageTemplates/{0}', format('{0}-{1}', parameters('name'), parameters('baseTime')))]","name":"[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.VirtualMachineImages/imageTemplates', format('{0}-{1}', parameters('name'), parameters('baseTime'))), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]","properties":{"roleDefinitionId":"[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]","principalId":"[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]","description":"[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]","principalType":"[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]","condition":"[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]","conditionVersion":"[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]","delegatedManagedIdentityResourceId":"[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]"},"dependsOn":["imageTemplate"]}},"outputs":{"resourceId":{"type":"string","metadata":{"description":"The resource ID of the image template."},"value":"[resourceId('Microsoft.VirtualMachineImages/imageTemplates', format('{0}-{1}', parameters('name'), parameters('baseTime')))]"},"resourceGroupName":{"type":"string","metadata":{"description":"The resource group the image template was deployed into."},"value":"[resourceGroup().name]"},"name":{"type":"string","metadata":{"description":"The full name of the deployed image template."},"value":"[format('{0}-{1}', parameters('name'), parameters('baseTime'))]"},"namePrefix":{"type":"string","metadata":{"description":"The prefix of the image template name provided as input."},"value":"[parameters('name')]"},"runThisCommand":{"type":"string","metadata":{"description":"The command to run in order to trigger the image build."},"value":"[format('Invoke-AzResourceAction -ResourceName {0} -ResourceGroupName {1} -ResourceType Microsoft.VirtualMachineImages/imageTemplates -Action Run -Force', format('{0}-{1}', parameters('name'), parameters('baseTime')), resourceGroup().name)]"},"location":{"type":"string","metadata":{"description":"The location the resource was deployed into."},"value":"[reference('imageTemplate', '2024-02-01', 'full').location]"}}},"templateLink":{"id":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg","uri":"https://deployment-uri"},"parameters":{"name":{"value":"image-003"},"baseTime":{"value":"0"},"distributions":{"value":[{"type":"ManagedImage","imageName":"image-003"}]},"imageSource":{"value":{"type":"PlatformImage","publisher":"canonical","offer":"ubuntu-24_04-lts","sku":"server","version":"latest"}},"managedIdentities":{"value":{}},"buildTimeoutInMinutes":{"value":60},"vmSize":{"value":"Standard_D2s_v3"}},"mode":"Incremental","provisioningState":"Accepted","templateHash":"374065","outputs":{}},"location":"eastus","type":"Microsoft.Resources/deployments","metadata":{"_generator":{"name":"bicep","version":"0.33.93.31351","templateHash":"17156102195331830052"},"name":"Virtual Machine Image Templates","description":"This module deploys a Virtual Machine Image Template that can be consumed by Azure Image Builder (AIB)."},"id":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg/providers/Microsoft.Resources/deployments/image_003-4cf31b4a1881c","scope":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg","rootDeployment":false,"_PSRule":{"path":"resources.image_003","source":[{"file":"tests\\PSRule.Rules.Azure.Tests\\Resources.ImageBuilder.Source.bicep","type":"Template"}]}},{"ResourceName":"46d3xbcp.res.virtualmachineimages-imagetemplate.0-5-0.3132","name":"46d3xbcp.res.virtualmachineimages-imagetemplate.0-5-0.3132","properties":{"template":{"$schema":"https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#","contentVersion":"1.0.0.0","resources":[],"outputs":{"telemetry":{"type":"String","value":"For more information, see https://aka.ms/avm/TelemetryInfo"}}},"templateLink":{"id":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg","uri":"https://deployment-uri"},"parameters":{"name":{"value":"image-003"},"baseTime":{"value":"0"},"distributions":{"value":[{"type":"ManagedImage","imageName":"image-003"}]},"imageSource":{"value":{"type":"PlatformImage","publisher":"canonical","offer":"ubuntu-24_04-lts","sku":"server","version":"latest"}},"managedIdentities":{"value":{}},"buildTimeoutInMinutes":{"value":60},"vmSize":{"value":"Standard_D2s_v3"}},"mode":"Incremental","provisioningState":"Accepted","templateHash":"30299306","outputs":{}},"location":"eastus","type":"Microsoft.Resources/deployments","metadata":null,"id":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg/providers/Microsoft.Resources/deployments/46d3xbcp.res.virtualmachineimages-imagetemplate.0-5-0.3132","scope":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg","rootDeployment":false,"_PSRule":{"path":"properties.template.resources.avmTelemetry","source":[{"file":"tests\\PSRule.Rules.Azure.Tests\\Resources.ImageBuilder.Source.bicep","type":"Template"}]}},{"type":"Microsoft.VirtualMachineImages/imageTemplates","apiVersion":"2024-02-01","name":"image-003-0","location":"eastus","identity":{"type":"UserAssigned","userAssignedIdentities":{}},"properties":{"buildTimeoutInMinutes":60,"vmProfile":{"vmSize":"Standard_D2s_v3","osDiskSizeGB":128,"userAssignedIdentities":[]},"source":{"type":"PlatformImage","publisher":"canonical","offer":"ubuntu-24_04-lts","sku":"server","version":"latest"},"distribute":[{"type":"ManagedImage","artifactTags":{"sourceType":"PlatformImage","sourcePublisher":"canonical","sourceOffer":"ubuntu-24_04-lts","sourceSku":"server","sourceVersion":"latest","creationTime":"0"},"runOutputName":"image-003-0-ManagedImage","location":"eastus","imageId":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg/providers/Microsoft.Compute/images/image-003-0"}],"autoRun":{"state":"Disabled"},"errorHandling":{"onCustomizerError":"cleanup","onValidationError":"cleanup"}},"scope":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg","id":"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg/providers/Microsoft.VirtualMachineImages/imageTemplates/image-003-0","_PSRule":{"path":"properties.template.resources.imageTemplate","source":[{"file":"tests\\PSRule.Rules.Azure.Tests\\Resources.ImageBuilder.Source.bicep","type":"Template","line":2347,"position":30}]}}] \ No newline at end of file