-
Notifications
You must be signed in to change notification settings - Fork 557
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2288 from dkirby-ms/new_vi_scenario
VI Scenario Update
- Loading branch information
Showing
11 changed files
with
5,360 additions
and
0 deletions.
There are no files selected for viewing
149 changes: 149 additions & 0 deletions
149
azure_arc_k8s_jumpstart/aks_hybrid/aks_edge_essentials_single_vi/artifacts/Bootstrap.ps1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
param ( | ||
[string]$adminUsername, | ||
[string]$appId, | ||
[string]$password, | ||
[string]$tenantId, | ||
[string]$subscriptionId, | ||
[string]$location, | ||
[string]$templateBaseUrl, | ||
[string]$resourceGroup, | ||
[string]$kubernetesDistribution, | ||
[string]$videoIndexerAccountName, | ||
[string]$videoIndexerAccountId, | ||
[string]$rdpPort | ||
) | ||
|
||
[System.Environment]::SetEnvironmentVariable('adminUsername', $adminUsername,[System.EnvironmentVariableTarget]::Machine) | ||
[System.Environment]::SetEnvironmentVariable('appId', $appId,[System.EnvironmentVariableTarget]::Machine) | ||
[System.Environment]::SetEnvironmentVariable('password', $password,[System.EnvironmentVariableTarget]::Machine) | ||
[System.Environment]::SetEnvironmentVariable('tenantId', $tenantId,[System.EnvironmentVariableTarget]::Machine) | ||
[System.Environment]::SetEnvironmentVariable('resourceGroup', $resourceGroup,[System.EnvironmentVariableTarget]::Machine) | ||
[System.Environment]::SetEnvironmentVariable('location', $location,[System.EnvironmentVariableTarget]::Machine) | ||
[System.Environment]::SetEnvironmentVariable('subscriptionId', $subscriptionId,[System.EnvironmentVariableTarget]::Machine) | ||
[System.Environment]::SetEnvironmentVariable('templateBaseUrl', $templateBaseUrl,[System.EnvironmentVariableTarget]::Machine) | ||
[System.Environment]::SetEnvironmentVariable('kubernetesDistribution', $kubernetesDistribution,[System.EnvironmentVariableTarget]::Machine) | ||
[System.Environment]::SetEnvironmentVariable('videoIndexerAccountName', $videoIndexerAccountName,[System.EnvironmentVariableTarget]::Machine) | ||
[System.Environment]::SetEnvironmentVariable('videoIndexerAccountId', $videoIndexerAccountId,[System.EnvironmentVariableTarget]::Machine) | ||
[System.Environment]::SetEnvironmentVariable('rdpPort', $rdpPort,[System.EnvironmentVariableTarget]::Machine) | ||
|
||
# Create path | ||
Write-Output "Create deployment path" | ||
$tempDir = "C:\Temp" | ||
New-Item -Path $tempDir -ItemType directory -Force | ||
|
||
Start-Transcript "C:\Temp\Bootstrap.log" | ||
|
||
$ErrorActionPreference = "SilentlyContinue" | ||
|
||
############################################################## | ||
# Change RDP Port | ||
############################################################## | ||
Write-Host "RDP port number from configuration is $rdpPort" | ||
if (($rdpPort -ne $null) -and ($rdpPort -ne "") -and ($rdpPort -ne "3389")) { | ||
Write-Host "Configuring RDP port number to $rdpPort" | ||
$TSPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server' | ||
$RDPTCPpath = $TSPath + '\Winstations\RDP-Tcp' | ||
Set-ItemProperty -Path $TSPath -name 'fDenyTSConnections' -Value 0 | ||
|
||
# RDP port | ||
$portNumber = (Get-ItemProperty -Path $RDPTCPpath -Name 'PortNumber').PortNumber | ||
Write-Host "Current RDP PortNumber: $portNumber" | ||
if (!($portNumber -eq $rdpPort)) { | ||
Write-Host Setting RDP PortNumber to $rdpPort | ||
Set-ItemProperty -Path $RDPTCPpath -name 'PortNumber' -Value $rdpPort | ||
Restart-Service TermService -force | ||
} | ||
|
||
#Setup firewall rules | ||
if ($rdpPort -eq 3389) { | ||
netsh advfirewall firewall set rule group="remote desktop" new Enable=Yes | ||
} | ||
else { | ||
$systemroot = get-content env:systemroot | ||
netsh advfirewall firewall add rule name="Remote Desktop - Custom Port" dir=in program=$systemroot\system32\svchost.exe service=termservice action=allow protocol=TCP localport=$RDPPort enable=yes | ||
} | ||
|
||
Write-Host "RDP port configuration complete." | ||
} | ||
|
||
# Downloading GitHub artifacts | ||
Invoke-WebRequest ($templateBaseUrl + "artifacts/LogonScript.ps1") -OutFile "C:\Temp\LogonScript.ps1" | ||
Invoke-WebRequest ($templateBaseUrl + "artifacts/longhorn.yaml") -OutFile "C:\Temp\longhorn.yaml" | ||
Invoke-WebRequest ($templateBaseUrl + "artifacts/video/video.mp4") -OutFile "C:\Temp\video.mp4" | ||
Invoke-WebRequest "https://raw.githubusercontent.com/microsoft/azure_arc/main/img/jumpstart_wallpaper.png" -OutFile "C:\Temp\wallpaper.png" | ||
Invoke-WebRequest "https://github.com/certbot/certbot/releases/latest/download/certbot-beta-installer-win_amd64_signed.exe" -OutFile "C:\Temp\certbot-beta-installer-win_amd64_signed.exe" | ||
|
||
############################################################## | ||
# Install Azure CLI (64-bit not available via Chocolatey) | ||
############################################################## | ||
$ProgressPreference = 'SilentlyContinue' | ||
Invoke-WebRequest -Uri https://aka.ms/installazurecliwindowsx64 -OutFile .\AzureCLI.msi | ||
Start-Process msiexec.exe -Wait -ArgumentList '/I AzureCLI.msi /quiet' | ||
Remove-Item .\AzureCLI.msi | ||
|
||
# Installing tools | ||
Write-Header "Installing Chocolatey Apps" | ||
$chocolateyAppList = 'az.powershell,kubernetes-cli,kubernetes-helm,vscode' | ||
Start-Process msiexec.exe -Wait -ArgumentList '/I AzureCLI.msi /quiet' | ||
Start-Process msiexec.exe -Wait -ArgumentList '/I AzureCLI.msi /quiet' | ||
Start-Process "C:\Temp\certbot-beta-installer-win_amd64_signed.exe" -Wait -ArgumentList '/S' | ||
|
||
try { | ||
choco config get cacheLocation | ||
} | ||
catch { | ||
Write-Output "Chocolatey not detected, trying to install now" | ||
Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) | ||
} | ||
|
||
Write-Host "Chocolatey Apps Specified" | ||
|
||
$appsToInstall = $chocolateyAppList -split "," | ForEach-Object { "$($_.Trim())" } | ||
|
||
foreach ($app in $appsToInstall) | ||
{ | ||
Write-Host "Installing $app" | ||
& choco install $app /y -Force | Write-Output | ||
} | ||
|
||
# Enable VirtualMachinePlatform feature, the vm reboot will be done in DSC extension | ||
Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform -NoRestart | ||
|
||
# Disable Microsoft Edge sidebar | ||
$RegistryPath = 'HKLM:\SOFTWARE\Policies\Microsoft\Edge' | ||
$Name = 'HubsSidebarEnabled' | ||
$Value = '00000000' | ||
# Create the key if it does not exist | ||
If (-NOT (Test-Path $RegistryPath)) { | ||
New-Item -Path $RegistryPath -Force | Out-Null | ||
} | ||
New-ItemProperty -Path $RegistryPath -Name $Name -Value $Value -PropertyType DWORD -Force | ||
|
||
# Disable Microsoft Edge first-run Welcome screen | ||
$RegistryPath = 'HKLM:\SOFTWARE\Policies\Microsoft\Edge' | ||
$Name = 'HideFirstRunExperience' | ||
$Value = '00000001' | ||
# Create the key if it does not exist | ||
If (-NOT (Test-Path $RegistryPath)) { | ||
New-Item -Path $RegistryPath -Force | Out-Null | ||
} | ||
New-ItemProperty -Path $RegistryPath -Name $Name -Value $Value -PropertyType DWORD -Force | ||
|
||
# Creating scheduled task for LogonScript.ps1 | ||
$Trigger = New-ScheduledTaskTrigger -AtLogOn | ||
$Action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument 'C:\Temp\LogonScript.ps1' | ||
Register-ScheduledTask -TaskName "LogonScript" -Trigger $Trigger -User $adminUsername -Action $Action -RunLevel "Highest" -Force | ||
|
||
# Disabling Windows Server Manager Scheduled Task | ||
Get-ScheduledTask -TaskName ServerManager | Disable-ScheduledTask | ||
|
||
# Install Hyper-V and reboot | ||
Write-Host "Installing Hyper-V and restart" | ||
Enable-WindowsOptionalFeature -Online -FeatureName Containers -All -NoRestart | ||
Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform -NoRestart | ||
Install-WindowsFeature -Name Hyper-V -IncludeAllSubFeature -IncludeManagementTools -Restart | ||
|
||
# Clean up Bootstrap.log | ||
Stop-Transcript | ||
$logSuppress = Get-Content C:\Temp\Bootstrap.log | Where-Object { $_ -notmatch "Host Application: powershell.exe" } | ||
$logSuppress | Set-Content C:\Temp\Bootstrap.log -Force |
235 changes: 235 additions & 0 deletions
235
azure_arc_k8s_jumpstart/aks_hybrid/aks_edge_essentials_single_vi/artifacts/LogonScript.ps1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,235 @@ | ||
Start-Transcript -Path C:\Temp\LogonScript.log | ||
|
||
Set-ExecutionPolicy Bypass -Scope Process -Force | ||
|
||
# Parameters | ||
$schemaVersionAksEdgeConfig = "1.9" | ||
$versionAksEdgeConfig = "1.0" | ||
$guid = ([System.Guid]::NewGuid()).ToString().subString(0,5).ToLower() | ||
$clusterName = "$Env:resourceGroup-$guid" | ||
|
||
# Configure AKS disk | ||
$storagePoolName = "AKS" | ||
$diskName = "AKSData" | ||
$disks = Get-Disk | Where-Object partitionStyle -eq "raw" | Get-PhysicalDisk | ||
$storageName = Get-StorageSubsystem | Select-Object -expand FriendlyName | ||
New-StoragePool -FriendlyName $storagePoolName -StorageSubSystemFriendlyName $storageName -PhysicalDisks $disks | ||
New-VirtualDisk -StoragePoolFriendlyName $storagePoolName -FriendlyName $diskName -Size (500GB) -ResiliencySettingName Simple | ||
Get-VirtualDisk -FriendlyName $diskName | Get-Disk | Initialize-Disk -Passthru | New-Partition -AssignDriveLetter -UseMaximumSize | Format-Volume -NewFileSystemLabel $diskName | ||
|
||
# Install AKS EE | ||
$letter = Get-Volume | Where-Object FileSystemLabel -eq $diskName | ||
$installPath = "$($letter.DriveLetter):\AKSEdge" | ||
New-Item -Path $installPath -ItemType Directory | ||
$aksEEk3sUrl = 'https://aka.ms/aks-edge/k3s-msi' | ||
$tempDir = "C:\Temp" | ||
$ProgressPreference = "SilentlyContinue" | ||
Invoke-WebRequest $aksEEk3sUrl -OutFile $tempDir\AKSEEK3s.msi | ||
msiexec.exe /i $tempDir\AKSEEK3s.msi INSTALLDIR=$installPath /q /passive | ||
Start-Sleep 45 | ||
|
||
Import-Module AksEdge | ||
Get-Command -Module AKSEdge | Format-Table Name, Version | ||
|
||
# Here string for the json content | ||
$aksedgeConfig = @" | ||
{ | ||
"SchemaVersion": "$schemaVersionAksEdgeConfig", | ||
"Version": "$versionAksEdgeConfig", | ||
"DeploymentType": "SingleMachineCluster", | ||
"Init": { | ||
"ServiceIPRangeSize": 30 | ||
}, | ||
"Network": { | ||
"NetworkPlugin": "$networkplugin", | ||
"InternetDisabled": false | ||
}, | ||
"User": { | ||
"AcceptEula": true, | ||
"AcceptOptionalTelemetry": true | ||
}, | ||
"Arc": { | ||
"ClusterName": "$clusterName", | ||
"Location": "${env:location}", | ||
"ResourceGroupName": "${env:resourceGroup}", | ||
"SubscriptionId": "${env:subscriptionId}", | ||
"TenantId": "${env:tenantId}", | ||
"ClientId": "${env:appId}", | ||
"ClientSecret": "${env:password}" | ||
}, | ||
"Machines": [ | ||
{ | ||
"LinuxNode": { | ||
"CpuCount": 12, | ||
"MemoryInMB": 50000, | ||
"DataSizeInGB": 300 | ||
} | ||
} | ||
] | ||
} | ||
"@ | ||
|
||
Set-Content -Path $tempDir\aksedge-config.json -Value $aksedgeConfig -Force | ||
|
||
New-AksEdgeDeployment -JsonConfigFilePath $tempDir\aksedge-config.json | ||
|
||
Write-Host "`n" | ||
Write-Host "Checking kubernetes nodes" | ||
Write-Host "`n" | ||
kubectl get nodes -o wide | ||
Write-Host "`n" | ||
|
||
# az version | ||
az -v | ||
|
||
# Login as service principal | ||
az login --service-principal --username $Env:appId --password $Env:password --tenant $Env:tenantId | ||
|
||
# Set default subscription to run commands against | ||
# "subscriptionId" value comes from clientVM.json ARM template, based on which | ||
# subscription user deployed ARM template to. This is needed in case Service | ||
# Principal has access to multiple subscriptions, which can break the automation logic | ||
az account set --subscription $Env:subscriptionId | ||
|
||
# Installing Azure CLI extensions | ||
az config set extension.use_dynamic_install=yes_without_prompt | ||
Write-Host "`n" | ||
Write-Host "Installing Azure CLI extensions" | ||
# az extension add --name connectedk8s --version 1.3.17 | ||
az extension add --name k8s-extension | ||
Write-Host "`n" | ||
|
||
# Registering Azure Arc providers | ||
Write-Host "Registering Azure Arc providers, hold tight..." | ||
Write-Host "`n" | ||
az provider register --namespace Microsoft.Kubernetes --wait | ||
az provider register --namespace Microsoft.KubernetesConfiguration --wait | ||
az provider register --namespace Microsoft.HybridCompute --wait | ||
az provider register --namespace Microsoft.GuestConfiguration --wait | ||
az provider register --namespace Microsoft.HybridConnectivity --wait | ||
az provider register --namespace Microsoft.ExtendedLocation --wait | ||
|
||
az provider show --namespace Microsoft.Kubernetes -o table | ||
Write-Host "`n" | ||
az provider show --namespace Microsoft.KubernetesConfiguration -o table | ||
Write-Host "`n" | ||
az provider show --namespace Microsoft.HybridCompute -o table | ||
Write-Host "`n" | ||
az provider show --namespace Microsoft.GuestConfiguration -o table | ||
Write-Host "`n" | ||
az provider show --namespace Microsoft.HybridConnectivity -o table | ||
Write-Host "`n" | ||
az provider show --namespace Microsoft.ExtendedLocation -o table | ||
Write-Host "`n" | ||
|
||
# Onboarding the cluster to Azure Arc | ||
Write-Host "Onboarding the AKS Edge Essentials cluster to Azure Arc..." | ||
Write-Host "`n" | ||
|
||
$kubectlMonShell = Start-Process -PassThru PowerShell { for (0 -lt 1) { kubectl get pod -A; Start-Sleep -Seconds 5; Clear-Host } } | ||
|
||
# Connect Arc-enabled kubernetes | ||
Connect-AksEdgeArc -JsonConfigFilePath $tempDir\aksedge-config.json | ||
|
||
##################################################################### | ||
### Install ingress-nginx | ||
##################################################################### | ||
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx | ||
helm repo update | ||
helm install ingress-nginx ingress-nginx/ingress-nginx | ||
|
||
##################################################################### | ||
### Longhorn setup for RWX-capable storage class | ||
##################################################################### | ||
Write-Host "Creating longhorn storage on AKS EE cluster." | ||
kubectl apply -f c:\temp\longhorn.yaml | ||
Start-Sleep -Seconds 30 | ||
|
||
##################################################################### | ||
### Video Indexer setup | ||
##################################################################### | ||
$viApiVersion="2023-06-02-preview" | ||
$extensionName="videoindexer" | ||
#$version="1.0.28-preview" # switch to blank | ||
$namespace="video-indexer" | ||
$releaseTrain="release" # switch to release | ||
$storageClass="longhorn" | ||
|
||
Write-Host "Create Cognitive Services on VI resource provider" | ||
$createResourceUri = "https://management.azure.com/subscriptions/${env:subscriptionId}/resourceGroups/${env:resourceGroup}/providers/Microsoft.VideoIndexer/accounts/${env:videoIndexerAccountName}/CreateExtensionDependencies?api-version=${viApiVersion}" | ||
$result = $(az rest --method post --uri $createResourceUri) | ConvertFrom-Json | ||
|
||
Write-Host "Retrieving Cognitive Service Credentials..." | ||
$getSecretsUri="https://management.azure.com/subscriptions/${env:subscriptionId}/resourceGroups/${env:resourceGroup}/providers/Microsoft.VideoIndexer/accounts/${env:videoIndexerAccountName}/ListExtensionDependenciesData?api-version=$viApiVersion" | ||
$csResourcesData=$(az rest --method post --uri $getSecretsUri) | ConvertFrom-Json | ||
Write-Host | ||
|
||
Write-Host "Getting VM public IP address..." | ||
$hostname = hostname | ||
$ipAddresses = az vm list-ip-addresses -g $env:resourceGroup -n $hostname | ConvertFrom-Json | ||
$ipAddress = $ipAddresses.virtualMachine.network.publicIpAddresses[0].ipAddress | ||
|
||
Write-Host "Installing Video Indexer extension into AKS EE cluster." | ||
az k8s-extension create --name $extensionName ` | ||
--extension-type Microsoft.VideoIndexer ` | ||
--scope cluster ` | ||
--release-namespace $namespace ` | ||
--cluster-name $clusterName ` | ||
--resource-group $Env:resourceGroup ` | ||
--cluster-type connectedClusters ` | ||
--release-train $releaseTrain ` | ||
--auto-upgrade-minor-version false ` | ||
--config-protected-settings "speech.endpointUri=$($csResourcesData.speechCognitiveServicesEndpoint)" ` | ||
--config-protected-settings "speech.secret=$($csResourcesData.speechCognitiveServicesPrimaryKey)" ` | ||
--config-protected-settings "translate.endpointUri=$($csResourcesData.translatorCognitiveServicesEndpoint)" ` | ||
--config-protected-settings "translate.secret=$($csResourcesData.translatorCognitiveServicesPrimaryKey)" ` | ||
--config "videoIndexer.accountId=${Env:videoIndexerAccountId}" ` | ||
--config "frontend.endpointUri=https://$ipAddress" ` | ||
--config "storage.storageClass=$storageClass" ` | ||
--config "storage.accessMode=ReadWriteMany" | ||
|
||
# Allow access to the frontend through the VM NIC interface | ||
Write-Host "Adding Windows Defender firewall rule for VI frontend..." | ||
New-NetFirewallRule -DisplayName "Allow Inbound Port 80" -Direction Inbound -LocalPort 80 -Protocol TCP -Action Allow | ||
New-NetFirewallRule -DisplayName "Allow Inbound Port 443" -Direction Inbound -LocalPort 443 -Protocol TCP -Action Allow | ||
|
||
Write-Host "Adding port forward for VI frontend..." | ||
Start-Sleep -Seconds 20 | ||
$ing = kubectl get ing videoindexer-vi-arc -n $namespace -o json | ConvertFrom-Json | ||
$ingIp = $ing.status.loadBalancer.ingress.ip | ||
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=80 connectaddress=$ingIp connectport=80 | ||
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=443 connectaddress=$ingIp connectport=443 | ||
|
||
# Kill the open PowerShell monitoring kubectl get pods | ||
Stop-Process -Id $kubectlMonShell.Id | ||
|
||
# Install Postman | ||
choco install postman /y -Force | ||
|
||
# Removing the LogonScript Scheduled Task so it won't run on next reboot | ||
Unregister-ScheduledTask -TaskName "LogonScript" -Confirm:$false | ||
Start-Sleep -Seconds 5 | ||
$ProgressPreference = "Continue" | ||
|
||
# Changing to Client VM wallpaper | ||
$imgPath = "C:\Temp\wallpaper.png" | ||
$code = @' | ||
using System.Runtime.InteropServices; | ||
namespace Win32{ | ||
public class Wallpaper{ | ||
[DllImport("user32.dll", CharSet=CharSet.Auto)] | ||
static extern int SystemParametersInfo (int uAction , int uParam , string lpvParam , int fuWinIni) ; | ||
public static void SetWallpaper(string thePath){ | ||
SystemParametersInfo(20,0,thePath,3); | ||
} | ||
} | ||
} | ||
'@ | ||
|
||
add-type $code | ||
[Win32.Wallpaper]::SetWallpaper($imgPath) | ||
Stop-Process -Name powershell -Force | ||
|
||
Stop-Transcript |
Oops, something went wrong.