Refresh deployment for the React portal and host settings - #32
Merged
Paul Lizer (paullizer) merged 5 commits intoSep 23, 2026
Merged
Conversation
Close the gaps found while redeploying a full environment: - Networking: add a linuxbroker.internal private DNS zone with VNet registration and integrate the API and task apps with the app subnet, so the API can reach Linux hosts by name over SSH. - API image: install openssh-client for host operations. - Linux hosts: use Gen2 RHEL 7/8/9 LVM images and fix the RHEL 9 xpra repository URL so the bootstrap no longer fails under set -e. - Profiles: optionally deploy a Premium Azure Files NFS share behind a private endpoint and wire its path into NFS_SHARE. - RBAC: grant the API identity Desktop Virtualization Power On Off Contributor on the host VM resource group. - AVD: publish a Linux Desktop RemoteApp, enable Entra SSO RDP properties, grant an optional users group access and VM User Login, and pass the API client ID and script root to the host extension. - Preprovision: create and wire the AVD users group, consent the frontend app, and enable Entra RDP authentication when possible. - Post-provision: retry and verify host identity group membership. - Docs: update DEPLOYMENT.md, the parameter example and READMEs. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- API: restore the private key's trailing newline before writing it for
SSH. The deployment hooks trim it on the way into Key Vault, and OpenSSH
refuses the key ("error in libcrypto"), so every checkout failed.
- Post-provision: assign the ScheduledTask role before the images start.
The function app requested its API token first, and the managed identity
service caches that role-less token for up to 24 hours, so released
hosts were never returned. The role assignment now retries and fails
loudly instead of reporting success after a failed call.
- RHEL 9 bootstrap: disable xpra when its proxy exits during startup, as
the upstream 6.5 packages do on RHEL 9, instead of leaving a failed unit.
- Document these, SkuNotAvailable, and a stale Entra device that blocks
the session host join.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The release agent unmounted a user's home whenever the user was not signed in. The broker mounts the home at checkout, before the user connects, and its own SSH login wakes the logind watcher, so the home was unmounted about two seconds after every checkout on the test deployment. Sessions then ran on the local disk, and userdel -r deleted that data at return. Profiles never roamed. - release-session.sh (RHEL) keeps the home mounted while the host holds the user's lease. - manage-lease.sh unmounts the home before it clears the lease, so userdel -r only removes the empty local mount point. If the user is still signed in, it clears the lease but leaves the home and account alone. - delete_remote_user runs manage-lease.sh first on both paths and refuses to run userdel -r while the home is still mounted. API 0.161. - DEPLOYMENT.md explains the symptom and the fix. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
create-user.sh can fail after it writes the lease marker, and hosts now keep the NFS home mounted for as long as the lease exists. The checkout failure path only released the database assignment, so the account, lease, and mount stayed behind. It now runs delete_remote_user before it returns the VM to the pool. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The RHEL release agent now keeps a mounted home only while its lease exists. create-user.sh bind-mounted the home before it wrote the lease, which left a short window where the agent could unmount it. Also note in manage-lease.sh that only the RHEL agent unmounts homes after a user signs out. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Paul Lizer (paullizer)
marked this pull request as ready for review
September 23, 2026 16:55
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes the gaps found while redeploying a complete environment with the new React portal, host settings, and hardening work, plus the problems that showed up while validating that deployment end to end.
Infrastructure (Bicep)
linuxbroker.internalzone with VNet auto-registration (only whendomainNameis empty). The API and task apps now use VNet integration on the app subnet, so the API can reach hosts at<host>.linuxbroker.internalover SSH.7lvm-gen2,8-lvm-gen2, and9-lvm-gen2.homeshare, a private endpoint, and aprivatelink.filezone. Its path is wired intoNFS_SHAREautomatically unlessnfsShareis set.Connect-LinuxBroker.ps1.Scripts
Initialize-DeploymentEnvironment.ps1:deployNfsShare,nfsShareQuotaGiB, andavdUsersGroupId.Assign-VmApiRoles.ps1: retries and re-checks each host identity's group membership, and fails instead of silently continuing.api/Dockerfile: installsopenssh-client.Configure-RHEL9-Host.sh: fixes the xpra repository URL (the old one returns 404 and failed the bootstrap underset -e).Configure-AVD-Host.ps1andConnect-LinuxBroker.ps1:TERMSRV/targets.Fixes from validating the deployment
Load key "/tmp/private_key.pem": error in libcrypto). The deployment hooks trim the private key's trailing newline on the way into Key Vault, and OpenSSH will not load a key without one. The API now normalizes the key before writing it (API 0.160, with a regression test).ScheduledTaskrole. The function app's first token had no role, and the managed identity service caches it for up to 24 hours, so a restart does not help. The role is now assigned before the images are built.Assign-ServicePrincipalApiRole.ps1also retries and throws on failure; it used to print success after a failed call.create-user.shbind-mounts the user's NFS home at checkout. The API's own SSH logins during checkout wake the logind watcher, andcheck_unmount_user_homesthen unmounted any home whose user had not signed in yet, which was always true at that point. Every session ran on the local disk, anduserdel -rdeleted it when the host was returned. The Ubuntu agent never unmounts, so thereuserdel -rwould have deleted the profile from the share instead.create-user.shwrites the lease before it mounts the home, so the agent never sees a mounted home without one.manage-lease.sh clearandclear-anyunmount the home before they remove the lease. If the user is still signed in, they remove the lease but leave the account and the mount alone.userdel -ron both return paths (the path without a lease used to delete first), and it refuses to runuserdel -rwhile the home is still mounted (API 0.161).create-user.shhas written the lease now cleans up the host before the VM goes back to the pool (API 0.162).aioquicis not packaged for EL9).systemctl enable --nowstill returns 0, so the old warning never fired and the host was left degraded. The bootstrap now checks that the unit stays up and disables it if not. xrdp is unaffected.SkuNotAvailableand a stale Entra device that blocks the session host join.Docs
Updated
DEPLOYMENT.md, the parameter example,api/README.md, andREADME.md. This includes how to pointscriptSourceRootat a branch or fork commit, the new post-provision order, and troubleshooting for each issue above, including home directories that are not on the share.Validation
Tested with a fresh deployment in East US 2: RHEL 9 with GNOME, the NFS share, two Linux hosts, and one AVD session host.
az bicep buildandaz bicep lintare clean. The PowerShell parser reports no errors on the changed scripts,bash -npasses on the RHEL 9 script, and the API tests pass (56). The new lease and checkout tests fail against the previous code.xrdp-sesmanfor a broker-created user.lnxhost-02with the home on the share, signed out, and the host was returned. The profile stayed on the share (84 files). The same user then checked outlnxhost-01, which mounted that home with the file written onlnxhost-02, ran another GNOME session there, and was returned cleanly again.manage-lease.sh: tested on a host against a bind-mounted home with a matching, mismatched, and missing lease, a signed-in user,clear-any, and an invalid username. The reorderedcreate-user.shwas run on both hosts against the real share, followed bymanage-lease.sh clearanduserdel -r; the files on the share survived.Known issues (existing behavior, not changed here)
UpdateVmAttributes, which resetsLastUpdateDateand restarts the 30-minute return timer.TriggerScalingLogicreturnsPoweredOn/PoweredOff, but the API compares againstPowerOn/PowerOff. The database state changes, but no Azure power operation runs.mcelog.servicefails there; this is cosmetic.Notes
scriptSourceRootto this branch's commit. The hosts otherwise download the scripts frommain, and themainscripts don't accept the new parameters.create-user.sh,manage-lease.sh, and the RHELrelease-session.shwere updated on them by hand.