From e796f0f30a430300564e45fbd58bd8ac4205bf6d Mon Sep 17 00:00:00 2001 From: MrMCake Date: Thu, 6 Jan 2022 17:16:11 +0100 Subject: [PATCH 1/2] Added deployment error fetching based on deployment name if provisioning failed without an exception --- .../New-ModuleDeployment.ps1 | 79 ++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/utilities/pipelines/resourceDeployment/New-ModuleDeployment.ps1 b/utilities/pipelines/resourceDeployment/New-ModuleDeployment.ps1 index 0085b7ba1b..e056496e66 100644 --- a/utilities/pipelines/resourceDeployment/New-ModuleDeployment.ps1 +++ b/utilities/pipelines/resourceDeployment/New-ModuleDeployment.ps1 @@ -1,4 +1,68 @@ #region helper + +<# +.SYNOPSIS +If a deployment failed, get its error message + +.DESCRIPTION +If a deployment failed, get its error message based on the deployment name in the given scope + +.PARAMETER DeploymentScope +Mandatory. The scope to fetch the deployment from (e.g. resourcegroup, tenant,...) + +.PARAMETER DeploymentName +Mandatory. The name of the deployment to search for (e.g. 'storageAccounts-20220105T0701282538Z') + +.PARAMETER ResourceGroupName +Optional. The resource group to search the deployment in, if the scope is 'resourcegroup' + +.EXAMPLE +Get-ErrorMessageForScope -DeploymentScope 'resourcegroup' -DeploymentName 'storageAccounts-20220105T0701282538Z' -ResourceGroupName 'validation-rg' + +Get the error message of any failed deployment into resource group 'validation-rg' that has the name 'storageAccounts-20220105T0701282538Z' + +.EXAMPLE +Get-ErrorMessageForScope -DeploymentScope 'subscription' -DeploymentName 'resourcegroups-20220106T0401282538Z' + +Get the error message of any failed deployment into the current subscription that has the name 'storageAccounts-20220105T0701282538Z' +#> +function Get-ErrorMessageForScope { + + [CmdletBinding()] + param ( + [Parameter(Mandatory)] + [string] $DeploymentScope, + + [Parameter(Mandatory)] + [string] $DeploymentName, + + [Parameter(Mandatory = $false)] + [string] $ResourceGroupName = '' + ) + + switch ($deploymentScope) { + 'resourcegroup' { + $deployments = Get-AzResourceGroupDeploymentOperation -DeploymentName $deploymentName -ResourceGroupName $resourceGroupName + break + } + 'subscription' { + $deployments = Get-AzDeploymentOperation -DeploymentName $deploymentName + break + } + 'managementgroup' { + $deployments = Get-AzManagementGroupDeploymentOperation -DeploymentName $deploymentName + break + } + 'tenant' { + $deployments = Get-AzTenantDeploymentOperation -DeploymentName $deploymentName + break + } + } + if ($deployments) { + return ($deployments | Where-Object { $_.ProvisioningState -ne 'Succeeded' }).StatusMessage + } +} + <# .SYNOPSIS Run a template deployment using a given parameter file @@ -194,9 +258,22 @@ function New-DeploymentWithParameterFile { } catch { if ($retryCount -ge $retryLimit) { if ($doNotThrow) { + + # In case a deployment failes but not throws an exception (i.e. the exception message is empty) we try to fetch it via the deployment name + if ([String]::IsNullOrEmpty($PSitem.Exception.Message)) { + $errorInputObject = @{ + DeploymentScope = $deploymentScope + DeploymentName = $deploymentName + ResourceGroupName = $resourceGroupName + } + $exceptionMessage = Get-ErrorMessageForScope @errorInputObject + } else { + $exceptionMessage = $PSitem.Exception.Message + } + return @{ DeploymentName = $deploymentName - Exception = $PSitem.Exception.Message + Exception = $exceptionMessage } } else { throw $PSitem.Exception.Message From 124483642e3023f217cd85c13d56519379633635 Mon Sep 17 00:00:00 2001 From: MrMCake Date: Thu, 6 Jan 2022 18:33:00 +0100 Subject: [PATCH 2/2] Bugfix --- arm/Microsoft.Storage/storageAccounts/deploy.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arm/Microsoft.Storage/storageAccounts/deploy.bicep b/arm/Microsoft.Storage/storageAccounts/deploy.bicep index 636d150d83..21d50045f9 100644 --- a/arm/Microsoft.Storage/storageAccounts/deploy.bicep +++ b/arm/Microsoft.Storage/storageAccounts/deploy.bicep @@ -327,7 +327,7 @@ output storageAccountName string = storageAccount.name output storageAccountResourceGroup string = resourceGroup().name @description('The primary blob endpoint reference if blob services are deployed.') -output storageAccountPrimaryBlobEndpoint string = !empty(blobServices) && contains(blobServices, 'containers')) ? reference('Microsoft.Storage/storageAccounts/${storageAccount.name}', '2019-04-01').primaryEndpoints.blob : '' +output storageAccountPrimaryBlobEndpoint string = !empty(blobServices) && contains(blobServices, 'containers') ? reference('Microsoft.Storage/storageAccounts/${storageAccount.name}', '2019-04-01').primaryEndpoints.blob : '' @description('The principal ID of the system assigned identity.') output systemAssignedPrincipalId string = systemAssignedIdentity && contains(storageAccount.identity, 'principalId') ? storageAccount.identity.principalId : ''