Skip to content

Commit

Permalink
Custom Templates (#34)
Browse files Browse the repository at this point in the history
* Switch to boolean check

* Update ClientId parameter logic

* Fix zone selection logic

* CustomTemplate

* Use Custom Template - pwsh7.4

* switch to case insensitive session host parameters

* Merge offline deployment into Dev (#33)

* Offline deployment (#32)

* Added a new document on steps to deploy offline.
* Updated bicep files to not deploy the FunctionApp.zip when running an offline deployment.

---------
* Fix readme and release body
---------
  • Loading branch information
WillyMoselhy authored Nov 9, 2024
1 parent 6fadbd9 commit 472bd46
Show file tree
Hide file tree
Showing 13 changed files with 440 additions and 297 deletions.
9 changes: 5 additions & 4 deletions Build/Build-Release-Body.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ ReleaseBody<<EOF
This release is built from $GitRef on $timeStamp
## Deploy This Release
| Deployment Type | Link |
| :------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Azure Portal UI | [![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/$urlDeployAVDSessionHostReplacer/uiFormDefinitionUri/$urlPortalUiUrl) [![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://portal.azure.us/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/$urlDeployAVDSessionHostReplacer/uiFormDefinitionUri/$urlPortalUiUrl) [![Deploy to Azure China](https://aka.ms/deploytoazurechinabutton)](https://portal.azure.cn/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/$urlDeployAVDSessionHostReplacer/uiFormDefinitionUri/$urlPortalUiUrl) |
| Command line (Bicep/ARM) | [![Powershell/Azure CLI](./docs/icons/powershell.png)](./docs/CodeDeploy.md)
| Deployment Type | Link |
| :-----------------------------| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Azure Portal UI | [![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/$urlDeployAVDSessionHostReplacer/uiFormDefinitionUri/$urlPortalUiUrl) [![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://portal.azure.us/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/$urlDeployAVDSessionHostReplacer/uiFormDefinitionUri/$urlPortalUiUrl) [![Deploy to Azure China](https://aka.ms/deploytoazurechinabutton)](https://portal.azure.cn/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/$urlDeployAVDSessionHostReplacer/uiFormDefinitionUri/$urlPortalUiUrl) |
| Command line (Bicep/ARM) | [![Powershell/Azure CLI](./docs/icons/powershell.png)](./docs/CodeDeploy.md) |
| Offline Deployment (no GitHub)| [![Offline Deployment](./docs/icons/powershell.png)](./docs/CodeDeploy-offline.md) |
EOF
"@

Expand Down
3 changes: 2 additions & 1 deletion FunctionApp/TimerTrigger1/run.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ $runningDeployments = Get-SHRRunningDeployment -ResourceGroupName $sessionHostRe
Write-PSFMessage -Level Host -Message "Found {0} running deployments" -StringValues $runningDeployments.Count

# load session host parameters
$sessionHostParameters = (Get-FunctionConfig _SessionHostParameters)
$sessionHostParameters = [hashtable]::new([System.StringComparer]::InvariantCultureIgnoreCase)
$sessionHostParameters += (Get-FunctionConfig _SessionHostParameters)

# Get latest version of session host image
Write-PSFMessage -Level Host -Message "Getting latest image version using Image Reference: {0}" -StringValues ($sessionHostParameters.ImageReference | Out-String)
Expand Down
4 changes: 2 additions & 2 deletions FunctionApp/profile.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ Set-PSFConfig -FullName PSFramework.Message.style.NoColor -Value $true #This is

## Version Banner ## Updated by Build\Build-Zip-File.ps1

Write-PSFMessage -Level Host -Message "This is SessionHostReplacer version {0}" -StringValues 'v0.3.1'

# This value is automatically maintanted using GitHub Actions.
Write-PSFMessage -Level Host -Message "This is SessionHostReplacer version {0}" -StringValues 'v0.3.2-beta.2'

# Import Function Parameters
try {
Expand Down
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ the AVD Session Host Replacer helps you manage the task of replacing old session

| Deployment Type | Link |
| :------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Azure Portal UI | [![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAVDSessionHostReplacer%2Fv0.3.1%2Fdeploy%2Farm%2FDeployAVDSessionHostReplacer.json/uiFormDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAVDSessionHostReplacer%2Fv0.3.1%2Fdeploy%2Fportal-ui%2Fportal-ui.json) [![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://portal.azure.us/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAVDSessionHostReplacer%2Fv0.3.1%2Fdeploy%2Farm%2FDeployAVDSessionHostReplacer.json/uiFormDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAVDSessionHostReplacer%2Fv0.3.1%2Fdeploy%2Fportal-ui%2Fportal-ui.json) [![Deploy to Azure China](https://aka.ms/deploytoazurechinabutton)](https://portal.azure.cn/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAVDSessionHostReplacer%2Fv0.3.1%2Fdeploy%2Farm%2FDeployAVDSessionHostReplacer.json/uiFormDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAVDSessionHostReplacer%2Fv0.3.1%2Fdeploy%2Fportal-ui%2Fportal-ui.json) |
| Command line (Bicep/ARM) | [![Powershell/Azure CLI](./docs/icons/powershell.png)](./docs/CodeDeploy.md)
| Offline Deployment | [![Offline Deployment](./docs/icons/powershell.png)](./docs/CodeDeploy-offline.md) |
| Azure Portal UI | [![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAVDSessionHostReplacer%2Fv0.3.2-beta.2%2Fdeploy%2Farm%2FDeployAVDSessionHostReplacer.json/uiFormDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAVDSessionHostReplacer%2Fv0.3.2-beta.2%2Fdeploy%2Fportal-ui%2Fportal-ui.json) [![Deploy to Azure Gov](https://aka.ms/deploytoazuregovbutton)](https://portal.azure.us/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAVDSessionHostReplacer%2Fv0.3.2-beta.2%2Fdeploy%2Farm%2FDeployAVDSessionHostReplacer.json/uiFormDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAVDSessionHostReplacer%2Fv0.3.2-beta.2%2Fdeploy%2Fportal-ui%2Fportal-ui.json) [![Deploy to Azure China](https://aka.ms/deploytoazurechinabutton)](https://portal.azure.cn/#blade/Microsoft_Azure_CreateUIDef/CustomDeploymentBlade/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAVDSessionHostReplacer%2Fv0.3.2-beta.2%2Fdeploy%2Farm%2FDeployAVDSessionHostReplacer.json/uiFormDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAVDSessionHostReplacer%2Fv0.3.2-beta.2%2Fdeploy%2Fportal-ui%2Fportal-ui.json) |
| Command line (Bicep/ARM) | [![Powershell/Azure CLI](./docs/icons/powershell.png)](./docs/CodeDeploy.md) |
| Offline Deployment (no GitHub) | [![Offline Deployment](./docs/icons/powershell.png)](./docs/CodeDeploy-offline.md) |


## Pre-requisites

The Session Host Replacer requires permissions to manage resources in Azure and, if the session hosts are Entra joined, permissions in Entra. The recommended approach is to create a User Managed Identity, assign the necessary permissions to it, and use it for all instances of the Session Host Replacer.

If you do not select a User Managed Identity, the deployment will create a System Managed Identity and assign permissions to it. However, some additional permissions may need to be assigned manually after deployment. This is not recommended if you have more than one instance of the Session Host Replacer.
Expand All @@ -25,6 +27,7 @@ Detailed instructions on the required permissions and how to assign them are ava
## How it works?

There are two criteria for replacing a session host,

1. **Image Version:** Is there a new image version available? If so, we create a new session host with the new image version. This can be from Marketplace or Gallery Image Definition.
2. **Session Host VM Age:** If the session host is older than a certain age, default is 45 days, we create a new session host and drain the old one.

Expand All @@ -43,6 +46,7 @@ When deleting an old session host, the function will check if it has existing se
- (If Entra Joined) Delete device from Entra ID

## FAQ

- **Can I use a custom Template Spec for Session Hosts deployment?**

Yes, you can use a custom Template Spec, right now this is not possible when using the portal UI as you need to customize the ARM template.
Expand Down Expand Up @@ -83,7 +87,7 @@ When deleting an old session host, the function will check if it has existing se

This project welcomes contributions and suggestions. Most contributions require you to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
the rights to use your contribution. For details, visit <https://cla.opensource.microsoft.com>.

When you submit a pull request, a CLA bot will automatically determine whether you need to provide
a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
Expand Down
3 changes: 3 additions & 0 deletions StandardSessionHostTemplate/DeploySessionHosts.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
param Location string = resourceGroup().location
param AvailabilityZones array = []
param VMNames array
param VMNamePrefixLength int

param VMSize string

param SubnetID string
Expand Down Expand Up @@ -41,6 +43,7 @@ module deploySessionHosts 'modules/AVDStandardSessionHost.bicep' = [for vm in VM
SecurityProfile: SecurityProfile
SubnetID: SubnetID
VMName: vm
VMNamePrefixLength: VMNamePrefixLength
VMSize: VMSize
DiskType: DiskType
WVDArtifactsURL: WVDArtifactsURL
Expand Down
16 changes: 13 additions & 3 deletions StandardSessionHostTemplate/DeploySessionHosts.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"_generator": {
"name": "bicep",
"version": "0.30.23.60470",
"templateHash": "18178878272492658007"
"templateHash": "14473546331683394413"

}
},
"parameters": {
Expand All @@ -20,6 +21,9 @@
"VMNames": {
"type": "array"
},
"VMNamePrefixLength": {
"type": "int"
},
"VMSize": {
"type": "string"
},
Expand Down Expand Up @@ -104,6 +108,9 @@
"VMName": {
"value": "[parameters('VMNames')[copyIndex()]]"
},
"VMNamePrefixLength": {
"value": "[parameters('VMNamePrefixLength')]"
},
"VMSize": {
"value": "[parameters('VMSize')]"
},
Expand Down Expand Up @@ -136,13 +143,16 @@
"_generator": {
"name": "bicep",
"version": "0.30.23.60470",
"templateHash": "18423800479986568485"
"templateHash": "7484271327926153268"
}
},
"parameters": {
"VMName": {
"type": "string"
},
"VMNamePrefixLength": {
"type": "int"
},
"VMSize": {
"type": "string"
},
Expand Down Expand Up @@ -200,7 +210,7 @@
},
"variables": {
"varRequireNvidiaGPU": "[or(startsWith(parameters('VMSize'), 'Standard_NC'), contains(parameters('VMSize'), '_A10_v5'))]",
"varVMNumber": "[int(substring(parameters('VMName'), add(lastIndexOf(parameters('VMName'), '-'), 1), sub(sub(length(parameters('VMName')), lastIndexOf(parameters('VMName'), '-')), 1)))]",
"varVMNumber": "[int(substring(parameters('VMName'), parameters('VMNamePrefixLength'), sub(length(parameters('VMName')), parameters('VMNamePrefixLength'))))]",
"varAvailabilityZone": "[if(equals(parameters('AvailabilityZones'), createArray()), createArray(), createArray(format('{0}', parameters('AvailabilityZones')[mod(variables('varVMNumber'), length(parameters('AvailabilityZones')))])))]"
},
"resources": [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// This is a sample bicep file //

param VMName string
param VMNamePrefixLength int
param VMSize string
param DiskType string
param Location string = resourceGroup().location
Expand Down Expand Up @@ -36,8 +37,8 @@ var varRequireNvidiaGPU = startsWith(VMSize, 'Standard_NC') || contains(VMSize,
var varVMNumber = int(
substring(
VMName,
(lastIndexOf(VMName, '-') + 1),
(length(VMName) - lastIndexOf(VMName, '-') - 1)
VMNamePrefixLength,
(length(VMName) - VMNamePrefixLength)
)
)

Expand Down
Loading

0 comments on commit 472bd46

Please sign in to comment.