Skip to content

Commit

Permalink
Merge pull request #1969 from chintalavr/arcbox_refresh
Browse files Browse the repository at this point in the history
ArcBox changes to address SQL BPA
  • Loading branch information
likamrat authored Jun 27, 2023
2 parents e25f804 + eafe5bc commit 4e07c58
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 75 deletions.
3 changes: 2 additions & 1 deletion azure_jumpstart_arcbox/ARM/mgmt/policyAzureArcBuiltins.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
"definitionId": "/providers/Microsoft.Authorization/policySetDefinitions/59e9c3eb-d8df-473b-8059-23fd38ddd0f0",
"flavors": [
"Full",
"ITPro"
"ITPro",
"DataOps"
],
"roleDefinition": [
"[concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]",
Expand Down
146 changes: 83 additions & 63 deletions azure_jumpstart_arcbox/artifacts/ArcServersLogonScript.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ if ([System.IO.File]::Exists($logFilePath)) {
Start-Transcript -Path $logFilePath -Force -ErrorAction SilentlyContinue

################################################
# Setup Hyper-V server before deploying VMs for each flavr
# Setup Hyper-V server before deploying VMs for each flavor
################################################
if ($Env:flavor -ne "DevOps") {
# Install and configure DHCP service (used by Hyper-V nested VMs)
Expand Down Expand Up @@ -158,10 +158,13 @@ if ($Env:flavor -ne "DevOps") {
az monitor log-analytics solution create --resource-group $resourceGroup --solution-type SQLAdvancedThreatProtection --workspace $Env:workspaceName --only-show-errors --no-wait
}

# Before deploying ArcBox SQL set resource group tag ArcSQLServerExtensionDeployment=Disabled to opt out of automatic SQL onboarding
az tag create --resource-id "/subscriptions/$subscriptionId/resourceGroups/$resourceGroup" --tags ArcSQLServerExtensionDeployment=Disabled

$SQLvmName = "ArcBox-SQL"
$SQLvmvhdPath = "$Env:ArcBoxVMDir\${SQLvmName}.vhdx"

Write-Host "Fetching Nested VMs"
Write-Host "Fetching SQL VM"

# Verify if VHD files already downloaded especially when re-running this script
if (!([System.IO.File]::Exists($SQLvmvhdPath) )) {
Expand Down Expand Up @@ -195,14 +198,6 @@ if ($Env:flavor -ne "DevOps") {
Write-Host "Starting SQL VM"
Start-VM -Name $SQLvmName

Write-Host "Creating VM Credentials"
# Hard-coded username and password for the nested VMs
$nestedWindowsUsername = "Administrator"
$nestedWindowsPassword = "ArcDemo123!!"

# Create Windows credential object
$secWindowsPassword = ConvertTo-SecureString $nestedWindowsPassword -AsPlainText -Force
$winCreds = New-Object System.Management.Automation.PSCredential ($nestedWindowsUsername, $secWindowsPassword)

# Restarting Windows VM Network Adapters
Write-Host "Restarting Network Adapters"
Expand All @@ -212,14 +207,12 @@ if ($Env:flavor -ne "DevOps") {

# Copy installation script to nested Windows VMs
Write-Output "Transferring installation script to nested Windows VMs..."
Copy-VMFile $SQLvmName -SourcePath "$agentScript\installArcAgent.ps1" -DestinationPath "$Env:ArcBoxDir\installArcAgent.ps1" -CreateFullPath -FileSource Host -Force
Copy-VMFile $SQLvmName -SourcePath "$agentScript\installArcAgentSQLSP.ps1" -DestinationPath "$Env:ArcBoxDir\installArcAgentSQL.ps1" -CreateFullPath -FileSource Host -Force

Write-Header "Onboarding Arc-enabled Servers"

# Onboarding the nested VMs as Azure Arc-enabled servers
Write-Output "Onboarding the nested Windows VMs as Azure Arc-enabled servers"
Invoke-Command -VMName $SQLvmName -ScriptBlock { powershell -File $Using:nestedVMArcBoxDir\installArcAgent.ps1 -spnClientId $Using:spnClientId, -spnClientSecret $Using:spnClientSecret, -spnTenantId $Using:spnTenantId, -subscriptionId $Using:subscriptionId, -resourceGroup $Using:resourceGroup, -azureLocation $Using:azureLocation } -Credential $winCreds
Invoke-Command -VMName $SQLvmName -ScriptBlock { powershell -File $Using:nestedVMArcBoxDir\installArcAgentSQL.ps1 -spnClientId $Using:spnClientId, -spnClientSecret $Using:spnClientSecret, -spnTenantId $Using:spnTenantId, -subscriptionId $Using:subscriptionId, -resourceGroup $Using:resourceGroup, -azureLocation $Using:azureLocation } -Credential $winCreds

# Configure SSH on the nested Windows VMs
Expand All @@ -229,78 +222,105 @@ if ($Env:flavor -ne "DevOps") {
azcmagent config set incomingconnections.ports 22
} -Credential $winCreds


# Install Log Analytics extension to support Defender for SQL
$mmaExtension = az connectedmachine extension list --machine-name $SQLvmName --resource-group $resourceGroup --query "[?name=='MicrosoftMonitoringAgent']" | ConvertFrom-Json
if ($mmaExtension.Count -le 0) {
# Get workspace information
$workspaceID = (az monitor log-analytics workspace show --resource-group $resourceGroup --workspace-name $Env:workspaceName --query "customerId" -o tsv)
$workspaceKey = (az monitor log-analytics workspace get-shared-keys --resource-group $resourceGroup --workspace-name $Env:workspaceName --query "primarySharedKey" -o tsv)

Write-Host "Deploying Microsoft Monitoring Agent to test Defender for SQL."
az connectedmachine extension create --machine-name $SQLvmName --name "MicrosoftMonitoringAgent" --settings "{'workspaceId':'$workspaceID'}" --protected-settings "{'workspaceKey':'$workspaceKey'}" --resource-group $resourceGroup --type-handler-version "1.0.18067.0" --type "MicrosoftMonitoringAgent" --publisher "Microsoft.EnterpriseCloud.Monitoring" --no-wait
Write-Host "Microsoft Monitoring Agent deployment initiated."
}

# Azure Monitor Agent extension is deployed automatically using Azure Policy. Wait until extension status is Succeded.
$retryCount = 0
do {
Start-Sleep(60)
$amaExtension = az connectedmachine extension list --machine-name $SQLvmName --resource-group $resourceGroup --query "[?name=='AzureMonitorWindowsAgent']" | ConvertFrom-Json
if ($amaExtension[0].properties.instanceView.status.code -eq 0) {
Write-Host "Azure Monitoring Agent extension installation complete."
break
}

$retryCount = $retryCount + 1
Write-Host "Waiting for Azure Monitoring Agent extension installation to complete ... Retry count: $retryCount"

if ($retryCount -gt 5) {
Write-Host "WARNING: Azure Monitor Agent extenstion is taking longger than expected. Enable SQL BPA later through Azure portal."
}

} while ($retryCount -le 5)

# Enable Best practices assessment
# Create custom log analytics table for SQL assessment
az monitor log-analytics workspace table create --resource-group $resourceGroup --workspace-name $Env:workspaceName -n SqlAssessment_CL --columns RawData=string TimeGenerated=datetime --only-show-errors

# Verify if Arc-enabled server and SQL server extensions are installed
$ArcServer = az connectedmachine show --name $SQLvmName --resource-group $resourceGroup
if ($null -ne $ArcServer) {
$sqlExtension = az connectedmachine extension list --machine-name $SQLvmName --resource-group $resourceGroup --query "[?name=='WindowsAgent.SqlServer']" | ConvertFrom-Json
if ($null -ne $sqlExtension) {
# SQL server extension is installed and ready to run SQL BPA
Write-Host "SQL server extension is installed and ready to run SQL BPA."
if ($amaExtension[0].properties.instanceView.status.code -eq 0) {

# Create custom log analytics table for SQL assessment
az monitor log-analytics workspace table create --resource-group $resourceGroup --workspace-name $Env:workspaceName -n SqlAssessment_CL --columns RawData=string TimeGenerated=datetime --only-show-errors

# Verify if Arc-enabled server and SQL server extensions are installed
$ArcServer = az connectedmachine show --name $SQLvmName --resource-group $resourceGroup
if ($null -ne $ArcServer) {
$sqlExtension = az connectedmachine extension list --machine-name $SQLvmName --resource-group $resourceGroup --query "[?name=='WindowsAgent.SqlServer']" | ConvertFrom-Json
if ($null -ne $sqlExtension) {
# SQL server extension is installed and ready to run SQL BPA
Write-Host "SQL server extension is installed and ready to run SQL BPA."
}
else {
# Arc SQL Server extension is not installed or still in progress.
Write-Host "SQL server extension is not installed and can't run SQL BPA."
Exit
}
}
else {
# Arc SQL Server extension is not installed or still in progress.
Write-Host "SQL server extension is not installed and can't run SQL BPA."
# ArcBox-SQL Arc-enabled server resource not found
Write-Host "ArcBox-SQL Arc-enabled server resource not found. Re-run onboard script to fix this issue."
Exit
}
}
else {
# ArcBox-SQL Arc-enabled server resource not found
Write-Host "ArcBox-SQL Arc-enabled server resource not found. Re-run onboard script to fix this issue."
Exit
}

# Verify if ArcBox SQL resource is created
$arcSQLStatus = az resource list --resource-group $resourceGroup --query "[?name=='$SQLvmName'] | [?type=='Microsoft.AzureArcData/SqlServerInstances'].[provisioningState]" -o tsv
if ($arcSQLStatus -ne "Succeeded"){
Write-Host "ArcBox-SQL Arc-enabled server resource not found. Wait for the resource to be created and follow troubleshooting guide to run assessment manually."
}
else {
<# Action when all if and elseif conditions are false #>
Write-Host "Enabling SQL server best practices assessment"
$bpaDeploymentTemplateUrl = "$Env:templateBaseUrl/artifacts/sqlbpa.json"
az deployment group create --resource-group $resourceGroup --template-uri $bpaDeploymentTemplateUrl --parameters workspaceName=$Env:workspaceName vmName=$SQLvmName arcSubscriptionId=$subscriptionId

# Verify if ArcBox SQL resource is created
$arcSQLStatus = az resource list --resource-group $resourceGroup --query "[?type=='Microsoft.AzureArcData/SqlServerInstances'].[provisioningState]" -o tsv
if ($arcSQLStatus -ne "Succeeded"){
Write-Host "WARNING: ArcBox-SQL Arc-enabled server resource not found. Wait for the resource to be created and follow troubleshooting guide to run assessment manually."
}
else {
<# Action when all if and elseif conditions are false #>
Write-Host "Enabling SQL server best practices assessment"
$bpaDeploymentTemplateUrl = "$Env:templateBaseUrl/artifacts/sqlbpa.json"
az deployment group create --resource-group $resourceGroup --template-uri $bpaDeploymentTemplateUrl --parameters workspaceName=$Env:workspaceName vmName=$SQLvmName arcSubscriptionId=$subscriptionId

# Run Best practices assessment
Write-Host "Execute SQL server best practices assessment"
# Run Best practices assessment
Write-Host "Execute SQL server best practices assessment"

# Wait for a minute to finish everyting and run assessment
Start-Sleep(60)
# Wait for a minute to finish everyting and run assessment
Start-Sleep(60)

# Get access token to make ARM REST API call for SQL server BPA
$armRestApiEndpoint = "https://management.azure.com/subscriptions/$subscriptionId/resourcegroups/$resourceGroup/providers/Microsoft.HybridCompute/machines/$SQLvmName/extensions/WindowsAgent.SqlServer?api-version=2019-08-02-preview"
$token = (az account get-access-token --subscription $subscriptionId --query accessToken --output tsv)
$headers = @{"Authorization" = "Bearer $token"; "Content-Type" = "application/json" }
# Get access token to make ARM REST API call for SQL server BPA
$armRestApiEndpoint = "https://management.azure.com/subscriptions/$subscriptionId/resourcegroups/$resourceGroup/providers/Microsoft.HybridCompute/machines/$SQLvmName/extensions/WindowsAgent.SqlServer?api-version=2019-08-02-preview"
$token = (az account get-access-token --subscription $subscriptionId --query accessToken --output tsv)
$headers = @{"Authorization" = "Bearer $token"; "Content-Type" = "application/json" }

# Build API request payload
$worspaceResourceId = "/subscriptions/$subscriptionId/resourcegroups/$resourceGroup/providers/microsoft.operationalinsights/workspaces/$Env:workspaceName".ToLower()
$sqlExtensionId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.HybridCompute/machines/$SQLvmName/extensions/WindowsAgent.SqlServer"
$sqlbpaPayloadTemplate = "$Env:templateBaseUrl/artifacts/sqlbpa.payload.json"
$settingsSaveTime = [DateTimeOffset]::UtcNow.ToUnixTimeSeconds()
$apiPayload = (Invoke-WebRequest -Uri $sqlbpaPayloadTemplate).Content -replace '{{RESOURCEID}}', $sqlExtensionId -replace '{{LOCATION}}', $azureLocation -replace '{{WORKSPACEID}}', $worspaceResourceId -replace '{{SAVETIME}}', $settingsSaveTime
# Build API request payload
$worspaceResourceId = "/subscriptions/$subscriptionId/resourcegroups/$resourceGroup/providers/microsoft.operationalinsights/workspaces/$Env:workspaceName".ToLower()
$sqlExtensionId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.HybridCompute/machines/$SQLvmName/extensions/WindowsAgent.SqlServer"
$sqlbpaPayloadTemplate = "$Env:templateBaseUrl/artifacts/sqlbpa.payload.json"
$settingsSaveTime = [DateTimeOffset]::UtcNow.ToUnixTimeSeconds()
$apiPayload = (Invoke-WebRequest -Uri $sqlbpaPayloadTemplate).Content -replace '{{RESOURCEID}}', $sqlExtensionId -replace '{{LOCATION}}', $azureLocation -replace '{{WORKSPACEID}}', $worspaceResourceId -replace '{{SAVETIME}}', $settingsSaveTime

# Call REST API to run best practices assessment
$httpResp = Invoke-WebRequest -Method Patch -Uri $armRestApiEndpoint -Body $apiPayload -Headers $headers
if (($httpResp.StatusCode -eq 200) -or ($httpResp.StatusCode -eq 202)){
Write-Host "Arc-enabled SQL server best practices assessment executed. Wait for assessment to complete to view results."
}
else {
<# Action when all if and elseif conditions are false #>
Write-Host "SQL Best Practices Assessment faild. Please refer troubleshooting guide to run manually."
# Call REST API to run best practices assessment
$httpResp = Invoke-WebRequest -Method Patch -Uri $armRestApiEndpoint -Body $apiPayload -Headers $headers
if (($httpResp.StatusCode -eq 200) -or ($httpResp.StatusCode -eq 202)){
Write-Host "Arc-enabled SQL server best practices assessment executed. Wait for assessment to complete to view results."
}
else {
<# Action when all if and elseif conditions are false #>
Write-Host "SQL Best Practices Assessment faild. Please refer troubleshooting guide to run manually."
}
}
}
} # End of SQL BPA

# Test Defender for SQL
Write-Header "Simulating SQL threats to generate alerts from Defender for Cloud"
Expand Down
11 changes: 0 additions & 11 deletions azure_jumpstart_arcbox/artifacts/sqlbpa.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,17 +125,6 @@
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"type": "Microsoft.HybridCompute/machines/extensions",
"apiVersion": "2021-12-10-preview",
"name": "[format('{0}/AzureMonitorWindowsAgent', parameters('vmName'))]",
"location": "[variables('location')]",
"properties": {
"publisher": "Microsoft.Azure.Monitor",
"type": "AzureMonitorWindowsAgent",
"autoUpgradeMinorVersion": true
}
},
{
"type": "Microsoft.Insights/dataCollectionRuleAssociations",
"apiVersion": "2021-09-01-preview",
Expand Down

0 comments on commit 4e07c58

Please sign in to comment.