From d2f18c9ea188f50fe0f95955ffac71731da8daca Mon Sep 17 00:00:00 2001 From: Jesper Fajers Date: Thu, 21 Dec 2023 23:23:37 +0000 Subject: [PATCH 01/20] UpdateLogicBase --- src/functions/Invoke-AzOpsPush.ps1 | 74 ++++++++++++++++++- src/internal/configurations/Core.ps1 | 1 + .../functions/New-AzOpsDeployment.ps1 | 28 ++++++- src/localized/en-us/Strings.psd1 | 5 ++ 4 files changed, 102 insertions(+), 6 deletions(-) diff --git a/src/functions/Invoke-AzOpsPush.ps1 b/src/functions/Invoke-AzOpsPush.ps1 index 90105c4c..7dd62a58 100644 --- a/src/functions/Invoke-AzOpsPush.ps1 +++ b/src/functions/Invoke-AzOpsPush.ps1 @@ -402,10 +402,80 @@ throw } - #Starting Tenant Deployment + #Starting deployment $WhatIfPreference = $WhatIfPreferenceState $uniqueProperties = 'Scope', 'DeploymentName', 'TemplateFilePath', 'TemplateParameterFilePath' - $deploymentList | Select-Object $uniqueProperties -Unique | New-AzOpsDeployment -WhatIf:$WhatIfPreference + $uniqueDeployment = $deploymentList | Select-Object $uniqueProperties -Unique + $deploymentResult = @() + + #Determine what deployment pattern to adopt serial or parallel + if ((Get-PSFConfigValue -FullName 'AzOps.Core.AllowMultipleTemplateParameterFiles') -eq $true -and (Get-PSFConfigValue -FullName 'AzOps.Core.ParallelDeploymentMultipleTemplateParameterFiles') -eq $true) { + Write-PSFMessage -Level Verbose @common -String 'Invoke-AzOpsPush.Deployment.ParallelCondition' + # Group deployments based on TemplateFilePath + $groups = $uniqueDeployment | Group-Object -Property TemplateFilePath | Where-Object { $_.Count -ge '2' -and $_.Name -ne $(Get-Item $AzOpsMainTemplate).FullName } + if ($groups) { + Write-PSFMessage -Level Verbose @common -String 'Invoke-AzOpsPush.Deployment.ParallelGroup' -StringValues $groups.Count + $processedTargets = @() + # Process each deployment and evaluate serial or parallel deployment pattern + foreach ($deployment in $uniqueDeployment) { + if ($deployment.TemplateFilePath -in $groups.Name -and $deployment -notin $processedTargets) { + $targets = $($groups | Where-Object { $_.Name -eq $deployment.TemplateFilePath }).Group + Write-PSFMessage -Level Verbose @common -String 'Invoke-AzOpsPush.Deployment.Parallel' -StringValues $deployment.TemplateFilePath, $targets.Count + # Prepare Input Data for parallel processing + $runspaceData = @{ + AzOpsPath = "$($script:ModuleRoot)\AzOps.psd1" + StatePath = $StatePath + WhatIfPreference = $WhatIfPreference + runspace_AzOpsAzManagementGroup = $script:AzOpsAzManagementGroup + runspace_AzOpsSubscriptions = $script:AzOpsSubscriptions + runspace_AzOpsPartialRoot = $script:AzOpsPartialRoot + runspace_AzOpsResourceProvider = $script:AzOpsResourceProvider + } + $deploymentResult += $targets | Foreach-Object -ThrottleLimit (Get-PSFConfigValue -FullName 'AzOps.Core.ThrottleLimit') -Parallel { + $deployment = $_ + $runspaceData = $using:runspaceData + + Import-Module "$([PSFramework.PSFCore.PSFCoreHost]::ModuleRoot)/PSFramework.psd1" + $azOps = Import-Module $runspaceData.AzOpsPath -Force -PassThru + + & $azOps { + $script:AzOpsAzManagementGroup = $runspaceData.runspace_AzOpsAzManagementGroup + $script:AzOpsSubscriptions = $runspaceData.runspace_AzOpsSubscriptions + $script:AzOpsPartialRoot = $runspaceData.runspace_AzOpsPartialRoot + $script:AzOpsResourceProvider = $runspaceData.runspace_AzOpsResourceProvider + } + + & $azOps { + $deployment | New-AzOpsDeployment -WhatIf:$runspaceData.WhatIfPreference + } + } + $processedTargets += $targets + } + elseif ($deployment -notin $processedTargets) { + Write-PSFMessage -Level Verbose @common -String 'Invoke-AzOpsPush.Deployment.Serial' -StringValues $deployment.Count + $deploymentResult += $deployment | New-AzOpsDeployment -WhatIf:$WhatIfPreference + } + else { + Write-PSFMessage -Level Verbose @common -String 'Invoke-AzOpsPush.Deployment.Skip' -StringValues $deployment.TemplateFilePath, $deployment.TemplateParameterFilePath + } + } + } + else { + # No deployments with matching TemplateFilePath identified + Write-PSFMessage -Level Verbose @common -String 'Invoke-AzOpsPush.Deployment.Serial' -StringValues $deployment.Count + $deploymentResult += $uniqueDeployment | New-AzOpsDeployment -WhatIf:$WhatIfPreference + } + } else { + # Perform serial deployment only + Write-PSFMessage -Level Verbose @common -String 'Invoke-AzOpsPush.Deployment.Serial' -StringValues $uniqueDeployment.Count + $deploymentResult += $uniqueDeployment | New-AzOpsDeployment -WhatIf:$WhatIfPreference + } + + if ($deploymentResult) { + foreach ($result in $deploymentResult) { + Set-AzOpsWhatIfOutput -FilePath $result.filePath -ParameterFilePath $result.parameterFilePath -Results $result.results + } + } #Removal of Supported resourceTypes $uniqueProperties = 'Scope', 'TemplateFilePath', 'TemplateParameterFilePath' diff --git a/src/internal/configurations/Core.ps1 b/src/internal/configurations/Core.ps1 index 8eebec11..a05d0834 100644 --- a/src/internal/configurations/Core.ps1 +++ b/src/internal/configurations/Core.ps1 @@ -29,5 +29,6 @@ Set-PSFConfig -Module AzOps -Name Core.TemplateParameterFileSuffix -Value '.json Set-PSFConfig -Module AzOps -Name Core.AllowMultipleTemplateParameterFiles -Value $false -Initialize -Validation string -Description 'Global flag to control multiple parameter file behaviour' Set-PSFConfig -Module AzOps -Name Core.DeployAllMultipleTemplateParameterFiles -Value $false -Initialize -Validation string -Description 'Global flag to control base template deployment behaviour with changes and un-changed multiple corresponding parameter files' Set-PSFConfig -Module AzOps -Name Core.MultipleTemplateParameterFileSuffix -Value '.x' -Initialize -Validation string -Description 'Multiple parameter file suffix identifier' +Set-PSFConfig -Module AzOps -Name Core.ParallelDeploymentMultipleTemplateParameterFiles -Value $false -Initialize -Validation string -Description 'Global flag to control parallel deployment of MultipleTemplateParameterFilesbehaviour' Set-PSFConfig -Module AzOps -Name Core.ThrottleLimit -Value 5 -Initialize -Validation integer -Description 'Throttle limit used in Foreach-Object -Parallel for resource/subscription discovery' Set-PSFConfig -Module AzOps -Name Core.WhatifExcludedChangeTypes -Value @('NoChange', 'Ignore') -Initialize -Validation stringarray -Description 'Exclude specific change types from WhatIf operations.' \ No newline at end of file diff --git a/src/internal/functions/New-AzOpsDeployment.ps1 b/src/internal/functions/New-AzOpsDeployment.ps1 index b0e084de..2fe111f7 100644 --- a/src/internal/functions/New-AzOpsDeployment.ps1 +++ b/src/internal/functions/New-AzOpsDeployment.ps1 @@ -23,6 +23,11 @@ .EXAMPLE > $AzOpsDeploymentList | Select-Object $uniqueProperties -Unique | Sort-Object -Property TemplateParameterFilePath | New-Deployment Deploy all unique deployments provided from $AzOpsDeploymentList + Name Value + ---- ----- + filePath /root/managementgroup/subscription/resourcegroup/template.json + parameterFilePath /root/managementgroup/subscription/resourcegroup/template.parameters.json + results Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkModels.Deployments.PSWhatIfOperationResult #> [CmdletBinding(SupportsShouldProcess = $true)] @@ -157,6 +162,11 @@ } # Proceed with WhatIf or Deployment if scope was found if ($scopeFound) { + $deploymentResult = [PSCustomObject]@{ + filePath = '' + parameterFilePath = '' + results = '' + } if ($TemplateParameterFilePath) { $parameters.TemplateParameterFile = $TemplateParameterFilePath } @@ -176,10 +186,13 @@ elseif ($resultsErrorMessage -match 'DeploymentWhatIfResourceError' -and $resultsErrorMessage -match "The request to predict template deployment") { Write-PSFMessage -Level Warning -String 'New-AzOpsDeployment.WhatIfWarning' -Target $scopeObject -Tag Error -StringValues $resultsErrorMessage if ($parameters.TemplateParameterFile) { - Set-AzOpsWhatIfOutput -FilePath $parameters.TemplateFile -ParameterFilePath $parameters.TemplateParameterFile -Results ('{0}WhatIf prediction failed with error - validate changes manually before merging:{0}{1}' -f [environment]::NewLine, $resultsErrorMessage) + $deploymentResult.filePath = $parameters.TemplateFile + $deploymentResult.parameterFilePath = $parameters.TemplateParameterFile + $deploymentResult.results = ('{0}WhatIf prediction failed with error - validate changes manually before merging:{0}{1}' -f [environment]::NewLine, $resultsErrorMessage) } else { - Set-AzOpsWhatIfOutput -FilePath $parameters.TemplateFile -Results ('{0}WhatIf prediction failed with error - validate changes manually before merging:{0}{1}' -f [environment]::NewLine, $resultsErrorMessage) + $deploymentResult.filePath = $parameters.TemplateFile + $deploymentResult.results = ('{0}WhatIf prediction failed with error - validate changes manually before merging:{0}{1}' -f [environment]::NewLine, $resultsErrorMessage) } } else { @@ -195,10 +208,13 @@ Write-PSFMessage -Level Verbose -String 'New-AzOpsDeployment.WhatIfResults' -StringValues ($results | Out-String) -Target $scopeObject Write-PSFMessage -Level Verbose -String 'New-AzOpsDeployment.WhatIfFile' -Target $scopeObject if ($parameters.TemplateParameterFile) { - Set-AzOpsWhatIfOutput -FilePath $parameters.TemplateFile -ParameterFilePath $parameters.TemplateParameterFile -Results $results + $deploymentResult.filePath = $parameters.TemplateFile + $deploymentResult.parameterFilePath = $parameters.TemplateParameterFile + $deploymentResult.results = $results } else { - Set-AzOpsWhatIfOutput -FilePath $parameters.TemplateFile -Results $results + $deploymentResult.filePath = $parameters.TemplateFile + $deploymentResult.results = $results } } # Remove ExcludeChangeType parameter as it doesn't exist for deployment cmdlets @@ -216,5 +232,9 @@ Write-PSFMessage -Level Verbose -String 'New-AzOpsDeployment.SkipDueToWhatIf' } } + #Return + if ($deploymentResult) { + return $deploymentResult + } } } \ No newline at end of file diff --git a/src/localized/en-us/Strings.psd1 b/src/localized/en-us/Strings.psd1 index 390e59b5..588ec637 100644 --- a/src/localized/en-us/Strings.psd1 +++ b/src/localized/en-us/Strings.psd1 @@ -189,6 +189,11 @@ 'Invoke-AzOpsPush.Deploy.ResourceProvider' = 'Invoking new state deployment - *.resourceproviders.json for a file {0}' # $addition 'Invoke-AzOpsPush.Deploy.Subscription' = 'Invoking new state deployment - *.subscription.json for a file {0}' # $addition 'Invoke-AzOpsPush.Deployment.Required' = 'Deployment required' # + 'Invoke-AzOpsPush.Deployment.Parallel' = 'Running parallel deployments of {1} items with matching TemplateFilePath: {0}' # $deployment, $targets + 'Invoke-AzOpsPush.Deployment.Serial' = 'Running {0} serial deployments' # $uniqueDeployment + 'Invoke-AzOpsPush.Deployment.Skip' = 'Skipping deployment of template: {0} with parameter: {1}, its already been deployed' # $deployment.TemplateFilePath, $deployment.TemplateParameterFilePath + 'Invoke-AzOpsPush.Deployment.ParallelCondition' = 'Parallel deployment condition true' # + 'Invoke-AzOpsPush.Deployment.ParallelGroup' = 'Identified {0} group of deployments with matching TemplateFilePath' # $groups 'Invoke-AzOpsPush.Dependency.Missing' = 'Missing resource dependency for successfull deletion. Error exiting runtime.' 'Invoke-AzOpsPush.DeploymentList.NotFound' = 'Expecting deploymentList object, it was not found. Error exiting runtime.' 'Invoke-AzOpsPush.Resolve.FoundTemplate' = 'Found template {1} for parameters {0}' # $FilePath, $templatePath From 9d68a01d0e6d58dfa901ca3d237b2285a80d773b Mon Sep 17 00:00:00 2001 From: Jesper Fajers Date: Thu, 21 Dec 2023 23:51:48 +0000 Subject: [PATCH 02/20] Update --- src/functions/Invoke-AzOpsPush.ps1 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/functions/Invoke-AzOpsPush.ps1 b/src/functions/Invoke-AzOpsPush.ps1 index 7dd62a58..cccf3ddd 100644 --- a/src/functions/Invoke-AzOpsPush.ps1 +++ b/src/functions/Invoke-AzOpsPush.ps1 @@ -419,6 +419,7 @@ # Process each deployment and evaluate serial or parallel deployment pattern foreach ($deployment in $uniqueDeployment) { if ($deployment.TemplateFilePath -in $groups.Name -and $deployment -notin $processedTargets) { + # Deployment part of group association for parallel processing, process entire group as parallel deployment $targets = $($groups | Where-Object { $_.Name -eq $deployment.TemplateFilePath }).Group Write-PSFMessage -Level Verbose @common -String 'Invoke-AzOpsPush.Deployment.Parallel' -StringValues $deployment.TemplateFilePath, $targets.Count # Prepare Input Data for parallel processing @@ -431,6 +432,7 @@ runspace_AzOpsPartialRoot = $script:AzOpsPartialRoot runspace_AzOpsResourceProvider = $script:AzOpsResourceProvider } + # Pass deployment targets for parallel processing and output deployment result for later $deploymentResult += $targets | Foreach-Object -ThrottleLimit (Get-PSFConfigValue -FullName 'AzOps.Core.ThrottleLimit') -Parallel { $deployment = $_ $runspaceData = $using:runspaceData @@ -449,13 +451,16 @@ $deployment | New-AzOpsDeployment -WhatIf:$runspaceData.WhatIfPreference } } + # Add targets to processed list to avoid duplicate deployment $processedTargets += $targets } elseif ($deployment -notin $processedTargets) { + # Deployment not part of group association for parallel processing, process this as serial deployment Write-PSFMessage -Level Verbose @common -String 'Invoke-AzOpsPush.Deployment.Serial' -StringValues $deployment.Count $deploymentResult += $deployment | New-AzOpsDeployment -WhatIf:$WhatIfPreference } else { + # Deployment already processed by group association from parallel processing, skip this duplicate deployment Write-PSFMessage -Level Verbose @common -String 'Invoke-AzOpsPush.Deployment.Skip' -StringValues $deployment.TemplateFilePath, $deployment.TemplateParameterFilePath } } @@ -472,6 +477,7 @@ } if ($deploymentResult) { + #Process deploymentResult and output result foreach ($result in $deploymentResult) { Set-AzOpsWhatIfOutput -FilePath $result.filePath -ParameterFilePath $result.parameterFilePath -Results $result.results } From 5917b7327c8430c88f5b60e55cd8dc54eff546e8 Mon Sep 17 00:00:00 2001 From: Jesper Fajers Date: Fri, 22 Dec 2023 01:02:13 +0000 Subject: [PATCH 03/20] Update --- src/functions/Invoke-AzOpsPush.ps1 | 2 +- src/localized/en-us/Strings.psd1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/functions/Invoke-AzOpsPush.ps1 b/src/functions/Invoke-AzOpsPush.ps1 index cccf3ddd..5b4a1f4e 100644 --- a/src/functions/Invoke-AzOpsPush.ps1 +++ b/src/functions/Invoke-AzOpsPush.ps1 @@ -414,7 +414,7 @@ # Group deployments based on TemplateFilePath $groups = $uniqueDeployment | Group-Object -Property TemplateFilePath | Where-Object { $_.Count -ge '2' -and $_.Name -ne $(Get-Item $AzOpsMainTemplate).FullName } if ($groups) { - Write-PSFMessage -Level Verbose @common -String 'Invoke-AzOpsPush.Deployment.ParallelGroup' -StringValues $groups.Count + Write-PSFMessage -Level Verbose @common -String 'Invoke-AzOpsPush.Deployment.ParallelGroup' $processedTargets = @() # Process each deployment and evaluate serial or parallel deployment pattern foreach ($deployment in $uniqueDeployment) { diff --git a/src/localized/en-us/Strings.psd1 b/src/localized/en-us/Strings.psd1 index 588ec637..de5aef3f 100644 --- a/src/localized/en-us/Strings.psd1 +++ b/src/localized/en-us/Strings.psd1 @@ -193,7 +193,7 @@ 'Invoke-AzOpsPush.Deployment.Serial' = 'Running {0} serial deployments' # $uniqueDeployment 'Invoke-AzOpsPush.Deployment.Skip' = 'Skipping deployment of template: {0} with parameter: {1}, its already been deployed' # $deployment.TemplateFilePath, $deployment.TemplateParameterFilePath 'Invoke-AzOpsPush.Deployment.ParallelCondition' = 'Parallel deployment condition true' # - 'Invoke-AzOpsPush.Deployment.ParallelGroup' = 'Identified {0} group of deployments with matching TemplateFilePath' # $groups + 'Invoke-AzOpsPush.Deployment.ParallelGroup' = 'Identified multiple deployments with matching TemplateFilePath' # $groups 'Invoke-AzOpsPush.Dependency.Missing' = 'Missing resource dependency for successfull deletion. Error exiting runtime.' 'Invoke-AzOpsPush.DeploymentList.NotFound' = 'Expecting deploymentList object, it was not found. Error exiting runtime.' 'Invoke-AzOpsPush.Resolve.FoundTemplate' = 'Found template {1} for parameters {0}' # $FilePath, $templatePath From f14bbf54cb24ff8d7a8759e2c82f3c145f8a8278 Mon Sep 17 00:00:00 2001 From: Jesper Fajers Date: Wed, 27 Dec 2023 09:18:29 +0000 Subject: [PATCH 04/20] Update --- docs/wiki/Frequently-Asked-Questions.md | 21 +++++++++++++++++++ docs/wiki/Settings.md | 11 +++++----- src/functions/Invoke-AzOpsPush.ps1 | 2 +- src/internal/configurations/Core.ps1 | 2 +- .../functions/Set-AzOpsWhatIfOutput.ps1 | 6 +++--- src/localized/en-us/Strings.psd1 | 3 +-- 6 files changed, 33 insertions(+), 12 deletions(-) diff --git a/docs/wiki/Frequently-Asked-Questions.md b/docs/wiki/Frequently-Asked-Questions.md index 53900427..274db810 100644 --- a/docs/wiki/Frequently-Asked-Questions.md +++ b/docs/wiki/Frequently-Asked-Questions.md @@ -17,6 +17,7 @@ This article answers frequently asked questions relating to AzOps. - [**I want to discover and manage several Azure Firewall Policy's and rule collections spread out across several resource groups and subscriptions**](#i-want-to-discover-and-manage-several-azure-firewall-policys-and-rule-collections-spread-out-across-several-resource-groups-and-subscriptions) - [Push scenarios and settings](#push-scenarios-and-settings) - [**I want to have multiple different deployments at scope using the same template file but different parameter files**](#i-want-to-have-multiple-different-deployments-at-scope-using-the-same-template-file-but-different-parameter-files) + - [**I have AllowMultipleTemplateParameterFiles set to true and want deployments performed in parallel**](#i-have-allowmultipletemplateparameterfiles-set-to-true-and-want-deployments-performed-in-parallel) - [**I have AllowMultipleTemplateParameterFiles set to true and when changes are made to a template no deployment is performed**](#i-have-allowmultipletemplateparameterfiles-set-to-true-and-when-changes-are-made-to-a-template-no-deployment-is-performed) - [**I am getting: Missing defaultValue and no parameter file found, skip deployment**](#i-am-getting-missing-defaultvalue-and-no-parameter-file-found-skip-deployment) @@ -185,6 +186,26 @@ scope/ ``` > Note: To avoid having AzOps deploy the base `template.bicep` unintentionally, ensure you have at least one parameter without default value in `template.bicep` and no lingering 1:1 matching parameter file. +### **I have AllowMultipleTemplateParameterFiles set to true and want deployments performed in parallel** + +Can AzOps perform parallel deployments of the below 3 separate parameter files? +```bash +scope/ +├── template.x1.bicepparam +├── template.x2.bicepparam +├── template.x3.parameters.json +└── template.bicep +``` +Yes, ensure the following setting combinations are applied + +```bash + "Core.AllowMultipleTemplateParameterFiles": true + + "Core.ParallelDeployMultipleTemplateParameterFiles": true +``` + +> Note: By default, AzOps performs serial deployments. + ### **I have AllowMultipleTemplateParameterFiles set to true and when changes are made to a template no deployment is performed** When using a custom deployment templates with multiple corresponding parameter files, can I ensure that changes made to the template triggers AzOps to create separate deployments for each corresponding parameter file? diff --git a/docs/wiki/Settings.md b/docs/wiki/Settings.md index d37fa2ad..87b0424f 100644 --- a/docs/wiki/Settings.md +++ b/docs/wiki/Settings.md @@ -35,11 +35,12 @@ The following configuration values can be modified within the `settings.json` fi | 23 | State | Folder to store AzOpsState artefact, defaults to `root` | `"Core.State: "/root"` | | 24 | SubscriptionsToIncludeResourceGroups | Filter which Subscription IDs should include Resource Groups in pull [Logic Updated in v2.0.0](https://github.com/Azure/AzOps/releases/tag/2.0.0) | `"Core.SubscriptionsToIncludeResourceGroups": ["*"]` | | 25 | TemplateParameterFileSuffix | Default template file suffix. *Not recommended to change* | `"Core.TemplateParameterFileSuffix": ".json"` | -| 26 | AllowMultipleTemplateParameterFiles | Control multiple parameter file behaviour. *Not recommended to change* | `"Core.AllowMultipleTemplateParameterFiles": false` | -| 27 | DeployAllMultipleTemplateParameterFiles | Control base template deployment behaviour with changes and un-changed multiple corresponding parameter files. | `"Core.DeployAllMultipleTemplateParameterFiles": false` | -| 28 | MultipleTemplateParameterFileSuffix | Multiple parameter file suffix identifier. *Example mytemplate.x1.bicepparam* | `"Core.MultipleTemplateParameterFileSuffix": ".x"` | -| 29 | ThrottleLimit | Value declaring number of parallel threads. [Read more](https://github.com/azure/azops/wiki/performance-considerations) | `"Core.ThrottleLimit": 5` | -| 30 | WhatifExcludedChangeTypes | Exclude specific change types from WhatIf operations | `"Core.WhatifExcludedChangeTypes": ["NoChange","Ignore"]` | +| 26 | AllowMultipleTemplateParameterFiles | Control multiple parameter file behaviour. *Not recommended to change* | `"Core.AllowMultipleTemplateParameterFiles": false` | +| 27 | DeployAllMultipleTemplateParameterFiles | Control base template deployment behaviour with changes and un-changed multiple corresponding parameter files. | `"Core.DeployAllMultipleTemplateParameterFiles": false` | +| 28 | MultipleTemplateParameterFileSuffix | Multiple parameter file suffix identifier. *Example mytemplate.x1.bicepparam* | `"Core.MultipleTemplateParameterFileSuffix": ".x"` | +| 29 | ParallelDeployMultipleTemplateParameterFiles | Control parallel deployment of MultipleTemplateParameterFiles behaviour | `"Core.ParallelDeployMultipleTemplateParameterFiles": false` | +| 30 | ThrottleLimit | Value declaring number of parallel threads. [Read more](https://github.com/azure/azops/wiki/performance-considerations) | `"Core.ThrottleLimit": 5` | +| 31 | WhatifExcludedChangeTypes | Exclude specific change types from WhatIf operations | `"Core.WhatifExcludedChangeTypes": ["NoChange","Ignore"]` | ## Workflow / Pipeline Settings diff --git a/src/functions/Invoke-AzOpsPush.ps1 b/src/functions/Invoke-AzOpsPush.ps1 index 5b4a1f4e..27e45029 100644 --- a/src/functions/Invoke-AzOpsPush.ps1 +++ b/src/functions/Invoke-AzOpsPush.ps1 @@ -409,7 +409,7 @@ $deploymentResult = @() #Determine what deployment pattern to adopt serial or parallel - if ((Get-PSFConfigValue -FullName 'AzOps.Core.AllowMultipleTemplateParameterFiles') -eq $true -and (Get-PSFConfigValue -FullName 'AzOps.Core.ParallelDeploymentMultipleTemplateParameterFiles') -eq $true) { + if ((Get-PSFConfigValue -FullName 'AzOps.Core.AllowMultipleTemplateParameterFiles') -eq $true -and (Get-PSFConfigValue -FullName 'AzOps.Core.ParallelDeployMultipleTemplateParameterFiles') -eq $true) { Write-PSFMessage -Level Verbose @common -String 'Invoke-AzOpsPush.Deployment.ParallelCondition' # Group deployments based on TemplateFilePath $groups = $uniqueDeployment | Group-Object -Property TemplateFilePath | Where-Object { $_.Count -ge '2' -and $_.Name -ne $(Get-Item $AzOpsMainTemplate).FullName } diff --git a/src/internal/configurations/Core.ps1 b/src/internal/configurations/Core.ps1 index a05d0834..95bb1284 100644 --- a/src/internal/configurations/Core.ps1 +++ b/src/internal/configurations/Core.ps1 @@ -29,6 +29,6 @@ Set-PSFConfig -Module AzOps -Name Core.TemplateParameterFileSuffix -Value '.json Set-PSFConfig -Module AzOps -Name Core.AllowMultipleTemplateParameterFiles -Value $false -Initialize -Validation string -Description 'Global flag to control multiple parameter file behaviour' Set-PSFConfig -Module AzOps -Name Core.DeployAllMultipleTemplateParameterFiles -Value $false -Initialize -Validation string -Description 'Global flag to control base template deployment behaviour with changes and un-changed multiple corresponding parameter files' Set-PSFConfig -Module AzOps -Name Core.MultipleTemplateParameterFileSuffix -Value '.x' -Initialize -Validation string -Description 'Multiple parameter file suffix identifier' -Set-PSFConfig -Module AzOps -Name Core.ParallelDeploymentMultipleTemplateParameterFiles -Value $false -Initialize -Validation string -Description 'Global flag to control parallel deployment of MultipleTemplateParameterFilesbehaviour' +Set-PSFConfig -Module AzOps -Name Core.ParallelDeployMultipleTemplateParameterFiles -Value $false -Initialize -Validation string -Description 'Global flag to control parallel deployment of MultipleTemplateParameterFiles behaviour' Set-PSFConfig -Module AzOps -Name Core.ThrottleLimit -Value 5 -Initialize -Validation integer -Description 'Throttle limit used in Foreach-Object -Parallel for resource/subscription discovery' Set-PSFConfig -Module AzOps -Name Core.WhatifExcludedChangeTypes -Value @('NoChange', 'Ignore') -Initialize -Validation stringarray -Description 'Exclude specific change types from WhatIf operations.' \ No newline at end of file diff --git a/src/internal/functions/Set-AzOpsWhatIfOutput.ps1 b/src/internal/functions/Set-AzOpsWhatIfOutput.ps1 index 5768394a..29f3442f 100644 --- a/src/internal/functions/Set-AzOpsWhatIfOutput.ps1 +++ b/src/internal/functions/Set-AzOpsWhatIfOutput.ps1 @@ -45,9 +45,9 @@ ) process { - Write-PSFMessage -Level Verbose -String 'Set-AzOpsWhatIfOutput.WhatIfFile' $tempPath = [System.IO.Path]::GetTempPath() if ((-not (Test-Path -Path ($tempPath + 'OUTPUT.md'))) -or (-not (Test-Path -Path ($tempPath + 'OUTPUT.json')))) { + Write-PSFMessage -Level Verbose -String 'Set-AzOpsWhatIfOutput.WhatIfFile' New-Item -Path ($tempPath + 'OUTPUT.md') -WhatIf:$false New-Item -Path ($tempPath + 'OUTPUT.json') -WhatIf:$false } @@ -69,7 +69,7 @@ # Gather current OUTPUT.json content $existingContent = @(Get-Content -Path ($tempPath + 'OUTPUT.json') -Raw | ConvertFrom-Json -Depth 100) # Export results to json file - Write-PSFMessage -Level Verbose -String 'Set-AzOpsWhatIfOutput.WhatIfFileAddingJson' + Write-PSFMessage -Level Verbose -String 'Set-AzOpsWhatIfOutput.WhatIfFileAdding' -StringValues 'json', $FilePath, $ParameterFilePath if ($RemoveAzOpsFlag) { $resultJson = [PSCustomObject]@{ WhatIfResult = $Results @@ -105,7 +105,7 @@ } } if ((($mdOutput | Measure-Object -Line -Character -Word).Characters + $existingContentStringMeasureMd.Characters) -le $ResultSizeMaxLimit) { - Write-PSFMessage -Level Verbose -String 'Set-AzOpsWhatIfOutput.WhatIfFileAddingMd' + Write-PSFMessage -Level Verbose -String 'Set-AzOpsWhatIfOutput.WhatIfFileAdding' -StringValues 'markdown', $FilePath, $ParameterFilePath Add-Content -Path ($tempPath + 'OUTPUT.md') -Value $mdOutput -WhatIf:$false } else { diff --git a/src/localized/en-us/Strings.psd1 b/src/localized/en-us/Strings.psd1 index de5aef3f..feb30461 100644 --- a/src/localized/en-us/Strings.psd1 +++ b/src/localized/en-us/Strings.psd1 @@ -299,8 +299,7 @@ 'Set-AzOpsStringLength.WithInLimit' = 'String {0} within limit of {1}' # $String 'Set-AzOpsWhatIfOutput.WhatIfFile' = 'Creating WhatIf markdown and json files' # - 'Set-AzOpsWhatIfOutput.WhatIfFileAddingJson' = 'Adding content to WhatIf json file' # - 'Set-AzOpsWhatIfOutput.WhatIfFileAddingMd' = 'Adding content to WhatIf markdown file' # + 'Set-AzOpsWhatIfOutput.WhatIfFileAdding' = 'Adding content to WhatIf {0} file for template {1} with parameter file {2}' # '', $FilePath, $ParameterFilePath 'Set-AzOpsWhatIfOutput.WhatIfFileMax' = 'WhatIf markdown and json files have reached character limit, unable to append more information to files. WhatIf is too large for comment field, for more details look at PR files to determine changes.' # $ResultSizeMaxLimit, $ResultSizeLimit 'Set-AzOpsWhatIfOutput.WhatIfMessageMax' = 'WhatIf have reached maximum character limit, unable to append warning message. WhatIf is too large for comment field, for more details look at PR files to determine changes.' # $ResultSizeMaxLimit, $ResultSizeLimit 'Set-AzOpsWhatIfOutput.WhatIfResults' = 'WhatIf Output {0}' # $results From bd20f12dac5c284308ae915239472de95cf40695 Mon Sep 17 00:00:00 2001 From: Jesper Fajers Date: Thu, 28 Dec 2023 09:57:10 +0000 Subject: [PATCH 05/20] Update --- src/tests/integration/Repository.Tests.ps1 | 38 +++++++++++++++++++ src/tests/templates/azuredeploy.jsonc | 6 +++ src/tests/templates/staparalleldeploy.bicep | 21 ++++++++++ .../staparalleldeploy.xabcd.bicepparam | 3 ++ .../staparalleldeploy.xabcde.bicepparam | 3 ++ .../staparalleldeploy.xabcdf.bicepparam | 3 ++ src/tests/templates/staserialdeploy2.bicep | 21 ++++++++++ .../staserialdeploy2.xabcdfg.bicepparam | 3 ++ 8 files changed, 98 insertions(+) create mode 100644 src/tests/templates/staparalleldeploy.bicep create mode 100644 src/tests/templates/staparalleldeploy.xabcd.bicepparam create mode 100644 src/tests/templates/staparalleldeploy.xabcde.bicepparam create mode 100644 src/tests/templates/staparalleldeploy.xabcdf.bicepparam create mode 100644 src/tests/templates/staserialdeploy2.bicep create mode 100644 src/tests/templates/staserialdeploy2.xabcdfg.bicepparam diff --git a/src/tests/integration/Repository.Tests.ps1 b/src/tests/integration/Repository.Tests.ps1 index 8182511e..5c5d4db7 100644 --- a/src/tests/integration/Repository.Tests.ps1 +++ b/src/tests/integration/Repository.Tests.ps1 @@ -132,6 +132,7 @@ Describe "Repository" { $script:policySetDefinitionsDep = Get-AzPolicySetDefinition -Name 'TestPolicySetDefinitionDep' -ManagementGroupName $($script:testManagementGroup.Name) $script:subscription = (Get-AzSubscription | Where-Object Id -eq $script:subscriptionId) $script:resourceGroup = (Get-AzResourceGroup | Where-Object ResourceGroupName -eq "App1-azopsrg") + $script:resourceGroupParallelDeploy = (Get-AzResourceGroup | Where-Object ResourceGroupName -eq "ParallelDeploy-azopsrg") $script:roleAssignments = (Get-AzRoleAssignment -ObjectId "023e7c1c-1fa4-4818-bb78-0a9c5e8b0217" | Where-Object { $_.Scope -eq "/subscriptions/$script:subscriptionId" -and $_.RoleDefinitionId -eq "acdd72a7-3385-48ef-bd42-f606fba81ae7" }) $script:policyExemptions = Get-AzPolicyExemption -Name "PolicyExemptionTest" -Scope "/subscriptions/$script:subscriptionId" $script:routeTable = (Get-AzResource -Name "RouteTable" -ResourceGroupName $($script:resourceGroup).ResourceGroupName) @@ -283,6 +284,11 @@ Describe "Repository" { $script:resourceGroupDeploymentName = "AzOps-{0}-{1}" -f $($script:resourceGroupPath.Name.Replace(".json", '')), $deploymentLocationId Write-PSFMessage -Level Debug -Message "ResourceGroupFile: $($script:resourceGroupFile)" -FunctionName "BeforeAll" + $script:resourceGroupParallelDeployPath = ($filePaths | Where-Object Name -eq "microsoft.resources_resourcegroups-$(($script:resourceGroupParallelDeploy.ResourceGroupName).toLower()).json") + $script:resourceGroupParallelDeployDirectory = ($script:resourceGroupParallelDeployPath).Directory + $script:resourceGroupParallelDeployFile = ($script:resourceGroupParallelDeployPath).FullName + Write-PSFMessage -Level Debug -Message "ParallelDeployResourceGroupFile: $($script:resourceGroupParallelDeployFile)" -FunctionName "BeforeAll" + $script:roleAssignmentsPath = ($filePaths | Where-Object Name -eq "microsoft.authorization_roleassignments-$(($script:roleAssignments.RoleAssignmentId).toLower() -replace ".*/").json") $script:roleAssignmentsDirectory = ($script:roleAssignmentsPath).Directory $script:roleAssignmentsFile = ($script:roleAssignmentsPath).FullName @@ -1114,6 +1120,38 @@ Describe "Repository" { $script:deployAllRtParamPathDeployment.Count | Should -Be 2 } #endregion + + #region Multiple deployments to test parallel deployment logic + It "Deploy parallel storage accounts and compare to serial timing" { + Set-PSFConfig -FullName AzOps.Core.AllowMultipleTemplateParameterFiles -Value $true + Set-PSFConfig -FullName AzOps.Core.DeployAllMultipleTemplateParameterFiles -Value $true + Set-PSFConfig -FullName AzOps.Core.ParallelDeployMultipleTemplateParameterFiles -Value $true + $script:deployAllSta1ParamPath = Get-ChildItem -Path "$($global:testRoot)/templates/staparalleldeploy*" | Copy-Item -Destination $script:resourceGroupParallelDeployDirectory -PassThru -Force + $script:deployAllSta2ParamPath = Get-ChildItem -Path "$($global:testRoot)/templates/staserialdeploy*" | Copy-Item -Destination $script:resourceGroupParallelDeployDirectory -PassThru -Force + $changeSet = @( + "A`t$($script:deployAllSta1ParamPath.FullName[0])", + "A`t$($script:deployAllSta2ParamPath.FullName[0])" + ) + {Invoke-AzOpsPush -ChangeSet $changeSet} | Should -Not -Throw + Start-Sleep -Seconds 10 + $script:deployAllStaParamPathDeployment = Get-AzResource -ResourceGroupName $($script:resourceGroupParallelDeploy).ResourceGroupName -ResourceType 'Microsoft.Storage/storageAccounts' + $script:deployAllStaParamPathDeployment.Count | Should -Be 4 + $query = "resourcechanges | where resourceGroup == '$($($script:resourceGroupParallelDeploy).ResourceGroupName)' and properties.targetResourceType == 'microsoft.storage/storageaccounts' and properties.changeType == 'Create' | extend changeTime=todatetime(properties.changeAttributes.timestamp) | project changeTime, properties.changeType, properties.targetResourceId, properties.targetResourceType, properties.changes | order by changeTime asc" + $createTime = Search-AzGraph -Query $query + # Calculate differences between creation timing + $diff1 = New-TimeSpan -Start $createTime.changeTime[0] -End $createTime.changeTime[1] + $diff2 = New-TimeSpan -Start $createTime.changeTime[0] -End $createTime.changeTime[2] + $diff3 = New-TimeSpan -Start $createTime.changeTime[1] -End $createTime.changeTime[2] + $diff4 = New-TimeSpan -Start $createTime.changeTime[0] -End $createTime.changeTime[3] + # Check if time difference is within x seconds + $allowedDiff = '8' + if ($diff1.TotalSeconds -le $allowedDiff -or $diff2.TotalSeconds -le $allowedDiff -or $diff3.TotalSeconds -le $allowedDiff -and $diff4.TotalSeconds -ge $allowedDiff) { + # Time difference is within x seconds of each other + $timeTest = "good" + } + $timeTest | Should -Be 'good' + } + #endregion } AfterAll { diff --git a/src/tests/templates/azuredeploy.jsonc b/src/tests/templates/azuredeploy.jsonc index d8a378f7..90d16405 100644 --- a/src/tests/templates/azuredeploy.jsonc +++ b/src/tests/templates/azuredeploy.jsonc @@ -518,6 +518,12 @@ "name": "Lock2-azopsrg", "location": "northeurope" }, + { + "type": "Microsoft.Resources/resourceGroups", + "apiVersion": "2019-10-01", + "name": "ParallelDeploy-azopsrg", + "location": "northeurope" + }, { "type": "Microsoft.Authorization/roleAssignments", "apiVersion": "2021-04-01-preview", diff --git a/src/tests/templates/staparalleldeploy.bicep b/src/tests/templates/staparalleldeploy.bicep new file mode 100644 index 00000000..ebe95f2c --- /dev/null +++ b/src/tests/templates/staparalleldeploy.bicep @@ -0,0 +1,21 @@ +param staName string +param location string = resourceGroup().location + +var storageName = '${toLower(staName)}${uniqueString(resourceGroup().id)}' + +resource storage_resource 'Microsoft.Storage/storageAccounts@2021-08-01' = { + name: storageName + location: location + kind: 'StorageV2' + sku: { + name: 'Standard_GZRS' + } + properties: { + minimumTlsVersion: 'TLS1_2' + networkAcls: { + bypass: 'None' + defaultAction: 'Deny' + } + supportsHttpsTrafficOnly: true + } +} diff --git a/src/tests/templates/staparalleldeploy.xabcd.bicepparam b/src/tests/templates/staparalleldeploy.xabcd.bicepparam new file mode 100644 index 00000000..0a38a67b --- /dev/null +++ b/src/tests/templates/staparalleldeploy.xabcd.bicepparam @@ -0,0 +1,3 @@ +using './staparalleldeploy.bicep' + +param staName = 'p1azops' diff --git a/src/tests/templates/staparalleldeploy.xabcde.bicepparam b/src/tests/templates/staparalleldeploy.xabcde.bicepparam new file mode 100644 index 00000000..87762ee7 --- /dev/null +++ b/src/tests/templates/staparalleldeploy.xabcde.bicepparam @@ -0,0 +1,3 @@ +using './staparalleldeploy.bicep' + +param staName = 'p2azops' diff --git a/src/tests/templates/staparalleldeploy.xabcdf.bicepparam b/src/tests/templates/staparalleldeploy.xabcdf.bicepparam new file mode 100644 index 00000000..10236da8 --- /dev/null +++ b/src/tests/templates/staparalleldeploy.xabcdf.bicepparam @@ -0,0 +1,3 @@ +using './staparalleldeploy.bicep' + +param staName = 'p3azops' diff --git a/src/tests/templates/staserialdeploy2.bicep b/src/tests/templates/staserialdeploy2.bicep new file mode 100644 index 00000000..ebe95f2c --- /dev/null +++ b/src/tests/templates/staserialdeploy2.bicep @@ -0,0 +1,21 @@ +param staName string +param location string = resourceGroup().location + +var storageName = '${toLower(staName)}${uniqueString(resourceGroup().id)}' + +resource storage_resource 'Microsoft.Storage/storageAccounts@2021-08-01' = { + name: storageName + location: location + kind: 'StorageV2' + sku: { + name: 'Standard_GZRS' + } + properties: { + minimumTlsVersion: 'TLS1_2' + networkAcls: { + bypass: 'None' + defaultAction: 'Deny' + } + supportsHttpsTrafficOnly: true + } +} diff --git a/src/tests/templates/staserialdeploy2.xabcdfg.bicepparam b/src/tests/templates/staserialdeploy2.xabcdfg.bicepparam new file mode 100644 index 00000000..2cde6083 --- /dev/null +++ b/src/tests/templates/staserialdeploy2.xabcdfg.bicepparam @@ -0,0 +1,3 @@ +using './staserialdeploy2.bicep' + +param staName = 's1azops' From db98fd4d7941384be5203da5916a7f5c1b888399 Mon Sep 17 00:00:00 2001 From: Jesper Fajers Date: Thu, 28 Dec 2023 14:42:06 +0000 Subject: [PATCH 06/20] Update --- src/internal/functions/New-AzOpsDeployment.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/internal/functions/New-AzOpsDeployment.ps1 b/src/internal/functions/New-AzOpsDeployment.ps1 index 2fe111f7..63e36ecf 100644 --- a/src/internal/functions/New-AzOpsDeployment.ps1 +++ b/src/internal/functions/New-AzOpsDeployment.ps1 @@ -224,7 +224,7 @@ $parameters.Name = $DeploymentName if ($PSCmdlet.ShouldProcess("Start $($scopeObject.type) Deployment with $deploymentCommand?")) { if (-not $invalidTemplate) { - & $deploymentCommand @parameters + & $deploymentCommand @parameters | Out-Null } } else { From e5654444fee8aff452124d4b966e170970e5ae97 Mon Sep 17 00:00:00 2001 From: Jesper Fajers Date: Thu, 28 Dec 2023 16:02:54 +0000 Subject: [PATCH 07/20] Update --- src/tests/integration/Repository.Tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/integration/Repository.Tests.ps1 b/src/tests/integration/Repository.Tests.ps1 index 5c5d4db7..3539c7d1 100644 --- a/src/tests/integration/Repository.Tests.ps1 +++ b/src/tests/integration/Repository.Tests.ps1 @@ -1137,7 +1137,7 @@ Describe "Repository" { $script:deployAllStaParamPathDeployment = Get-AzResource -ResourceGroupName $($script:resourceGroupParallelDeploy).ResourceGroupName -ResourceType 'Microsoft.Storage/storageAccounts' $script:deployAllStaParamPathDeployment.Count | Should -Be 4 $query = "resourcechanges | where resourceGroup == '$($($script:resourceGroupParallelDeploy).ResourceGroupName)' and properties.targetResourceType == 'microsoft.storage/storageaccounts' and properties.changeType == 'Create' | extend changeTime=todatetime(properties.changeAttributes.timestamp) | project changeTime, properties.changeType, properties.targetResourceId, properties.targetResourceType, properties.changes | order by changeTime asc" - $createTime = Search-AzGraph -Query $query + $createTime = Search-AzGraph -Query $query -Subscription $script:subscriptionId # Calculate differences between creation timing $diff1 = New-TimeSpan -Start $createTime.changeTime[0] -End $createTime.changeTime[1] $diff2 = New-TimeSpan -Start $createTime.changeTime[0] -End $createTime.changeTime[2] From c823c7f14e7d531c1f3ac0025bbfb988edd295cd Mon Sep 17 00:00:00 2001 From: Jesper Fajers Date: Fri, 29 Dec 2023 09:56:21 +0000 Subject: [PATCH 08/20] Update --- src/tests/integration/Repository.Tests.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/integration/Repository.Tests.ps1 b/src/tests/integration/Repository.Tests.ps1 index 3539c7d1..31023e55 100644 --- a/src/tests/integration/Repository.Tests.ps1 +++ b/src/tests/integration/Repository.Tests.ps1 @@ -1133,10 +1133,10 @@ Describe "Repository" { "A`t$($script:deployAllSta2ParamPath.FullName[0])" ) {Invoke-AzOpsPush -ChangeSet $changeSet} | Should -Not -Throw - Start-Sleep -Seconds 10 + Start-Sleep -Seconds 30 $script:deployAllStaParamPathDeployment = Get-AzResource -ResourceGroupName $($script:resourceGroupParallelDeploy).ResourceGroupName -ResourceType 'Microsoft.Storage/storageAccounts' $script:deployAllStaParamPathDeployment.Count | Should -Be 4 - $query = "resourcechanges | where resourceGroup == '$($($script:resourceGroupParallelDeploy).ResourceGroupName)' and properties.targetResourceType == 'microsoft.storage/storageaccounts' and properties.changeType == 'Create' | extend changeTime=todatetime(properties.changeAttributes.timestamp) | project changeTime, properties.changeType, properties.targetResourceId, properties.targetResourceType, properties.changes | order by changeTime asc" + $query = "resourcechanges | where resourceGroup =~ '$($($script:resourceGroupParallelDeploy).ResourceGroupName)' and properties.targetResourceType == 'microsoft.storage/storageaccounts' and properties.changeType == 'Create' | extend changeTime=todatetime(properties.changeAttributes.timestamp), targetResourceId=tostring(properties.targetResourceId) | summarize arg_max(changeTime, *) by targetResourceId | project changeTime, targetResourceId, properties.changeType, properties.targetResourceType | order by changeTime asc" $createTime = Search-AzGraph -Query $query -Subscription $script:subscriptionId # Calculate differences between creation timing $diff1 = New-TimeSpan -Start $createTime.changeTime[0] -End $createTime.changeTime[1] From 1ab07fb3b05160ce75327a759e137972d3d1b475 Mon Sep 17 00:00:00 2001 From: Jesper Fajers Date: Fri, 29 Dec 2023 11:22:13 +0000 Subject: [PATCH 09/20] Update --- src/tests/integration/Repository.Tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/integration/Repository.Tests.ps1 b/src/tests/integration/Repository.Tests.ps1 index 31023e55..ec89b013 100644 --- a/src/tests/integration/Repository.Tests.ps1 +++ b/src/tests/integration/Repository.Tests.ps1 @@ -1145,7 +1145,7 @@ Describe "Repository" { $diff4 = New-TimeSpan -Start $createTime.changeTime[0] -End $createTime.changeTime[3] # Check if time difference is within x seconds $allowedDiff = '8' - if ($diff1.TotalSeconds -le $allowedDiff -or $diff2.TotalSeconds -le $allowedDiff -or $diff3.TotalSeconds -le $allowedDiff -and $diff4.TotalSeconds -ge $allowedDiff) { + if ($diff1.TotalSeconds -le $allowedDiff -and $diff2.TotalSeconds -le $allowedDiff -and $diff3.TotalSeconds -le $allowedDiff -and $diff4.TotalSeconds -ge $allowedDiff) { # Time difference is within x seconds of each other $timeTest = "good" } From 50cffa5615ae203417f8f788180a9477dcc74aa7 Mon Sep 17 00:00:00 2001 From: Jesper Fajers Date: Tue, 2 Jan 2024 12:58:51 +0000 Subject: [PATCH 10/20] Update --- src/internal/classes/AzOpsScope.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/src/internal/classes/AzOpsScope.ps1 b/src/internal/classes/AzOpsScope.ps1 index b5c99586..5155337c 100644 --- a/src/internal/classes/AzOpsScope.ps1 +++ b/src/internal/classes/AzOpsScope.ps1 @@ -371,7 +371,6 @@ return $null } [string] IsResourceProvider() { - if ($this.Scope -match $this.regex_managementgroupProvider) { return (($this.regex_managementgroupProvider.Split($this.Scope) | Select-Object -last 1) -split '/')[1] } From b463b3727801bed76eaeea071a977db3c82ff899 Mon Sep 17 00:00:00 2001 From: Jesper Fajers Date: Tue, 2 Jan 2024 14:48:51 +0000 Subject: [PATCH 11/20] Update ScopeCorrection --- src/functions/Invoke-AzOpsPush.ps1 | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/functions/Invoke-AzOpsPush.ps1 b/src/functions/Invoke-AzOpsPush.ps1 index 27e45029..96f63c41 100644 --- a/src/functions/Invoke-AzOpsPush.ps1 +++ b/src/functions/Invoke-AzOpsPush.ps1 @@ -104,12 +104,18 @@ if (Test-Path $templatePath) { Write-PSFMessage -Level Verbose @common -String 'Invoke-AzOpsPush.Resolve.FoundTemplate' -StringValues $FilePath, $templatePath $result.TemplateFilePath = $templatePath + $newScopeObject = New-AzOpsScope -Path $result.TemplateFilePath -StatePath $StatePath -ErrorAction Stop + $result.ScopeObject = $newScopeObject + $result.Scope = $newScopeObject.Scope return $result } elseif (Test-Path $bicepTemplatePath) { Write-PSFMessage -Level Verbose @common -String 'Invoke-AzOpsPush.Resolve.FoundBicepTemplate' -StringValues $FilePath, $bicepTemplatePath $transpiledTemplatePaths = ConvertFrom-AzOpsBicepTemplate -BicepTemplatePath $bicepTemplatePath -SkipParam $result.TemplateFilePath = $transpiledTemplatePaths.transpiledTemplatePath + $newScopeObject = New-AzOpsScope -Path $result.TemplateFilePath -StatePath $StatePath -ErrorAction Stop + $result.ScopeObject = $newScopeObject + $result.Scope = $newScopeObject.Scope return $result } } @@ -126,6 +132,9 @@ $transpiledTemplatePaths = ConvertFrom-AzOpsBicepTemplate -BicepTemplatePath $bicepTemplatePath -BicepParamTemplatePath $fileItem.FullName $result.TemplateFilePath = $transpiledTemplatePaths.transpiledTemplatePath $result.TemplateParameterFilePath = $transpiledTemplatePaths.transpiledParametersPath + $newScopeObject = New-AzOpsScope -Path $result.TemplateFilePath -StatePath $StatePath -ErrorAction Stop + $result.ScopeObject = $newScopeObject + $result.Scope = $newScopeObject.Scope return $result } } From 0bae4311b81b098063efa33b6f0162d249d7fcd9 Mon Sep 17 00:00:00 2001 From: Jesper Fajers Date: Tue, 2 Jan 2024 20:43:07 +0000 Subject: [PATCH 12/20] Update --- src/functions/Invoke-AzOpsPush.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/functions/Invoke-AzOpsPush.ps1 b/src/functions/Invoke-AzOpsPush.ps1 index 96f63c41..ee76e395 100644 --- a/src/functions/Invoke-AzOpsPush.ps1 +++ b/src/functions/Invoke-AzOpsPush.ps1 @@ -459,7 +459,7 @@ & $azOps { $deployment | New-AzOpsDeployment -WhatIf:$runspaceData.WhatIfPreference } - } + } -UseNewRunspace # Add targets to processed list to avoid duplicate deployment $processedTargets += $targets } From e5f2aafbdef7ba855cd4f1b85188b4778b454381 Mon Sep 17 00:00:00 2001 From: Jesper Fajers Date: Wed, 3 Jan 2024 11:08:03 +0000 Subject: [PATCH 13/20] Update --- src/functions/Initialize-AzOpsEnvironment.ps1 | 2 + src/functions/Invoke-AzOpsPush.ps1 | 4 +- .../ConvertFrom-AzOpsBicepTemplate.ps1 | 42 +++++++++++-------- 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/src/functions/Initialize-AzOpsEnvironment.ps1 b/src/functions/Initialize-AzOpsEnvironment.ps1 index 33cbc621..418a12bf 100644 --- a/src/functions/Initialize-AzOpsEnvironment.ps1 +++ b/src/functions/Initialize-AzOpsEnvironment.ps1 @@ -113,6 +113,8 @@ $script:AzOpsResourceProvider = Get-AzResourceProvider -ListAvailable $script:AzOpsAzManagementGroup = @() $script:AzOpsPartialRoot = @() + $script:AzOpsTranspiledTemplate = @() + $script:AzOpsTranspiledParameter = @() #endregion Initialize & Prepare #region Management Group Processing diff --git a/src/functions/Invoke-AzOpsPush.ps1 b/src/functions/Invoke-AzOpsPush.ps1 index ee76e395..fe78276d 100644 --- a/src/functions/Invoke-AzOpsPush.ps1 +++ b/src/functions/Invoke-AzOpsPush.ps1 @@ -420,8 +420,8 @@ #Determine what deployment pattern to adopt serial or parallel if ((Get-PSFConfigValue -FullName 'AzOps.Core.AllowMultipleTemplateParameterFiles') -eq $true -and (Get-PSFConfigValue -FullName 'AzOps.Core.ParallelDeployMultipleTemplateParameterFiles') -eq $true) { Write-PSFMessage -Level Verbose @common -String 'Invoke-AzOpsPush.Deployment.ParallelCondition' - # Group deployments based on TemplateFilePath - $groups = $uniqueDeployment | Group-Object -Property TemplateFilePath | Where-Object { $_.Count -ge '2' -and $_.Name -ne $(Get-Item $AzOpsMainTemplate).FullName } + # Group deployments based on TemplateFilePath and Scope + $groups = $uniqueDeployment | Group-Object -Property TemplateFilePath, Scope | Where-Object { $_.Count -ge '2' -and $_.Name -ne $(Get-Item $AzOpsMainTemplate).FullName } if ($groups) { Write-PSFMessage -Level Verbose @common -String 'Invoke-AzOpsPush.Deployment.ParallelGroup' $processedTargets = @() diff --git a/src/internal/functions/ConvertFrom-AzOpsBicepTemplate.ps1 b/src/internal/functions/ConvertFrom-AzOpsBicepTemplate.ps1 index 27e66a97..b81bede3 100644 --- a/src/internal/functions/ConvertFrom-AzOpsBicepTemplate.ps1 +++ b/src/internal/functions/ConvertFrom-AzOpsBicepTemplate.ps1 @@ -31,15 +31,18 @@ Assert-AzOpsBicepDependency -Cmdlet $PSCmdlet } process { - # Convert bicep template - $transpiledTemplatePath = $BicepTemplatePath -replace '\.bicep', '.json' - Write-PSFMessage -Level Verbose -String 'ConvertFrom-AzOpsBicepTemplate.Resolve.ConvertBicepTemplate' -StringValues $BicepTemplatePath, $transpiledTemplatePath - Invoke-AzOpsNativeCommand -ScriptBlock { bicep build $bicepTemplatePath --outfile $transpiledTemplatePath } - # Check if bicep build created (ARM) template - if (-not (Test-Path $transpiledTemplatePath)) { - # If bicep build did not produce file exit with error - Write-PSFMessage -Level Error -String 'ConvertFrom-AzOpsBicepTemplate.Resolve.ConvertBicepTemplate.Error' -StringValues $BicepTemplatePath - throw + $transpiledTemplatePath = [IO.Path]::GetFullPath("$($BicepTemplatePath -replace '\.bicep', '.json')") + if ($transpiledTemplatePath -notin $script:AzOpsTranspiledTemplate) { + # Convert bicep template + Write-PSFMessage -Level Verbose -String 'ConvertFrom-AzOpsBicepTemplate.Resolve.ConvertBicepTemplate' -StringValues $BicepTemplatePath, $transpiledTemplatePath + Invoke-AzOpsNativeCommand -ScriptBlock { bicep build $bicepTemplatePath --outfile $transpiledTemplatePath } + $script:AzOpsTranspiledTemplate += $transpiledTemplatePath + # Check if bicep build created (ARM) template + if (-not (Test-Path $transpiledTemplatePath)) { + # If bicep build did not produce file exit with error + Write-PSFMessage -Level Error -String 'ConvertFrom-AzOpsBicepTemplate.Resolve.ConvertBicepTemplate.Error' -StringValues $BicepTemplatePath + throw + } } if (-not $SkipParam) { if (-not $BicepParamTemplatePath) { @@ -53,15 +56,18 @@ Write-PSFMessage -Level Verbose -String 'ConvertFrom-AzOpsBicepTemplate.Resolve.BicepParam' -StringValues $BicepTemplatePath, $bicepParametersPath } if ($bicepParametersPath -and (Test-Path $bicepParametersPath)) { - # Convert bicepparam to ARM parameter file - $transpiledParametersPath = $bicepParametersPath -replace '\.bicepparam', '.parameters.json' - Write-PSFMessage -Level Verbose -String 'ConvertFrom-AzOpsBicepTemplate.Resolve.ConvertBicepParam' -StringValues $bicepParametersPath, $transpiledParametersPath - Invoke-AzOpsNativeCommand -ScriptBlock { bicep build-params $bicepParametersPath --outfile $transpiledParametersPath } - # Check if bicep build-params created (ARM) parameters - if (-not (Test-Path $transpiledParametersPath)) { - # If bicep build-params did not produce file exit with error - Write-PSFMessage -Level Error -String 'ConvertFrom-AzOpsBicepTemplate.Resolve.ConvertBicepParam.Error' -StringValues $bicepParametersPath - throw + $transpiledParametersPath = [IO.Path]::GetFullPath("$($bicepParametersPath -replace '\.bicepparam', '.parameters.json')") + if ($transpiledParametersPath -notin $script:AzOpsTranspiledParameter) { + # Convert bicepparam to ARM parameter file + Write-PSFMessage -Level Verbose -String 'ConvertFrom-AzOpsBicepTemplate.Resolve.ConvertBicepParam' -StringValues $bicepParametersPath, $transpiledParametersPath + Invoke-AzOpsNativeCommand -ScriptBlock { bicep build-params $bicepParametersPath --outfile $transpiledParametersPath } + $script:AzOpsTranspiledParameter += $transpiledParametersPath + # Check if bicep build-params created (ARM) parameters + if (-not (Test-Path $transpiledParametersPath)) { + # If bicep build-params did not produce file exit with error + Write-PSFMessage -Level Error -String 'ConvertFrom-AzOpsBicepTemplate.Resolve.ConvertBicepParam.Error' -StringValues $bicepParametersPath + throw + } } } else { From 4a3fd1003e58804770be44abf5599d0f3a6275f0 Mon Sep 17 00:00:00 2001 From: Jesper Fajers Date: Wed, 3 Jan 2024 11:57:23 +0000 Subject: [PATCH 14/20] Update --- src/functions/Invoke-AzOpsPush.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/functions/Invoke-AzOpsPush.ps1 b/src/functions/Invoke-AzOpsPush.ps1 index fe78276d..ee76e395 100644 --- a/src/functions/Invoke-AzOpsPush.ps1 +++ b/src/functions/Invoke-AzOpsPush.ps1 @@ -420,8 +420,8 @@ #Determine what deployment pattern to adopt serial or parallel if ((Get-PSFConfigValue -FullName 'AzOps.Core.AllowMultipleTemplateParameterFiles') -eq $true -and (Get-PSFConfigValue -FullName 'AzOps.Core.ParallelDeployMultipleTemplateParameterFiles') -eq $true) { Write-PSFMessage -Level Verbose @common -String 'Invoke-AzOpsPush.Deployment.ParallelCondition' - # Group deployments based on TemplateFilePath and Scope - $groups = $uniqueDeployment | Group-Object -Property TemplateFilePath, Scope | Where-Object { $_.Count -ge '2' -and $_.Name -ne $(Get-Item $AzOpsMainTemplate).FullName } + # Group deployments based on TemplateFilePath + $groups = $uniqueDeployment | Group-Object -Property TemplateFilePath | Where-Object { $_.Count -ge '2' -and $_.Name -ne $(Get-Item $AzOpsMainTemplate).FullName } if ($groups) { Write-PSFMessage -Level Verbose @common -String 'Invoke-AzOpsPush.Deployment.ParallelGroup' $processedTargets = @() From 52fb37da60de24db21701349f112d17f419286af Mon Sep 17 00:00:00 2001 From: Jesper Fajers Date: Wed, 3 Jan 2024 16:35:11 +0000 Subject: [PATCH 15/20] Update --- src/internal/functions/Set-AzOpsContext.ps1 | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/internal/functions/Set-AzOpsContext.ps1 b/src/internal/functions/Set-AzOpsContext.ps1 index 10134e50..d8566fea 100644 --- a/src/internal/functions/Set-AzOpsContext.ps1 +++ b/src/internal/functions/Set-AzOpsContext.ps1 @@ -6,7 +6,7 @@ .DESCRIPTION Changes the currently active azure context to the subscription of the specified scope object. .PARAMETER ScopeObject - The scope object into which context to change. + The scope object [AzOpsScope] into which context to change. .EXAMPLE > Set-AzOpsContext -ScopeObject $scopeObject Changes the current context to the subscription of $scopeObject. @@ -15,7 +15,6 @@ [CmdletBinding()] param ( [Parameter(Mandatory = $true)] - [AzOpsScope] $ScopeObject ) @@ -25,7 +24,6 @@ process { if (-not $ScopeObject.Subscription) { return } - if ($context.Subscription.Id -ne $ScopeObject.Subscription) { Write-PSFMessage -Level Verbose -String 'Set-AzOpsContext.Change' -StringValues $context.Subscription.Name, $ScopeObject.SubscriptionDisplayName, $ScopeObject.Subscription Set-AzContext -SubscriptionId $scopeObject.Subscription -WhatIf:$false From cc28e0b0fc67e59324ed6473327140d5bb91caaa Mon Sep 17 00:00:00 2001 From: Jesper Fajers Date: Thu, 4 Jan 2024 09:59:26 +0000 Subject: [PATCH 16/20] Update Test Trigger --- .github/workflows/tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8f5b2d93..51675dc1 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -8,6 +8,7 @@ on: branches: [main] paths: - "src/**" + - "!src/AzOps.psd1" permissions: id-token: write From 1d056a955074bd7249231f36c9796756f31a32c5 Mon Sep 17 00:00:00 2001 From: Jesper Fajers Date: Thu, 4 Jan 2024 18:01:49 +0000 Subject: [PATCH 17/20] Update --- src/functions/Invoke-AzOpsPush.ps1 | 2 ++ src/internal/functions/New-AzOpsDeployment.ps1 | 3 ++- src/internal/functions/Set-AzOpsWhatIfOutput.ps1 | 4 ++-- .../Microsoft.Authorization/policyAssignments/scenario.ps1 | 2 +- .../Microsoft.Authorization/roleAssignments/scenario.ps1 | 2 +- .../functional/Microsoft.Compute/virtualMachines/scenario.ps1 | 2 +- .../Microsoft.Insights/activityLogAlerts/scenario.ps1 | 2 +- src/tests/functional/Microsoft.KeyVault/vaults/scenario.ps1 | 2 +- src/tests/functional/Microsoft.Logic/workflows/scenario.ps1 | 2 +- .../userAssignedIdentities/scenario.ps1 | 2 +- .../Microsoft.Management/managementGroups/scenario.ps1 | 2 +- .../functional/Microsoft.Network/azureFirewalls/scenario.ps1 | 2 +- .../functional/Microsoft.Network/bastionHosts/scenario.ps1 | 2 +- .../functional/Microsoft.Network/connections/scenario.ps1 | 2 +- .../Microsoft.Network/localNetworkGateways/scenario.ps1 | 2 +- .../Microsoft.Network/networkInterfaces/scenario.ps1 | 2 +- .../Microsoft.Network/networkSecurityGroups/scenario.ps1 | 2 +- .../functional/Microsoft.Network/privateDnsZones/scenario.ps1 | 2 +- .../Microsoft.Network/privateEndpoints/scenario.ps1 | 2 +- .../Microsoft.Network/publicIPAddresses/scenario.ps1 | 2 +- .../functional/Microsoft.Network/routeTables/scenario.ps1 | 2 +- .../functional/Microsoft.Network/virtualNetworks/scenario.ps1 | 2 +- .../Microsoft.Resources/resourceGroups/scenario.ps1 | 2 +- .../functional/Microsoft.Storage/storageAccounts/scenario.ps1 | 2 +- src/tests/functional/Microsoft.Web/serverfarms/scenario.ps1 | 2 +- src/tests/functional/Microsoft.Web/sites/scenario.ps1 | 2 +- 26 files changed, 29 insertions(+), 26 deletions(-) diff --git a/src/functions/Invoke-AzOpsPush.ps1 b/src/functions/Invoke-AzOpsPush.ps1 index ee76e395..1c35ac9c 100644 --- a/src/functions/Invoke-AzOpsPush.ps1 +++ b/src/functions/Invoke-AzOpsPush.ps1 @@ -486,6 +486,8 @@ } if ($deploymentResult) { + # Output deploymentResult outside module + $deploymentResult #Process deploymentResult and output result foreach ($result in $deploymentResult) { Set-AzOpsWhatIfOutput -FilePath $result.filePath -ParameterFilePath $result.parameterFilePath -Results $result.results diff --git a/src/internal/functions/New-AzOpsDeployment.ps1 b/src/internal/functions/New-AzOpsDeployment.ps1 index 63e36ecf..b6577216 100644 --- a/src/internal/functions/New-AzOpsDeployment.ps1 +++ b/src/internal/functions/New-AzOpsDeployment.ps1 @@ -166,6 +166,7 @@ filePath = '' parameterFilePath = '' results = '' + deployment = '' } if ($TemplateParameterFilePath) { $parameters.TemplateParameterFile = $TemplateParameterFilePath @@ -224,7 +225,7 @@ $parameters.Name = $DeploymentName if ($PSCmdlet.ShouldProcess("Start $($scopeObject.type) Deployment with $deploymentCommand?")) { if (-not $invalidTemplate) { - & $deploymentCommand @parameters | Out-Null + $deploymentResult.deployment = & $deploymentCommand @parameters } } else { diff --git a/src/internal/functions/Set-AzOpsWhatIfOutput.ps1 b/src/internal/functions/Set-AzOpsWhatIfOutput.ps1 index 29f3442f..73ca8c7c 100644 --- a/src/internal/functions/Set-AzOpsWhatIfOutput.ps1 +++ b/src/internal/functions/Set-AzOpsWhatIfOutput.ps1 @@ -48,8 +48,8 @@ $tempPath = [System.IO.Path]::GetTempPath() if ((-not (Test-Path -Path ($tempPath + 'OUTPUT.md'))) -or (-not (Test-Path -Path ($tempPath + 'OUTPUT.json')))) { Write-PSFMessage -Level Verbose -String 'Set-AzOpsWhatIfOutput.WhatIfFile' - New-Item -Path ($tempPath + 'OUTPUT.md') -WhatIf:$false - New-Item -Path ($tempPath + 'OUTPUT.json') -WhatIf:$false + New-Item -Path ($tempPath + 'OUTPUT.md') -WhatIf:$false | Out-Null + New-Item -Path ($tempPath + 'OUTPUT.json') -WhatIf:$false | Out-Null } if ($ParameterFilePath) { diff --git a/src/tests/functional/Microsoft.Authorization/policyAssignments/scenario.ps1 b/src/tests/functional/Microsoft.Authorization/policyAssignments/scenario.ps1 index 0b438c66..78169c5e 100644 --- a/src/tests/functional/Microsoft.Authorization/policyAssignments/scenario.ps1 +++ b/src/tests/functional/Microsoft.Authorization/policyAssignments/scenario.ps1 @@ -85,7 +85,7 @@ Describe "Scenario - policyAssignments" { #region Push Test It "Push should be successful" { - $script:push.ProvisioningState | Should -Be "Succeeded" + $script:push.deployment.ProvisioningState | Should -Be "Succeeded" } #endregion Push Test } diff --git a/src/tests/functional/Microsoft.Authorization/roleAssignments/scenario.ps1 b/src/tests/functional/Microsoft.Authorization/roleAssignments/scenario.ps1 index 28b1f9be..faada35f 100644 --- a/src/tests/functional/Microsoft.Authorization/roleAssignments/scenario.ps1 +++ b/src/tests/functional/Microsoft.Authorization/roleAssignments/scenario.ps1 @@ -85,7 +85,7 @@ Describe "Scenario - roleAssignments" { #region Push Test It "Push should be successful" { - $script:push.ProvisioningState | Should -Be "Succeeded" + $script:push.deployment.ProvisioningState | Should -Be "Succeeded" } #endregion Push Test } diff --git a/src/tests/functional/Microsoft.Compute/virtualMachines/scenario.ps1 b/src/tests/functional/Microsoft.Compute/virtualMachines/scenario.ps1 index 99b83c90..9ec4b297 100644 --- a/src/tests/functional/Microsoft.Compute/virtualMachines/scenario.ps1 +++ b/src/tests/functional/Microsoft.Compute/virtualMachines/scenario.ps1 @@ -88,7 +88,7 @@ Describe "Scenario - virtualMachines" { #region Push Test It "Push should be successful" { - $script:push.ProvisioningState | Should -Be "Succeeded" + $script:push.deployment.ProvisioningState | Should -Be "Succeeded" } #endregion Push Test } diff --git a/src/tests/functional/Microsoft.Insights/activityLogAlerts/scenario.ps1 b/src/tests/functional/Microsoft.Insights/activityLogAlerts/scenario.ps1 index 5fe0f97f..5f7fe9ef 100644 --- a/src/tests/functional/Microsoft.Insights/activityLogAlerts/scenario.ps1 +++ b/src/tests/functional/Microsoft.Insights/activityLogAlerts/scenario.ps1 @@ -76,7 +76,7 @@ Describe "Scenario - activityLogAlerts" { #region Push Test It "Push should be successful" { - $script:push.ProvisioningState | Should -Be "Succeeded" + $script:push.deployment.ProvisioningState | Should -Be "Succeeded" } #endregion Push Test } diff --git a/src/tests/functional/Microsoft.KeyVault/vaults/scenario.ps1 b/src/tests/functional/Microsoft.KeyVault/vaults/scenario.ps1 index b817af2c..90888ad8 100644 --- a/src/tests/functional/Microsoft.KeyVault/vaults/scenario.ps1 +++ b/src/tests/functional/Microsoft.KeyVault/vaults/scenario.ps1 @@ -73,7 +73,7 @@ Describe "Scenario - vaults" { #region Push Test It "Push should be successful" { - $script:push.ProvisioningState | Should -Be "Succeeded" + $script:push.deployment.ProvisioningState | Should -Be "Succeeded" } #endregion Push Test } diff --git a/src/tests/functional/Microsoft.Logic/workflows/scenario.ps1 b/src/tests/functional/Microsoft.Logic/workflows/scenario.ps1 index ca576ee8..5d865468 100644 --- a/src/tests/functional/Microsoft.Logic/workflows/scenario.ps1 +++ b/src/tests/functional/Microsoft.Logic/workflows/scenario.ps1 @@ -73,7 +73,7 @@ Describe "Scenario - workflows" { #region Push Test It "Push should be successful" { - $script:push.ProvisioningState | Should -Be "Succeeded" + $script:push.deployment.ProvisioningState | Should -Be "Succeeded" } #endregion Push Test } diff --git a/src/tests/functional/Microsoft.ManagedIdentity/userAssignedIdentities/scenario.ps1 b/src/tests/functional/Microsoft.ManagedIdentity/userAssignedIdentities/scenario.ps1 index dcfa89ae..bb6fd931 100644 --- a/src/tests/functional/Microsoft.ManagedIdentity/userAssignedIdentities/scenario.ps1 +++ b/src/tests/functional/Microsoft.ManagedIdentity/userAssignedIdentities/scenario.ps1 @@ -70,7 +70,7 @@ Describe "Scenario - userAssignedIdentities" { #region Push Test It "Push should be successful" { - $script:push.ProvisioningState | Should -Be "Succeeded" + $script:push.deployment.ProvisioningState | Should -Be "Succeeded" } #endregion Push Test } diff --git a/src/tests/functional/Microsoft.Management/managementGroups/scenario.ps1 b/src/tests/functional/Microsoft.Management/managementGroups/scenario.ps1 index 7a12f97f..f3409c99 100644 --- a/src/tests/functional/Microsoft.Management/managementGroups/scenario.ps1 +++ b/src/tests/functional/Microsoft.Management/managementGroups/scenario.ps1 @@ -67,7 +67,7 @@ Describe "Scenario - managementGroups" { #region Push Test It "Push should be successful" { - $script:push.ProvisioningState | Should -Be "Succeeded" + $script:push.deployment.ProvisioningState | Should -Be "Succeeded" } #endregion Push Test } diff --git a/src/tests/functional/Microsoft.Network/azureFirewalls/scenario.ps1 b/src/tests/functional/Microsoft.Network/azureFirewalls/scenario.ps1 index c84aa053..e69ed1e4 100644 --- a/src/tests/functional/Microsoft.Network/azureFirewalls/scenario.ps1 +++ b/src/tests/functional/Microsoft.Network/azureFirewalls/scenario.ps1 @@ -76,7 +76,7 @@ Describe "Scenario - azureFirewalls" { #region Push Test It "Push should be successful" { - $script:push.ProvisioningState | Should -Be "Succeeded" + $script:push.deployment.ProvisioningState | Should -Be "Succeeded" } #endregion Push Test } diff --git a/src/tests/functional/Microsoft.Network/bastionHosts/scenario.ps1 b/src/tests/functional/Microsoft.Network/bastionHosts/scenario.ps1 index 21dc7e17..3628f3a2 100644 --- a/src/tests/functional/Microsoft.Network/bastionHosts/scenario.ps1 +++ b/src/tests/functional/Microsoft.Network/bastionHosts/scenario.ps1 @@ -76,7 +76,7 @@ Describe "Scenario - bastionHosts" { #region Push Test It "Push should be successful" { - $script:push.ProvisioningState | Should -Be "Succeeded" + $script:push.deployment.ProvisioningState | Should -Be "Succeeded" } #endregion Push Test } diff --git a/src/tests/functional/Microsoft.Network/connections/scenario.ps1 b/src/tests/functional/Microsoft.Network/connections/scenario.ps1 index 78270043..a3d7f884 100644 --- a/src/tests/functional/Microsoft.Network/connections/scenario.ps1 +++ b/src/tests/functional/Microsoft.Network/connections/scenario.ps1 @@ -70,7 +70,7 @@ Describe "Scenario - connections" { #region Push Test It "Push should be successful" { - $script:push.ProvisioningState | Should -Be "Succeeded" + $script:push.deployment.ProvisioningState | Should -Be "Succeeded" } #endregion Push Test } diff --git a/src/tests/functional/Microsoft.Network/localNetworkGateways/scenario.ps1 b/src/tests/functional/Microsoft.Network/localNetworkGateways/scenario.ps1 index 24f30a2d..969e0b8c 100644 --- a/src/tests/functional/Microsoft.Network/localNetworkGateways/scenario.ps1 +++ b/src/tests/functional/Microsoft.Network/localNetworkGateways/scenario.ps1 @@ -73,7 +73,7 @@ Describe "Scenario - localNetworkGateways" { #region Push Test It "Push should be successful" { - $script:push.ProvisioningState | Should -Be "Succeeded" + $script:push.deployment.ProvisioningState | Should -Be "Succeeded" } #endregion Push Test } diff --git a/src/tests/functional/Microsoft.Network/networkInterfaces/scenario.ps1 b/src/tests/functional/Microsoft.Network/networkInterfaces/scenario.ps1 index 17c9530b..9a1c8a65 100644 --- a/src/tests/functional/Microsoft.Network/networkInterfaces/scenario.ps1 +++ b/src/tests/functional/Microsoft.Network/networkInterfaces/scenario.ps1 @@ -73,7 +73,7 @@ Describe "Scenario - networkInterfaces" { #region Push Test It "Push should be successful" { - $script:push.ProvisioningState | Should -Be "Succeeded" + $script:push.deployment.ProvisioningState | Should -Be "Succeeded" } #endregion Push Test } diff --git a/src/tests/functional/Microsoft.Network/networkSecurityGroups/scenario.ps1 b/src/tests/functional/Microsoft.Network/networkSecurityGroups/scenario.ps1 index 650421ef..747e7c60 100644 --- a/src/tests/functional/Microsoft.Network/networkSecurityGroups/scenario.ps1 +++ b/src/tests/functional/Microsoft.Network/networkSecurityGroups/scenario.ps1 @@ -70,7 +70,7 @@ Describe "Scenario - networkSecurityGroups" { #region Push Test It "Push should be successful" { - $script:push.ProvisioningState | Should -Be "Succeeded" + $script:push.deployment.ProvisioningState | Should -Be "Succeeded" } #endregion Push Test } diff --git a/src/tests/functional/Microsoft.Network/privateDnsZones/scenario.ps1 b/src/tests/functional/Microsoft.Network/privateDnsZones/scenario.ps1 index 8355713d..256e715a 100644 --- a/src/tests/functional/Microsoft.Network/privateDnsZones/scenario.ps1 +++ b/src/tests/functional/Microsoft.Network/privateDnsZones/scenario.ps1 @@ -67,7 +67,7 @@ Describe "Scenario - privateDnsZones" { #region Push Test It "Push should be successful" { - $script:push.ProvisioningState | Should -Be "Succeeded" + $script:push.deployment.ProvisioningState | Should -Be "Succeeded" } #endregion Push Test } diff --git a/src/tests/functional/Microsoft.Network/privateEndpoints/scenario.ps1 b/src/tests/functional/Microsoft.Network/privateEndpoints/scenario.ps1 index e238d89b..2d1e681e 100644 --- a/src/tests/functional/Microsoft.Network/privateEndpoints/scenario.ps1 +++ b/src/tests/functional/Microsoft.Network/privateEndpoints/scenario.ps1 @@ -70,7 +70,7 @@ Describe "Scenario - privateEndpoints" { #region Push Test It "Push should be successful" { - $script:push.ProvisioningState | Should -Be "Succeeded" + $script:push.deployment.ProvisioningState | Should -Be "Succeeded" } #endregion Push Test } diff --git a/src/tests/functional/Microsoft.Network/publicIPAddresses/scenario.ps1 b/src/tests/functional/Microsoft.Network/publicIPAddresses/scenario.ps1 index 4bc9c96d..49ae497c 100644 --- a/src/tests/functional/Microsoft.Network/publicIPAddresses/scenario.ps1 +++ b/src/tests/functional/Microsoft.Network/publicIPAddresses/scenario.ps1 @@ -70,7 +70,7 @@ Describe "Scenario - publicIPAddresses" { #region Push Test It "Push should be successful" { - $script:push.ProvisioningState | Should -Be "Succeeded" + $script:push.deployment.ProvisioningState | Should -Be "Succeeded" } #endregion Push Test } diff --git a/src/tests/functional/Microsoft.Network/routeTables/scenario.ps1 b/src/tests/functional/Microsoft.Network/routeTables/scenario.ps1 index 49129d4c..c9a81dcc 100644 --- a/src/tests/functional/Microsoft.Network/routeTables/scenario.ps1 +++ b/src/tests/functional/Microsoft.Network/routeTables/scenario.ps1 @@ -70,7 +70,7 @@ Describe "Scenario - routeTables" { #region Push Test It "Push should be successful" { - $script:push.ProvisioningState | Should -Be "Succeeded" + $script:push.deployment.ProvisioningState | Should -Be "Succeeded" } #endregion Push Test } diff --git a/src/tests/functional/Microsoft.Network/virtualNetworks/scenario.ps1 b/src/tests/functional/Microsoft.Network/virtualNetworks/scenario.ps1 index 403f93f3..1ba692be 100644 --- a/src/tests/functional/Microsoft.Network/virtualNetworks/scenario.ps1 +++ b/src/tests/functional/Microsoft.Network/virtualNetworks/scenario.ps1 @@ -73,7 +73,7 @@ Describe "Scenario - virtualNetworks" { #region Push Test It "Push should be successful" { - $script:push.ProvisioningState | Should -Be "Succeeded" + $script:push.deployment.ProvisioningState | Should -Be "Succeeded" } #endregion Push Test } diff --git a/src/tests/functional/Microsoft.Resources/resourceGroups/scenario.ps1 b/src/tests/functional/Microsoft.Resources/resourceGroups/scenario.ps1 index 5cf05c11..b49e07de 100644 --- a/src/tests/functional/Microsoft.Resources/resourceGroups/scenario.ps1 +++ b/src/tests/functional/Microsoft.Resources/resourceGroups/scenario.ps1 @@ -67,7 +67,7 @@ Describe "Scenario - resourceGroups" { #region Push Test It "Push should be successful" { - $script:push.ProvisioningState | Should -Be "Succeeded" + $script:push.deployment.ProvisioningState | Should -Be "Succeeded" } #endregion Push Test } diff --git a/src/tests/functional/Microsoft.Storage/storageAccounts/scenario.ps1 b/src/tests/functional/Microsoft.Storage/storageAccounts/scenario.ps1 index e802d240..f20811b4 100644 --- a/src/tests/functional/Microsoft.Storage/storageAccounts/scenario.ps1 +++ b/src/tests/functional/Microsoft.Storage/storageAccounts/scenario.ps1 @@ -73,7 +73,7 @@ Describe "Scenario - storageAccounts" { #region Push Test It "Push should be successful" { - $script:push.ProvisioningState | Should -Be "Succeeded" + $script:push.deployment.ProvisioningState | Should -Be "Succeeded" } #endregion Push Test } diff --git a/src/tests/functional/Microsoft.Web/serverfarms/scenario.ps1 b/src/tests/functional/Microsoft.Web/serverfarms/scenario.ps1 index f0256984..a39da9f0 100644 --- a/src/tests/functional/Microsoft.Web/serverfarms/scenario.ps1 +++ b/src/tests/functional/Microsoft.Web/serverfarms/scenario.ps1 @@ -73,7 +73,7 @@ Describe "Scenario - serverfarms" { #region Push Test It "Push should be successful" { - $script:push.ProvisioningState | Should -Be "Succeeded" + $script:push.deployment.ProvisioningState | Should -Be "Succeeded" } #endregion Push Test } diff --git a/src/tests/functional/Microsoft.Web/sites/scenario.ps1 b/src/tests/functional/Microsoft.Web/sites/scenario.ps1 index 3c77ba8f..1df7daba 100644 --- a/src/tests/functional/Microsoft.Web/sites/scenario.ps1 +++ b/src/tests/functional/Microsoft.Web/sites/scenario.ps1 @@ -73,7 +73,7 @@ Describe "Scenario - sites" { #region Push Test It "Push should be successful" { - $script:push.ProvisioningState | Should -Be "Succeeded" + $script:push.deployment.ProvisioningState | Should -Be "Succeeded" } #endregion Push Test } From 0f445680804f2a30c201e4a8de96794e7741c9e8 Mon Sep 17 00:00:00 2001 From: Jesper Fajers Date: Fri, 5 Jan 2024 11:49:06 +0000 Subject: [PATCH 18/20] Update --- src/functions/Initialize-AzOpsEnvironment.ps1 | 2 - src/functions/Invoke-AzOpsPush.ps1 | 42 +++++++++++++++---- .../ConvertFrom-AzOpsBicepTemplate.ps1 | 25 ++++++++--- 3 files changed, 54 insertions(+), 15 deletions(-) diff --git a/src/functions/Initialize-AzOpsEnvironment.ps1 b/src/functions/Initialize-AzOpsEnvironment.ps1 index 418a12bf..33cbc621 100644 --- a/src/functions/Initialize-AzOpsEnvironment.ps1 +++ b/src/functions/Initialize-AzOpsEnvironment.ps1 @@ -113,8 +113,6 @@ $script:AzOpsResourceProvider = Get-AzResourceProvider -ListAvailable $script:AzOpsAzManagementGroup = @() $script:AzOpsPartialRoot = @() - $script:AzOpsTranspiledTemplate = @() - $script:AzOpsTranspiledParameter = @() #endregion Initialize & Prepare #region Management Group Processing diff --git a/src/functions/Invoke-AzOpsPush.ps1 b/src/functions/Invoke-AzOpsPush.ps1 index 1c35ac9c..b94d4e3c 100644 --- a/src/functions/Invoke-AzOpsPush.ps1 +++ b/src/functions/Invoke-AzOpsPush.ps1 @@ -48,12 +48,14 @@ param ( [AzOpsScope] $ScopeObject, - [string] $FilePath, - [string] - $AzOpsMainTemplate + $AzOpsMainTemplate, + [array] + $ConvertedTemplate, + [array] + $ConvertedParameter ) #region Initialization Prep @@ -66,7 +68,9 @@ $result = [PSCustomObject] @{ TemplateFilePath = $null + TranspiledTemplateNew = $false TemplateParameterFilePath = $null + TranspiledParametersNew = $false DeploymentName = $null ScopeObject = $ScopeObject Scope = $ScopeObject.Scope @@ -111,7 +115,8 @@ } elseif (Test-Path $bicepTemplatePath) { Write-PSFMessage -Level Verbose @common -String 'Invoke-AzOpsPush.Resolve.FoundBicepTemplate' -StringValues $FilePath, $bicepTemplatePath - $transpiledTemplatePaths = ConvertFrom-AzOpsBicepTemplate -BicepTemplatePath $bicepTemplatePath -SkipParam + $transpiledTemplatePaths = ConvertFrom-AzOpsBicepTemplate -BicepTemplatePath $bicepTemplatePath -SkipParam -ConvertedTemplate $ConvertedTemplate + $result.TranspiledTemplateNew = $transpiledTemplatePaths.transpiledTemplateNew $result.TemplateFilePath = $transpiledTemplatePaths.transpiledTemplatePath $newScopeObject = New-AzOpsScope -Path $result.TemplateFilePath -StatePath $StatePath -ErrorAction Stop $result.ScopeObject = $newScopeObject @@ -129,7 +134,9 @@ } if (Test-Path $bicepTemplatePath) { Write-PSFMessage -Level Verbose @common -String 'Invoke-AzOpsPush.Resolve.FoundBicepTemplate' -StringValues $FilePath, $bicepTemplatePath - $transpiledTemplatePaths = ConvertFrom-AzOpsBicepTemplate -BicepTemplatePath $bicepTemplatePath -BicepParamTemplatePath $fileItem.FullName + $transpiledTemplatePaths = ConvertFrom-AzOpsBicepTemplate -BicepTemplatePath $bicepTemplatePath -BicepParamTemplatePath $fileItem.FullName -ConvertedTemplate $ConvertedTemplate -ConvertedParameter $ConvertedParameter + $result.TranspiledTemplateNew = $transpiledTemplatePaths.transpiledTemplateNew + $result.TranspiledParametersNew = $transpiledTemplatePaths.transpiledParametersNew $result.TemplateFilePath = $transpiledTemplatePaths.transpiledTemplatePath $result.TemplateParameterFilePath = $transpiledTemplatePaths.transpiledParametersPath $newScopeObject = New-AzOpsScope -Path $result.TemplateFilePath -StatePath $StatePath -ErrorAction Stop @@ -193,7 +200,7 @@ # Process possible parameter files for template equivalent if (($fileItem.FullName.Split('.')[-2] -eq $paramFile.FullName.Split('.')[-3]) -or ($fileItem.FullName.Split('.')[-2] -eq $paramFile.FullName.Split('.')[-4])) { Write-PSFMessage -Level Verbose @common -String 'Invoke-AzOpsPush.Resolve.MultipleTemplateParameterFile' -StringValues $paramFile.FullName - $multiResult += Resolve-ArmFileAssociation -ScopeObject $scopeObject -FilePath $paramFile -AzOpsMainTemplate $AzOpsMainTemplate + $multiResult += Resolve-ArmFileAssociation -ScopeObject $scopeObject -FilePath $paramFile -AzOpsMainTemplate $AzOpsMainTemplate -ConvertedTemplate $ConvertedTemplate -ConvertedParameter $ConvertedParameter } } if ($multiResult) { @@ -238,6 +245,10 @@ $WhatIfPreferenceState = $WhatIfPreference $WhatIfPreference = $false + # Create arrays to track bicep file conversion + $AzOpsTranspiledTemplate = @() + $AzOpsTranspiledParameter = @() + # Remove lingering files from previous run $tempPath = [System.IO.Path]::GetTempPath() if ((Test-Path -Path ($tempPath + 'OUTPUT.md')) -or (Test-Path -Path ($tempPath + 'OUTPUT.json'))) { @@ -350,7 +361,13 @@ # Handle Bicep templates if ($addition.EndsWith(".bicep")) { - $transpiledTemplatePaths = ConvertFrom-AzOpsBicepTemplate -BicepTemplatePath $addition | Select-Object transpiledTemplatePath + $transpiledTemplatePaths = ConvertFrom-AzOpsBicepTemplate -BicepTemplatePath $addition -ConvertedTemplate $AzOpsTranspiledTemplate -ConvertedParameter $AzOpsTranspiledParameter + if ($transpiledTemplatePaths.transpiledTemplateNew -eq $true) { + $AzOpsTranspiledTemplate += $transpiledTemplatePaths.transpiledTemplatePath + } + if ($transpiledTemplatePaths.transpiledParametersNew -eq $true) { + $AzOpsTranspiledParameter += $transpiledTemplatePaths.transpiledParametersPath + } $addition = $transpiledTemplatePaths.transpiledTemplatePath } @@ -362,7 +379,16 @@ continue } - Resolve-ArmFileAssociation -ScopeObject $scopeObject -FilePath $addition -AzOpsMainTemplate $AzOpsMainTemplate + $resolvedArmFileAssociation = Resolve-ArmFileAssociation -ScopeObject $scopeObject -FilePath $addition -AzOpsMainTemplate $AzOpsMainTemplate -ConvertedTemplate $AzOpsTranspiledTemplate -ConvertedParameter $AzOpsTranspiledParameter + foreach ($fileAssociation in $resolvedArmFileAssociation) { + if ($fileAssociation.transpiledTemplateNew -eq $true) { + $AzOpsTranspiledTemplate += $fileAssociation.TemplateFilePath + } + if ($fileAssociation.transpiledParametersNew -eq $true) { + $AzOpsTranspiledParameter += $fileAssociation.TemplateParameterFilePath + } + } + $resolvedArmFileAssociation } $deletionList = foreach ($deletion in $deleteSet | Where-Object { $_ -match ((Get-Item $StatePath).Name) }) { diff --git a/src/internal/functions/ConvertFrom-AzOpsBicepTemplate.ps1 b/src/internal/functions/ConvertFrom-AzOpsBicepTemplate.ps1 index b81bede3..21fad679 100644 --- a/src/internal/functions/ConvertFrom-AzOpsBicepTemplate.ps1 +++ b/src/internal/functions/ConvertFrom-AzOpsBicepTemplate.ps1 @@ -9,10 +9,16 @@ BicepParamTemplatePath, when provided function does not attempt default parameter file discovery. .PARAMETER SkipParam Switch when set will avoid parameter file discovery. + .PARAMETER ConvertedTemplate + Array of already converted base template, if file is on list skip conversion. + .PARAMETER ConvertedParameter + Array of already converted parameter, if file is on list skip conversion. .EXAMPLE ConvertFrom-AzOpsBicepTemplate -BicepTemplatePath "root/tenant root group (xxxx-xxxx-xxxx-xxxx-xxxx)/es (es)/subscription (xxxx-xxxx-xxxx-xxxx)/resource-rg/main.bicep" transpiledTemplatePath : root/tenant root group (xxxx-xxxx-xxxx-xxxx-xxxx)/es (es)/subscription (xxxx-xxxx-xxxx-xxxx)/resource-rg/main.json + transpiledTemplateNew : True transpiledParametersPath : root/tenant root group (xxxx-xxxx-xxxx-xxxx-xxxx)/es (es)/subscription (xxxx-xxxx-xxxx-xxxx)/resource-rg/main.parameters.json + transpiledParametersNew : True #> [CmdletBinding()] @@ -23,20 +29,27 @@ [string] $BicepParamTemplatePath, [switch] - $SkipParam + $SkipParam, + [array] + $ConvertedTemplate, + [array] + $ConvertedParameter ) begin { # Assert bicep binaries Assert-AzOpsBicepDependency -Cmdlet $PSCmdlet + # Default transpiled values to false + $transpiledTemplateNew = $false + $transpiledParametersNew = $false } process { $transpiledTemplatePath = [IO.Path]::GetFullPath("$($BicepTemplatePath -replace '\.bicep', '.json')") - if ($transpiledTemplatePath -notin $script:AzOpsTranspiledTemplate) { + if ($transpiledTemplatePath -notin $ConvertedTemplate) { # Convert bicep template Write-PSFMessage -Level Verbose -String 'ConvertFrom-AzOpsBicepTemplate.Resolve.ConvertBicepTemplate' -StringValues $BicepTemplatePath, $transpiledTemplatePath Invoke-AzOpsNativeCommand -ScriptBlock { bicep build $bicepTemplatePath --outfile $transpiledTemplatePath } - $script:AzOpsTranspiledTemplate += $transpiledTemplatePath + $transpiledTemplateNew = $true # Check if bicep build created (ARM) template if (-not (Test-Path $transpiledTemplatePath)) { # If bicep build did not produce file exit with error @@ -57,11 +70,11 @@ } if ($bicepParametersPath -and (Test-Path $bicepParametersPath)) { $transpiledParametersPath = [IO.Path]::GetFullPath("$($bicepParametersPath -replace '\.bicepparam', '.parameters.json')") - if ($transpiledParametersPath -notin $script:AzOpsTranspiledParameter) { + if ($transpiledParametersPath -notin $ConvertedParameter) { # Convert bicepparam to ARM parameter file Write-PSFMessage -Level Verbose -String 'ConvertFrom-AzOpsBicepTemplate.Resolve.ConvertBicepParam' -StringValues $bicepParametersPath, $transpiledParametersPath Invoke-AzOpsNativeCommand -ScriptBlock { bicep build-params $bicepParametersPath --outfile $transpiledParametersPath } - $script:AzOpsTranspiledParameter += $transpiledParametersPath + $transpiledParametersNew = $true # Check if bicep build-params created (ARM) parameters if (-not (Test-Path $transpiledParametersPath)) { # If bicep build-params did not produce file exit with error @@ -77,7 +90,9 @@ # Return transpiled (ARM) template paths $return = [PSCustomObject]@{ transpiledTemplatePath = $transpiledTemplatePath + transpiledTemplateNew = $transpiledTemplateNew transpiledParametersPath = $transpiledParametersPath + transpiledParametersNew = $transpiledParametersNew } return $return } From 6e3b5f2662fe665accd6da0a953ce9c3c840e1c3 Mon Sep 17 00:00:00 2001 From: Jesper Fajers Date: Fri, 5 Jan 2024 12:06:55 +0000 Subject: [PATCH 19/20] Update --- src/functions/Invoke-AzOpsPush.ps1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/functions/Invoke-AzOpsPush.ps1 b/src/functions/Invoke-AzOpsPush.ps1 index b94d4e3c..bf9fd4b9 100644 --- a/src/functions/Invoke-AzOpsPush.ps1 +++ b/src/functions/Invoke-AzOpsPush.ps1 @@ -362,10 +362,10 @@ # Handle Bicep templates if ($addition.EndsWith(".bicep")) { $transpiledTemplatePaths = ConvertFrom-AzOpsBicepTemplate -BicepTemplatePath $addition -ConvertedTemplate $AzOpsTranspiledTemplate -ConvertedParameter $AzOpsTranspiledParameter - if ($transpiledTemplatePaths.transpiledTemplateNew -eq $true) { + if ($true -eq $transpiledTemplatePaths.transpiledTemplateNew) { $AzOpsTranspiledTemplate += $transpiledTemplatePaths.transpiledTemplatePath } - if ($transpiledTemplatePaths.transpiledParametersNew -eq $true) { + if ($true -eq $transpiledTemplatePaths.transpiledParametersNew) { $AzOpsTranspiledParameter += $transpiledTemplatePaths.transpiledParametersPath } $addition = $transpiledTemplatePaths.transpiledTemplatePath @@ -381,10 +381,10 @@ $resolvedArmFileAssociation = Resolve-ArmFileAssociation -ScopeObject $scopeObject -FilePath $addition -AzOpsMainTemplate $AzOpsMainTemplate -ConvertedTemplate $AzOpsTranspiledTemplate -ConvertedParameter $AzOpsTranspiledParameter foreach ($fileAssociation in $resolvedArmFileAssociation) { - if ($fileAssociation.transpiledTemplateNew -eq $true) { + if ($true -eq $fileAssociation.transpiledTemplateNew) { $AzOpsTranspiledTemplate += $fileAssociation.TemplateFilePath } - if ($fileAssociation.transpiledParametersNew -eq $true) { + if ($true -eq $fileAssociation.transpiledParametersNew) { $AzOpsTranspiledParameter += $fileAssociation.TemplateParameterFilePath } } From 06c22854710eebaf5bcb4b0e82f2e40d8bbf067f Mon Sep 17 00:00:00 2001 From: Jesper Fajers Date: Fri, 5 Jan 2024 12:17:18 +0000 Subject: [PATCH 20/20] Update --- src/functions/Invoke-AzOpsPush.ps1 | 10 +++++----- .../functions/ConvertFrom-AzOpsBicepTemplate.ps1 | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/functions/Invoke-AzOpsPush.ps1 b/src/functions/Invoke-AzOpsPush.ps1 index bf9fd4b9..5e0e48a3 100644 --- a/src/functions/Invoke-AzOpsPush.ps1 +++ b/src/functions/Invoke-AzOpsPush.ps1 @@ -52,9 +52,9 @@ $FilePath, [string] $AzOpsMainTemplate, - [array] + [string[]] $ConvertedTemplate, - [array] + [string[]] $ConvertedParameter ) @@ -245,9 +245,9 @@ $WhatIfPreferenceState = $WhatIfPreference $WhatIfPreference = $false - # Create arrays to track bicep file conversion - $AzOpsTranspiledTemplate = @() - $AzOpsTranspiledParameter = @() + # Create array of strings to track bicep file conversion + [string[]] $AzOpsTranspiledTemplate = @() + [string[]] $AzOpsTranspiledParameter = @() # Remove lingering files from previous run $tempPath = [System.IO.Path]::GetTempPath() diff --git a/src/internal/functions/ConvertFrom-AzOpsBicepTemplate.ps1 b/src/internal/functions/ConvertFrom-AzOpsBicepTemplate.ps1 index 21fad679..4aa0a2d3 100644 --- a/src/internal/functions/ConvertFrom-AzOpsBicepTemplate.ps1 +++ b/src/internal/functions/ConvertFrom-AzOpsBicepTemplate.ps1 @@ -10,9 +10,9 @@ .PARAMETER SkipParam Switch when set will avoid parameter file discovery. .PARAMETER ConvertedTemplate - Array of already converted base template, if file is on list skip conversion. + Array of strings, already converted base template, if file is on list skip conversion. .PARAMETER ConvertedParameter - Array of already converted parameter, if file is on list skip conversion. + Array of strings, already converted parameter, if file is on list skip conversion. .EXAMPLE ConvertFrom-AzOpsBicepTemplate -BicepTemplatePath "root/tenant root group (xxxx-xxxx-xxxx-xxxx-xxxx)/es (es)/subscription (xxxx-xxxx-xxxx-xxxx)/resource-rg/main.bicep" transpiledTemplatePath : root/tenant root group (xxxx-xxxx-xxxx-xxxx-xxxx)/es (es)/subscription (xxxx-xxxx-xxxx-xxxx)/resource-rg/main.json @@ -30,9 +30,9 @@ $BicepParamTemplatePath, [switch] $SkipParam, - [array] + [string[]] $ConvertedTemplate, - [array] + [string[]] $ConvertedParameter )