Skip to content

Commit 3a52f7b

Browse files
authored
Add retry for deployment failures and check result for every operation (#262)
1 parent bbee303 commit 3a52f7b

File tree

11 files changed

+278
-159
lines changed

11 files changed

+278
-159
lines changed

Tools/PowershellModule/src/Library/Connect-ToAzure.ps1

+4-4
Original file line numberDiff line numberDiff line change
@@ -70,28 +70,28 @@ Function Connect-ToAzure
7070
if($SubscriptionName -and $SubscriptionId) {
7171
## Attempts a connection to Azure using both the Subscription Name and Subscription Id
7272
Write-Information "Initiating a connection to your Azure Subscription Name $SubscriptionName and Subscription Id $SubscriptionId"
73-
Connect-AzAccount -SubscriptionName $SubscriptionName -SubscriptionId $SubscriptionId
73+
$ConnectResult = Connect-AzAccount -SubscriptionName $SubscriptionName -SubscriptionId $SubscriptionId
7474

7575
$TestAzureConnection = Test-ConnectionToAzure -SubscriptionName $SubscriptionName -SubscriptionId $SubscriptionId
7676
}
7777
elseif($SubscriptionName) {
7878
## Attempts a connection to Azure using Subscription Name
7979
Write-Information "Initiating a connection to your Azure Subscription Name $SubscriptionName"
80-
Connect-AzAccount -SubscriptionName $SubscriptionName
80+
$ConnectResult = Connect-AzAccount -SubscriptionName $SubscriptionName
8181

8282
$TestAzureConnection = Test-ConnectionToAzure -SubscriptionName $SubscriptionName
8383
}
8484
elseif($SubscriptionId) {
8585
## Attempts a connection to Azure using Subscription Id
8686
Write-Information "Initiating a connection to your Azure Subscription Id $SubscriptionId"
87-
Connect-AzAccount -SubscriptionId $SubscriptionId
87+
$ConnectResult = Connect-AzAccount -SubscriptionId $SubscriptionId
8888

8989
$TestAzureConnection = Test-ConnectionToAzure -SubscriptionId $SubscriptionId
9090
}
9191
else{
9292
## Attempts a connection to Azure with the users default Subscription
9393
Write-Information "Initiating a connection to your Azure environment."
94-
Connect-AzAccount
94+
$ConnectResult = Connect-AzAccount
9595

9696
$TestAzureConnection = Test-ConnectionToAzure
9797
}

Tools/PowershellModule/src/Library/Find-WinGetManifest.ps1

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ Function Find-WinGetManifest
5959

6060
###############################
6161
## Connects to Azure, if not already connected.
62-
Write-Verbose "Testing connection to Azure."
62+
Write-Verbose "Validating connection to azure, will attempt to connect if not already connected."
6363
$Result = Connect-ToAzure -SubscriptionName $SubscriptionName
6464
if(!($Result)) {
6565
Write-Error "Failed to connect to Azure. Please run Connect-AzAccount to connect to Azure, or re-run the cmdlet and enter your credentials." -ErrorAction Stop

Tools/PowershellModule/src/Library/Get-WinGetManifest.ps1

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ Function Get-WinGetManifest
7575
"Azure" {
7676
###############################
7777
## Connects to Azure, if not already connected.
78-
Write-Verbose "Testing connection to Azure."
78+
Write-Verbose "Validating connection to azure, will attempt to connect if not already connected."
7979
$Result = Connect-ToAzure -SubscriptionName $SubscriptionName
8080
if(!($Result)) {
8181
Write-Error "Failed to connect to Azure. Please run Connect-AzAccount to connect to Azure, or re-run the cmdlet and enter your credentials." -ErrorAction Stop

Tools/PowershellModule/src/Library/New-ARMObjects.ps1

+72-62
Large diffs are not rendered by default.

Tools/PowershellModule/src/Library/New-ARMParameterObjects.ps1

+7-10
Original file line numberDiff line numberDiff line change
@@ -138,31 +138,28 @@ Function New-ARMParameterObjects
138138
$AzContext = Get-AzContext
139139
$AzTenantID = $AzContext.Tenant.Id
140140
$AzTenantDomain = $AzContext.Tenant.Domains[0]
141-
$DeployAppConfigValues = $false
142141

143142
if ($AzContext.Account.Type -eq "User")
144143
{
144+
$LocalDeployment = $true
145145
$AzObjectID = $(Get-AzADUser -SignedIn).Id
146146
if (!$PublisherEmail) {
147147
$PublisherEmail = $AzContext.Account.Id
148148
}
149149
if (!$PublisherName) {
150150
$PublisherName = $AzContext.Account.Id
151151
}
152-
153-
$DeployAppConfigValues = $false
154152
}
155153
else
156154
{
155+
$LocalDeployment = $false
157156
$AzObjectID = $(Get-AzADServicePrincipal -ApplicationId $AzContext.Account.ID).Id
158157
if (!$PublisherEmail) {
159158
$PublisherEmail = "WinGetRestSource@$AzTenantDomain"
160159
}
161160
if (!$PublisherName) {
162161
$PublisherName = "WinGetRestSource@$AzTenantDomain"
163162
}
164-
165-
$DeployAppConfigValues = $true
166163
}
167164
Write-Verbose -Message "Retrieved the Azure Object Id: $AzObjectID"
168165

@@ -206,17 +203,17 @@ Function New-ARMParameterObjects
206203
isZoneRedundant = $false
207204
}
208205
)
209-
$ApiManagementSku = "Basicv2"
206+
$ApiManagementSku = "Basic"
210207
}
211208
"Enhanced" {
212209
$AppConfigSku = "Standard"
213210
$KeyVaultSKU = "Standard"
214-
$StorageAccountPerformance = "Standard_GZRS"
211+
$StorageAccountPerformance = "Standard_GRS"
215212
$AspSku = "P1V2"
216213
$CosmosDBAEnableFreeTier = $false
217214
## To enable Serverless then set CosmosDBACapatilities to "[{"name": ""EnableServerless""}]"
218215
$CosmosDBACapabilities = "[]"
219-
$CosmosDBAConsistency = "Strong"
216+
$CosmosDBAConsistency = "Session"
220217
$CosmosDBALocations = @(
221218
@{
222219
locationName = $PrimaryRegionName
@@ -229,7 +226,7 @@ Function New-ARMParameterObjects
229226
isZoneRedundant = $false
230227
}
231228
)
232-
$ApiManagementSku = "Standardv2"
229+
$ApiManagementSku = "Standard"
233230
}
234231
}
235232

