Skip to main content
This guide introduces IT administrators to managing a deployed MacStadium VDI environment. Once you’ve completed the initial deployment following Getting started: MSDC-hosted or Getting started: self-hosted, this document covers ongoing operations, user management, and system maintenance. What this guide covers:
  • Understanding your role and responsibilities in the support and maintenance of your organization’s MacStadium VDI architecture
  • Navigating core management interfaces (the management UI and Ansible, Citrix Cloud, Orka Engine)
  • Executing common operational tasks (provisioning desktops, managing images, troubleshooting)
  • Establishing operational best practices for your MacStadium VDI environment

Your role in managing MacStadium VDI

As an administrator, you will be responsible for managing the three interconnected systems that make up MacStadium VDI. These are: Orka Engine (virtualization layer):
  • Hosts macOS VMs on Apple silicon hardware
  • Manages VM lifecycle (create, start, stop, delete)
  • Handles image storage and distribution
Your responsibility: Managing capacity, host health, and VM distribution. Citrix DaaS/CVAD (delivery layer):
  • Brokers user connections to desktops
  • Manages Machine Catalogs and Delivery Groups
  • Controls access policies and user assignments
Your responsibility: User entitlements, session policies, and VDA registration. Ansible and the management UI (orchestration layer):
  • Automates VM deployment and lifecycle operations
  • Maintains configuration consistency
  • Coordinates image management across hosts
  • Runs from the command line on your Ansible controller, or from the browser-based management UI, which runs the same playbooks as task templates
Your responsibility: Playbook execution, inventory management, workflow automation Day-to-day activities can vary, but will often consist of a mix of provisioning new desktops, managing golden images, performance and capacity monitoring, troubleshooting user access issues, and planning capacity expansions.

Key concepts and terminology

Orka-specific terms:
  • Orka host: Physical Mac running Orka Engine (for example, Mac mini M4, Mac Studio)
  • VM name prefix: Orka Engine has no group object. Instead, give related VMs a shared name prefix (for example, citrix-vda-finance-01 and citrix-vda-finance-02). list.yml, vm.yml, and delete.yml match VM names by prefix, so you can list, start, stop, or delete those VMs together.
  • Golden image: Template VM with macOS, Citrix VDA, and applications pre-installed
  • Max VMs per host: 2. Apple’s macOS EULA allows no more than two macOS VMs per host, and the deployment playbook enforces that cap.
  • Bridged networking: VMs receive IPs directly from your network. Set network_interface (for example, en0) when you deploy and every time you start a VM. VMs deployed or started without it use NAT, which Citrix Cloud and end users can’t reach.
Citrix-specific terms:
  • Machine catalog: Collection of VMs with similar configuration. Naming the VMs in a catalog with a shared prefix keeps them easy to manage together in Orka.
  • Delivery group: Links machine catalog to users and defines access policies
  • VDA (Virtual delivery agent): Software on macOS VM that registers with Citrix Cloud
  • Enrollment token: Time-limited credential for VDA registration
  • Rendezvous protocol: Enables HDX connections to non-domain-joined VMs
Ansible-specific terms:
  • Inventory: List of Orka hosts (the dev/inventory file in your orka-engine-orchestration clone)
  • Playbook: YAML file that performs one operation (for example, deploy.yml, vm.yml, install_citrix_vda.yml)
  • Group vars: Configuration variables shared across hosts (dev/group_vars/all/main.yml, next to dev/inventory)
  • Tags: Selective playbook execution (for example, --tags plan for dry runs)
  • Management UI: Browser-based interface on your Ansible controller that runs the same playbooks as task templates, such as Virtual Machines | Deploy VM. Each template prompts for its inputs when you click Run.

Architecture overview:

MacStadium VDI architecture diagram

Getting Started

Ansible access and credentials setup

You will want to verify that you have access to all three MacStadium VDI management layers.

Ansible control node:

The Ansible control node (also known as an “Ansible controller” or “Ansible runner”) is where you run playbooks and the management UI to manage Orka hosts. SSH to the Ansible control node and change to the directory where you cloned the orchestration repository during setup:
Verify Ansible access:
The getting started guides install ansible-core 2.18.4 with pipx. The management UI runs on the controller on port 3000. From the controller itself, open http://localhost:3000 and log in with the admin credentials from semaphore/.env.

Credentials used by the orchestration:

Ansible connects to the Mac hosts over SSH with the key you copied to each host during setup (~/.ssh/id_ed25519 if you accepted the default path). There’s no separate Orka Engine API or API token: each playbook runs orka-engine commands on the hosts over SSH. The playbooks take the following secrets as variables. Store these as secrets in the management UI or pass them at run time with -e. Don’t commit them to Git. In the management UI, the Key Store holds the Mac hosts SSH key, the Base VM Credentials variable group holds vm_username, vm_password, citrix_installer_url, and hostname_suffix, and the OCI Credentials variable group holds oci_username and oci_password. configure_semaphore.py sets these values during setup. The VDI | Register Citrix VDA template prompts for enrollment_token each time you run it. Common Ansible tasks:
  • Deploying a VM: ansible-playbook deploy.yml -i dev/inventory -e "vm_name=<VM_NAME>" -e "vm_image=<IMAGE>" -e "network_interface=en0"
  • Managing VM state: ansible-playbook vm.yml -i dev/inventory -e "vm_name=<VM_NAME>" -e "desired_state=<STATE>". When <STATE> is running, also pass -e "network_interface=en0".
  • Installing and registering the Citrix VDA: install_citrix_vda.yml, then register_citrix_vda.yml
  • Creating images: ansible-playbook create_image.yml -i dev/inventory -e "vm_image=<BASE_IMAGE>" -e "remote_image_name=<IMAGE_DESTINATION>"
  • Checking hosts: ansible-playbook validate.yml -i dev/inventory --tags images -e "validate_image_name=<IMAGE>" confirms an image is cached on every host
Each of these except validate.yml is also a task template in the management UI. For every playbook and its variables, see the Ansible quick reference.

Citrix Cloud Console access and credentials setup

Citrix Cloud Console is the web-based management control plane for Citrix DaaS. Access URL: https://citrix.cloud.com
Login: Your Citrix Cloud administrator credentials

Key sections:

  • Web studio: Machine catalogs, delivery groups, enrollment tokens
  • Monitor: Session metrics, connection quality, active users
  • Policies: HDX settings, access control, feature restrictions

Credentials needed:

  • Citrix Cloud administrator account
  • Customer ID (visible in Cloud Console, used in VDA configuration)

Common tasks performed in Citrix Cloud Console:

  • Generating enrollment tokens
  • Creating or modifying Delivery Groups
  • Assigning users to desktops
  • Monitoring session health

