Skip to content

Commit 1878cfe

Browse files
authored
Update ApiVersion Logic to compare RP with Graph (#915)
* Init * Update * Wiki * Update
1 parent 98822b6 commit 1878cfe

7 files changed

Lines changed: 58 additions & 21 deletions

File tree

docs/wiki/Frequently-Asked-Questions.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ This article answers frequently asked questions relating to AzOps.
1010
- [Management groups not showing up in repository](#management-groups-not-showing-up-in-repository)
1111
- [Push fail with deployment already exists in location error](#push-fail-with-deployment-already-exists-in-location-error)
1212
- [Does AzOps use temporary files](#does-azops-use-temporary-files)
13+
- [How does AzOps Pull set API version](#how-does-azops-pull-set-api-version)
1314
- [Pull fail with active pull request already exists error](#pull-fail-with-active-pull-request-already-exists-error)
1415
- [Discovery scenarios and settings](#discovery-scenarios-and-settings)
1516
- [**I want to discover all resources across all resource groups in one specific subscription**](#i-want-to-discover-all-resources-across-all-resource-groups-in-one-specific-subscription)
@@ -71,6 +72,23 @@ AzOps utilizes the temporary directory for storing temporary information either
7172

7273
>Due to the different usage patterns of temporary files they are either created and deleted during module invocation or created and left for further processing at a later stage. As a part of AzOps invocation the initialize procedure looks for lingering temporary files (e.g. `OUTPUT.md / OUTPUT.json`) and removes them to ensure a clean execution.
7374
75+
## How does AzOps Pull set API version
76+
77+
When AzOps performs a Pull it gathers resource information and performs several formatting steps to ensure a deployable template is generated. During these steps AzOps dynamically determines the API version of each resource.
78+
79+
To make this determination the following information and logic is utilized:
80+
81+
First AzOps performs:
82+
- `Get-AzResourceProvider -ListAvailable` gathers available resource providers and their API versions from ARM.
83+
84+
Based on this information AzOps derives ga and preview versions from `Get-AzResourceProvider` and prefers the latest ga version, unless there is no ga version then a preview version is considered.
85+
86+
>Due to that API versions gathered at this step could be versions that are being rolled out and might not be available everywhere AzOps corroborate this with additional data in the next step to avoid inconsistencies as new API versions are rolled out.
87+
88+
- `Search-AzGraph -UseTenantScope -Query $Query -AllowPartialScope` gathers available API version from Azure Resource Graph.
89+
90+
Based on this additional datapoint AzOps derives if the API version from `Get-AzResourceProvider` and `Search-AzGraph` differ while the `Search-AzGraph` version exists in `Get-AzResourceProvider` and overrides the `Get-AzResourceProvider` version if they don’t match.
91+
7492
## Pull fail with active pull request already exists error
7593

7694
Pull pipeline failed during `Create Pull Request to automerge` task with an error as below:

src/functions/Initialize-AzOpsEnvironment.ps1

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@
110110
}
111111
$script:AzOpsSubscriptions = Get-AzOpsSubscription -ExcludedOffers $ExcludedSubOffer -ExcludedStates $ExcludedSubState -TenantId $tenantId
112112
$script:AzOpsResourceProvider = Get-AzResourceProvider -ListAvailable
113+
$query = "Resources | project type, apiVersion | union (PolicyResources | project type, apiVersion) | union (ResourceContainers | project type, apiVersion) | where isnotnull(apiVersion) | summarize apiVersion=max(apiVersion) by type | order by type asc"
114+
$script:AzOpsGraphResourceProvider = Search-AzOpsAzGraph -UseTenantScope -Query $query
113115
$script:AzOpsAzManagementGroup = @()
114116
$script:AzOpsPartialRoot = @()
115117
#endregion Initialize & Prepare

src/functions/Invoke-AzOpsPush.ps1

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -559,13 +559,14 @@
559559
Write-AzOpsMessage -LogLevel Debug -LogString 'Invoke-AzOpsPush.Deployment.Parallel' -LogStringValues $deployment.TemplateFilePath, $targets.Count
560560
# Prepare Input Data for parallel processing
561561
$runspaceData = @{
562-
AzOpsPath = "$($script:ModuleRoot)\AzOps.psd1"
563-
StatePath = $StatePath
564-
WhatIfPreference = $WhatIfPreference
565-
runspace_AzOpsAzManagementGroup = $script:AzOpsAzManagementGroup
566-
runspace_AzOpsSubscriptions = $script:AzOpsSubscriptions
567-
runspace_AzOpsPartialRoot = $script:AzOpsPartialRoot
568-
runspace_AzOpsResourceProvider = $script:AzOpsResourceProvider
562+
AzOpsPath = "$($script:ModuleRoot)\AzOps.psd1"
563+
StatePath = $StatePath
564+
WhatIfPreference = $WhatIfPreference
565+
runspace_AzOpsAzManagementGroup = $script:AzOpsAzManagementGroup
566+
runspace_AzOpsSubscriptions = $script:AzOpsSubscriptions
567+
runspace_AzOpsPartialRoot = $script:AzOpsPartialRoot
568+
runspace_AzOpsResourceProvider = $script:AzOpsResourceProvider
569+
runspace_AzOpsGraphResourceProvider = $script:AzOpsGraphResourceProvider
569570
}
570571
# Pass deployment targets for parallel processing and output deployment result for later
571572
$deploymentResult += $targets | Foreach-Object -ThrottleLimit (Get-PSFConfigValue -FullName 'AzOps.Core.ThrottleLimit') -Parallel {
@@ -580,6 +581,7 @@
580581
$script:AzOpsSubscriptions = $runspaceData.runspace_AzOpsSubscriptions
581582
$script:AzOpsPartialRoot = $runspaceData.runspace_AzOpsPartialRoot
582583
$script:AzOpsResourceProvider = $runspaceData.runspace_AzOpsResourceProvider
584+
$script:AzOpsGraphResourceProvider = $runspaceData.runspace_AzOpsGraphResourceProvider
583585
}
584586

585587
& $azOps {

src/internal/functions/ConvertTo-AzOpsState.ps1

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,13 @@
234234
} else {
235235
$apiVersion = $gaApiVersion | Select-Object -First 1
236236
}
237+
# Compare Providers - List API version to Graph API version
238+
$graphApiVersion = ($script:AzOpsGraphResourceProvider | Where-Object { $_.type -eq "$providerNamespace/$resourceApiTypeName" })?.apiVersion
239+
if ($null -ne $graphApiVersion -and $apiVersion -ne $graphApiVersion -and $graphApiVersion -in $apiVersions) {
240+
# If the Graph API version is not null and differs from the current API version while also existing in $apiVersions, update the API version
241+
Write-AzOpsMessage -LogLevel Debug -LogString 'ConvertTo-AzOpsState.GenerateTemplate.ApiVersionGraphOverride' -LogStringValues $apiVersion, $graphApiVersion, $resourceType
242+
$apiVersion = $graphApiVersion
243+
}
237244
Write-AzOpsMessage -LogLevel Debug -LogString 'ConvertTo-AzOpsState.GenerateTemplate.ApiVersion' -LogStringValues $resourceType, $apiVersion
238245
$object.resources[0].apiVersion = $apiVersion
239246
$object.resources[0].type = $resourceType

src/internal/functions/Get-AzOpsResourceDefinition.ps1

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -103,14 +103,15 @@
103103
$maxRetryCount = 3
104104
# Prepare Input Data for parallel processing
105105
$runspaceData = @{
106-
AzOpsPath = "$($script:ModuleRoot)\AzOps.psd1"
107-
StatePath = $StatePath
108-
runspace_AzOpsAzManagementGroup = $script:AzOpsAzManagementGroup
109-
runspace_AzOpsSubscriptions = $script:AzOpsSubscriptions
110-
runspace_AzOpsPartialRoot = $script:AzOpsPartialRoot
111-
runspace_AzOpsResourceProvider = $script:AzOpsResourceProvider
112-
BackoffMultiplier = $backoffMultiplier
113-
MaxRetryCount = $maxRetryCount
106+
AzOpsPath = "$($script:ModuleRoot)\AzOps.psd1"
107+
StatePath = $StatePath
108+
runspace_AzOpsAzManagementGroup = $script:AzOpsAzManagementGroup
109+
runspace_AzOpsSubscriptions = $script:AzOpsSubscriptions
110+
runspace_AzOpsPartialRoot = $script:AzOpsPartialRoot
111+
runspace_AzOpsResourceProvider = $script:AzOpsResourceProvider
112+
runspace_AzOpsGraphResourceProvider = $script:AzOpsGraphResourceProvider
113+
BackoffMultiplier = $backoffMultiplier
114+
MaxRetryCount = $maxRetryCount
114115
}
115116
}
116117

@@ -151,6 +152,7 @@
151152
$script:AzOpsSubscriptions = $runspaceData.runspace_AzOpsSubscriptions
152153
$script:AzOpsPartialRoot = $runspaceData.runspace_AzOpsPartialRoot
153154
$script:AzOpsResourceProvider = $runspaceData.runspace_AzOpsResourceProvider
155+
$script:AzOpsGraphResourceProvider = $runspaceData.runspace_AzOpsGraphResourceProvider
154156
}
155157
# Process Privileged Identity Management resources and Roles at managementGroup scope
156158
if ((-not $using:SkipPim) -or (-not $using:SkipRole)) {
@@ -189,6 +191,7 @@
189191
$script:AzOpsSubscriptions = $runspaceData.runspace_AzOpsSubscriptions
190192
$script:AzOpsPartialRoot = $runspaceData.runspace_AzOpsPartialRoot
191193
$script:AzOpsResourceProvider = $runspaceData.runspace_AzOpsResourceProvider
194+
$script:AzOpsGraphResourceProvider = $runspaceData.runspace_AzOpsGraphResourceProvider
192195
}
193196
# Process Privileged Identity Management resources, Locks and Roles at subscription scope
194197
if ((-not $using:SkipPim) -or (-not $using:SkipLock) -or (-not $using:SkipRole)) {
@@ -247,6 +250,7 @@
247250
$script:AzOpsSubscriptions = $runspaceData.runspace_AzOpsSubscriptions
248251
$script:AzOpsPartialRoot = $runspaceData.runspace_AzOpsPartialRoot
249252
$script:AzOpsResourceProvider = $runspaceData.runspace_AzOpsResourceProvider
253+
$script:AzOpsGraphResourceProvider = $runspaceData.runspace_AzOpsGraphResourceProvider
250254
}
251255
# Create Resource Group in file system
252256
& $azOps {
@@ -336,6 +340,7 @@
336340
$script:AzOpsSubscriptions = $runspaceData.runspace_AzOpsSubscriptions
337341
$script:AzOpsPartialRoot = $runspaceData.runspace_AzOpsPartialRoot
338342
$script:AzOpsResourceProvider = $runspaceData.runspace_AzOpsResourceProvider
343+
$script:AzOpsGraphResourceProvider = $runspaceData.runspace_AzOpsGraphResourceProvider
339344
}
340345
$context = Get-AzContext
341346
$context.Subscription.Id = $resource.subscriptionId

src/internal/functions/Save-AzOpsManagementGroupChild.ps1

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,13 @@
113113
if ($subscriptions) {
114114
# Prepare Input Data for parallel processing
115115
$runspaceData = @{
116-
AzOpsPath = "$($script:ModuleRoot)\AzOps.psd1"
117-
StatePath = $StatePath
118-
runspace_AzOpsAzManagementGroup = $script:AzOpsAzManagementGroup
119-
runspace_AzOpsSubscriptions = $script:AzOpsSubscriptions
120-
runspace_AzOpsPartialRoot = $script:AzOpsPartialRoot
121-
runspace_AzOpsResourceProvider = $script:AzOpsResourceProvider
116+
AzOpsPath = "$($script:ModuleRoot)\AzOps.psd1"
117+
StatePath = $StatePath
118+
runspace_AzOpsAzManagementGroup = $script:AzOpsAzManagementGroup
119+
runspace_AzOpsSubscriptions = $script:AzOpsSubscriptions
120+
runspace_AzOpsPartialRoot = $script:AzOpsPartialRoot
121+
runspace_AzOpsResourceProvider = $script:AzOpsResourceProvider
122+
runspace_AzOpsGraphResourceProvider = $script:AzOpsGraphResourceProvider
122123
}
123124
$subscriptions | Foreach-Object -ThrottleLimit (Get-PSFConfigValue -FullName 'AzOps.Core.ThrottleLimit') -Parallel {
124125
$subscription = $_
@@ -132,6 +133,7 @@
132133
$script:AzOpsSubscriptions = $runspaceData.runspace_AzOpsSubscriptions
133134
$script:AzOpsPartialRoot = $runspaceData.runspace_AzOpsPartialRoot
134135
$script:AzOpsResourceProvider = $runspaceData.runspace_AzOpsResourceProvider
136+
$script:AzOpsGraphResourceProvider = $runspaceData.runspace_AzOpsGraphResourceProvider
135137
}
136138

137139
& $azOps {

src/localized/en-us/Strings.psd1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
'ConvertTo-AzOpsState.GenerateTemplate.ResourceTypeName' = 'Resource type: {0}' # $resourceTypeName
7373
'ConvertTo-AzOpsState.GenerateTemplate.ResourceApiTypeName' = 'Resource api type: {0}' # $resourceApiTypeName
7474
'ConvertTo-AzOpsState.GenerateTemplate.ApiVersion' = 'Determined api version: {1} for resource type name: {0}' # $resourceType, $apiVersions
75+
'ConvertTo-AzOpsState.GenerateTemplate.ApiVersionGraphOverride' = 'Determined that AzResourceProvider api version: {0} did not match Graph api version: {1} for resource type name: {2}, overriding with Graph api version.' # $apiVersion, $graphApiVersion, $resourceType
7576
'ConvertTo-AzOpsState.GenerateTemplate.NoApiVersion' = 'Unable to determine api version from resource type name: {0}' # $resourceTypeName
7677
'ConvertTo-AzOpsState.GenerateTemplate.ChildResource' = 'Appending child resource name: {0}' # $resourceName
7778
'ConvertTo-AzOpsState.ObjectType.Resolved.Generic' = 'Unable to determine object type: {0}' # $($_.GetType())

0 commit comments

Comments
 (0)