@@ -79,6 +79,8 @@ param (
7979 [switch ] $OutFile
8080)
8181
82+ . $PSScriptRoot / SubConfig- Helpers.ps1
83+
8284# By default stop for any error.
8385if (! $PSBoundParameters.ContainsKey (' ErrorAction' )) {
8486 $ErrorActionPreference = ' Stop'
@@ -126,7 +128,7 @@ function LoadCloudConfig([string] $env)
126128function MergeHashes ([hashtable ] $source , [psvariable ] $dest )
127129{
128130 foreach ($key in $source.Keys ) {
129- if ($dest.Value.ContainsKey ($key ) -and $dest.Value [$key ] -ne $source [$key ]) {
131+ if ($dest.Value.Contains ($key ) -and $dest.Value [$key ] -ne $source [$key ]) {
130132 Write-Warning (" Overwriting '$ ( $dest.Name ) .$ ( $key ) ' with value '$ ( $dest.Value [$key ]) ' " +
131133 " to new value '$ ( $source [$key ]) '" )
132134 }
@@ -155,6 +157,93 @@ function BuildBicepFile([System.IO.FileSystemInfo] $file)
155157 return $templateFilePath
156158}
157159
160+ function BuildDeploymentOutputs ([string ]$serviceDirectoryPrefix , [object ]$azContext , [object ]$deployment ) {
161+ # Add default values
162+ $deploymentOutputs = [Ordered ]@ {
163+ " ${serviceDirectoryPrefix} CLIENT_ID" = $TestApplicationId ;
164+ " ${serviceDirectoryPrefix} CLIENT_SECRET" = $TestApplicationSecret ;
165+ " ${serviceDirectoryPrefix} TENANT_ID" = $azContext.Tenant.Id ;
166+ " ${serviceDirectoryPrefix} SUBSCRIPTION_ID" = $azContext.Subscription.Id ;
167+ " ${serviceDirectoryPrefix} RESOURCE_GROUP" = $resourceGroup.ResourceGroupName ;
168+ " ${serviceDirectoryPrefix} LOCATION" = $resourceGroup.Location ;
169+ " ${serviceDirectoryPrefix} ENVIRONMENT" = $azContext.Environment.Name ;
170+ " ${serviceDirectoryPrefix} AZURE_AUTHORITY_HOST" = $azContext.Environment.ActiveDirectoryAuthority ;
171+ " ${serviceDirectoryPrefix} RESOURCE_MANAGER_URL" = $azContext.Environment.ResourceManagerUrl ;
172+ " ${serviceDirectoryPrefix} SERVICE_MANAGEMENT_URL" = $azContext.Environment.ServiceManagementUrl ;
173+ }
174+
175+ MergeHashes $EnvironmentVariables $ (Get-Variable deploymentOutputs)
176+
177+ foreach ($key in $deployment.Outputs.Keys ) {
178+ $variable = $deployment.Outputs [$key ]
179+
180+ # Work around bug that makes the first few characters of environment variables be lowercase.
181+ $key = $key.ToUpperInvariant ()
182+
183+ if ($variable.Type -eq ' String' -or $variable.Type -eq ' SecureString' ) {
184+ $deploymentOutputs [$key ] = $variable.Value
185+ }
186+ }
187+
188+ return $deploymentOutputs
189+ }
190+
191+ function SetDeploymentOutputs ([string ]$serviceName , [object ]$azContext , [object ]$deployment , [object ]$templateFile ) {
192+ $serviceDirectoryPrefix = $serviceName.ToUpperInvariant () + " _"
193+ $deploymentOutputs = BuildDeploymentOutputs $serviceDirectoryPrefix $azContext $deployment
194+
195+ if ($OutFile ) {
196+ if (! $IsWindows ) {
197+ Write-Host ' File option is supported only on Windows'
198+ }
199+
200+ $outputFile = " $ ( $templateFile.originalFilePath ) .env"
201+
202+ $environmentText = $deploymentOutputs | ConvertTo-Json ;
203+ $bytes = [System.Text.Encoding ]::UTF8.GetBytes($environmentText )
204+ $protectedBytes = [Security.Cryptography.ProtectedData ]::Protect($bytes , $null , [Security.Cryptography.DataProtectionScope ]::CurrentUser)
205+
206+ Set-Content $outputFile - Value $protectedBytes - AsByteStream - Force
207+
208+ Write-Host " Test environment settings`n $environmentText `n stored into encrypted $outputFile "
209+ } else {
210+ if (! $CI ) {
211+ # Write an extra new line to isolate the environment variables for easy reading.
212+ Log " Persist the following environment variables based on your detected shell ($shell ):`n "
213+ }
214+
215+ # Marking values as secret by allowed keys below is not sufficient, as there may be outputs set in the ARM/bicep
216+ # file that re-mark those values as secret (since all user-provided deployment outputs are treated as secret by default).
217+ # This variable supports a second check on not marking previously allowed keys/values as secret.
218+ $notSecretValues = @ ()
219+ foreach ($key in $deploymentOutputs.Keys ) {
220+ $value = $deploymentOutputs [$key ]
221+ $EnvironmentVariables [$key ] = $value
222+
223+ if ($CI ) {
224+ if (ShouldMarkValueAsSecret $serviceDirectoryPrefix $key $value $notSecretValues ) {
225+ # Treat all ARM template output variables as secrets since "SecureString" variables do not set values.
226+ # In order to mask secrets but set environment variables for any given ARM template, we set variables twice as shown below.
227+ Write-Host " ##vso[task.setvariable variable=_$key ;issecret=true;]$value "
228+ Write-Host " Setting variable as secret '$key ': $value "
229+ } else {
230+ Write-Host " Setting variable '$key ': $value "
231+ $notSecretValues += $value
232+ }
233+ Write-Host " ##vso[task.setvariable variable=$key ;]$value "
234+ } else {
235+ Write-Host ($shellExportFormat -f $key , $value )
236+ }
237+ }
238+
239+ if ($key ) {
240+ # Isolate the environment variables for easy reading.
241+ Write-Host " `n "
242+ $key = $null
243+ }
244+ }
245+ }
246+
158247# Support actions to invoke on exit.
159248$exitActions = @ ({
160249 if ($exitActions.Count -gt 1 ) {
@@ -580,78 +669,7 @@ try {
580669 Write-Verbose " Successfully deployed template '$ ( $templateFile.jsonFilePath ) ' to resource group '$ ( $resourceGroup.ResourceGroupName ) '"
581670 }
582671
583- $serviceDirectoryPrefix = $serviceName.ToUpperInvariant () + " _"
584-
585- # Add default values
586- $deploymentOutputs = @ {
587- " $ ( $serviceDirectoryPrefix ) CLIENT_ID" = $TestApplicationId ;
588- " $ ( $serviceDirectoryPrefix ) CLIENT_SECRET" = $TestApplicationSecret ;
589- " $ ( $serviceDirectoryPrefix ) TENANT_ID" = $context.Tenant.Id ;
590- " $ ( $serviceDirectoryPrefix ) SUBSCRIPTION_ID" = $context.Subscription.Id ;
591- " $ ( $serviceDirectoryPrefix ) RESOURCE_GROUP" = $resourceGroup.ResourceGroupName ;
592- " $ ( $serviceDirectoryPrefix ) LOCATION" = $resourceGroup.Location ;
593- " $ ( $serviceDirectoryPrefix ) ENVIRONMENT" = $context.Environment.Name ;
594- " $ ( $serviceDirectoryPrefix ) AZURE_AUTHORITY_HOST" = $context.Environment.ActiveDirectoryAuthority ;
595- " $ ( $serviceDirectoryPrefix ) RESOURCE_MANAGER_URL" = $context.Environment.ResourceManagerUrl ;
596- " $ ( $serviceDirectoryPrefix ) SERVICE_MANAGEMENT_URL" = $context.Environment.ServiceManagementUrl ;
597- " $ ( $serviceDirectoryPrefix ) STORAGE_ENDPOINT_SUFFIX" = $context.Environment.StorageEndpointSuffix ;
598- }
599-
600- MergeHashes $EnvironmentVariables $ (Get-Variable deploymentOutputs)
601-
602- foreach ($key in $deployment.Outputs.Keys ) {
603- $variable = $deployment.Outputs [$key ]
604-
605- # Work around bug that makes the first few characters of environment variables be lowercase.
606- $key = $key.ToUpperInvariant ()
607-
608- if ($variable.Type -eq ' String' -or $variable.Type -eq ' SecureString' ) {
609- $deploymentOutputs [$key ] = $variable.Value
610- }
611- }
612-
613- if ($OutFile ) {
614- if (! $IsWindows ) {
615- Write-Host ' File option is supported only on Windows'
616- }
617-
618- $outputFile = " $ ( $templateFile.originalFilePath ) .env"
619-
620- $environmentText = $deploymentOutputs | ConvertTo-Json ;
621- $bytes = [System.Text.Encoding ]::UTF8.GetBytes($environmentText )
622- $protectedBytes = [Security.Cryptography.ProtectedData ]::Protect($bytes , $null , [Security.Cryptography.DataProtectionScope ]::CurrentUser)
623-
624- Set-Content $outputFile - Value $protectedBytes - AsByteStream - Force
625-
626- Write-Host " Test environment settings`n $environmentText `n stored into encrypted $outputFile "
627- } else {
628-
629- if (! $CI ) {
630- # Write an extra new line to isolate the environment variables for easy reading.
631- Log " Persist the following environment variables based on your detected shell ($shell ):`n "
632- }
633-
634- foreach ($key in $deploymentOutputs.Keys ) {
635- $value = $deploymentOutputs [$key ]
636- $EnvironmentVariables [$key ] = $value
637-
638- if ($CI ) {
639- # Treat all ARM template output variables as secrets since "SecureString" variables do not set values.
640- # In order to mask secrets but set environment variables for any given ARM template, we set variables twice as shown below.
641- Write-Host " Setting variable '$key ': ***"
642- Write-Host " ##vso[task.setvariable variable=_$key ;issecret=true;]$ ( $value ) "
643- Write-Host " ##vso[task.setvariable variable=$key ;]$ ( $value ) "
644- } else {
645- Write-Host ($shellExportFormat -f $key , $value )
646- }
647- }
648-
649- if ($key ) {
650- # Isolate the environment variables for easy reading.
651- Write-Host " `n "
652- $key = $null
653- }
654- }
672+ SetDeploymentOutputs $serviceName $context $deployment $templateFile
655673
656674 $postDeploymentScript = $templateFile.originalFilePath | Split-Path | Join-Path - ChildPath ' test-resources-post.ps1'
657675 if (Test-Path $postDeploymentScript ) {
0 commit comments