Orka Hosts

As an IT administrator, you will need direct SSH access to physical Macs running Orka Engine. This access is used for troubleshooting, not routine operations. You can access your Orka Engine hosts by SSHing directly to the host IP:
When you’ll need this:
  • Debugging Orka Engine issues
  • Checking disk space: df -h /opt/orka
  • Reviewing Orka Engine logs: tail -100 /opt/orka/logs/com.macstadium.orka-engine.server.managed.log
  • Manually inspecting VMs: orka-engine vm list
Credentials:
  • SSH key: The same key Ansible uses (~/.ssh/id_ed25519 if you accepted the default path during setup)
  • User: administrator, or whichever user you set as ansible_user during deployment
Important: Routine, daily operations should use the management UI or Ansible playbooks, not direct host access. Direct access is for troubleshooting only.

OCI registry

An OCI registry is a container registry for storing your organization’s golden images. This can be public (GHCR) or private (Harbor, Artifactory, etc.)

MacStadium’s public GHCR registry:

  • URL: ghcr.io/macstadium/orka-images
  • No authentication required
  • Base images: sonoma:latest, sequoia:latest, tahoe:latest

Private OCI registry:

  • URL: The full image reference you pass as vm_image or remote_image_name (for example, registry.example.com/citrix-vda/sonoma-finance:v2.0)
  • Credentials: registry_username and registry_password for pull_image.yml and create_image.yml; oci_username and oci_password for deploy.yml and push_image.yml
  • Contains: Your golden images with Citrix VDA pre-installed

Common tasks performed when managing OCI images:

  • Pulling images to every host: pull_image.yml
  • Building and pushing a golden image: create_image.yml
  • Pushing an image from a running VM: push_image.yml
  • Listing images cached on the hosts: list_images.yml
  • Removing a cached image from the hosts: delete_image.yml
See Managing images for the commands.

Citrix Cloud Console Navigation

After logging in to https://citrix.cloud.com:
  1. Hamburger menu: Navigate between services
    • Select “DaaS” or “Virtual Apps and Desktops” to access Web Studio
  2. Web Studio:
    • Machine Catalogs: View registered VMs, enrollment tokens
    • Delivery Groups: User assignments, published desktops
    • Policies: HDX settings, security policies
  3. Monitor tab:
    • Real-time session data
    • Connection quality metrics
    • Historical trends
  4. Support menu:
    • Documentation links
    • Support case management
You may wish to run some quick checks to verify service health:
  • Machine Catalogs → Select your catalog → Verify VMs show “Registered”
  • Monitor → Check session launch success rate >95%
  • Monitor → Verify there have been no “Unregistered” machines in past 24 hours

Connecting to the Ansible Management Node

Initial connection:
Expected output:

Testing Ansible connectivity

If Ansible connectivity fails:

  • Verify the SSH key exists: ls -la ~/.ssh/id_ed25519
  • Test direct SSH connectivity: ssh administrator@10.0.100.10
  • Check that your Ansible inventory file has the correct IPs listed
Common environment variables: Review your group variables file:
Key Ansible variables:
  • ansible_user: SSH user on the Mac hosts (administrator in the getting started guides)
  • vm_image: Default golden image to deploy from
  • max_vms_per_host: VM capacity limit. This is 2, the maximum that Apple’s macOS EULA allows.
  • engine_binary: Path to the Orka Engine binary (/usr/local/bin/orka-engine)
  • network_interface: (Optional) Host network interface for bridged networking, for example en0
Reviewing Mac Host inventory
  • List all Orka hosts: ansible hosts -i dev/inventory --list-hosts
  • Check that Orka Engine is running on all hosts: ansible hosts -i dev/inventory -m shell -a "/usr/local/bin/orka-engine info". It exits with an error if the Engine service isn’t reachable, and prints the Engine version and data directory.
  • List every VM and the host it runs on:
list.yml prints one line per VM in the following format:
When you pass -e "vm_name=<PREFIX>", it lists only the VMs whose names start with that prefix, and each line starts with the prefix you passed. Count the VMs per host to see where you have free slots: each host can run two.
  • Check how much capacity is free without deploying anything:
The plan output reports the total capacity available across your hosts. Only running VMs count against a host’s two slots.
  • Check available disk space: ansible hosts -i dev/inventory -m shell -a "df -h /opt/orka"
Look for:
  • <70% used: Healthy
  • 70-85% used: Plan for cleanup or expansion
  • 85% used: Action required (delete old images, expand storage)
Document your inventory: Create a reference document containing the following information:
  • Host IP
  • Hardware model (Mac mini M4, Mac Studio M2 Ultra, etc.)
  • Current VM count
  • Available capacity
  • Network interface (10Gb vs 1Gb)
  • Notes (for example, “Reserved for engineering team”)
Having this information documented and updated regularly helps with capacity planning and troubleshooting.

Core workflows

Provisioning a new desktop

MacStadium VDI VM provisioning flow: sequence diagram showing the IT Admin, Control Plane, Automation, Orka Engine, Image Registry, MDM, and Session Broker steps Follow this workflow when a user requests access to a macOS virtual desktop. Be sure the following prerequisites have been met before proceeding:
  • The user account exists in your identity provider (Azure AD, Okta, etc.)
  • The user is assigned to the appropriate Delivery Group in Citrix Cloud
  • There is available capacity on your Orka hosts (at least one host running fewer than two VMs)
  • The appropriate golden image is cached on the hosts. This is optional, but deployments start faster when the image doesn’t need to be downloaded.
  • You have a Citrix enrollment token for the Machine Catalog. See Citrix DaaS configuration.
Each step lists the Ansible command. To use the management UI instead, open the Orka Engine Orchestration project, run the template named in the step, and fill in the same values in the form. To provision many desktops at once, see Bulk VM lifecycle management.
1

Select the golden image

Choose the image based on the user’s department, role, and access needs. To list the images cached on each host, run list_images.yml (management UI: Images | List Images):
Each image prints as <IMAGE>:<TAG> | Size: <SIZE> (used: <USED>) | Host: <HOST>.If the golden image isn’t cached, pull it to every host with pull_image.yml (management UI: Images | Pull Image). Add -e "registry_username=<REGISTRY_USERNAME>" -e "registry_password=<REGISTRY_PASSWORD>" if the registry requires authentication. The management UI template doesn’t prompt for these, so use the CLI for a registry that requires them.
(This can take 5-15 minutes depending on the image size and your network speed)
2

Deploy the VM

