Framework/Core/CAwithACI/ContinuousAssurance.ps1
Set-StrictMode -Version Latest class ContinuousAssurance: AzCommandBase { hidden [string] $ResourceGroup hidden [string] $ContainerName hidden [string] $FunctionAppName hidden [string] $FunctionAppPrefix hidden [string] $ContainerImage hidden [string] $CALocation hidden [string] $ResourceGroupNames hidden [string] $StorageAccountName hidden $EnvironmentVariables = @{} hidden [Hashtable] $reportStorageTags = @{} hidden [string] $LAWSId hidden [string] $LAWSSharedKey hidden [string] $AltLAWSId hidden [string] $AltLAWSSharedKey hidden [bool] $UpdateScheduler hidden [string] $CAScanOutputLogsContainerName = [Constants]::CAScanOutputLogsContainerName hidden [string] $ContainerMSI hidden [string] $FunctionAppMSI ContinuousAssurance( [string] $subscriptionId, ` [InvocationInfo] $invocationContext, ` [string] $ResourceGroupNames, ` [string] $LAWSId, ` [string] $LAWSSharedKey, ` [string] $AltLAWSId, ` [string] $AltLAWSSharedKey) : Base($subscriptionId, $invocationContext) { $this.PublishCustomMessage([Constants]::SingleDashLine+"`r`nWarning: You are running a preview command`r`n"+[Constants]::SingleDashLine, [MessageType]::Warning) $this.ResourceGroupNames = $ResourceGroupNames $this.CALocation = [UserSubscriptionDataHelper]::GetUserSubscriptionRGLocation() $this.ResourceGroup = [UserSubscriptionDataHelper]::GetUserSubscriptionRGName() $this.ContainerName = [UserSubscriptionDataHelper]::GetContainerName() $this.FunctionAppPrefix = "azskcasheduler" #Needs to change $this.ContainerImage = [Constants]::AzSKContainerImage # if(-not [string]::IsNullOrWhiteSpace($CALocation)) # { # $this.CALocation = $CALocation # } $this.SetEnvironmentVariables($ResourceGroupNames, $LAWSId, $LAWSSharedKey, $AltLAWSId, $AltLAWSSharedKey) } ContinuousAssurance( [string] $subscriptionId, ` [InvocationInfo] $invocationContext, ` [string] $ResourceGroupNames, ` [string] $LAWSId, ` [string] $LAWSSharedKey, ` [string] $AltLAWSId, ` [string] $AltLAWSSharedKey, ` [bool] $UpdateScheduler) : Base($subscriptionId, $invocationContext) { $this.PublishCustomMessage([Constants]::SingleDashLine+"`r`nWarning: You are running a preview command`r`n"+[Constants]::SingleDashLine, [MessageType]::Warning) $this.CALocation = [UserSubscriptionDataHelper]::GetUserSubscriptionRGLocation() if(-not [string]::IsNullOrWhiteSpace($ResourceGroupNames)) { $this.ResourceGroupNames = $ResourceGroupNames } if(-not [string]::IsNullOrWhiteSpace($LAWSId)) { $this.LAWSId = $LAWSId } if(-not [string]::IsNullOrWhiteSpace($LAWSSharedKey)) { $this.LAWSSharedKey = $LAWSSharedKey } if(-not [string]::IsNullOrWhiteSpace($AltLAWSId)) { $this.AltLAWSId = $AltLAWSId } if(-not [string]::IsNullOrWhiteSpace($AltLAWSSharedKey)) { $this.AltLAWSSharedKey = $AltLAWSSharedKey } $this.ResourceGroup = [UserSubscriptionDataHelper]::GetUserSubscriptionRGName() $this.ContainerName = [UserSubscriptionDataHelper]::GetContainerName() $this.FunctionAppPrefix = "azskcasheduler" $this.ContainerImage = [Constants]::AzSKContainerImage } ContinuousAssurance( [string] $subscriptionId, ` [InvocationInfo] $invocationContext) : Base($subscriptionId, $invocationContext) { $this.PublishCustomMessage([Constants]::SingleDashLine+"`r`nWarning: You are running a preview command`r`n"+[Constants]::SingleDashLine, [MessageType]::Warning) $this.CALocation = [UserSubscriptionDataHelper]::GetUserSubscriptionRGLocation() $this.ResourceGroup = [UserSubscriptionDataHelper]::GetUserSubscriptionRGName() $this.ContainerName = [UserSubscriptionDataHelper]::GetContainerName() $this.FunctionAppPrefix = "azskcasheduler" $this.ContainerImage = [Constants]::AzSKContainerImage } hidden [void] SetEnvironmentVariables([string] $ResourceGroupNames, [string] $LAWSId, [string] $LAWSSharedKey,[string] $AltLAWSId, [string] $AltLAWSSharedKey) { $this.EnvironmentVariables.Add('ResourceGroupNames', $ResourceGroupNames) $this.EnvironmentVariables.Add('SubscriptionId', $this.SubscriptionContext.SubscriptionId) $this.EnvironmentVariables.Add('ACIRG', $this.ResourceGroup) if(-not [string]::IsNullOrWhiteSpace($LAWSId) -and -not [string]::IsNullOrWhiteSpace($LAWSSharedKey)) { $this.EnvironmentVariables.Add('LAWSId', $LAWSId) $this.EnvironmentVariables.Add('LAWSSharedKey', $LAWSSharedKey) } if(-not [string]::IsNullOrWhiteSpace($AltLAWSId) -and -not [string]::IsNullOrWhiteSpace($AltLAWSSharedKey)) { $this.EnvironmentVariables.Add('AltLAWSId', $AltLAWSId) $this.EnvironmentVariables.Add('AltLAWSSharedKey', $AltLAWSSharedKey) } } hidden [void] CreteAzSKContainer() { #register resource provider if not registered [ResourceHelper]::RegisterResourceProviderIfNotRegistered("Microsoft.ContainerInstance") $AzSKContainer = New-AzContainerGroup -ResourceGroupName $this.ResourceGroup -Name $this.ContainerName -Image $this.ContainerImage -AssignIdentity -RestartPolicy OnFailure ` -EnvironmentVariable $this.EnvironmentVariables -Location $this.CALocation #Stop the container as it starts immediately after the creation Invoke-AzResourceAction -ResourceGroupName $this.ResourceGroup -ResourceName $this.ContainerName -Action Stop -ResourceType Microsoft.ContainerInstance/containerGroups -Force $this.ContainerMSI = $AzSKContainer.Identity.PrincipalId } # Can add more parameters if required hidden [void] UpdateAzSKContainer($ContainerVariables) { $this.EnvironmentVariables = $ContainerVariables if(-not [string]::IsNullOrWhiteSpace($this.ResourceGroupNames)) { $this.EnvironmentVariables['ResourceGroupNames'] = $this.ResourceGroupNames } if(-not [string]::IsNullOrWhiteSpace($this.LAWSId)) { $this.EnvironmentVariables['LAWSId'] = $this.LAWSId } if(-not [string]::IsNullOrWhiteSpace($this.LAWSSharedKey)) { $this.EnvironmentVariables['LAWSSharedKey'] = $this.LAWSSharedKey } if(-not [string]::IsNullOrWhiteSpace($this.AltLAWSId)) { $this.EnvironmentVariables['AltLAWSId'] = $this.AltLAWSId } if(-not [string]::IsNullOrWhiteSpace($this.AltLAWSSharedKey)) { $this.EnvironmentVariables['AltLAWSSharedKey'] = $this.AltLAWSSharedKey } $AzSKContainer = New-AzContainerGroup -ResourceGroupName $this.ResourceGroup -Name $this.ContainerName -Image $this.ContainerImage -AssignIdentity -RestartPolicy OnFailure ` -EnvironmentVariable $this.EnvironmentVariables -Location $this.CALocation #Stop the container as it starts immediately after the creation Invoke-AzResourceAction -ResourceGroupName $this.ResourceGroup -ResourceName $this.ContainerName -Action Stop -ResourceType Microsoft.ContainerInstance/containerGroups -Force $this.ContainerMSI = $AzSKContainer.Identity.PrincipalId } hidden [bool] CheckRBACAccess($ObjectId, $Scope, $Role) { $RoleAssignments = Get-AzRoleAssignment -ObjectId $ObjectId -Scope $Scope -RoleDefinitionId $Role if(($RoleAssignments|Measure-Object).count -gt 0) { #$hasAccess = ($RoleAssignments | Where-Object {$_.scope -eq $Scope -and $_.RoleDefinitionId -eq $Role}).count -gt 0 return $true } return $false } hidden [void] SetRBACAccess($ObjectId, $Scope, $Role) { New-AzRoleAssignment -ObjectId $ObjectId -RoleDefinitionId $Role -Scope $Scope Start-Sleep -Seconds 10 } hidden [void] SetContainerMSIAccess() { #Reader access on Sub $hasSubAccess = $this.CheckRBACAccess($this.ContainerMSI, "/subscriptions/$($this.SubscriptionContext.SubscriptionId)", 'acdd72a7-3385-48ef-bd42-f606fba81ae7') if(-not $hasSubAccess) { $this.SetRBACAccess($this.ContainerMSI, "/subscriptions/$($this.SubscriptionContext.SubscriptionId)", 'acdd72a7-3385-48ef-bd42-f606fba81ae7') } #Contributor access on AzSKRG $hasRGAccess = $this.CheckRBACAccess($this.ContainerMSI, "/subscriptions/$($this.SubscriptionContext.SubscriptionId)/resourcegroups/$($this.ResourceGroup)", 'b24988ac-6180-42a0-ab88-20f7382dd24c') if(-not $hasRGAccess) { $this.SetRBACAccess($this.ContainerMSI, "/subscriptions/$($this.SubscriptionContext.SubscriptionId)/resourcegroups/$($this.ResourceGroup)", 'b24988ac-6180-42a0-ab88-20f7382dd24c') } } hidden [void] SetFunctionAppMSIAccess() { #Contributor access on AzSKRG $hasRGAccess = $this.CheckRBACAccess($this.FunctionAppMSI, "/subscriptions/$($this.SubscriptionContext.SubscriptionId)/resourcegroups/$($this.ResourceGroup)", 'b24988ac-6180-42a0-ab88-20f7382dd24c') if(-not $hasRGAccess) { $this.SetRBACAccess($this.FunctionAppMSI, "/subscriptions/$($this.SubscriptionContext.SubscriptionId)/resourcegroups/$($this.ResourceGroup)", 'b24988ac-6180-42a0-ab88-20f7382dd24c') } } hidden [PSObject] GetCAContainerInstance() { $ContainerObject = Get-AzContainerGroup -ResourceGroupName $this.ResourceGroup -Name $this.ContainerName -ErrorAction SilentlyContinue return $ContainerObject } hidden [PSObject] GetFnAppInstance() { $FunctionAppObject = Get-AzResource -ResourceGroupName $this.ResourceGroup -ResourceType "Microsoft.Web/sites" | Where-Object { $_.Name.StartsWith($this.FunctionAppPrefix)} return $FunctionAppObject } hidden [PSObject] GetFnAppResource() { $FnAppResource = Get-AzWebApp -ResourceGroupName $this.ResourceGroup -Name $this.FunctionAppName -ErrorAction SilentlyContinue return $FnAppResource } hidden [void] ResolveStorageCompliance($storageName,$ResourceId,$resourceGroup,$containerName) { $storageObject = Get-AzStorageAccount -ResourceGroupName $resourceGroup -Name $storageName -ErrorAction Stop $keys = Get-AzStorageAccountKey -ResourceGroupName $resourceGroup -Name $storageName $currentContext = New-AzStorageContext -StorageAccountName $storageName -StorageAccountKey $keys[0].Value -Protocol Https #Azure_Storage_AuthN_Dont_Allow_Anonymous $keys = Get-AzStorageAccountKey -ResourceGroupName $resourceGroup -Name $storageName $storageContext = New-AzStorageContext -StorageAccountName $storageName -StorageAccountKey $keys[0].Value -Protocol Https $existingContainer = Get-AzStorageContainer -Name $containerName -Context $storageContext -ErrorAction SilentlyContinue if($existingContainer) { Set-AzStorageContainerAcl -Name $containerName -Permission 'Off' -Context $currentContext } $storageSku = [Constants]::NewStorageSku Set-AzStorageAccount -Name $storageName -ResourceGroupName $resourceGroup -SkuName $storageSku #Azure_Storage_Audit_AuthN_Requests $currentContext = $storageObject.Context Set-AzStorageServiceLoggingProperty -ServiceType Blob -LoggingOperations All -Context $currentContext -RetentionDays 365 -PassThru Set-AzStorageServiceMetricsProperty -MetricsType Hour -ServiceType Blob -Context $currentContext -MetricsLevel ServiceAndApi -RetentionDays 365 -PassThru #Azure_Storage_DP_Encrypt_In_Transit Set-AzStorageAccount -ResourceGroupName $resourceGroup -Name $storageName -EnableHttpsTrafficOnly $true } #TBD hidden [void] UpdateAzSKFunctionApp() { $storageConnectionStringformat = "DefaultEndpointsProtocol=https;AccountName=$($this.StorageAccountName);AccountKey={0};EndpointSuffix=core.windows.net"; $keys = Get-AzStorageAccountKey -ResourceGroupName $this.ResourceGroup -Name $this.StorageAccountName $value = $keys[0].Value; $StorageAccountConnectionString = $storageConnectionStringformat -f $value; $timeTrigger = [System.DateTime]::UtcNow.AddMinutes(15) $AppSettings = @{ 'AzureWebJobsStorage' = $StorageAccountConnectionString; 'FUNCTIONS_EXTENSION_VERSION' = '~2'; "FUNCTIONS_WORKER_RUNTIME" = "powershell"; "schedule" = "0 $($timeTrigger.Minute) $($timeTrigger.Hour) * * *"; } $functionAppObjet = $this.GetFnAppInstance() $functionAppResource = $this.GetFnAppResource() if($null -ne $functionAppResource) { if(($functionAppResource.SiteConfig.AppSettings | Measure-Object).Count -gt 0) { $appSettingsList = $functionAppResource.SiteConfig.AppSettings; ForEach ($item in $appSettingsList){ $AppSettings[$item.Name] = $item.Value; } } } if(($functionAppObjet | Measure-Object).Count -le 0) { New-AzResource -ResourceType 'Microsoft.Web/Sites' -ResourceName $this.FunctionAppName -kind 'functionapp' -Location $this.CALocation -ResourceGroupName $this.ResourceGroup -Properties @{} -Force; } $AzSKFunctionApp = Set-AzWebApp -Name $this.FunctionAppName -ResourceGroupName $this.ResourceGroup -AppSettings $AppSettings -AssignIdentity $true -HttpsOnly $true Start-Sleep -Seconds 10 $this.FunctionAppMSI = $AzSKFunctionApp.Identity.PrincipalId $zipFilePath = Join-Path (Get-Item -Path $PSScriptRoot).Parent.Parent.FullName -ChildPath "Configurations" | Join-Path -ChildPath "ContinuousAssurance" | Join-Path -ChildPath "FunctionApp.zip"; $pub = $this.FunctionAppName + '/publishingcredentials'; $pubCredResourceType = "Microsoft.Web/sites/config"; $pubCreds = @(); $pubCred= Invoke-AzResourceAction -ResourceGroupName $this.ResourceGroup -ResourceName $pub -ResourceType $pubCredResourceType -Action list -ApiVersion 2015-08-01 -Force; if(($pubCred | Measure-Object).Count -gt 0) { $pubCreds += $pubCred; $pubName = $pubCreds[0].Properties.PublishingUserName; $pubpwd = $pubCreds[0].Properties.PublishingPassword; $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $pubName,$pubpwd))) $apiUrl = "https://"+$($this.FunctionAppName)+".scm.azurewebsites.net/api/zipdeploy"; $this.PublishCustomMessage("Adding/updating scanner function on [$($this.FunctionAppName)] function app...") Invoke-RestMethod -Uri $apiUrl -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method PUT -InFile $zipFilePath -ContentType "multipart/form-data"; } else { $this.PublishCustomMessage("Not able to fetch publish credentials..."); } } [void] InstallAzSKContinuousAssurancewithACI() { #Using a trick to exclude non CSEO users..To be removed if(-not [ConfigurationManager]::GetAzSKSettings().EnableAADAuthForOnlinePolicyStore) { $this.PublishCustomMessage("Container based CA is currently not available to your org ", [MessageType]::Error) return } #create AzSKRG resource group if not exists [ResourceGroupHelper]::CreateNewResourceGroupIfNotExists($this.ResourceGroup, $this.CALocation,$this.GetCurrentModuleVersion()) #create storage account if not exists $ExistingStorage = [UserSubscriptionDataHelper]::GetUserSubscriptionStorage() if(($ExistingStorage|Measure-Object).Count -gt 0) { $this.StorageAccountName = $ExistingStorage.Name $this.PublishCustomMessage("Preparing a storage account for storing reports from CA scans...`r`nFound existing AzSK storage account: ["+ $this.StorageAccountName +"]. This will be used to store reports from CA scans.") } else { #create new storage $this.StorageAccountName = ("azsk" + (Get-Date).ToUniversalTime().ToString("yyyyMMddHHmmss")) $this.PublishCustomMessage("Creating a storage account: ["+ $this.StorageAccountName +"] for storing reports from CA scans.") $newStorage = [StorageHelper]::NewAzskCompliantStorage($this.StorageAccountName, $this.ResourceGroup, $this.CALocation) if(!$newStorage) { $this.cleanupFlag = $true throw ([SuppressedException]::new(($this.exceptionMsg + "Failed to create storage account."), [SuppressedExceptionType]::Generic)) } else { #apply tags $timestamp = $(get-date).ToUniversalTime().ToString("yyyyMMdd_HHmmss") $this.reportStorageTags += @{ "CreationTime"=$timestamp; "LastModified"=$timestamp } Set-AzStorageAccount -ResourceGroupName $newStorage.ResourceGroupName -Name $newStorage.StorageAccountName -Tag $this.reportStorageTags -Force -ErrorAction SilentlyContinue } } $this.EnvironmentVariables.Add('StorageAccountName', $this.StorageAccountName) $ContainerIntstance = $this.GetCAContainerInstance() if($ContainerIntstance) { $this.PublishCustomMessage("AzSK CA container instance [$($this.ContainerName)] already exists. Please delete it before running install command", [MessageType]::Error) return } $this.PublishCustomMessage("Creating Azure container instance: [" + $this.ContainerName + "]") $this.CreteAzSKContainer() $this.PublishCustomMessage("Configuring permissions for AzSK Container MSI...") $this.SetContainerMSIAccess() $FunctionAppInstance = $this.GetFnAppInstance() if($FunctionAppInstance) { $this.FunctionAppName = $FunctionAppInstance.Name $this.PublishCustomMessage("AzSK CA function app [$($this.FunctionAppName)] already exists. Please delete it before running install command", [MessageType]::Error) # TBD: delete ACI return } #Use class variable $this.FunctionAppName = "azskcasheduler" + (Get-Date).ToUniversalTime().ToString("yyyyMMddHHmmss") $this.PublishCustomMessage("Creating Azure function app: [$($this.FunctionAppName)] ") $this.UpdateAzSKFunctionApp() $this.PublishCustomMessage("Configuring permissions for AzSK function app MSI...") $this.SetFunctionAppMSIAccess() } [void] UpdateAzSKContinuousAssurancewithACI() { #Using a trick to exclude non CSEO users..To be removed if(-not [ConfigurationManager]::GetAzSKSettings().EnableAADAuthForOnlinePolicyStore) { $this.PublishCustomMessage("Container based CA is currently not available to your org ", [MessageType]::Error) return } $ContainerIntstance = $this.GetCAContainerInstance() if(($ContainerIntstance|Measure-Object).Count -eq 0) { throw ([SuppressedException]::new(("Continuous Assurance(CA) is not configured in this subscription. Please install with required parameters."), [SuppressedExceptionType]::InvalidOperation)) } #create storage account if not exists $ExistingStorage = [UserSubscriptionDataHelper]::GetUserSubscriptionStorage() if(($ExistingStorage|Measure-Object).Count -gt 0) { $this.PublishCustomMessage("Found existing AzSK storage account: ["+ $ExistingStorage.Name +"]") $this.StorageAccountName = $ExistingStorage.Name #make storage compliant to azsk $this.ResolveStorageCompliance($ExistingStorage.Name, $ExistingStorage.ResourceId, $this.ResourceGroup,$this.CAScanOutputLogsContainerName) } else { #create default storage $newStorageName = ("azsk" + (Get-Date).ToUniversalTime().ToString("yyyyMMddHHmmss")) $this.PublishCustomMessage("Creating Storage Account: [$newStorageName] for storing reports from CA scans.") $this.StorageAccountName = $newStorageName $newStorage = [StorageHelper]::NewAzskCompliantStorage($newStorageName, $this.ResourceGroup, $this.CALocation) if(!$newStorage) { throw ([SuppressedException]::new(($this.exceptionMsg + "Failed to create storage account."), [SuppressedExceptionType]::Generic)) } else { #apply tags $timestamp = $(get-date).ToUniversalTime().ToString("yyyyMMdd_HHmmss") $this.reportStorageTags += @{ "CreationTime"=$timestamp; "LastModified"=$timestamp } Set-AzStorageAccount -ResourceGroupName $newStorage.ResourceGroupName -Name $newStorage.StorageAccountName -Tag $this.reportStorageTags -Force -ErrorAction SilentlyContinue } } $this.EnvironmentVariables.Add('StorageAccountName', $this.StorageAccountName) $this.PublishCustomMessage("Updating Azure container instance: [" + $this.ContainerName + "]") $ContainerVariables = $ContainerIntstance.Containers[0].EnvironmentVariables $this.UpdateAzSKContainer($ContainerVariables) # To update the daily scan time if($this.UpdateScheduler) { $this.PublishCustomMessage("Updating CA scan scheduler time") $FunctionAppInstance = $this.GetFnAppInstance() if($FunctionAppInstance) { $this.FunctionAppName = $FunctionAppInstance.Name } else { $this.FunctionAppName = "azskcasheduler" + (Get-Date).ToUniversalTime().ToString("yyyyMMddHHmmss") $this.PublishCustomMessage("AzSK CA function app is not present. Creating it", [MessageType]::Info) } #TBD: take time as i/p instead of current time $this.UpdateAzSKFunctionApp() $this.SetFunctionAppMSIAccess() } } [void] GetAzSKContinuousAssurancewithACI() { #Using a trick to exclude non CSEO users..To be removed if(-not [ConfigurationManager]::GetAzSKSettings().EnableAADAuthForOnlinePolicyStore) { $this.PublishCustomMessage("Container based CA is currently not available to your org ", [MessageType]::Error) return } $currentMessage = [MessageData]::new([Constants]::DoubleDashLine + "`r`nStarted validating your AzSK Continuous Assurance (CA) setup...`r`n"+[Constants]::DoubleDashLine); $this.PublishCustomMessage($currentMessage); # validate container $ContainerIntstance = $this.GetCAContainerInstance() if($ContainerIntstance) { $this.PublishCustomMessage("Found AzSK CA container instance [$($this.ContainerName)] with below configurations ", [MessageType]::Update) $ContainerConfig = @{} $ContainerConfig.Add('MSI', $ContainerIntstance.Identity.PrincipalId) $ContainerConfig.Add('LAWSId', $ContainerIntstance.Containers[0].EnvironmentVariables.LAWSId) $ContainerConfig.Add('LAWSSharedKey', $ContainerIntstance.Containers[0].EnvironmentVariables.LAWSSharedKey) $ContainerConfig = $ContainerConfig.GetEnumerator() | Format-Table -AutoSize -Wrap | Out-String $this.PublishCustomMessage($ContainerConfig, [MessageType]::Info) #TBD: Altvar, container health: restart count, errors etc.... } else { $this.PublishCustomMessage("AzSK CA container instance [$($this.ContainerName)] is missing. Please run install command", [MessageType]::Error) return } $this.PublishCustomMessage([Constants]::SingleDashLine, [MessageType]::Info) # validate fn app $FunctionAppInstance = $this.GetFnAppInstance() if($FunctionAppInstance) { $this.FunctionAppName = $FunctionAppInstance.Name $this.PublishCustomMessage("Found AzSK CA function app [$($this.FunctionAppName)] ", [MessageType]::Update) } else { $this.PublishCustomMessage("AzSK CA function app [$($this.FunctionAppPrefix)].... is missing. Please run update command", [MessageType]::Error) return } $this.PublishCustomMessage([Constants]::SingleDashLine, [MessageType]::Info) # Validate MSI access $hasSubAccess = $this.CheckRBACAccess($ContainerIntstance.Identity.PrincipalId, "/subscriptions/$($this.SubscriptionContext.SubscriptionId)", 'acdd72a7-3385-48ef-bd42-f606fba81ae7') # Guid of reader role $hasRGAccess = $this.CheckRBACAccess($ContainerIntstance.Identity.PrincipalId, "/subscriptions/$($this.SubscriptionContext.SubscriptionId)/resourcegroups/$($this.ResourceGroup)", 'b24988ac-6180-42a0-ab88-20f7382dd24c') # Guid of contributor role if($hasSubAccess -and $hasRGAccess) { $this.PublishCustomMessage("AzSK CA container MSI [$($ContainerIntstance.Identity.PrincipalId)] has required permissions", [MessageType]::Update) } else { $this.PublishCustomMessage("AzSK CA container MSI [$($ContainerIntstance.Identity.PrincipalId)] doesn't have required permissions. Please run update command", [MessageType]::Error) } $hasRGAccess = $this.CheckRBACAccess($FunctionAppInstance.Identity.PrincipalId, "/subscriptions/$($this.SubscriptionContext.SubscriptionId)/resourcegroups/$($this.ResourceGroup)", 'b24988ac-6180-42a0-ab88-20f7382dd24c') if($hasRGAccess) { $this.PublishCustomMessage("AzSK CA function app MSI [$($FunctionAppInstance.Identity.PrincipalId)] has required permissions", [MessageType]::Update) } else { $this.PublishCustomMessage("AzSK CA function app MSI [$($FunctionAppInstance.Identity.PrincipalId)] doesn't have required permissions. Please run update command", [MessageType]::Error) } $this.PublishCustomMessage([Constants]::SingleDashLine, [MessageType]::Info) $reportsStorageAccount = [UserSubscriptionDataHelper]::GetUserSubscriptionStorage(); if(($reportsStorageAccount|Measure-Object).Count -eq 1) { $this.PublishCustomMessage("AzSK reports storage account is correctly set up.", [MessageType]::Update) } else { $this.PublishCustomMessage("AzSK reports storage account does not exist.", [MessageType]::Error) } } [void] RemoveAzSKContinuousAssurancewithACI() { #Using a trick to exclude non CSEO users..To be removed if(-not [ConfigurationManager]::GetAzSKSettings().EnableAADAuthForOnlinePolicyStore) { $this.PublishCustomMessage("Container based CA is currently not available to your org ", [MessageType]::Error) return } $this.PublishCustomMessage("This command will delete resources in your subscription which were installed by AzSK Continuous Assurance using containers",[MessageType]::Warning); Remove-AzContainerGroup -ResourceGroupName $this.ResourceGroup -Name $this.ContainerName $this.PublishCustomMessage("Removed Container instance : [$($this.ContainerName)] from resource group: [$($this.ResourceGroup)]") $this.PublishCustomMessage([Constants]::SingleDashLine, [MessageType]::Info) $FunctionAppInstance = $this.GetFnAppInstance() if($FunctionAppInstance) { $this.FunctionAppName = $FunctionAppInstance.Name Remove-AzWebApp -ResourceGroupName $this.ResourceGroup -Name $this.FunctionAppName -Force $this.PublishCustomMessage("Removed Function app : [$($this.FunctionAppName)] from resource group: [$($this.ResourceGroup)]") } } } |