Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ArcBox 3.0 - VM auto shutdown and misc updates #2659

Merged
merged 12 commits into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 43 additions & 1 deletion azure_jumpstart_arcbox/artifacts/DataOpsLogonScript.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,48 @@ $clusters = @(

Start-Transcript -Path $Env:ArcBoxLogsDir\DataOpsLogonScript.log

# Remove registry keys that are used to automatically logon the user (only used for first-time setup)
$registryPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
$keys = @("AutoAdminLogon", "DefaultUserName", "DefaultPassword")

foreach ($key in $keys) {
try {
$property = Get-ItemProperty -Path $registryPath -Name $key -ErrorAction Stop
Remove-ItemProperty -Path $registryPath -Name $key
Write-Host "Removed registry key that are used to automatically logon the user: $key"
} catch {
Write-Verbose "Key $key does not exist."
}
}

# Create Windows Terminal desktop shortcut
$WshShell = New-Object -comObject WScript.Shell
$WinTerminalPath = (Get-ChildItem "C:\Program Files\WindowsApps" -Recurse | Where-Object { $_.name -eq "wt.exe" }).FullName
$Shortcut = $WshShell.CreateShortcut("$Env:USERPROFILE\Desktop\Windows Terminal.lnk")
$Shortcut.TargetPath = $WinTerminalPath
$shortcut.WindowStyle = 3
$shortcut.Save()

# Create desktop shortcut for Logs-folder
$WshShell = New-Object -comObject WScript.Shell
$LogsPath = "C:\ArcBox\Logs"
$Shortcut = $WshShell.CreateShortcut("$Env:USERPROFILE\Desktop\Logs.lnk")
$Shortcut.TargetPath = $LogsPath
$shortcut.WindowStyle = 3
$shortcut.Save()

# Configure Windows Terminal as the default terminal application
$registryPath = "HKCU:\Console\%%Startup"

if (Test-Path $registryPath) {
Set-ItemProperty -Path $registryPath -Name "DelegationConsole" -Value "{2EACA947-7F5F-4CFA-BA87-8F7FBEEFBE69}"
Set-ItemProperty -Path $registryPath -Name "DelegationTerminal" -Value "{E12CFF52-A866-4C77-9A90-F570A7AA2C6B}"
} else {
New-Item -Path $registryPath -Force | Out-Null
Set-ItemProperty -Path $registryPath -Name "DelegationConsole" -Value "{2EACA947-7F5F-4CFA-BA87-8F7FBEEFBE69}"
Set-ItemProperty -Path $registryPath -Name "DelegationTerminal" -Value "{E12CFF52-A866-4C77-9A90-F570A7AA2C6B}"
}

$cliDir = New-Item -Path "$Env:ArcBoxDir\.cli\" -Name ".dataops" -ItemType Directory

if (-not $($cliDir.Parent.Attributes.HasFlag([System.IO.FileAttributes]::Hidden))) {
Expand Down Expand Up @@ -386,7 +428,7 @@ $clusters | Foreach-Object -ThrottleLimit 5 -Parallel {
Write-Host "Error creating custom location: $_" -ForegroundColor Red
Exit 1
}

Start-Sleep -Seconds 10

# Deploying the Azure Arc Data Controller
Expand Down
44 changes: 43 additions & 1 deletion azure_jumpstart_arcbox/artifacts/DevOpsLogonScript.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,48 @@ $clusters = @(

Start-Transcript -Path $Env:ArcBoxLogsDir\DevOpsLogonScript.log

# Remove registry keys that are used to automatically logon the user (only used for first-time setup)
$registryPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
$keys = @("AutoAdminLogon", "DefaultUserName", "DefaultPassword")

foreach ($key in $keys) {
try {
$property = Get-ItemProperty -Path $registryPath -Name $key -ErrorAction Stop
Remove-ItemProperty -Path $registryPath -Name $key
Write-Host "Removed registry key that are used to automatically logon the user: $key"
} catch {
Write-Verbose "Key $key does not exist."
}
}

# Create Windows Terminal desktop shortcut
$WshShell = New-Object -comObject WScript.Shell
$WinTerminalPath = (Get-ChildItem "C:\Program Files\WindowsApps" -Recurse | Where-Object { $_.name -eq "wt.exe" }).FullName
$Shortcut = $WshShell.CreateShortcut("$Env:USERPROFILE\Desktop\Windows Terminal.lnk")
$Shortcut.TargetPath = $WinTerminalPath
$shortcut.WindowStyle = 3
$shortcut.Save()

# Create desktop shortcut for Logs-folder
$WshShell = New-Object -comObject WScript.Shell
$LogsPath = "C:\ArcBox\Logs"
$Shortcut = $WshShell.CreateShortcut("$Env:USERPROFILE\Desktop\Logs.lnk")
$Shortcut.TargetPath = $LogsPath
$shortcut.WindowStyle = 3
$shortcut.Save()

# Configure Windows Terminal as the default terminal application
$registryPath = "HKCU:\Console\%%Startup"

if (Test-Path $registryPath) {
Set-ItemProperty -Path $registryPath -Name "DelegationConsole" -Value "{2EACA947-7F5F-4CFA-BA87-8F7FBEEFBE69}"
Set-ItemProperty -Path $registryPath -Name "DelegationTerminal" -Value "{E12CFF52-A866-4C77-9A90-F570A7AA2C6B}"
} else {
New-Item -Path $registryPath -Force | Out-Null
Set-ItemProperty -Path $registryPath -Name "DelegationConsole" -Value "{2EACA947-7F5F-4CFA-BA87-8F7FBEEFBE69}"
Set-ItemProperty -Path $registryPath -Name "DelegationTerminal" -Value "{E12CFF52-A866-4C77-9A90-F570A7AA2C6B}"
}

# Required for azcopy and Get-AzResource
Connect-AzAccount -Identity -Tenant $env:tenantId -Subscription $env:subscriptionId

Expand Down Expand Up @@ -100,7 +142,7 @@ foreach ($cluster in $clusters) {

$nicName = $cluster.clusterName + "-NIC"
$k3sVIP = az network nic ip-config list --resource-group $Env:resourceGroup --nic-name $nicName --query "[?primary == ``true``].privateIPAddress" -otsv

Write-Header "Installing istio on K3s cluster"
istioctl install --skip-confirmation

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ properties:
SwitchName: 'InternalNATSwitch'
VhdPath: F:\Virtual Machines\ArcBox-Win2K19.vhdx
ProcessorCount: 2
StartupMemory: '12GB'
StartupMemory: '4GB'
RestartIfNeeded: true
State: Running
Generation: 2
Expand All @@ -27,7 +27,7 @@ properties:
SwitchName: 'InternalNATSwitch'
VhdPath: F:\Virtual Machines\ArcBox-Win2K22.vhdx
ProcessorCount: 2
StartupMemory: '12GB'
StartupMemory: '4GB'
RestartIfNeeded: true
State: Running
Generation: 2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ properties:
SwitchName: 'InternalNATSwitch'
VhdPath: F:\Virtual Machines\ArcBox-SQL.vhdx
ProcessorCount: 2
StartupMemory: '12GB'
StartupMemory: '6GB'
RestartIfNeeded: true
State: Running
Generation: 2
Expand Down
70 changes: 58 additions & 12 deletions azure_jumpstart_arcbox/artifacts/installK3s.sh
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,17 @@ sudo chmod +x /usr/local/bin/azcopy
# Authorize azcopy by using a system-wide managed identity
export AZCOPY_AUTO_LOGIN_TYPE=MSI

# Function to check if dpkg lock is in place
check_dpkg_lock() {
while fuser /var/lib/dpkg/lock-frontend >/dev/null 2>&1; do
echo "Waiting for other package management processes to complete..."
sleep 5
done
}

# Run the lock check before attempting the installation
check_dpkg_lock

# Installing Azure CLI & Azure Arc extensions
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash

Expand Down Expand Up @@ -155,24 +166,57 @@ if [[ "$k3sControlPlane" == "true" ]]; then

sudo -u $adminUsername az connectedk8s connect --name $vmName --resource-group $resourceGroup --location $location
echo "Onboarding the k3s cluster to Azure Arc completed"

# Verify if cluster is connected to Azure Arc successfully
connectedClusterInfo=$(sudo -u $adminUsername az connectedk8s show --name $vmName --resource-group $resourceGroup)
echo "Connected cluster info: $connectedClusterInfo"

# Wait
# Enabling Container Insights and Microsoft Defender for Containers cluster extensions
echo ""
echo "Enabling Container Insights and Microsoft Defender for Containers cluster extensions"
echo ""
# Function to check if an extension is already installed
is_extension_installed() {
extension_name=$1
extension_count=$(sudo -u $adminUsername az k8s-extension list --cluster-name $vmName --resource-group $resourceGroup --cluster-type connectedClusters --query "[?name=='$extension_name'] | length(@)")

if [ "$extension_count" -gt 0 ]; then
return 0 # Extension is installed
else
return 1 # Extension is not installed
fi
}

# Enabling Container Insights and Microsoft Defender for Containers cluster extensions
echo ""
echo "Enabling Container Insights and Microsoft Defender for Containers cluster extensions"
echo ""

# Check and install azuremonitor-containers extension
if is_extension_installed "azuremonitor-containers"; then
echo "Extension 'azuremonitor-containers' is already installed."
else
echo "Extension 'azuremonitor-containers' is not installed - triggering installation"
sudo -u $adminUsername az k8s-extension create -n "azuremonitor-containers" --cluster-name $vmName --resource-group $resourceGroup --cluster-type connectedClusters --extension-type Microsoft.AzureMonitor.Containers --configuration-settings logAnalyticsWorkspaceResourceID=$workspaceResourceId --only-show-errors
sudo -u $adminUsername az k8s-extension create -n "azure-defender" --cluster-name $vmName --resource-group $resourceGroup --cluster-type connectedClusters --extension-type Microsoft.AzureDefender.Kubernetes --configuration-settings logAnalyticsWorkspaceResourceID=$workspaceResourceId --only-show-errors
fi

# Enabling Azure Policy for Kubernetes on the cluster
echo ""
echo "Enabling Azure Policy for Kubernetes on the cluster"
echo ""
sudo -u $adminUsername az k8s-extension create --name "arc-azurepolicy" --cluster-name $vmName --resource-group $resourceGroup --cluster-type connectedClusters --extension-type Microsoft.PolicyInsights --only-show-errors
# Check and install microsoft.azuredefender.kubernetes extension
if is_extension_installed "microsoft.azuredefender.kubernetes"; then
echo "Extension 'microsoft.azuredefender.kubernetes' is already installed."
else
echo "Extension 'microsoft.azuredefender.kubernetes' is not installed - triggering installation"
sudo -u $adminUsername az k8s-extension create -n "microsoft.azuredefender.kubernetes" --cluster-name $vmName --resource-group $resourceGroup --cluster-type connectedClusters --extension-type Microsoft.AzureDefender.Kubernetes --configuration-settings logAnalyticsWorkspaceResourceID=$workspaceResourceId --only-show-errors
fi

# Enabling Azure Policy for Kubernetes on the cluster
echo ""
echo "Enabling Azure Policy for Kubernetes on the cluster"
echo ""

# Check and install arc-azurepolicy extension
if is_extension_installed "azurepolicy"; then
echo "Extension 'azurepolicy' is already installed."
else
echo "Extension 'azurepolicy' is not installed - triggering installation"
sudo -u $adminUsername az k8s-extension create --name "azurepolicy" --cluster-name $vmName --resource-group $resourceGroup --cluster-type connectedClusters --extension-type Microsoft.PolicyInsights --only-show-errors
fi

else
# Downloading k3s control plane details
Expand Down Expand Up @@ -204,4 +248,6 @@ echo ""
exec 1>&3 2>&4 # Further commands will now output to the original stdout and stderr and not the log file
log="/home/$adminUsername/jumpstart_logs/installK3s-$vmName.log"
storageContainerNameLower=$(echo $storageContainerName | tr '[:upper:]' '[:lower:]')
azcopy cp $log "https://$stagingStorageAccountName.blob.core.windows.net/$storageContainerNameLower/installK3s-$vmName.log" --check-length=false >/dev/null 2>&1
azcopy cp $log "https://$stagingStorageAccountName.blob.core.windows.net/$storageContainerNameLower/installK3s-$vmName.log" --check-length=false >/dev/null 2>&1

exit 0
28 changes: 27 additions & 1 deletion azure_jumpstart_arcbox/bicep/clientVm/clientVm.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ param vmsDiskSku string = 'Premium_LRS'
@description('Use this parameter to enable or disable debug mode for the automation scripts on the client VM, effectively configuring PowerShell ErrorActionPreference to Break. Default is false.')
param debugEnabled bool = false

param autoShutdownEnabled bool = false
param autoShutdownTime string = '1800' // The time for auto-shutdown in HHmm format (24-hour clock)
param autoShutdownTimezone string = 'UTC' // Timezone for the auto-shutdown
param autoShutdownEmailRecipient string = ''

var bastionName = '${namingPrefix}-Bastion'
var publicIpAddressName = deployBastion == false ? '${vmName}-PIP' : '${bastionName}-PIP'
var networkInterfaceName = '${vmName}-NIC'
Expand Down Expand Up @@ -175,7 +180,7 @@ resource vm 'Microsoft.Compute/virtualMachines@2022-03-01' = {
}
properties: {
hardwareProfile: {
vmSize: flavor == 'DevOps' ? 'Standard_B4ms' : flavor == 'DataOps' ? 'Standard_D8s_v5' : 'Standard_D16s_v5'
vmSize: flavor == 'DevOps' ? 'Standard_B4ms' : flavor == 'DataOps' ? 'Standard_D4s_v5' : 'Standard_D8s_v5'
}
storageProfile: {
osDisk: {
Expand Down Expand Up @@ -277,5 +282,26 @@ resource vmRoleAssignment_Storage 'Microsoft.Authorization/roleAssignments@2022-
}
}

resource autoShutdown 'Microsoft.DevTestLab/schedules@2018-09-15' = if (autoShutdownEnabled) {
name: 'shutdown-computevm-${vm.name}'
location: location
properties: {
status: 'Enabled'
taskType: 'ComputeVmShutdownTask'
dailyRecurrence: {
time: autoShutdownTime
}
timeZoneId: autoShutdownTimezone
notificationSettings: {
status: 'Enabled'
timeInMinutes: 30
webhookUrl: ''
emailRecipient: autoShutdownEmailRecipient
notificationLocale: 'en'
}
targetResourceId: vm.id
}
}

output adminUsername string = windowsAdminUsername
output publicIP string = deployBastion == false ? concat(publicIpAddress.properties.ipAddress) : ''
9 changes: 9 additions & 0 deletions azure_jumpstart_arcbox/bicep/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ param resourceTags object = {
@description('The naming prefix for the nested virtual machines and all Azure resources deployed. The maximum length for the naming prefix is 7 characters,example: `ArcBox-Win2k19`')
param namingPrefix string = 'ArcBox'

param autoShutdownEnabled bool = false
param autoShutdownTime string = '1800' // The time for auto-shutdown in HHmm format (24-hour clock)
param autoShutdownTimezone string = 'UTC' // Timezone for the auto-shutdown
param autoShutdownEmailRecipient string = ''

var templateBaseUrl = 'https://raw.githubusercontent.com/${githubAccount}/azure_arc/${githubBranch}/azure_jumpstart_arcbox/'
var aksArcDataClusterName = '${namingPrefix}-AKS-Data-${guid}'
var aksDrArcDataClusterName = '${namingPrefix}-AKS-DR-Data-${guid}'
Expand Down Expand Up @@ -159,6 +164,10 @@ module clientVmDeployment 'clientVm/clientVm.bicep' = {
customLocationRPOID: customLocationRPOID
namingPrefix: namingPrefix
debugEnabled: debugEnabled
autoShutdownEnabled: autoShutdownEnabled
autoShutdownTime: autoShutdownTime
autoShutdownTimezone: autoShutdownTimezone
autoShutdownEmailRecipient: autoShutdownEmailRecipient
}
dependsOn: [
updateVNetDNSServers
Expand Down
17 changes: 17 additions & 0 deletions azure_jumpstart_arcbox/bicep/mgmt/policyAzureArc.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ param resourceTags object = {

param azureUpdateManagerArcPolicyId string = '/providers/Microsoft.Authorization/policyDefinitions/bfea026e-043f-4ff4-9d1b-bf301ca7ff46'
param azureUpdateManagerAzurePolicyId string = '/providers/Microsoft.Authorization/policyDefinitions/59efceea-0c96-497e-a4a1-4eb2290dac15'
param sshPostureControlAzurePolicyId string = '/providers/Microsoft.Authorization/policyDefinitions/a8f3e6a6-dcd2-434c-b0f7-6f309ce913b4'

param tagsRoleDefinitionId string = '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c'

Expand Down Expand Up @@ -203,3 +204,19 @@ resource updateManagerAzurePolicyLinux 'Microsoft.Authorization/policyAssignmen
}
}
}

resource sshPostureControlAudit 'Microsoft.Authorization/policyAssignments@2024-04-01' = {
name: '(ArcBox) Enable SSH Posture Control audit'
location: azureLocation
scope: resourceGroup()
properties:{
displayName: '(ArcBox) Enable SSH Posture Control audit'
description: 'Enable SSH Posture Control in audit mode'
policyDefinitionId: sshPostureControlAzurePolicyId
parameters: {
IncludeArcMachines: {
value: 'true'
}
}
}
}