deploy.yml deploys one VM, named with the vm_name you pass. If a VM with that name already exists, it doesn’t deploy a new one. Choose a name that starts with the prefix you use for this group of desktops, such as citrix-vda-finance-11.Always run --tags plan first:
The plan shows whether a VM with that name already exists, which host the VM will deploy to, and the total capacity available. It doesn’t create the VM.Next, deploy the VM (management UI: Virtual Machines | Deploy VM):
Set network_interface to the host’s network interface, for example en0, for every VDI VM (bridged networking). The examples on this page use en0. Without it, the VM uses NAT, and Citrix Cloud and end users can’t reach it. Orka Engine doesn’t save the network interface with the VM, so pass it again every time you start the VM.
If the image is in a private registry and isn’t cached on the host, also pass -e "public_image=false" -e "oci_username=<OCI_USERNAME>" -e "oci_password=<OCI_PASSWORD>" so the playbook pulls it with credentials.The playbook selects a host with a free slot, starts the VM, waits for it to get an IP address, and prints the VM’s name, IP, state, CPU, and memory. It doesn’t install or register the Citrix VDA: the next two steps do that.To check on the VM from another terminal, run:
3

Install the Citrix VDA

Run this step even if your golden image already has the Citrix VDA installed: it’s the only step that sets the VM’s hostname to vm_name, and VMs deployed from the same image otherwise all keep the image’s hostname.Run install_citrix_vda.yml (management UI: VDI | Install Citrix VDA):
The playbook installs the .NET runtime prerequisites, sets the VM hostname, installs the VDA, and reboots the VM. Wait for the reboot to finish before you register the VDA. For details on each variable, see Citrix DaaS configuration.
4

Register the VDA with Citrix Cloud

Run register_citrix_vda.yml with your enrollment token (management UI: VDI | Register Citrix VDA):
install_citrix_vda.yml and register_citrix_vda.yml act only on the VM whose name exactly matches vm_name.
5

Verify VDA registration in Citrix

  • Navigate to Citrix Cloud Console → Web Studio → Machine Catalogs
  • Select your Machine Catalog (for example, “Orka-macOS-Sonoma-Finance”)
  • Refresh the machine list
  • New VMs should appear with:
    • Registration state: ‘Registered’
    • Power state: ‘On’
    • Fault state: ‘None’
If the VM doesn’t appear after 10 minutes, confirm the VM is running and note its IP and host:
Then connect to the VM through its host, the same way the playbooks do, and check that the Citrix services are running:
The VDA logs are in /Library/Application Support/Citrix/VDA/Logs/ on the VM. To troubleshoot VDA registration failures, see the Troubleshooting quick reference.
6

Assign to user/delivery group

If you’re using a static/dedicated assignment:
  • In Citrix Cloud Console → Web Studio → Delivery Groups
  • Select Delivery Group (for example, “Finance-macOS-VDI”)
  • Click “Edit Delivery Group” → “Users” tab
  • Add user: Search for user account, select, assign to specific VM
If using pooled/random assignments:No action is needed if the user has already been assigned to a Delivery Group. The next available VM will be assigned automatically when the user launches a desktop. You will want to verify that the user has access by:
  • Having the user launch the Citrix Workspace application
  • User logs in
  • Desktop should appear: “Mac OS Finance Desktop” (or configured display name)
  • User clicks desktop → session launches successfully
If the user needs their own local macOS account on the VM, create it with provision_user.yml (management UI: Virtual Machines | Provision User to VM):
The desktop should appear in Citrix Workspace immediately after being assigned to a Delivery Group, and should launch within 15-30 seconds. When the provisioning workflow has completed, the user will now have access to their macOS virtual desktop.

Managing images

Golden images are the foundation for rapid desktop provisioning. The image lifecycle is typically:
  • Create: Build a golden image with macOS + VDA + applications
  • Test: Deploy a test VM and validate its functionality
  • Publish: Push your image to an OCI registry with an applicable version tag
  • Cache: Pull an image to all Orka hosts
  • Deploy: Use an image for new VM provisioning
  • Update: Apply patches and create a new image version
  • Retire: Remove old image versions after migration to a new version is complete
You will need to create new golden images when a new application is required for your team (for example, Microsoft Office, Slack, etc.), Citrix VDA updates, or you have department-specific configurations to consider (design tools such as Adobe, or engineering IDEs such as Jetbrains or Visual Studio Code). Before beginning this workflow, ensure the following prerequisites have been met:
  • Configuration scripts are prepared in the scripts/ directory at the root of your orka-engine-orchestration clone
  • A base macOS image is available
  • You have push credentials for your registry (registry_username and registry_password)
The management UI template (Images | Create Image) doesn’t prompt for registry_username or registry_password, so run create_image.yml from the CLI when your registry requires them. The create_image.yml playbook automates the following:
  • Deploy a temporary VM named image-host from the base image you pass as vm_image
  • Install macOS updates, if you pass upgrade_os=true
  • Run each configuration script on the VM
  • Save the VM as an image and push it to the registry destination you pass as remote_image_name, including its tag
  • Delete the temporary VM
The repository doesn’t include a scripts/ directory, so create it first:
The playbook runs every *.sh file directly inside scripts/ (it doesn’t look in subdirectories). It doesn’t sort the scripts, so don’t rely on the order they run in: if one step depends on another, put both in the same script. An example script structure would be:
Example script (install_vscode.sh), which copies an app bundle into /Applications without sudo:
Important notes:
  • Scripts run on the VM as the VM’s admin user, without sudo. Build scripts can’t run root commands: admin in the MacStadium base images doesn’t have passwordless sudo, and the scripts run without a terminal or password, so a sudo command, such as sudo installer for a .pkg, fails the image build.
  • The playbook connects to the VM as admin with the password admin. If your base image uses different credentials, pass them with -e "configure_vm_hosts_vm_user=<VM_USER>" -e "configure_vm_hosts_vm_password=<VM_PASSWORD>".
  • Test scripts individually before image creation
  • Include error handling (set -e, exit codes)
  • Clean up temporary files
Next, you’ll want to run the create_image playbook:
What happens when running this playbook:
  • The playbook deploys a temporary VM named image-host on a host with a free slot
  • It waits for the VM to get an IP address, then connects to it over SSH through the host
  • If you passed upgrade_os=true, it installs macOS updates
  • It runs each script in scripts/
  • It saves the VM as an image and pushes it to registry.example.com/citrix-vda/sonoma-finance:v2.0
  • It deletes the temporary VM with delete.yml
