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

removed dependency on Az Module #1062

Merged
merged 6 commits into from
Aug 9, 2024
Merged
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
4 changes: 0 additions & 4 deletions src/bicep/add-ons/imaging/README.md
Original file line number Diff line number Diff line change
@@ -40,10 +40,6 @@ Ensure the following software is installed on your client workstation:

Upload the following scripts and files to your storage account container:

* [Az.Accounts 2.12.1 PowerShell Module](https://www.powershellgallery.com/api/v2/package/Az.Accounts/2.12.1)
* [Az.Automation 1.9.0 PowerShell Module](https://www.powershellgallery.com/api/v2/package/Az.Automation/1.9.0)
* [Az.Compute 5.7.0 PowerShell Module](https://www.powershellgallery.com/api/v2/package/Az.Compute/5.7.0)
* [Az.Resources 6.6.0 PowerShell Module](https://www.powershellgallery.com/api/v2/package/Az.Resources/6.6.0)
* [Office Installer](https://www.microsoft.com/en-us/download/details.aspx?id=49117)
* [vDot Installers](https://github.com/The-Virtual-Desktop-Team/Virtual-Desktop-Optimization-Tool/archive/refs/heads/main.zip)
* [Teams Installer - Commercial](https://teams.microsoft.com/downloads/desktopurl?env=production&plat=windows&arch=x64&managedInstaller=true&download=true)
135 changes: 55 additions & 80 deletions src/bicep/add-ons/imaging/modules/automationAccount.bicep
Original file line number Diff line number Diff line change
@@ -73,6 +73,7 @@ param wsusServer string

var parameters = {
arcGisProInstaller: arcGisProInstaller
computeGalleryImageResourceId: computeGalleryImageResourceId
computeGalleryResourceId: computeGalleryResourceId
containerName: containerName
customizations: string(customizations)
@@ -111,7 +112,7 @@ var parameters = {
officeInstaller: officeInstaller
replicaCount: string(replicaCount)
resourceGroupName: resourceGroupName
computeGalleryImageResourceId: computeGalleryImageResourceId
resourceManagerUri: environment().resourceManager
sourceImageType: sourceImageType
storageAccountResourceId: storageAccountResourceId
subnetResourceId: subnetResourceId
@@ -131,7 +132,6 @@ var parameters = {
}
var privateEndpointName = 'pe-${automationAccountName}'
var runbookName = 'New-AzureZeroTrustImageBuild'
var storageEndpoint = environment().suffixes.storage
var subscriptionId = subscription().subscriptionId
var tenantId = subscription().tenantId

@@ -205,7 +205,21 @@ resource privateDnsZoneGroup 'Microsoft.Network/privateEndpoints/privateDnsZoneG
}
}

resource runCommand 'Microsoft.Compute/virtualMachines/runCommands@2023-07-01' = {
resource runBook 'Microsoft.Automation/automationAccounts/runbooks@2023-11-01' = {
parent: automationAccount
name: runbookName
properties: {
runbookType: 'PowerShell'
logProgress: true
logVerbose: true
}
tags: union(
contains(tags, 'Microsoft.Automation/automationAccounts/runbooks') ? tags['Microsoft.Automation/automationAccounts/runbooks'] : {},
mlzTags
)
}

resource updateRunBook 'Microsoft.Compute/virtualMachines/runCommands@2023-07-01' = {
name: 'runbook'
location: location
tags: union(
@@ -218,96 +232,57 @@ resource runCommand 'Microsoft.Compute/virtualMachines/runCommands@2023-07-01' =
asyncExecution: false
parameters: [
{
name: 'AutomationAccountName'
value: automationAccountName
}
{
name: 'ContainerName'
value: containerName
}
{
name: 'Environment'
value: environment().name
}
{
name: 'ResourceGroupName'
value: resourceGroup().name
name: 'RunBookResourceId'
value: runBook.id
}
{
name: 'RunbookName'
value: runbookName
name: 'ResourceManagerUri'
value: environment().resourceManager
}
{
name: 'StorageAccountName'
value: split(storageAccountResourceId, '/')[8]
}
{
name: 'StorageEndpoint'
value: storageEndpoint
}
{
name: 'SubscriptionId'
value: subscription().subscriptionId
}
{
name: 'TenantId'
value: tenant().tenantId
name: 'RunbBookScriptContent'
value: loadTextContent('../scripts/New-AzureZeroTrustImageBuild.ps1')
}
{
name: 'UserAssignedIdentityClientId'
value: userAssignedIdentityClientId
}
{
name: 'UserAssignedIdentityObjectId'
value: userAssignedIdentityPrincipalId
}
]
source: {
script: '''
param (
[string]$AutomationAccountName,
[string]$ContainerName,
[string]$Environment,
[string]$ResourceGroupName,
[string]$RunbookName,
[string]$StorageAccountName,
[string]$StorageEndpoint,
[string]$SubscriptionId,
[string]$TenantId,
[string]$UserAssignedIdentityClientId,
[string]$UserAssignedIdentityObjectId
param(
[string]$ResourceManagerUri,
[string]$RunBookResourceId,
[string]$RunBookScriptContent,
[string]$UserAssignedIdentityClientId
)
$ErrorActionPreference = 'Stop'
$WarningPreference = 'SilentlyContinue'
$BlobName = 'New-AzureZeroTrustImageBuild.ps1'
$StorageAccountUrl = "https://" + $StorageAccountName + ".blob." + $StorageEndpoint + "/"
$TokenUri = "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=$StorageAccountUrl&object_id=$UserAssignedIdentityObjectId"
$AccessToken = ((Invoke-WebRequest -Headers @{Metadata=$true} -Uri $TokenUri -UseBasicParsing).Content | ConvertFrom-Json).access_token
$File = "$env:windir\temp\$BlobName"
do
{
try
{
Write-Output "Download Attempt $i"
Invoke-WebRequest -Headers @{"x-ms-version"="2017-11-09"; Authorization ="Bearer $AccessToken"} -Uri "$StorageAccountUrl$ContainerName/$BlobName" -OutFile $File
}
catch [System.Net.WebException]
{
Start-Sleep -Seconds 60
$i++
if($i -gt 10){throw}
continue
}
catch
{
$Output = $_ | select *
Write-Output $Output
throw

Try {
# Fix the resource manager URI since only AzureCloud contains a trailing slash
$ResourceManagerUriFixed = if($ResourceManagerUri[-1] -eq '/'){$ResourceManagerUri.Substring(0,$ResourceManagerUri.Length - 1)} else {$ResourceManagerUri}

# Get an access token for Azure resources
$AzureManagementAccessToken = (Invoke-RestMethod `
-Headers @{Metadata="true"} `
-Uri $('http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=' + $ResourceManagerUriFixed + '&client_id=' + $UserAssignedIdentityClientId)).access_token

# Set header for Azure Management API
$AzureManagementHeader = @{
'Content-Type'='application/json'
'Authorization'='Bearer ' + $AzureManagementAccessToken
}

# Upload Content to Draft
Invoke-RestMethod -Headers $AzureManagementHeader -Method 'PUT' -Uri $($ResourceManagerUriFixed + $RunBookResourceId + '/draft/content?api-version=2023-11-01') -Body $RunBookScriptContent

# Publish the RunBook
Invoke-RestMethod -Headers $AzureManagementHeader -Method 'POST' -Uri $($ResourceManagerUriFixed + $RunBookResourceId + '/publish?api-version=2023-11-01')
}
catch {
throw
}
until(Test-Path -Path $File)
Connect-AzAccount -Environment $Environment -Tenant $TenantId -Subscription $SubscriptionId -Identity -AccountId $UserAssignedIdentityClientId | Out-Null
Import-AzAutomationRunbook -Name $RunbookName -Path $File -Type PowerShell -AutomationAccountName $AutomationAccountName -ResourceGroupName $ResourceGroupName -Published -Force | Out-Null
'''
}
}
@@ -341,7 +316,7 @@ resource jobSchedule 'Microsoft.Automation/automationAccounts/jobSchedules@2022-
}
}
dependsOn: [
runCommand
updateRunBook
]
}

@@ -371,7 +346,7 @@ resource hybridRunbookWorker 'Microsoft.Automation/automationAccounts/hybridRunb
vmResourceId: virtualMachine.id
}
dependsOn: [
runCommand
updateRunBook
]
}

@@ -391,7 +366,7 @@ resource extension_HybridWorker 'Microsoft.Compute/virtualMachines/extensions@20
}
}
dependsOn: [
runCommand
updateRunBook
]
}

@@ -420,6 +395,6 @@ resource extension_JsonADDomainExtension 'Microsoft.Compute/virtualMachines/exte
}
dependsOn: [
extension_HybridWorker
runCommand
updateRunBook
]
}
6 changes: 3 additions & 3 deletions src/bicep/add-ons/imaging/modules/buildAutomation.bicep
Original file line number Diff line number Diff line change
@@ -136,17 +136,17 @@ module managementVM 'managementVM.bicep' = {
name: 'management-vm-${deploymentNameSuffix}'
scope: resourceGroup(subscriptionId, resourceGroupName)
params: {
containerName: containerName

diskEncryptionSetResourceId: diskEncryptionSetResourceId
hybridUseBenefit: hybridUseBenefit
localAdministratorPassword: localAdministratorPassword
localAdministratorUsername: localAdministratorUsername
location: location
mlzTags: mlzTags
storageAccountName: split(storageAccountResourceId, '/')[8]

subnetResourceId: subnetResourceId
tags: tags
userAssignedIdentityPrincipalId: userAssignedIdentityPrincipalId

userAssignedIdentityResourceId: userAssignedIdentityResourceId
virtualMachineName: managementVirtualMachineName
}
74 changes: 44 additions & 30 deletions src/bicep/add-ons/imaging/modules/generalizeVirtualMachine.bicep
Original file line number Diff line number Diff line change
@@ -33,50 +33,64 @@ resource generalizeVirtualMachine 'Microsoft.Compute/virtualMachines/runCommands
asyncExecution: false
parameters: [
{
name: 'Environment'
value: environment().name
}
{
name: 'ResourceGroupName'
value: resourceGroupName
}
{
name: 'SubscriptionId'
value: subscription().subscriptionId
}
{
name: 'TenantId'
value: tenant().tenantId
name: 'ResourceManagerUri'
value: environment().resourceManager
}
{
name: 'UserAssignedIdentityClientId'
value: userAssignedIdentityClientId
}
{
name: 'VirtualMachineName'
value: imageVirtualMachine.name
name: 'VmResourceId'
value: imageVirtualMachine.id
}
]
source: {
script: '''
param(
[string]$Environment,
[string]$ResourceGroupName,
[string]$SubscriptionId,
[string]$TenantId,
[string]$UserAssignedIdentityClientId,
[string]$VirtualMachineName
[Parameter(Mandatory=$true)]
[string]$ResourceManagerUri,

[Parameter(Mandatory=$true)]
[string]$UserAssignedIdentityClientId,

[Parameter(Mandatory=$true)]
[string]$VmResourceId
)

$ErrorActionPreference = 'Stop'
Connect-AzAccount -Environment $Environment -Tenant $TenantId -Subscription $SubscriptionId -Identity -AccountId $UserAssignedIdentityClientId | Out-Null
$PowerStatus = ''
while ($PowerStatus -ne 'VM stopped')
{
Start-Sleep -Seconds 5
$PowerStatus = (Get-AzVM -ResourceGroupName $ResourceGroupName -Name $VirtualMachineName -Status).Statuses[1].DisplayStatus
$WarningPreference = 'SilentlyContinue'

Try {
# Fix the resource manager URI since only AzureCloud contains a trailing slash
$ResourceManagerUriFixed = if($ResourceManagerUri[-1] -eq '/'){$ResourceManagerUri.Substring(0,$ResourceManagerUri.Length - 1)} else {$ResourceManagerUri}

# Get an access token for Azure resources
$AzureManagementAccessToken = (Invoke-RestMethod `
-Headers @{Metadata="true"} `
-Uri $('http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=' + $ResourceManagerUriFixed + '&client_id=' + $UserAssignedIdentityClientId)).access_token

# Set header for Azure Management API
$AzureManagementHeader = @{
'Content-Type'='application/json'
'Authorization'='Bearer ' + $AzureManagementAccessToken
}

# Stop the VM
$null = Invoke-RestMethod -Headers $AzureManagementHeader -Method 'Post' -Uri $($ResourceManagerUriFixed + $VmResourceId + '/powerOff?api-version=2024-03-01')
# Wait for it to show as stopped in Azure
Do {
Start-Sleep -Seconds 5
$VmStatus = Invoke-RestMethod -Headers $AzureManagementHeader -Method 'Get' -Uri $($ResourceManagerUriFixed + $VmResourceId + '/instanceView?api-version=2024-03-01')
$VMPowerState = ($VMStatus.statuses | Where-Object {$_.code -like 'PowerState*'}).displayStatus

} Until ($VMPowerState -eq 'VM stopped')
# Generatlize the VM
$null = Invoke-RestMethod -Headers $AzureManagementHeader -Method 'Post' -Uri $($ResourceManagerUriFixed + $VmResourceId + '/generalize?api-version=2024-03-01')
}
catch {
throw
}
Set-AzVm -ResourceGroupName $ResourceGroupName -Name $VirtualMachineName -Generalized
Start-Sleep -Seconds 30
'''
}
}
3 changes: 0 additions & 3 deletions src/bicep/add-ons/imaging/modules/imageBuild.bicep
Original file line number Diff line number Diff line change
@@ -81,17 +81,14 @@ module managementVM 'managementVM.bicep' =
name: 'management-vm-${deploymentNameSuffix}'
scope: resourceGroup(subscriptionId, resourceGroupName)
params: {
containerName: containerName
diskEncryptionSetResourceId: diskEncryptionSetResourceId
hybridUseBenefit: hybridUseBenefit
localAdministratorPassword: localAdministratorPassword
localAdministratorUsername: localAdministratorUsername
location: location
mlzTags: mlzTags
storageAccountName: split(storageAccountResourceId, '/')[8]
subnetResourceId: subnetResourceId
tags: tags
userAssignedIdentityPrincipalId: userAssignedIdentityPrincipalId
userAssignedIdentityResourceId: userAssignedIdentityResourceId
virtualMachineName: managementVirtualMachineName
}
9 changes: 5 additions & 4 deletions src/bicep/add-ons/imaging/modules/managementVM.bicep
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ Copyright (c) Microsoft Corporation.
Licensed under the MIT License.
*/

param containerName string
//param containerName string
param diskEncryptionSetResourceId string
param hybridUseBenefit bool
@secure()
@@ -12,10 +12,10 @@ param localAdministratorPassword string
param localAdministratorUsername string
param location string
param mlzTags object
param storageAccountName string
//param storageAccountName string
param subnetResourceId string
param tags object
param userAssignedIdentityPrincipalId string
//param userAssignedIdentityPrincipalId string
param userAssignedIdentityResourceId string
param virtualMachineName string

@@ -122,7 +122,7 @@ resource virtualMachine 'Microsoft.Compute/virtualMachines@2022-03-01' = {
licenseType: hybridUseBenefit ? 'Windows_Server' : null
}
}

/*
resource modules 'Microsoft.Compute/virtualMachines/runCommands@2023-03-01' = {
name: 'appAzModules'
location: location
@@ -209,5 +209,6 @@ resource modules 'Microsoft.Compute/virtualMachines/runCommands@2023-03-01' = {
}
}
}
*/

output name string = virtualMachine.name
Loading