Skip to main content
Ansible playbooks automate VM lifecycle operations for Citrix VDA deployment. These are automation scripts written in YAML that define a series of tasks to be executed on remote systems. They describe the desired state of your infrastructure and document the steps needed to achieve it.
All playbooks on this page are sourced from the orka-engine-orchestration repository. The management UI is the recommended interface for day-to-day playbook execution. It provides a browser-based dashboard with pre-configured task templates for every playbook listed here. The CLI is available for advanced workflows and troubleshooting. See Getting Started: MSDC-Hosted or Getting Started: Self-Hosted for management UI setup instructions.
How playbooks work: A playbook contains one or more “plays,” each targeting specific hosts and executing a sequence of tasks:
  1. Inventory defines which hosts to target (for example, the hosts group containing your physical Mac machines)
  2. Tasks specify actions to perform (deploy VM, install software, configure settings)
  3. Variables customize behavior for different environments or use cases
  4. Handlers respond to changes (restart services after configuration updates)
An example of an inventory file:
[hosts]
10.0.0.31
10.0.0.32
10.0.0.33
Playbooks eliminate manual work by automating repetitive tasks, ensuring consistency, rapid recovery, providing audit trails, and simplifying updates. Each task in a playbook runs sequentially, and if any task fails, Ansible reports the error and stops execution, preventing partial deployments.

Core Ansible Playbook Examples

VM Deploy

# Plan deployment (dry-run)
ansible-playbook -i inventory deploy.yml -e "vm_name=citrix-vda-01" -e "vm_image=<your-image>" --tags plan

# Execute deployment
ansible-playbook -i inventory deploy.yml -e "vm_name=citrix-vda-01" -e "vm_image=<your-image>"

Delete a Single VM

ansible-playbook -i inventory vm.yml -e "vm_name=citrix-vda-abc123" -e "desired_state=absent"

Delete a VM by Name

# Plan deletion (dry-run)
ansible-playbook -i inventory delete.yml -e "vm_name=citrix-vda-test-01" --tags plan

# Execute deletion
ansible-playbook -i inventory delete.yml -e "vm_name=citrix-vda-test-01"
Run this command once for each VM to remove. To delete a VM on a specific host, use:
ansible-playbook -i inventory vm.yml -e "vm_name=citrix-vda-abc123" -e "desired_state=absent" --limit 10.0.100.10
Create backup file(s) before deleting a VM Note: This implementation does not have a dedicated backup Ansible playbook. To preserve VM configurations:
  1. Use create_image.yml to create versioned images
  2. Store images in your OCI registry
  3. To restore: Deploy new VMs from the backed-up image version
VM deletion playbook workflow:
  1. Deletes VM from Orka Engine
  2. Frees up resources on host

Create a VM Image

create_image.yml is the primary way to build a golden image for your VDI fleet. It deploys a temporary VM from a base image, runs your configuration scripts, commits the result to your OCI registry with a version tag, then deletes the temporary VM. The resulting image is the source for all VM deployments. See Golden image lifecycle for the full build-to-deploy loop.
ansible-playbook -i inventory create_image.yml -e "vm_image=ghcr.io/macstadium/orka-images/sonoma:latest" -e "remote_image_name=registry.example.com/citrix-vda/sonoma-golden:v1.0"
Before running:
  1. Place your configuration scripts (VDA install, etc.) in the /scripts directory
  2. Scripts will be executed in alphabetical order
  3. Example scripts:
- 01_install_dotnet.sh 
- 02_install_citrix_vda.sh 
- 03_configure_system.sh

Cache a VM Image

pull_image.yml pre-pulls an image to all hosts in your inventory so VMs deploy immediately without waiting for a registry download. Run this after create_image.yml and before deploying VMs in production.
ansible-playbook -i inventory pull_image.yml -e "remote_image_name=registry.example.com/citrix-vda/sonoma-finance:v2.0" 
Note: pull_image.yml automatically caches the image on all hosts in the inventory.

Recreate a VM Image

This implementation doesn’t have a dedicated playbook. To refresh VMs with a new image:
ansible-playbook -i inventory vm.yml -e "vm_name=citrix-vda-abc123" -e "desired_state=absent"
VM recreation playbook workflow:
  1. Delete existing VM
  2. Create a new VM from specified image

Provision User to VM

Provisions a new admin user account on a running VM. The playbook connects to the VM via the Mac host as a jump proxy, so sshpass must be installed on the Ansible runner. Apple Command Line Tools will be installed on the VM automatically if not already present.
ansible-playbook -i inventory provision_user.yml -e "vm_name=<vm_name>" -e "vm_username=<existing_admin_username>" -e "vm_password=<existing_admin_password>" -e "new_username=<new_username>" -e "new_user_password=<new_user_password>"
The playbook is idempotent. If the user already exists it will skip creation.

Install Citrix VDA

Installs Citrix Virtual Delivery Agent on a running VM. The playbook locates the VM across all hosts, installs prerequisites (.NET runtime, developer tools), sets the VM hostname, downloads and installs the Citrix VDA package, grants required TCC permissions, then reboots the VM to complete installation. sshpass must be installed on the Ansible runner. We recommend hosting your Citrix VDA installer in an S3 bucket with a presigned URL.
ansible-playbook -i inventory install_citrix_vda.yml -e "vm_name=<vm_name>" -e "vm_username=<admin_username>" -e "vm_password=<admin_password>" -e "citrix_installer_url=<citrix_dmg_url>" -e "hostname_suffix=<domain_suffix>"
Where:
  • vm_name: the exact name of the running VM (also used as the VM hostname)
  • citrix_installer_url: download URL for the Citrix VDA .dmg
  • hostname_suffix: domain suffix appended to vm_name to form the full hostname (for example, corp.example.com). Leave blank to use the VM name as the hostname.

Register Citrix VDA

Registers an installed Citrix VDA with a Delivery Controller using an enrollment token. Run this after install_citrix_vda.yml has completed successfully.
ansible-playbook -i inventory register_citrix_vda.yml -e "vm_name=<vm_name>" -e "vm_username=<admin_username>" -e "vm_password=<admin_password>" -e "enrollment_token=<enrollment_token>"

Playbook Customization for Your Environment

The Ansible playbook examples referenced throughout this document will require additional customization to match your infrastructure and organizational requirements. Environment-specific variables: Create a group_vars/all.yml file with the following settings as an example:
ansible_user: admin
vm_image: registry.example.com/citrix-vda/sonoma-finance:latest
max_vms_per_host: 2

Test Basic VM Lifecycle Operations

Before deploying to production, validate all playbook operations in a test environment.

Test Sequence

  1. Test connectivity
  2. Test image operations
  3. Test VM deployment
  4. Test VDA registration
  5. Test VM lifecycle
  6. Test image creation
  7. Test VM recreation
  8. Test VM deletion
  9. Test end-to-end user sessions
  10. Use verbose output for troubleshooting:
ansible-playbook -i inventory deploy.yml -vvv -e "vm_name=test-vm-debug" -e "vm_image=<your-image>"