This can take 20-40 minutes depending on the number of applications to install, if there are any macOS updates, and the network speed.
Every run uses the VM name image-host, so run one image build at a time. If a VM named image-host already exists, for example after a failed run, the playbook reuses it instead of deploying a fresh VM from your base image. Delete it before you run create_image.yml again. The cleanup step deletes every VM whose name starts with image-host, so don’t give your own VMs names that start with image-host.
Testing new images is critical. To test an image before production use, deploy a test VM from it:
Then install the VDA with install_citrix_vda.yml, which also sets the hostname, and register it with Citrix using register_citrix_vda.yml, as described in Provisioning a new desktop. You will want to verify that the VM has deployed successfully, the VDA registers with Citrix Cloud, applications launch correctly, there are no errors in the VDA logs, and test users can launch sessions and access applications. If issues are found, you can fix any script errors in the scripts/ directory, delete the failed image from your container registry, and re-run create_image.yml with the corrected scripts. Once the image has been validated, deploy production VMs from the tested version tag by passing it as vm_image, for example registry.example.com/citrix-vda/sonoma-finance:v2.0. Don’t re-run create_image.yml to apply a :latest tag: each run rebuilds the image from the base image and your scripts, so the result isn’t the build you tested. You can also set the version as the default vm_image in your group variables file. To capture a VM that you configured by hand as an image, use push_image.yml (management UI: Images | Push Image) instead. vm_name must exactly match the VM’s name:

Updating Existing Images

Patch an existing golden image:
  1. Build a new image version with create_image.yml, passing your current production image (or a fresh base image) as vm_image and a new version tag in remote_image_name
  2. Test the image thoroughly
  3. Update the vm_image default to the new version
  4. Recreate VMs from the new image
Changing vm_image only affects VMs you deploy afterward. Existing VMs keep running the image they were deployed from, whether they’re pooled or dedicated, until you delete and redeploy them. For non-persistent (pooled) desktops:
  • Update the vm_image default image
  • Delete and redeploy the pooled VMs, during off-hours if possible, then run install_citrix_vda.yml and register_citrix_vda.yml on each new VM
For persistent (dedicated) desktops:
  • Schedule a maintenance window
  • Delete old VMs
  • Deploy a VM from the newly created image
  • Run install_citrix_vda.yml, which also sets the hostname, then register the new VM with Citrix
  • Restore user data from backups (if applicable)

Caching Images Across Hosts

Why cache:
  • Faster VM deployment (no download wait)
  • Reduces network bandwidth during deployments
  • Ensures consistency across hosts
Cache images on all hosts:
Verify cached image:
To check that an image is cached on every host, run validate.yml with the images tag. The check matches the image name and tag separately, so confirm with list_images.yml if you have several images with the same tag:
Cache multiple images:
Run pull_image.yml once per image:
Remove old image versions to free space:
Check disk usage, then delete the old image with delete_image.yml (management UI: Images | Delete Image). Use the image name and tag exactly as list_images.yml shows them. If you leave off the tag, the playbook deletes the latest tag. Add -e "node_name=<HOST_IP>" to delete the image from one host only.
Best practice: Maintain 2-3 recent versions cached, and delete older versions quarterly.

Version control and rollback

Version numbering scheme:

Use semantic versioning: MAJOR.MINOR.PATCH
  • v1.0.0: Initial release
  • v1.1.0: Added new application
  • v1.1.1: Security patch
  • v2.0.0: Major update (macOS version upgrade)
Track versions by maintaining a CHANGELOG.MD in your Git repository. If a new image causes issues, you can identify the last known good version by checking the CHANGELOG.MD or registry tags. Next, set the last known good version as the default vm_image in your group variables file (for example, to roll back to v1.2.1):
Deleting VMs matches names by prefix. delete.yml, and vm.yml with desired_state=absent, delete every VM whose name starts with the vm_name you pass, not only the VM with that exact name. For example, vm_name=citrix-vda-finance deletes every VM in that group. Before you delete, run list.yml and make sure no VM you want to keep has a name that starts with the value you’re passing.
Then, you will want to recreate the affected VMs by deleting the VMs using the problematic image, and redeploying from the rollback image. List the VMs first, then delete them by their shared prefix:
The --tags plan run shows which VMs on which hosts will be deleted, without deleting anything. deploy.yml deploys one VM per run, so redeploy each VM that list.yml showed, by name. For example, if the group was citrix-vda-finance-01 through -10:
For larger groups, use the deploy subcommand in Bulk VM lifecycle management. It names each VM with your prefix and a random suffix, so the new VMs don’t keep their old names. After the VMs are deployed, run install_citrix_vda.yml on each VM, which also sets its hostname, and register each VM with register_citrix_vda.yml. You will want to communicate this change to users: “We’ve rolled back to the previous desktop image version due to [the previously identified issue]. Your desktop has been recreated from the previous image.” Rollback time is estimated to take between 30-60 minutes for 20-30 VMs.

User assignment and policies

This involves managing which users can access specific desktops, and what they can do within active sessions.

Working with Citrix Delivery Groups

Delivery Groups link Machine Catalogs (VMs) to your users. To view existing Delivery Groups: Navigate to Citrix Cloud Console → Web Studio → Delivery Groups. You should then see a list of configured Delivery Groups. For example: Finance-macOS-VDI: 50 VMs, pooled, 150 users

Create a new Delivery Group

In a scenario where a team needs new macOS desktops within your MacStadium VDI instance, deploy the VMs with a shared name prefix, such as citrix-vda-marketing-, then install and register the Citrix VDA on each one. deploy.yml deploys one VM per run, as shown in Provisioning a new desktop. For 15 VMs, use the deploy and install-citrix subcommands in Bulk VM lifecycle management, then register each VM with register_citrix_vda.yml. After the VMs show as Registered in their Machine Catalog, proceed through the following steps:
  1. Navigate to Citrix Cloud Console → Delivery Groups → Create New Delivery Group
  2. Select machines by choosing the Machine Catalog containing the new VMs created in the previous step(s)
  3. Add users by clicking “Add”, searching for the specified team, and selecting the correct AD/Azure AD group. Alternatively, you can add users individually.
  4. To configure desktops, give them a display name (for example, “macOS Marketing Desktop”) and add a description for the VM.
  5. Choose Published Desktop as the delivery type

Modify existing Delivery Groups

Add a user to an existing group:
  1. Delivery Groups → Select group → Edit
  2. Users tab → Add → Search for the selected user → Assign
Remove user:
  1. Delivery Groups → Select group → Edit
  2. Users tab → Select user → Remove

Assignment types:

Static (dedicated):
  • Each user is assigned permanently to a specific VM
  • The VM retains the user’s settings, files (if they are stored locally)
  • Best used for: Developers, power users
Pooled (random):
  • User gets the next available VM
  • The VM isn’t reset between sessions. Changes a user makes stay on the VM until you delete and redeploy it.
  • Best used for: Individual task workers and call centers
