Skip to content

Instantly share code, notes, and snippets.

@colbylwilliams
Created July 7, 2023 18:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save colbylwilliams/175e33349bf09afdf1456d515bb79c1d to your computer and use it in GitHub Desktop.
Save colbylwilliams/175e33349bf09afdf1456d515bb79c1d to your computer and use it in GitHub Desktop.
Test creating custom images for DevBox using first party CPC and VS base images and Azure Image Builder.
param location string = resourceGroup().location
@description('Object ID for the first-party Windows 365 enterprise application in your tenant. You find this ID in the Azure portal or via the Azure CLI: `az ad sp show --id 0af06dc6-e4b5-4f28-818e-e78e62d137a5 --query id`')
param windows365PrinicalId string
param version string = '1.0.0'
param replicationRegions array = [ 'eastus' ]
param tags object = {}
param images object = {
'20h2-ent-cpc-m365-g2': {
publisher: 'MicrosoftWindowsDesktop'
offer: 'windows-ent-cpc'
sku: '20h2-ent-cpc-m365-g2'
version: 'latest'
}
'20h2-ent-cpc-os-g2': {
publisher: 'MicrosoftWindowsDesktop'
offer: 'windows-ent-cpc'
sku: '20h2-ent-cpc-os-g2'
version: 'latest'
}
'21h1-ent-cpc-m365-g2': {
publisher: 'MicrosoftWindowsDesktop'
offer: 'windows-ent-cpc'
sku: '21h1-ent-cpc-m365-g2'
version: 'latest'
}
'21h1-ent-cpc-os-g2': {
publisher: 'MicrosoftWindowsDesktop'
offer: 'windows-ent-cpc'
sku: '21h1-ent-cpc-os-g2'
version: 'latest'
}
'win10-21h2-ent-cpc-m365-g2': {
publisher: 'MicrosoftWindowsDesktop'
offer: 'windows-ent-cpc'
sku: 'win10-21h2-ent-cpc-m365-g2'
version: 'latest'
}
'win10-21h2-ent-cpc-os-g2': {
publisher: 'MicrosoftWindowsDesktop'
offer: 'windows-ent-cpc'
sku: 'win10-21h2-ent-cpc-os-g2'
version: 'latest'
}
'win10-22h2-ent-cpc-m365': {
publisher: 'MicrosoftWindowsDesktop'
offer: 'windows-ent-cpc'
sku: 'win10-22h2-ent-cpc-m365'
version: 'latest'
}
'win10-22h2-ent-cpc-os': {
publisher: 'MicrosoftWindowsDesktop'
offer: 'windows-ent-cpc'
sku: 'win10-22h2-ent-cpc-os'
version: 'latest'
}
'win11-21h2-ent-cpc-m365': {
publisher: 'MicrosoftWindowsDesktop'
offer: 'windows-ent-cpc'
sku: 'win11-21h2-ent-cpc-m365'
version: 'latest'
}
'win11-21h2-ent-cpc-os': {
publisher: 'MicrosoftWindowsDesktop'
offer: 'windows-ent-cpc'
sku: 'win11-21h2-ent-cpc-os'
version: 'latest'
}
'win11-22h2-ent-cpc-m365': {
publisher: 'MicrosoftWindowsDesktop'
offer: 'windows-ent-cpc'
sku: 'win11-22h2-ent-cpc-m365'
version: 'latest'
}
'win11-22h2-ent-cpc-os': {
publisher: 'MicrosoftWindowsDesktop'
offer: 'windows-ent-cpc'
sku: 'win11-22h2-ent-cpc-os'
version: 'latest'
}
// MicrosoftVisualStudio
'vs-2019-ent-general-win10-m365-gen2': {
publisher: 'MicrosoftVisualStudio'
offer: 'visualstudio2019plustools'
sku: 'vs-2019-ent-general-win10-m365-gen2'
version: 'latest'
}
'vs-2019-pro-general-win10-m365-gen2': {
publisher: 'MicrosoftVisualStudio'
offer: 'visualstudio2019plustools'
sku: 'vs-2019-pro-general-win10-m365-gen2'
version: 'latest'
}
'vs-2019-pro-general-win11-m365-gen2': {
publisher: 'MicrosoftVisualStudio'
offer: 'visualstudio2019plustools'
sku: 'vs-2019-pro-general-win11-m365-gen2'
version: 'latest'
}
'vs-2022-ent-general-win10-m365-gen2': {
publisher: 'MicrosoftVisualStudio'
offer: 'visualstudioplustools'
sku: 'vs-2022-ent-general-win10-m365-gen2'
version: 'latest'
}
'vs-2022-ent-general-win11-m365-gen2': {
publisher: 'MicrosoftVisualStudio'
offer: 'visualstudioplustools'
sku: 'vs-2022-ent-general-win11-m365-gen2'
version: 'latest'
}
'vs-2022-pro-general-win10-m365-gen2': {
publisher: 'MicrosoftVisualStudio'
offer: 'visualstudioplustools'
sku: 'vs-2022-pro-general-win10-m365-gen2'
version: 'latest'
}
'vs-2022-pro-general-win11-m365-gen2': {
publisher: 'MicrosoftVisualStudio'
offer: 'visualstudioplustools'
sku: 'vs-2022-pro-general-win11-m365-gen2'
version: 'latest'
}
'base-win10-gen2': {
publisher: 'MicrosoftVisualStudio'
offer: 'windowsplustools'
sku: 'base-win10-gen2'
version: 'latest'
}
'base-win10-m365-gen2': {
publisher: 'MicrosoftVisualStudio'
offer: 'windowsplustools'
sku: 'base-win10-m365-gen2'
version: 'latest'
}
'base-win11-gen2': {
publisher: 'MicrosoftVisualStudio'
offer: 'windowsplustools'
sku: 'base-win11-gen2'
version: 'latest'
}
'base-win11-m365-gen2': {
publisher: 'MicrosoftVisualStudio'
offer: 'windowsplustools'
sku: 'base-win11-m365-gen2'
version: 'latest'
}
}
var resourceName = take('s${uniqueString(resourceGroup().id)}', 24)
// create the a new azure compute gallery
resource gallery 'Microsoft.Compute/galleries@2022-03-03' = {
name: resourceName
location: location
properties: {
description: 'Test Gallery'
}
}
// create a new dev center
resource devcenter 'Microsoft.DevCenter/devcenters@2023-04-01' = {
name: resourceName
location: location
identity: {
type: 'SystemAssigned'
}
tags: tags
}
// attach the gallery to the dev center
resource devcenterGallery 'Microsoft.DevCenter/devcenters/galleries@2023-04-01' = {
name: resourceName
parent: devcenter
properties: {
galleryResourceId: gallery.id
}
dependsOn: [ galleryOwnerRole ]
}
// create a user assigned identity for AIB and the deployment scripts
resource identity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
name: resourceName
location: location
}
// assign the identity access to the resource group
resource rgContributorRole 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(gallery.id, identity.id)
properties: {
principalId: identity.properties.principalId
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')
principalType: 'ServicePrincipal'
}
}
// assign the identity access to the gallery
resource galleryOwnerRole 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(gallery.id, devcenter.id)
scope: gallery
properties: {
principalId: devcenter.identity.principalId
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')
principalType: 'ServicePrincipal'
}
}
// assign reader permission to the Windows 365 first-party SP
resource galleryReaderRole 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(gallery.id, windows365PrinicalId)
scope: gallery
properties: {
principalId: windows365PrinicalId
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')
principalType: 'ServicePrincipal'
}
}
// create the managed VM images
resource image 'Microsoft.Compute/galleries/images@2022-03-03' = [for img in items(images): {
name: img.key
location: location
parent: gallery
properties: {
identifier: {
sku: img.key
offer: 'devbox'
publisher: gallery.name
}
osState: 'Generalized'
osType: 'Windows'
hyperVGeneration: 'V2'
features: [
{ name: 'SecurityType', value: 'TrustedLaunch' }
]
}
tags: tags
}]
// create the VM image templates
resource template 'Microsoft.VirtualMachineImages/imageTemplates@2022-07-01' = [for (img, index) in items(images): {
name: img.key
location: location
identity: {
type: 'UserAssigned'
userAssignedIdentities: {
'${identity.id}': {}
}
}
properties: {
vmProfile: { vmSize: 'Standard_D8s_v3' }
source: union({ type: 'PlatformImage' }, img.value)
stagingResourceGroup: '${resourceGroup().id}-${img.key}-${version}'
distribute: [
{
type: 'SharedImage'
galleryImageId: '${image[index].id}/versions/${version}'
runOutputName: '${img.key}-${version}-SI'
replicationRegions: replicationRegions
storageAccountType: 'Standard_LRS'
}
]
customize: [
{
type: 'WindowsUpdate'
}
{
type: 'PowerShell'
inline: [ 'Write-Host "Hello World!"' ]
}
{
type: 'WindowsRestart'
}
]
}
tags: tags
dependsOn: [ image[index] ]
}]
// kick of the image template builds
resource deploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = [for (item, index) in items(images): {
name: item.key
kind: 'AzureCLI'
location: location
identity: {
type: 'UserAssigned'
userAssignedIdentities: {
'${identity.id}': {}
}
}
properties: {
azCliVersion: '2.48.1'
timeout: 'PT2H'
retentionInterval: 'PT1H'
cleanupPreference: 'OnExpiration'
scriptContent: 'az resource invoke-action --resource-type Microsoft.VirtualMachineImages/imageTemplates -g ${resourceGroup().name} --action Run -n ${item.key}'
}
dependsOn: [ template[index] ]
}]
// create the devbox definitions from the images created by the AIB image templates
resource devboxDefinitions 'Microsoft.DevCenter/devcenters/devboxdefinitions@2023-04-01' = [for (img, index) in items(images): {
name: img.key
location: location
parent: devcenter
properties: {
imageReference: {
id: '${devcenterGallery.id}/images/${img.key}/versions/${version}'
}
sku: {
name: 'general_a_8c32gb_v1'
}
osStorageType: 'ssd_256gb'
}
dependsOn: [ deploymentScript[index] ]
}]
// go to the dev center in the portal and confirm the devbox definitions were valid
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment