@@ -39,7 +39,7 @@ param (
39
39
# Azure SDK Developer Playground subscription
40
40
[Parameter ()]
41
41
[ValidatePattern (' ^[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}$' )]
42
- [string ] $SubscriptionId = ' faa080af-c1d8-40ad-9cce-e1a450ca5b57 ' ,
42
+ [string ] $SubscriptionId ,
43
43
44
44
[Parameter (ParameterSetName = ' Provisioner' , Mandatory = $true )]
45
45
[ValidatePattern (' ^[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}$' )]
@@ -49,8 +49,8 @@ param (
49
49
[string ] $ProvisionerApplicationSecret ,
50
50
51
51
[Parameter ()]
52
- [ValidateRange (0 , [int ]::MaxValue)]
53
- [int ] $DeleteAfterHours ,
52
+ [ValidateRange (1 , [int ]::MaxValue)]
53
+ [int ] $DeleteAfterHours = 48 ,
54
54
55
55
[Parameter ()]
56
56
[string ] $Location = ' ' ,
@@ -166,7 +166,7 @@ try {
166
166
Log " Generated base name '$BaseName ' for CI build"
167
167
} elseif (! $BaseName ) {
168
168
$BaseName = " $UserName$ServiceDirectory "
169
- Log " BaseName was not set. Using default base name: '$BaseName '"
169
+ Log " BaseName was not set. Using default base name '$BaseName '"
170
170
}
171
171
172
172
# Make sure pre- and post-scripts are passed formerly required arguments.
@@ -200,35 +200,74 @@ try {
200
200
# Make sure the user is logged in to create a service principal.
201
201
$context = Get-AzContext ;
202
202
if (! $context ) {
203
- $subscriptionName = $SubscriptionId
203
+ Log ' User not logged in. Logging in now...'
204
+ $context = (Connect-AzAccount ).Context
205
+ }
204
206
205
- # Use cache of well-known team subs without having to be authenticated.
206
- $wellKnownSubscriptions = @ {
207
- ' faa080af-c1d8-40ad-9cce-e1a450ca5b57' = ' Azure SDK Developer Playground'
208
- ' a18897a6-7e44-457d-9260-f2854c0aca42' = ' Azure SDK Engineering System'
209
- ' 2cd617ea-1866-46b1-90e3-fffb087ebf9b' = ' Azure SDK Test Resources'
207
+ $currentSubcriptionId = $context.Subscription.Id
208
+
209
+ # If no subscription was specified, try to select the Azure SDK Developer Playground subscription.
210
+ # Ignore errors to leave the automatically selected subscription.
211
+ if ($SubscriptionId ) {
212
+ if ($currentSubcriptionId -ne $SubscriptionId ) {
213
+ Log " Selecting subscription '$SubscriptionId '"
214
+ $null = Select-AzSubscription - Subscription $SubscriptionId
215
+
216
+ $exitActions += {
217
+ Log " Selecting previous subscription '$currentSubcriptionId '"
218
+ $null = Select-AzSubscription - Subscription $currentSubcriptionId
219
+ }
220
+
221
+ # Update the context.
222
+ $context = Get-AzContext
210
223
}
224
+ } else {
225
+ if ($currentSubcriptionId -ne ' faa080af-c1d8-40ad-9cce-e1a450ca5b57' ) {
226
+ Log " Attempting to select subscription 'Azure SDK Developer Playground (faa080af-c1d8-40ad-9cce-e1a450ca5b57)'"
227
+ $null = Select-AzSubscription - Subscription ' faa080af-c1d8-40ad-9cce-e1a450ca5b57' - ErrorAction Ignore
211
228
212
- if ( $wellKnownSubscriptions .ContainsKey ( $SubscriptionId )) {
213
- $subscriptionName = ' {0} ({1}) ' -f $wellKnownSubscriptions [ $SubscriptionId ] , $SubscriptionId
229
+ # Update the context.
230
+ $context = Get-AzContext
214
231
}
215
232
216
- Log " You are not logged in; connecting to $subscriptionName "
217
- $context = (Connect-AzAccount - Subscription $SubscriptionId ).Context
233
+ $SubscriptionId = $context.Subscription.Id
234
+ $PSBoundParameters [' SubscriptionId' ] = $SubscriptionId
235
+ }
236
+
237
+ # Use cache of well-known team subs without having to be authenticated.
238
+ $wellKnownSubscriptions = @ {
239
+ ' faa080af-c1d8-40ad-9cce-e1a450ca5b57' = ' Azure SDK Developer Playground'
240
+ ' a18897a6-7e44-457d-9260-f2854c0aca42' = ' Azure SDK Engineering System'
241
+ ' 2cd617ea-1866-46b1-90e3-fffb087ebf9b' = ' Azure SDK Test Resources'
242
+ }
243
+
244
+ # Print which subscription is currently selected.
245
+ $subscriptionName = $context.Subscription.Id
246
+ if ($wellKnownSubscriptions.ContainsKey ($subscriptionName )) {
247
+ $subscriptionName = ' {0} ({1})' -f $wellKnownSubscriptions [$subscriptionName ], $subscriptionName
248
+ }
249
+
250
+ Log " Using subscription '$subscriptionName '"
251
+
252
+ # Make sure the TenantId is also updated from the current context.
253
+ # PSBoundParameters is not updated to avoid confusing parameter sets.
254
+ if (! $TenantId ) {
255
+ $TenantId = $context.Subscription.TenantId
218
256
}
219
257
220
258
# If no test application ID is specified during an interactive session, create a new service principal.
221
259
if (! $TestApplicationId ) {
222
260
223
261
# Cache the created service principal in this session for frequent reuse.
224
- $servicePrincipal = if ($AzureTestPrincipal -and (Get-AzADServicePrincipal - ApplicationId $AzureTestPrincipal.ApplicationId )) {
262
+ $servicePrincipal = if ($AzureTestPrincipal -and (Get-AzADServicePrincipal - ApplicationId $AzureTestPrincipal.ApplicationId ) -and $AzureTestSubscription -eq $SubscriptionId ) {
225
263
Log " TestApplicationId was not specified; loading cached service principal '$ ( $AzureTestPrincipal.ApplicationId ) '"
226
264
$AzureTestPrincipal
227
265
} else {
228
- Log ' TestApplicationId was not specified; creating a new service principal'
229
- $global :AzureTestPrincipal = New-AzADServicePrincipal - Role Owner
266
+ Log " TestApplicationId was not specified; creating a new service principal in subscription '$SubscriptionId '"
267
+ $global :AzureTestPrincipal = New-AzADServicePrincipal - Role Owner - Scope " /subscriptions/$SubscriptionId "
268
+ $global :AzureTestSubscription = $SubscriptionId
230
269
231
- Log " Created service principal '$AzureTestPrincipal '"
270
+ Log " Created service principal '$ ( $ AzureTestPrincipal.ApplicationId ) '"
232
271
$AzureTestPrincipal
233
272
}
234
273
@@ -251,13 +290,15 @@ try {
251
290
if ($ProvisionerApplicationId ) {
252
291
$null = Disable-AzContextAutosave - Scope Process
253
292
254
- Log " Logging into service principal '$ProvisionerApplicationId '"
293
+ Log " Logging into service principal '$ProvisionerApplicationId '."
294
+ Write-Warning ' Logging into service principal may fail until the principal is fully propagated.'
295
+
255
296
$provisionerSecret = ConvertTo-SecureString - String $ProvisionerApplicationSecret - AsPlainText - Force
256
297
$provisionerCredential = [System.Management.Automation.PSCredential ]::new($ProvisionerApplicationId , $provisionerSecret )
257
298
258
299
# Use the given subscription ID if provided.
259
300
$subscriptionArgs = if ($SubscriptionId ) {
260
- @ {SubscriptionId = $SubscriptionId }
301
+ @ {Subscription = $SubscriptionId }
261
302
} else {
262
303
@ {}
263
304
}
@@ -292,7 +333,7 @@ try {
292
333
293
334
# If the ServiceDirectory is an absolute path use the last directory name
294
335
# (e.g. D:\foo\bar\ -> bar)
295
- $serviceName = if (Split-Path - IsAbsolute $ServiceDirectory ) {
336
+ $serviceName = if (Split-Path - IsAbsolute $ServiceDirectory ) {
296
337
Split-Path - Leaf $ServiceDirectory
297
338
} else {
298
339
$ServiceDirectory
@@ -307,16 +348,15 @@ try {
307
348
" rg-$BaseName "
308
349
}
309
350
310
- # Tag the resource group to be deleted after a certain number of hours if specified.
311
351
$tags = @ {
312
352
Creator = $UserName
313
353
ServiceDirectory = $ServiceDirectory
314
354
}
315
355
316
- if ( $PSBoundParameters .ContainsKey ( ' DeleteAfterHours ' )) {
317
- $deleteAfter = [ DateTime ]::UtcNow.AddHours( $ DeleteAfterHours)
318
- $tags .Add ( ' DeleteAfter ' , $deleteAfter .ToString (' o' ) )
319
- }
356
+ # Tag the resource group to be deleted after a certain number of hours.
357
+ Write-Warning " Any clean-up scripts running against subscription ' $SubscriptionId ' may delete resource group ' $ResourceGroupName ' after $ DeleteAfterHours hours. "
358
+ $deleteAfter = [ DateTime ]::UtcNow.AddHours( $DeleteAfterHours ) .ToString(' o' )
359
+ $tags [ ' DeleteAfter ' ] = $deleteAfter
320
360
321
361
if ($CI ) {
322
362
# Add tags for the current CI job.
@@ -348,11 +388,15 @@ try {
348
388
# New-AzResourceGroup would've written an error and stopped the pipeline by default anyway.
349
389
Write-Verbose " Successfully created resource group '$ ( $resourceGroup.ResourceGroupName ) '"
350
390
}
351
- elseif (! $resourceGroup -and ! $PSCmdlet.ShouldProcess ($resourceGroupName )) {
352
- # If the -WhatIf flag was passed, there will be no resource group created. Fake it.
353
- $resourceGroup = [PSCustomObject ]@ {
354
- ResourceGroupName = $resourceGroupName
355
- Location = $Location
391
+ elseif (! $resourceGroup ) {
392
+ if (! $PSCmdlet.ShouldProcess ($resourceGroupName )) {
393
+ # If the -WhatIf flag was passed, there will be no resource group created. Fake it.
394
+ $resourceGroup = [PSCustomObject ]@ {
395
+ ResourceGroupName = $resourceGroupName
396
+ Location = $Location
397
+ }
398
+ } else {
399
+ Write-Error " Resource group '$ResourceGroupName ' already exists." - Category ResourceExists - RecommendedAction " Delete resource group '$ResourceGroupName ', or overwrite it when redeploying."
356
400
}
357
401
}
358
402
@@ -413,16 +457,16 @@ try {
413
457
$lastDebugPreference = $DebugPreference
414
458
try {
415
459
if ($CI ) {
416
- $DebugPreference = " Continue"
460
+ $DebugPreference = ' Continue'
417
461
}
418
- New-AzResourceGroupDeployment - Name $BaseName - ResourceGroupName $resourceGroup.ResourceGroupName - TemplateFile $templateFile - TemplateParameterObject $templateFileParameters
462
+ New-AzResourceGroupDeployment - Name $BaseName - ResourceGroupName $resourceGroup.ResourceGroupName - TemplateFile $templateFile - TemplateParameterObject $templateFileParameters - Mode Complete - Force: $Force
419
463
} catch {
420
- Write-Output @"
464
+ Write-Output @'
421
465
#####################################################
422
466
# For help debugging live test provisioning issues, #
423
467
# see http://aka.ms/azsdk/engsys/live-test-help, #
424
468
#####################################################
425
- " @
469
+ ' @
426
470
throw
427
471
} finally {
428
472
$DebugPreference = $lastDebugPreference
@@ -466,7 +510,7 @@ try {
466
510
467
511
if ($OutFile ) {
468
512
if (! $IsWindows ) {
469
- Write-Host " File option is supported only on Windows"
513
+ Write-Host ' File option is supported only on Windows'
470
514
}
471
515
472
516
$outputFile = " $templateFile .env"
@@ -595,7 +639,11 @@ is passed to the ARM template as 'tenantId'.
595
639
Optional subscription ID to use for new resources when logging in as a
596
640
provisioner. You can also use Set-AzContext if not provisioning.
597
641
598
- The default is the Azure SDK Developer Playground subscription ID.
642
+ If you do not specify a SubscriptionId and are not logged in, one will be
643
+ automatically selected for you by the Connect-AzAccount cmdlet.
644
+
645
+ Once you are logged in (or were previously), the selected SubscriptionId
646
+ will be used for subsequent operations that are specific to a subscription.
599
647
600
648
. PARAMETER ProvisionerApplicationId
601
649
The AAD Application ID used to provision test resources when a provisioner is
@@ -614,17 +662,14 @@ If none is specified New-TestResources.ps1 uses the TestApplicationSecret.
614
662
This value is not passed to the ARM template.
615
663
616
664
. PARAMETER DeleteAfterHours
617
- Optional. Positive integer number of hours from the current time to set the
665
+ Positive integer number of hours from the current time to set the
618
666
'DeleteAfter' tag on the created resource group. The computed value is a
619
667
timestamp of the form "2020-03-04T09:07:04.3083910Z".
620
668
621
- If this value is not specified no 'DeleteAfter' tag will be assigned to the
622
- created resource group.
623
-
624
669
An optional cleanup process can delete resource groups whose "DeleteAfter"
625
670
timestamp is less than the current time.
626
671
627
- This isused for CI automation.
672
+ This is used for CI automation.
628
673
629
674
. PARAMETER Location
630
675
Optional location where resources should be created. If left empty, the default
@@ -660,8 +705,8 @@ Save test environment settings into a test-resources.json.env file next to test-
660
705
The environment file would be scoped to the current repository directory.
661
706
662
707
. EXAMPLE
663
- Connect-AzAccount -Subscription " REPLACE_WITH_SUBSCRIPTION_ID"
664
- New-TestResources.ps1 -ServiceDirectory ' keyvault'
708
+ Connect-AzAccount -Subscription ' REPLACE_WITH_SUBSCRIPTION_ID'
709
+ New-TestResources.ps1 keyvault
665
710
666
711
Run this in a desktop environment to create new AAD apps and Service Principals
667
712
that can be used to provision resources and run live tests.
0 commit comments