Change assignment type:
Typically, you cannot change an existing Delivery Group’s assignment type. Instead, you can do the following:
  1. Create a new Delivery Group with the desired assignment type
  2. Migrate your users to the new group
  3. Delete the old Delivery Group

Access Control and Entitlements

These settings control which users can access desktops and from where.

User entitlements:

In Citrix, entitlements are what grant users permission to access specific resources.
Grant access:
  • Assign the user to a Delivery Group (see Provisioning a new desktop, earlier on this page)
  • The user sees the assigned desktop in Citrix Workspace immediately
Revoke access:
  • Remove the user from a Delivery Group
  • The desktop disappears from the user’s Workspace within 5 minutes
Conditional access:
Require specific conditions for desktop access:
  1. Citrix Cloud Console → Web Studio → Policies
  2. Create a new policy, or edit an existing policy
  3. Configure conditions:
    • Device type: macOS, iOS, web only
    • Network location: Internal network only, or allow external network
    • Device compliance: Require managed device (if using MDM) Example policy: “The finance team can only access desktops from inside the corporate network or via a VPN”

Multi-factor authentication (MFA):

This is enforced at the identity provider level (Azure AD, Okta), not in Citrix directly. Configure MFA from within your IdP:
  • Require MFA for Citrix Workspace access
  • Users will be prompted for a second factor during login

Session Policies and Preferences

These control user session behavior.
Session timeout:
  1. Navigate to Citrix Cloud Console → Web Studio → Policies
  2. Edit the policy for the necessary Delivery Group
  3. Configure session settings:
    • Session idle timeout: Disconnect after X hours idle (default: 24 hours)
    • Disconnected session timeout: Log off user(s) after X hours disconnected (default: never) Recommended settings:
  • Pooled desktops: 8 hours idle, 30 minutes disconnected (aggressive cleanup)
  • Dedicated desktops: 24 hours idle, never disconnect (preserve work)
Reconnection:
This allows users to reconnect to disconnected sessions:
  • Policy → Session → Connection → Enable “Session reconnection”
  • When users close Workspace without logging out, their session is preserved
  • When users reopen their Workspace, they can reconnect to same session

Feature policies (HDX settings):

These control what users can do within sessions. Common policies:
Clipboard:
  • Bidirectional: Copy/paste both ways (client ↔ VM)
  • Client to VM only: Users can paste into the VM, but not copy out
  • Disabled: No clipboard access
Configure:
  1. Policies → HDX Settings → Clipboard redirection
  2. Select: Allowed / Prohibited / Client to VM only
File transfer:
  • Allow: Users can drag files between client and VM
  • Prohibit: No file transfers are allowed
Configure:
  1. Policies → HDX Settings → Client drive redirection
  2. Select: Allowed / Prohibited
USB redirection:
  • Allow specific devices: Keyboards, mice, smart cards
  • Prohibit all: Block USB entirely
Configure:
  1. Policies → HDX Settings → USB device redirection
  2. Select device classes allowed
Printing:
  • Client printer mapping: The user’s local printers appear in the VM
  • Disable: No printing
Configure:
  1. Policies → Printing → Client printer redirection
  2. Select: Allowed / Prohibited
Example policy set (Finance team - secure):
  • Clipboard: Client to VM only (prevent data exfiltration)
  • File transfer: Prohibited
  • USB: Prohibited
  • Printing: Allowed
  • Session timeout: 8 hours idle
Example policy set (Engineering team - open):
  • Clipboard: Bidirectional
  • File transfer: Allowed
  • USB: Allowed (specific devices)
  • Printing: Allowed
  • Session timeout: 24 hours idle
Apply policies to a specific Delivery Group:
  1. Create a policy with the desired settings configured
  2. In Citrix Cloud Console, navigate to Policies → Filter → Set filter to Delivery Group name
  3. The chosen policy applies to all users in that group
Tip: Create policy templates for common user types (Standard, Power User, Secure) and apply these templates to corresponding Delivery Groups to save time during setup.

Lifecycle operations

These consist of day-to-day VM management operations. You will likely need to Start, Stop, and Delete VMs on a regular basis as needed to troubleshoot VM issues, apply configuration changes requiring a restart, and to help conserve resources during off-peak hours. Use vm.yml (management UI: Virtual Machines | Manage VM) for all three. vm.yml acts on every VM whose name starts with the vm_name you pass, so vm_name=citrix-vda-finance- starts or stops the whole group. To act on one host only, add --limit <HOST_IP>.
Start a VM:
Pass network_interface every time you start a VM, including when vm.yml starts a whole prefix group. Orka Engine doesn’t save the network interface with the VM, so a VM started without it comes up on NAT, where Citrix Cloud and end users can’t reach it. The Virtual Machines | Manage VM template has no network_interface field, so set network_interface: en0 in dev/group_vars/all/main.yml, which the management UI loads too.
Stop a VM:
After a VM has been stopped, the VDA can no longer reach Citrix, so the desktop becomes unavailable. A stopped VM doesn’t count against its host’s two-VM limit. Users cannot access the desktop until the VM has been restarted.
Deleting VMs matches names by prefix. delete.yml, and vm.yml with desired_state=absent, delete every VM whose name starts with the vm_name you pass, not only the VM with that exact name. For example, vm_name=citrix-vda-finance deletes every VM in that group. Before you delete, run list.yml and make sure no VM you want to keep has a name that starts with the value you’re passing.
Delete a VM:
There’s no exact-match delete. For example, vm_name=citrix-vda-finance-1 also matches citrix-vda-finance-10 through citrix-vda-finance-19. Run list.yml with the same vm_name first, and only delete when the list shows just the VMs you intend to remove. Running VMs are stopped before they’re deleted.
You may also need to recreate a VM in order to refresh pooled desktops to a golden image (remove user changes), fix corrupted VMs, or apply an updated golden image to an existing VM. To delete and re-deploy a VM, delete it, deploy a new VM with the same name, install the VDA (which also sets the hostname), and register it with Citrix:
To recreate VMs in a batch, delete them by prefix and redeploy them, as shown in Version control and rollback, or use the delete and deploy subcommands in Bulk VM lifecycle management. To recreate an estimated 10 VMs, this process will take 30-60 minutes to run. User impact will vary depending on if VMs are pooled or dedicated. If a VM is pooled, user impact should be minimal if recreation is done during off-hours. If a VM is assigned to a dedicated user, that user will lose their local data unless it is backed up upon VM recreation. It is considered a best practice to schedule VM reconfiguration during specific maintenance windows, and to notify users in advance. When considering the VM deprovisioning and cleanup process, you will want to remove desktop access when a user leaves your organization, or a VM is no longer needed. To remove users from a Citrix Delivery Group:
  1. Navigate to Citrix Cloud Console → Delivery Groups → Select group
  2. Edit → Users tab → Remove user
