Framework/Configurations/Migration/PolicyMigration.ps1
Set-StrictMode -Version Latest class PolicyMigrationHelper { static [string] $PolicyRGName static [string] $NewPolicyRGName static [void] StartMigration([SubscriptionContext] $subscriptionContext, [PSObject] $PolicyInstance, [PSObject] $OPolicyInstance) { [PSObject] $MigrationOutput = @{} [bool] $ErrorOccurred = $false; #Prepar Policy RG Name [PolicyMigrationHelper]::PolicyRGName = $OPolicyInstance.ResourceGroupName; [PolicyMigrationHelper]::NewPolicyRGName = $PolicyInstance.ResourceGroupName; #region Step 1: Validate if Policy Exists if(-not [PolicyMigrationHelper]::MigrationPrerequisiteCheck()) { return } #endregion #region Step 2: Get meta data for existing policy Write-Host ([Constants]::DoubleDashLine + "`r`nUpdating your current Org policy with latest AzSK resources...`r`n" + [Constants]::DoubleDashLine) -ForegroundColor Cyan; #region clear any existing locks try { Write-Host ("Checking if there are any resource locks on old Org policy resource group...") -ForegroundColor Yellow; $azskRGScope = "/subscriptions/$($subscriptionContext.SubscriptionId)/resourceGroups/$([PolicyMigrationHelper]::PolicyRGName)" $resourceLocks = @(); $resourceLocks += Get-AzureRmResourceLock -Scope $azskRGScope -ErrorAction Stop if($resourceLocks.Count -gt 0) { $resourceLocks | ForEach-Object { Remove-AzureRmResourceLock -LockId $_.LockId -Force } Write-Host ("Successfully removed the locks on old Org policy resource group.") -ForegroundColor Green; } else { Write-Host ("No locks found on old Org policy resource group.") -ForegroundColor Green; } $MigrationOutput.LockRemoval = "Success" } catch { Write-Host "An error occurred during removal of locks on old Org policy resource group: [$([PolicyMigrationHelper]::PolicyRGName)]" -ForegroundColor Red $MigrationOutput.LockRemoval = "Failed. Message[$_]" $ErrorOccurred = $true; throw; } #endregion #endregion #region capture the existing information $oldResourceGroupLocation = [ConfigurationManager]::GetAzSKConfigData().AzSKLocation; try { Write-Host ("Extracting policy files from old Org policy resources...") -ForegroundColor Yellow; $oldRg = Get-AzureRmResourceGroup -Name $([PolicyMigrationHelper]::PolicyRGName) -ErrorAction SilentlyContinue if($oldRg) { $oldResourceGroupLocation = $oldRg.Location; } #region extract storage policies $storageAccounts = @(); $storageAccounts += Get-AzureRmStorageAccount -ResourceGroupName $([PolicyMigrationHelper]::PolicyRGName) -ErrorAction SilentlyContinue; $storageAccounts = $storageAccounts | Where-Object { $_.StorageAccountName -like "$([OldConstants]::StorageAccountPreName)*" } ; if(($storageAccounts | Measure-Object).Count -ne 1) { return; } $context = $storageAccounts[0].Context; $policyBlobs = Get-AzureStorageBlob -Container "policies" -Context $context -ErrorAction SilentlyContinue if(($policyBlobs | Measure-Object).Count -gt 0) { if(-not (Test-Path "$($PolicyInstance.ConfigFolderPath)")) { mkdir -Path "$($PolicyInstance.ConfigFolderPath)" -ErrorAction Stop | Out-Null } else { Remove-Item -Path "$($PolicyInstance.ConfigFolderPath)\*" -Force -Recurse } ForEach($blob in $policyBlobs ) { $splitNames = $blob.Name.Split("/") $fileName = $splitNames[($splitNames.Count-1)] if($fileName -eq "AzSDK.json") { $fileName = "AzSK.json" } if($fileName -eq "RunbookScanAgent.ps1") { continue } $filepath = "$($PolicyInstance.ConfigFolderPath)\$fileName" Get-AzureStorageBlobContent -Blob $blob.Name -Container "policies" -Destination $filepath -Context $context -Force -ErrorAction SilentlyContinue } } #endregion Write-Host ("Successfully completed extracting policy files from old Org policy resources.") -ForegroundColor Green; $MigrationOutput.CurrentDataExtraction = "Success" } catch{ Write-Host "An error while extracting current metadata and copying policy files from old Org policy resources" -ForegroundColor Red $MigrationOutput.CurrentDataExtraction = "Failed. Message[$_]" $ErrorOccurred = $true; throw; } #endregion #region creating new resources try { #region copy subscription migration to policy Write-Host ("Copying subscription migration script to policy folder...") -ForegroundColor Yellow; $migrationScriptContent = [ConfigurationHelper]::LoadOfflineConfigFile("Migration.ps1") Out-File -InputObject $migrationScriptContent -Force -FilePath "$($PolicyInstance.ConfigFolderPath)\Migration.ps1" -Encoding utf8 Write-Host ("Successfully completed copying subscription migration script to policy folder.") -ForegroundColor Green; #endregion Write-Host ("Setting up Org policy using the *AzSK* module...`r`n"+[Constants]::GTLine) -ForegroundColor Yellow; [PolicyMigrationHelper]::SetupPolicyResources($PolicyInstance) Write-Host ([Constants]::GTLine+"`r`nSuccessfully completed setting up Org policy using the *AzSK* module.`r`n"+[Constants]::SingleDashLine) -ForegroundColor Green; $MigrationOutput.ResourceCreation = "Success" } catch{ Write-Host "An error occurred during setting up Org policy with latest AzSK. See migration log for details." -ForegroundColor Red $MigrationOutput.ResourceCreation = "Failed. Message[$_]" $ErrorOccurred = $true; throw; } #endregion Write-Host ("Performing last couple of steps...") -ForegroundColor Yellow; #Override existing IWR Write-Host ("Updating old Org-specific installer ('iwr')...") -ForegroundColor Yellow; Set-AzureStorageBlobContent -File $PolicyInstance.InstallerFile -Container $($PolicyInstance.InstallerContainerName) -BlobType Block -Context $context -Force -ErrorAction Stop Write-Host ("Successfully updated installer.") -ForegroundColor Green; Write-Host ("Uploading Org policy migration log to storage [$($PolicyInstance.StorageAccountName)]...") -ForegroundColor Yellow; [PolicyMigrationHelper]::PersistMigrationOutput($subscriptionContext.SubscriptionId,[PolicyMigrationHelper]::NewPolicyRGName, $MigrationOutput); Write-Host ("Successfully uploaded log.") -ForegroundColor Green; #region complete migration $MigrationOutput.ErrorOccurred = $ErrorOccurred if($MigrationOutput.ErrorOccurred -eq $false) { [PolicyMigrationHelper]::CompleteMigration($subscriptionContext.SubscriptionId,[PolicyMigrationHelper]::NewPolicyRGName, $MigrationOutput) #endregion write-host ([Constants]::SingleDashLine + "`r`n Org policy migration completed successfully`r`n"+[Constants]::SingleDashLine) -ForegroundColor Green write-host ([Constants]::SingleDashLine + "`r`n Follow next steps at: https://aka.ms/devopskit/extmigration#org-policy") -ForegroundColor Green } else { [PolicyMigrationHelper]::PersistMigrationOutput($subscriptionContext.SubscriptionId, $MigrationOutput) write-host ([Constants]::SingleDashLine + "`r`nAn error during policy migration, please retry again. If issue still continue please reach out to support team.`r`n"+[Constants]::SingleDashLine) -ForegroundColor Red } } static [bool] MigrationPrerequisiteCheck() { $PrerequisiteCheckResult = $true $PolicyRG= Get-AzureRmResourceGroup -Name $([PolicyMigrationHelper]::PolicyRGName) -ErrorAction SilentlyContinue if(-not $PolicyRG) { $PrerequisiteCheckResult = $false Write-Host ("WARNING: No policy setup found for Org in the subscription. Migration does not apply. You can use the AzSK module directly to setup new policy.") -ForegroundColor Yellow; return $PrerequisiteCheckResult } $tagName = [Constants]::PolicyMigrationTagName $OrgRGName = [PolicyMigrationHelper]::NewPolicyRGName $resourceGroupTags = [Helpers]::GetResourceGroupTags($OrgRGName) $migrationTag = $resourceGroupTags.GetEnumerator() | Where-Object { $_.Name -eq $tagName } if(($migrationTag | Measure-Object).Count -gt 0) { $PrerequisiteCheckResult = $false Write-Host ("WARNING: Policy is already migrated.") -ForegroundColor Yellow; return $PrerequisiteCheckResult } return $PrerequisiteCheckResult } static SetupPolicyResources([PSObject] $PolicyInstance) { # Install Policy $PolicyInstance.InstallPolicy([Constants]::NewModuleName) } static [void] CompleteMigration([string] $subscriptionId,[string] $OrgRGName, [PSObject] $MigrationOutput) { #apply tag $tagName = [Constants]::PolicyMigrationTagName $resourceGroupTags = [Helpers]::GetResourceGroupTags($OrgRGName) $resourceGroupTags.Add($tagName,[DateTime]::UtcNow.ToString("yyyyMMdd_HHmmss")); [Helpers]::SetResourceGroupTags($OrgRGName,$resourceGroupTags,$false,$false) ; } static [void] PersistMigrationOutput([string] $subscriptionId,[string] $OrgRGName, [PSObject] $MigrationOutput) { if($null -ne $MigrationOutput) { $temp = ($env:temp + "\AzSKTemp\"); $fileName = "MigrationOutput_"+ (Get-Date).ToUniversalTime().ToString("yyyyMMddHHmmss")+ ".json" if(-not (Test-Path -Path $temp)) { mkdir -Path $temp -Force } [Helpers]::ConvertToJsonCustom($MigrationOutput) | Out-File "$temp\$fileName" -Force; try{ $newStorageRGName = $OrgRGName $newStorageAccount = Get-AzureRmResource -ResourceGroupName $newStorageRGName -ResourceType 'Microsoft.Storage/storageAccounts' if($newStorageAccount) { $storageHelper = [StorageHelper]::new($subscriptionId,$newStorageRGName,$newStorageAccount.Location, $newStorageAccount.Name); $fileInfos = @(); $fileInfos += [System.IO.FileInfo]::new("$temp\$fileName"); $storageHelper.UploadFilesToBlob("migration", "", $fileInfos, $true); } } catch { #Kept blank to avoid issue with posting migration logs to new storage } } } } [PolicyMigrationHelper]::StartMigration($subscriptionContext,$PolicyInstance, $OPolicyInstance) |