@@ -293,7 +290,7 @@ Function New-ARMParameterObjects
293290
appConfigName = @{ value = $appConfigName } # Name used to contain the Storage Account connection string in the Key Value
294291
location = @{ value = $Region } # Azure hosting location
295292
sku = @{ value = $AppConfigSku }
296-
deployAppConfigValues = @{ value = $DeployAppConfigValues }
293+
localDeployment = @{ value = $LocalDeployment }
297294
}
298295
}
299296
},

Tools/PowershellModule/src/Library/New-MicrosoftEntraIdApp.ps1

+3-3
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ Function New-MicrosoftEntraIdApp
4848

4949
## Add App Id Uri
5050
$AppId = $App.AppId
51-
Update-AzADApplication -ApplicationId $AppId -IdentifierUri "api://$AppId" -ErrorVariable ErrorUpdate
51+
$App = Update-AzADApplication -ApplicationId $AppId -IdentifierUri "api://$AppId" -ErrorVariable ErrorUpdate
5252
if ($ErrorUpdate)
5353
{
5454
Write-Error "Failed to add App Id Uri. Error: $ErrorUpdate"
@@ -72,7 +72,7 @@ Function New-MicrosoftEntraIdApp
7272
}
7373
)
7474
}
75-
Update-AzADApplication -ApplicationId $AppId -Api $Api -ErrorVariable ErrorUpdate
75+
$App = Update-AzADApplication -ApplicationId $AppId -Api $Api -ErrorVariable ErrorUpdate
7676
if ($ErrorUpdate)
7777
{
7878
Write-Error "Failed to add Api scope. Error: $ErrorUpdate"
@@ -96,7 +96,7 @@ Function New-MicrosoftEntraIdApp
9696
}
9797
)
9898
}
99-
Update-AzADApplication -ApplicationId $AppId -Api $Api -ErrorVariable ErrorUpdate
99+
$App = Update-AzADApplication -ApplicationId $AppId -Api $Api -ErrorVariable ErrorUpdate
100100
if ($ErrorUpdate)
101101
{
102102
Write-Error "Failed to add authorized clients"

Tools/PowershellModule/src/Library/New-WinGetSource.ps1

+35-16
Original file line numberDiff line numberDiff line change
@@ -62,22 +62,25 @@ Function New-WinGetSource
6262
.PARAMETER ShowConnectionInstructions
6363
[Optional] If specified, the instructions for connecting to the Windows Package Manager REST source. (Default: False)
6464
65+
.PARAMETER MaxRetryCount
66+
[Optional] Max ARM template deployment retry count upon failure. (Default: 5)
67+
6568
.EXAMPLE
66-
New-WinGetSource -Name "contosorestsource"
69+
New-WinGetSource -Name "contosorestsource" -InformationAction Continue -Verbose
6770
6871
Creates the Windows Package Manager REST source in Azure with resources named "contosorestsource" in the westus region of
6972
Azure with the basic level performance.
7073
7174
.EXAMPLE
72-
New-WinGetSource -Name "contosorestsource" -ResourceGroup "WinGet" -SubscriptionName "Visual Studio Subscription" -Region "westus" -ParameterOutput "C:\WinGet" -ImplementationPerformance "Basic" -ShowConnectionInformation
75+
New-WinGetSource -Name "contosorestsource" -ResourceGroup "WinGet" -SubscriptionName "Visual Studio Subscription" -Region "westus" -ParameterOutput "C:\WinGet" -ImplementationPerformance "Basic" -ShowConnectionInformation -InformationAction Continue -Verbose
7376
7477
Creates the Windows Package Manager REST source in Azure with resources named "contosorestsource" in the westus region of
7578
Azure with the basic level performance in the "Visual Studio Subscription" Subscription. Displays the required command
7679
to connect the WinGet client to the new REST source after the REST source has been created.
7780
7881
#>
7982
PARAM(
80-
[Parameter(Position=0, Mandatory=$true)] [string]$Name,
83+
[Parameter(Position=0, Mandatory=$true)] [string]$Name,
8184
[Parameter(Mandatory=$false)] [string]$ResourceGroup = "WinGetRestSource",
8285
[Parameter(Mandatory=$false)] [string]$SubscriptionName = "",
8386
[Parameter(Mandatory=$false)] [string]$Region = "westus",
@@ -93,7 +96,8 @@ Function New-WinGetSource
9396
[Parameter()] [switch]$CreateNewMicrosoftEntraIdAppRegistration,
9497
[Parameter(Mandatory=$false)] [string]$MicrosoftEntraIdResource = "",
9598
[Parameter(Mandatory=$false)] [string]$MicrosoftEntraIdResourceScope = "",
96-
[Parameter()] [switch]$ShowConnectionInstructions
99+
[Parameter()] [switch]$ShowConnectionInstructions,
100+
[Parameter(Mandatory=$false)] [int]$MaxRetryCount = 5
97101
)
98102

99103
if($ImplementationPerformance -eq "Developer") {
@@ -106,11 +110,11 @@ Function New-WinGetSource
106110

107111
###############################
108112
## Check input paths
109-
if(!$(Test-Path -Path $TemplateFolderPath)) {
113+
if (!$(Test-Path -Path $TemplateFolderPath)) {
110114
Write-Error "REST Source Function Code is missing in specified path ($TemplateFolderPath)"
111115
return $false
112116
}
113-
if(!$(Test-Path -Path $RestSourcePath)) {
117+
if (!$(Test-Path -Path $RestSourcePath)) {
114118
Write-Error "REST Source Function Code is missing in specified path ($RestSourcePath)"
115119
return $false
116120
}
@@ -125,7 +129,7 @@ Function New-WinGetSource
125129
###############################
126130
## Create folder for the Parameter output path
127131
$Result = New-Item -ItemType Directory -Path $ParameterOutputPath -Force
128-
if($Result) {
132+
if ($Result) {
129133
Write-Verbose -Message "Created Directory to contain the ARM Parameter files ($($Result.FullName))."
130134
}
131135
else {
@@ -135,9 +139,9 @@ Function New-WinGetSource
135139

136140
###############################
137141
## Connects to Azure, if not already connected.
138-
Write-Information "Testing connection to Azure."
142+
Write-Information "Validating connection to azure, will attempt to connect if not already connected."
139143
$Result = Connect-ToAzure -SubscriptionName $SubscriptionName
140-
if(!($Result)) {
144+
if (!($Result)) {
141145
Write-Error "Failed to connect to Azure. Please run Connect-AzAccount to connect to Azure, or re-run the cmdlet and enter your credentials."
142146
return $false
143147
}
@@ -173,7 +177,8 @@ Function New-WinGetSource
173177
return $false
174178
}
175179

176-
#### Verifies ARM Parameters are correct
180+
###############################
181+
## Verifies ARM Parameters are correct. If any failed, the return results will contain failed objects. Otherwise, success.
177182
$Result = Test-ARMTemplates -ARMObjects $ARMObjects -ResourceGroup $ResourceGroup
178183
if($Result){
179184
$ErrReturnObject = @{
@@ -188,11 +193,25 @@ Function New-WinGetSource
188193

189194
###############################
190195
## Creates Azure Objects with ARM Templates and Parameters
191-
$Result = New-ARMObjects -ARMObjects $ARMObjects -RestSourcePath $RestSourcePath -ResourceGroup $ResourceGroup
192-
if (!$Result) {
193-
Write-Error "Failed to create Azure resources for WinGet rest source"
194-
return $false
195-
}
196+
$Attempt = 0
197+
$Retry = $false
198+
do {
199+
$Attempt++
200+
$Retry = $false
201+
202+
$Result = New-ARMObjects -ARMObjects ([ref]$ARMObjects) -RestSourcePath $RestSourcePath -ResourceGroup $ResourceGroup
203+
if (!$Result) {
204+
if ($Attempt -lt $MaxRetryCount) {
205+
$Retry = $true
206+
Write-Verbose "Retrying deployment after 15 seconds."
207+
Start-Sleep -Seconds 15
208+
}
209+
else {
210+
Write-Error "Failed to create Azure resources for WinGet rest source."
211+
return $false
212+
}
213+
}
214+
} while ($Retry)
196215

197216
###############################
198217
## Shows how to connect local Windows Package Manager Client to newly created REST source
@@ -203,7 +222,7 @@ Function New-WinGetSource
203222
## Post script Run Informational:
204223
#### Instructions on how to add the REST source to your Windows Package Manager Client
205224
Write-Information -MessageData "Use the following command to register the new REST source with your Windows Package Manager Client:" -InformationAction Continue
206-
Write-Information -MessageData " winget source add -n ""restsource"" -a ""$ApiManagementURL/winget/"" -t ""Microsoft.Rest""" -InformationAction Continue
225+
Write-Information -MessageData " winget source add -n ""$Name"" -a ""$ApiManagementURL/winget/"" -t ""Microsoft.Rest""" -InformationAction Continue
207226

208227
#### For more information about how to use the solution, visit the aka.ms link.
209228
Write-Information -MessageData "`nFor more information on the Windows Package Manager Client, go to: https://aka.ms/winget-command-help`n" -InformationAction Continue

0 commit comments

Comments
 (0)