The desktop will disappear from the user’s Workspace immediately. If a VM has been statically assigned, find the user’s VM, confirm that the name matches only that VM, and delete it:
If the user’s desktop had local data on it, you will want to SSH into the VM before deletion (ssh -J administrator@<HOST_IP> <VM_USERNAME>@<VM_IP>), copy the user’s home directory, and delete the VM after the backup has been confirmed. To delete an entire set of VMs that share a prefix, preview the deletion plan, then run delete.yml (management UI: Virtual Machines | Delete VM):
You can also use the delete subcommand in Bulk VM lifecycle management.

VM cleanup task checklist:

  1. Remove User from the Citrix Delivery Group
  2. Delete the VM from Orka
  3. Archive User data (if necessary)
  4. Update capacity tracking spreadsheet/software
  5. Confirm that the VM has been removed from the Machine Catalog in Citrix

Monitoring and Troubleshooting

Key metrics to watch:

Check daily:
  1. VM registration status. Check this by navigating to Citrix Cloud Console → Monitor → Machine Catalogs. You will want to look for:
    1. Unregistered Machines: Should be 0
    2. Power state “Off”: Investigate why VMs are powered off
    3. Faults: Any VM faults which require attention
  2. Session launch success rate. Check this by navigating to Citrix Cloud Console → Monitor → User Activity.
    1. Target: >95% success rate.
    2. If User Activity is <95%: Review failed connection attempts, identify any patterns to help determine the cause (specific users, times issues occur, VMs impacted)
  3. Host capacity. This can be checked by running ansible-playbook list.yml -i dev/inventory and verifying:
    1. Host capacity: Count the running VMs per host in the Host column. A host running two VMs is at capacity.
    2. Disk usage: Run ansible hosts -i dev/inventory -m shell -a "df -h /opt/orka" and confirm usage is below 85%.
    3. If usage is above 85%, plan for disk expansion or cleanup.
Check weekly:
  1. Performance trends. You can review these by navigating to Citrix Cloud Console → Monitor → Trends. Review the following:
    1. Average session launch time (target: <30 seconds)
    2. Session quality (should be “Good” or “Excellent”)
    3. Peak concurrent users (plan capacity for 20% growth)
  2. Host health can be verified by confirming available disk space using: ansible hosts -i dev/inventory -m shell -a "df -h /opt/orka"
    1. Check for any errors in the Orka Engine logs: ansible hosts -i dev/inventory -m shell -a "grep -i error /opt/orka/logs/com.macstadium.orka-engine.server.managed.log | tail -20"
  3. Image currency
    1. Are VMs running the latest golden image version?
    2. Are there any security patches pending?
    3. If yes, schedule any updates that are needed and communicate any downtime to Users.
Check monthly:
  1. Capacity planning
    1. Confirm your current VM count vs. your total VM capacity
    2. Calculate anticipated user growth trends
    3. Use these calculations to help determine your projected need for additional hosts
  2. User feedback
    1. Are there any session quality complaints? If so, what are they, and are there any trends to surface? Track these in an internal spreadsheet or other tool for additional sentiment analysis.
    2. Application performance issues
    3. Feature requests or service improvements
  3. Security review
    1. Verify whether enrollment tokens have been rotated in the last 90 days
    2. Confirm SSH keys are up-to-date
    3. Review audit logs
  4. Alert thresholds
    1. Set up relevant monitoring alerts via email/Slack/Teams/etc.
    2. Confirm which alerts require immediate response (Critical)
      1. VDA registration drops below 80% of expected targets
      2. All VMs in a Delivery Group are unavailable
      3. Host disk space >90%
    3. Confirm which alerts require a response within 4 hours:
      1. 10% of sessions launched fail over 15 minutes
      2. Host CPU sustained usage >80% for 30 minutes
      3. Available disk space >75%
    4. If session launch time exceeds baseline by 50%, or a new “Unregistered” VM appears, review this information daily.

Common issues and resolutions

VM deployed, but is not registered in Citrix:
Symptoms:
  • The VM appears in the list.yml output
  • The Citrix Machine Catalog shows no new VM
  • Desktop is not available in Workspace
Resolution:
  1. Confirm the VDA was installed and registered. deploy.yml only deploys the VM: run install_citrix_vda.yml (even if the golden image includes the VDA, since it sets the hostname), and then run register_citrix_vda.yml for every new VM. See Provisioning a new desktop.
  2. Check the VDA service is running. Get the VM’s IP address and host from list.yml, connect to the VM through its host, and list the Citrix services:
Expected: Service running with PID
  1. Check enrollment token:
    • Citrix Cloud → Machine Catalogs → Enrollment Token
    • Verify that the token is not expired
    • If the token is expired: Generate a new enrollment token in Web Studio and re-run register_citrix_vda.yml with the new enrollment_token. You don’t need to redeploy the VM.
  2. Check the Citrix VDA logs in /Library/Application Support/Citrix/VDA/Logs/ on the VM. Look for any registration errors, and follow up on any that appear.
  3. Test network connectivity from the VM, in the same SSH session:
Any HTTP response shows that the VM can reach Citrix Cloud. A timeout or a name resolution error points to a DNS, firewall, or proxy problem. The VM needs outbound TCP 443 to *.xendesktop.net and outbound TCP/UDP 443 to *.*.nssvc.net. If this problem persists, review the Troubleshooting quick reference.
Issue: Session launch timeout
Symptoms:
  • User clicks on the desktop in their Citrix Workspace
  • A connection progress bar appears
  • The session eventually times out with a “Cannot connect” error
Resolution:
  1. Verify the VM is running: ansible-playbook list.yml -i dev/inventory -e "vm_name=<VM_NAME>"
  2. Confirm the Citrix Machine Catalog shows that the VM is both “Registered” and “Available”
  3. Check Rendezvous connectivity. The VM needs outbound access to *.*.nssvc.net on TCP/UDP 443, and no inbound ports. Confirm that your firewall allows that traffic and that no HTTP proxy is blocking WebSocket connections. See Citrix DaaS configuration.
  4. Try a different client device to isolate if the problem is a client-side vs. server-side issue
Issue: Disk space full on Orka host
Symptoms:
  • VM deployments or image pulls fail on the host
  • Host disk usage >90%
