Skip to content

Commit

Permalink
Migrating to Invoke-AzRestMethod (#450)
Browse files Browse the repository at this point in the history
  • Loading branch information
techlake authored Jan 18, 2024
1 parent 10e84cf commit 2ffd935
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 53 deletions.
74 changes: 43 additions & 31 deletions Scripts/Deploy/Deploy-RolesPlan.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ else {
Write-Information "Remove ($($removedRoleAssignments.psbase.Count)) obsolete Role assignments"
Write-Information "---------------------------------------------------------------------------------------------------"
foreach ($roleAssignment in $removedRoleAssignments) {
Write-Information "PrincipalId $($roleAssignment.principalId), role $($roleAssignment.roleDisplayName)($($roleAssignment.roleDefinitionId)) at $($roleAssignment.scope) -- id '$($roleAssignment.id)'"
Write-Information "PrincipalId $($roleAssignment.principalId), role $($roleAssignment.roleDisplayName)($($roleAssignment.roleDefinitionId)) at $($roleAssignment.scope)"
$null = Remove-AzRoleAssignmentRestMethod -RoleAssignmentId $roleAssignment.id
}
Write-Information ""
Expand All @@ -101,46 +101,58 @@ else {
Write-Information "==================================================================================================="
Write-Information "Add ($($addedRoleAssignments.psbase.Count)) new Role assignments"
Write-Information "---------------------------------------------------------------------------------------------------"
$retriesLimit = 4
$identitiesByAssignmentId = @{}

# Get identities for policy assignments from plan or by calling the REST API to retrieve the Policy Assignment
$assignmentById = @{}
foreach ($roleAssignment in $addedRoleAssignments) {
$principalId = $roleAssignment.principalId
$scope = $roleAssignment.scope
$roleDefinitionId = ($roleAssignment.roleDefinitionId -split "/")[-1]
$assignmentDisplayName = $roleAssignment.displayName
if ($null -eq $principalId) {
$policyAssignmentId = $roleAssignment.assignmentId
$identity = $null
if ($identitiesByAssignmentId.ContainsKey($policyAssignmentId)) {
$identity = $identitiesByAssignmentId.$policyAssignmentId
}
else {
$policyAssignment = Get-AzPolicyAssignment -Id $roleAssignment.assignmentId -WarningAction SilentlyContinue
$identity = $policyAssignment.Identity
$null = $identitiesByAssignmentId.Add($policyAssignmentId, $identity)
}
$principalId = $identity.PrincipalId
$roleAssignment.principalId = $principalId
}
Write-Information "$($assignmentDisplayName)($principalId): $($roleAssignment.roleDisplayName)($($roleDefinitionId)) at $($scope)"

if (Get-AzRoleAssignment -Scope $scope -ObjectId $principalId -RoleDefinitionId $roleDefinitionId) {
Write-Information "Role assignment already exists"
}
else {
while ($retries -le $retriesLimit) {
# Write-Information "Attempt $retries of $retriesLimit"
$result = New-AzRoleAssignment -Scope $scope -ObjectType $roleAssignment.objectType -ObjectId $principalId -RoleDefinitionId $roleDefinitionId -WarningAction SilentlyContinue
if ($null -ne $result) {
break
$principalId = ""
if (-not $assignmentById.ContainsKey($policyAssignmentId)) {
$policyAssignment = Get-AzPolicyAssignmentRestMethod -AssignmentId $roleAssignment.assignmentId
$identity = $policyAssignment.identity
if ($identity -and $identity.type -ne "None") {
$principalId = ""
if ($identity.type -eq "SystemAssigned") {
$principalId = $identity.principalId
}
else {
$userAssignedIdentityId = $identity.userAssignedIdentities.PSObject.Properties.Name
$principalId = $identity.userAssignedIdentities.$userAssignedIdentityId.principalId
}
}
else {
Start-Sleep -Seconds 10
$retries++
Write-Error "Identity not found for assignment '$($policyAssignmentId)'" -ErrorAction Stop
}
$null = $assignmentById.Add($policyAssignmentId, @{
principalId = $principalId
displayName = $policyAssignment.properties.displayName
})
}
}

else {
$null = $assignmentById.Add($roleAssignment.assignmentId, @{
principalId = $principalId
displayName = $roleAssignment.displayName
})
}
}

# Add the role assignments using the information collected above
foreach ($roleAssignment in $addedRoleAssignments) {
$assignmentId = $roleAssignment.assignmentId
$assignmentInfo = $assignmentById.$assignmentId
$splat = @{
Scope = $roleAssignment.scope
ObjectType = $roleAssignment.objectType
ObjectId = $assignmentInfo.principalId
RoleDefinitionId = $roleAssignment.roleDefinitionId
RoleDisplayName = $roleAssignment.roleDisplayName
AssignmentDisplayName = $assignmentInfo.displayName
}
Set-AzRoleAssignmentRestMethod @splat -IgnoreDuplicateError
}
}
Write-Information ""
Expand Down
3 changes: 2 additions & 1 deletion Scripts/Helpers/Add-HelperScripts.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
. "$PSScriptRoot/Find-AzNonCompliantResources.ps1"

. "$PSScriptRoot/Get-AssignmentsDetails.ps1"
. "$PSScriptRoot/Get-AzPolicyExemptionsAtScopeRestMethod.ps1"
. "$PSScriptRoot/Get-AzPolicyAssignmentRestMethod.ps1"
. "$PSScriptRoot/Get-AzPolicyResources.ps1"
. "$PSScriptRoot/Get-AzScopeTree.ps1"
. "$PSScriptRoot/Get-CustomMetadata.ps1"
Expand Down Expand Up @@ -91,6 +91,7 @@
. "$PSScriptRoot/Set-AzPolicyDefinitionRestMethod.ps1"
. "$PSScriptRoot/Set-AzPolicySetDefinitionRestMethod.ps1"
. "$PSScriptRoot/Set-AzPolicyExemptionRestMethod.ps1"
. "$PSScriptRoot/Set-AzRoleAssignmentRestMethod.ps1"

. "$PSScriptRoot/Export-AssignmentNode.ps1"
. "$PSScriptRoot/Set-ExportNode.ps1"
Expand Down
18 changes: 18 additions & 0 deletions Scripts/Helpers/Get-AzPolicyAssignmentRestMethod.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
function Get-AzPolicyAssignmentRestMethod {
[CmdletBinding()]
param (
[string] $AssignmentID
)

# Invoke the REST API
$response = Invoke-AzRestMethod -Path "$($AssignmentId)?api-version=2022-06-01" -Method GET

# Process response
$statusCode = $response.StatusCode
if ($statusCode -lt 200 -or $statusCode -ge 300) {
$content = $response.Content
Write-Error "Get Policy Assignment error for '$policyAssignmentId' $($statusCode) -- $($content)" -ErrorAction Stop
}

return $response.Content | ConvertFrom-Json -Depth 100
}
20 changes: 0 additions & 20 deletions Scripts/Helpers/Get-AzPolicyExemptionsAtScopeRestMethod.ps1

This file was deleted.

2 changes: 1 addition & 1 deletion Scripts/Helpers/Set-AzCloudTenantSubscription.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ function Set-AzCloudTenantSubscription {
[Parameter(Mandatory = $true)] [bool] $Interactive
)

if (!(Get-Module Az.ResourceGraph -ListAvailable)) {
if ($null -eq (Get-Module Az.ResourceGraph -ListAvailable)) {
Write-Information "Installing Az.ResourceGraph module"
Install-Module Az.ResourceGraph -Force -Repository PSGallery
}
Expand Down
45 changes: 45 additions & 0 deletions Scripts/Helpers/Set-AzRoleAssignmentRestMethod.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
function Set-AzRoleAssignmentRestMethod {
[CmdletBinding()]
param (
$Scope,
$ObjectType,
$ObjectId,
$RoleDefinitionId,
$AssignmentDisplayName,
$RoleDisplayName,
[switch] $IgnoreDuplicateError
)

# Write log info
Write-Information "Assignment '$AssignmentDisplayName', principalId $ObjectId, role $RoleDisplayName($roleDefinitionId) at $scope"

# Build the Path
$guid = New-Guid
$path = "$scope/providers/Microsoft.Authorization/roleAssignments/$($guid.ToString())?api-version=2022-04-01"

# Build the REST API body
$body = @{
properties = @{
roleDefinitionId = $RoleDefinitionId
principalId = $ObjectId
principalType = $ObjectType
}
}

# Invoke the REST API
$bodyJson = ConvertTo-Json $body -Depth 100 -Compress
$response = Invoke-AzRestMethod -Path $path -Method PUT -Payload $bodyJson

# Process response
$statusCode = $response.StatusCode
if ($statusCode -lt 200 -or $statusCode -ge 300) {
$content = $response.Content
if ($IgnoreDuplicateError -and $statusCode -eq 409) {
$errorBody = $content | ConvertFrom-Json -Depth 100
Write-Information $errorBody.error.message
}
else {
Write-Error "Role Assignment error $($statusCode) -- $($content)" -ErrorAction Stop
}
}
}

0 comments on commit 2ffd935

Please sign in to comment.