Resolution:
  1. Check disk usage: ansible hosts -i dev/inventory -m shell -a "df -h /opt/orka"
  2. List the images cached on the host: ansible-playbook list_images.yml -i dev/inventory -e "node_name=<HOST_IP>"
  3. Remove old image versions from the host: ansible-playbook delete_image.yml -i dev/inventory -e "image_name=registry.example.com/citrix-vda/sonoma-finance:v1.0" -e "node_name=<HOST_IP>"
  4. If disk space is still low: delete VMs you no longer need and redeploy them on other hosts, expand storage, or add new host(s)
For more symptoms and fixes, see the Troubleshooting quick reference and Monitoring.

Log Locations

Orka Engine logs:

  • Location: /opt/orka/logs/com.macstadium.orka-engine.server.managed.log on each Mac host
  • View: tail -100 /opt/orka/logs/com.macstadium.orka-engine.server.managed.log
  • Contains: VM lifecycle events, image operations, errors

Citrix VDA logs:

  • Location: /Library/Application Support/Citrix/VDA/Logs/ on each VM
  • View: Connect to the VM with ssh -J administrator@<HOST_IP> <VM_USERNAME>@<VM_IP>, then list the directory with ls "/Library/Application Support/Citrix/VDA/Logs/" and open the log you need

System logs:

  • Location: /var/log/system.log
  • View: sudo tail -100 /var/log/system.log
  • Contains: macOS system events, service crashes

Ansible logs:

  • Location: Playbook output (stdout). The management UI keeps each task’s full output in its task history.
  • Verbose mode: Add -vvv to playbook command
  • Example: ansible-playbook deploy.yml -i dev/inventory -e "vm_name=<VM_NAME>" -e "vm_image=<IMAGE>" -vvv

Centralized logging (if configured):

  • Check your logging infrastructure (Splunk, ELK, CloudWatch)
  • Search by hostname, VM name, or error keywords

When to Escalate to MacStadium Support

Escalate when:
  • The Orka Engine service crashes repeatedly
  • If you are unable to deploy VMs after following the documented troubleshooting steps
  • You suspect hardware failure (host unresponsive)
  • Image operations fail consistently
  • You need guidance on capacity planning or architecture changes
Before escalating an issue, gather the following information:
  • The problem description and its symptoms/potential root causes. If you have noticed any trends or patterns when the issue occurs, provide this information as well.
  • The steps you have already taken to troubleshoot the issue
  • Relevant log excerpts (Orka Engine, VDA)
  • Output of any diagnostic commands you have run
  • Timeline of the issue (when it started, issue frequency)
Contact MacStadium Support: For response times by severity and support plan, see MacStadium support tiers.

Security and Compliance

Network Isolation Best Practices

VLAN segmentation:
Your deployment should use separate VLANs:
  • Management VLAN: Mac host management interfaces and the Ansible control node (restricted access)
  • VM VLAN: Citrix VDA VMs (isolated from management)
  • User VLAN: End-user access (if applicable)
You can check each VM’s IP address in the output of ansible-playbook list.yml -i dev/inventory. VMs should be on a VM VLAN subnet, not a management VLAN.

Firewall rules:

Orka hosts should allow:
  • Inbound: SSH (port 22) from the Ansible control node only. Ansible manages Orka Engine over SSH; there’s no separate Orka Engine API port to open.
  • Outbound: Container registry (port 443)
  • Outbound: Internet access for macOS updates (port 80/443)

VMs should allow:

  • Inbound: No inbound ports are required when you use the Rendezvous protocol, the default for non-domain-joined VDAs. The VDA opens an outbound connection to the Citrix Gateway Service.
  • Outbound: Citrix Cloud (TCP 443 to *.xendesktop.net, and TCP/UDP 443 to *.*.nssvc.net)
  • Outbound: Internet access for application updates

Block unnecessary traffic:

  • VM-to-VM traffic (unless required by applications)
  • VM-to-management-VLAN traffic
  • Direct VM-to-Internet (route connections through a company proxy if required by policy)

SSH key management

Key rotation schedule:
Rotate SSH keys annually, and/or after personnel changes.
Generate a new SSH key:
Deploy the new SSH key to your host(s):
Point Ansible at the new key, and if you use the management UI, re-run configure_semaphore.py --ssh-key-file with the new key, which replaces the SSH Key entry in Key Store that the inventory uses. The script also rewrites Base VM Credentials, so pass the same --base-vm-username and --base-vm-password you used at setup (or set BASE_VM_USERNAME and BASE_VM_PASSWORD). Confirm that playbooks still connect before you remove the old key.
Remove old SSH key(s) from a host:
Replace <OLD_KEY_COMMENT> with the comment at the end of the old public key:

SSH key storage

  • Store private keys securely
  • Never commit private keys to Git
  • Limit access to keys (only authorized admins)

If a key is compromised

  • Generate a new key immediately
  • Deploy the new SSH key to all hosts
  • Remove the compromised key from all hosts
  • Review access logs for unauthorized use
  • Document the incident for additional review

Audit logging

You will want to enable audit logging for security compliance.
Citrix:
  • Configuration Logging: Tracks changes to Machine Catalogs, Delivery Groups, policies
  • Access: Citrix Cloud Console → Configuration → Logging
  • Retention period: 90 days (configurable)
Orka:
  • Orka Engine logs all VM operations
  • Location: /opt/orka/logs/com.macstadium.orka-engine.server.managed.log on each Mac host
  • Retention period: Configure log rotation to match your retention policy
Ansible:
  • Playbook execution logs. The management UI keeps each task’s output in its task history.
  • For command-line runs, capture stdout: ansible-playbook ... | tee -a /var/log/ansible-playbook.log
  • Include timestamp(s), operator name, and the command(s) executed

What to log

  • VM provisioning and deprovisioning
  • User access grants and revocations
  • Policy changes
  • Image updates
  • Configuration changes

Log review

  • Weekly: Review logs for any anomalies
  • Monthly: Summarize log activity for management
  • Quarterly: Audit logs for compliance

Data Sovereignty Considerations

Where data resides:
VM data:
  • Stored on the Orka host local disk, in /opt/orka/data/<VM_NAME>/
  • A physical location: Your data center (on-premises) or MacStadium data center (hosted)
Images:
  • Stored in an OCI registry
  • A physical location: Your data center (on-premises) or MacStadium data center (hosted)
User data:
  • Within the VM. VMs aren’t reset between sessions, so user data stays on the VM until you delete it, for both pooled and dedicated access.
  • Backup location: Your backup infrastructure
Citrix metadata:
  • Stored in Citrix Cloud (US or EU region, depending on account)
  • Contains: User assignments, policies, and session logs (no VM content)

Compliance considerations

GDPR (European users):
  • Ensure Citrix Cloud region is EU
  • Document data flows
  • Implement data retention policies (delete VMs when a user leaves the organization)
HIPAA (U.S.-based healthcare policy):
  • Encrypt data at rest (FileVault on VMs)
  • Encrypt data in transit (HDX uses TLS)
  • Implement audit logging
  • Sign BAA with Citrix
Data residency requirements:
  • Deploy Orka hosts in the required geographic region
  • Use a container registry located in the same region
  • Verify Citrix Cloud region compliance

Best practices

Image Hygiene and Update Cadence

Monthly:
  • Apply macOS security updates to golden images
  • Update applications (Office, browsers, etc.)
  • Test the updated image thoroughly
  • Deploy the image to production
Quarterly:
  • Review installed applications (remove any unused applications)
  • Update the Citrix VDA to the latest version
  • Audit image sizes (optimize if these are >50GB)
  • Document any changes made in your CHANGELOG.MD file and push these updates to Git.
Annually:
  • Upgrade macOS major version (for example, Sonoma → Sequoia)
  • Review all configuration scripts
  • Rebuild images from scratch (vs. doing incremental updates)
Image testing checklist:
  1. VM deploys successfully
  2. The VDA registers with Citrix
  3. All applications launch as expected
  4. No errors appear in the VDA logs
  5. Test that user(s) can access the desktop
  6. Confirm session performance is acceptable

Capacity planning

Current capacity formula:
Total Capacity = (Number of Hosts) × (max_vms_per_host) = (3 hosts) × (2 VMs/host) = 6 VMs
Estimate concurrent users:
Current users: 50 - Expected growth: +20 per quarter - Concurrent usage rate: 60% (30 users at peak)
Calculate your VM needs:
Required VMs = (Total Users) × (Concurrent Rate) × (Buffer) = (50) × (0.6) × (1.2 buffer) = 36 VMs
Determine your host requirement(s):
Hosts Needed = (Required VMs) / (max_vms_per_host) = 36 / 2 = 18 hosts

Change management procedures

Procurement timeline:
  • Order hosts 60 days before capacity constraint
  • Allow 14 days for delivery (if hosted with MacStadium)
  • Allow one week for deployment and testing
Monitoring triggers:
  • VM utilization >75%: Start planning for host expansion
  • VM utilization >90%: Expedite new hosts

Backup and Disaster Recovery

What to back up: Golden images:
  • Store these in an OCI registry (off-site)
  • Maintain at least three recent versions
  • Test the golden image VM restoration process quarterly

User data (persistent desktops only):

  • Do daily backups via Time Machine or an enterprise backup tool
  • 30-day retention of user data
  • Test data restoration process and procedures monthly

Configuration:

  • Ansible playbooks and inventory: Store these in a Git repository
  • Citrix configuration: Export this monthly via PowerShell
  • Documentation: Store this in a company wiki such as Confluence, in Git, or on a shared drive

Disaster recovery scenarios:

Scenario 1: Single host failure
  • Impact: 2 VMs unavailable
  • RTO: 4 hours
  • Procedure:
    1. Provision a replacement Mac
    2. Add the machine to your existing Ansible inventory
    3. Install Orka Engine on the machine with install_engine.yml
    4. Pull golden images with pull_image.yml
    5. Deploy VMs to the new host from the golden image, then register them with Citrix using register_citrix_vda.yml
Scenario 2: Complete site failure
  • Impact: All VMs are unavailable
  • RTO: 8-12 hours
  • Procedure:
    1. Provision Macs at an alternate site (or host these directly with MacStadium)
    2. Restore your last known good Ansible configuration from Git
    3. Install Orka Engine on the new hosts with install_engine.yml
    4. Pull images from your OCI registry
    5. Deploy new VMs
    6. Verify VDA registration in Citrix
Disaster recovery (DR) testing:
  • Annually: Conduct a full DR exercise
  • Quarterly: Conduct a partial failover test
  • Document lessons learned

Change Management Procedures

Before any production change:
  1. Document the change:
  • What: Description of the suggested change
  • Why: Business justification for making the change
  • Impact: Affected systems, users, and any anticipated downtime
  • Rollback plan: Steps necessary to revert the change if any issues occur
  1. Test in a non-production environment:
  • Deploy test VMs with their own name prefix, separate from production VMs
  • Validate functionality
  • Measure performance impact
  1. Schedule a change maintenance window:
  • Communicate the change to users 1 week in advance
  • Choose a low-usage time (evenings, weekends)
  • Change duration: 2× expected time (buffer for issues)
  1. Execute the change:
  • Follow the documented change procedure
  • Monitor for any issues
  • Validate success criteria has been met
  • Communicate change completion
  1. Post-change review process:
  • Document the actual vs. planned change(s)
  • Capture any lessons learned during the change process
  • Update change procedure(s) if needed

Example change: Update golden image from v1.2 to v2.0

Change request:
  • Change: Update finance golden image to v2.0 (adds Microsoft Teams)
  • Impact: 50 finance VMs, 200 users
  • Downtime: 2 hours (pooled desktops, off-hours)
  • Rollback: Revert vm_image to v1.2, redeploy VMs
Test plan:
  • Deploy 2 test VMs from v2.0 image
  • Validate Microsoft Teams launches correctly
  • Test user session quality is acceptable
Change execution plan:
  1. Update vm_image in group vars to v2.0
  2. Delete any existing VMs: delete.yml (30 min)
  3. Deploy the new VMs: deploy.yml (60 min)
  4. Register the new VMs with Citrix using register_citrix_vda.yml, and verify VDA registration in Citrix (15 min)
  5. Test user sessions (15 min)
Change rollback plan (if adverse issues occur):
  1. Update the vm_image back to v1.2
  2. Delete v2.0 VMs
  3. Redeploy VMs from v1.2 and register them with Citrix
Change communication:
  • 1 week before scheduled change: “Scheduled maintenance Sunday 2 AM-4 AM, desktops will be unavailable”
  • Day of change: “Maintenance is currently in progress, desktops will be available by 4 AM”
  • After change is complete: “Maintenance is now complete, Microsoft Teams is now available on finance desktops.”

Resources and support

Documentation:

MacStadium
Citrix
Ansible:

Support Contact Information

MacStadium Support:
When contacting MacStadium support, please provide the following information:
  • Your Account ID
  • Affected host IPs or VM names
  • Problem description and timeline
  • The troubleshooting steps you have already taken
  • Log excerpts (Orka Engine, VDA)
Citrix Support:
  • Portal: Citrix Support
  • Access via Citrix Cloud Console → Support
  • Include: Your Customer ID, Machine Catalog name, applicable error messages

Citrix community forums: