An Ansible collection for managing SUSE Harvester HCI resources using the harvesterpy Python library.
This role provides Ansible modules to manage virtual machines, images, volumes, and networks in SUSE Harvester HCI. It wraps the harvesterpy Python library to offer idempotent, declarative infrastructure management through Ansible playbooks.
- Ansible 2.15 or higher
- Python 3.8 or higher
- harvesterpy Python library (see below for local development)
- passlib Python library (required for password hashing in cloud-init)
- Access to a SUSE Harvester HCI cluster
ansible-galaxy collection install bpmconsultag.harvestergit clone https://github.com/bpmconsultag/harvester.git
cd harvester
ansible-galaxy collection build --force
ansible-galaxy collection install ./bpmconsultag-harvester-*.tar.gz --forceOr install directly from Git:
ansible-galaxy collection install git+https://github.com/bpmconsultag/harvester.gitIf you are developing or testing with the local harvesterpy source (not the PyPI package), you must install it into your Python environment:
From the root of the repository:
cd /path/to/harvesterpy # project root containing setup.py or pyproject.toml
pip install -e .Alternatively, you can set the PYTHONPATH environment variable before running Ansible:
export PYTHONPATH=$PWD:$PYTHONPATHThis should be run from the project root.
If you see errors about the harvesterpy library not being found, ensure you have performed one of the above steps in the same environment where Ansible runs.
Available variables are listed below, along with default values (see defaults/main.yml):
# Harvester API connection settings
harvester_host: "" # Harvester host URL (required)
harvester_token: "" # API token for authentication
harvester_verify_ssl: true # Verify SSL certificates
harvester_timeout: 30 # Request timeout in seconds
# Default namespace for resources
harvester_namespace: "default"
# VM defaults
harvester_vm_state: "present" # State: present, absent, started, stopped, restarted
harvester_vm_running: true # Whether VM should be running
harvester_vm_cpu_cores: 2 # Default CPU cores
harvester_vm_memory: "4Gi" # Default memory allocation
# Image defaults
harvester_image_state: "present" # State: present, absent
# Volume defaults
harvester_volume_state: "present" # State: present, absent
harvester_volume_access_modes: # Default access modes
- ReadWriteOnce
harvester_volume_storage: "10Gi" # Default storage size
# Network defaults
harvester_network_state: "present" # State: present, absentThe role includes the following custom Ansible modules:
Manage virtual machines in Harvester.
Parameters:
host: Harvester host URL (required)tokenorusername/password: Authentication credentials (required)name: VM name (required)namespace: Namespace (default: "default")state: Desired state (present, absent, started, stopped, restarted)cpu_cores: Number of CPU coresmemory: Memory allocationdisks: List of disk configurationsnetworks: List of network configurationslabels: Labels to apply to the VMspec: Complete VM specification (advanced)
Manage VM images in Harvester.
Parameters:
host: Harvester host URL (required)tokenorusername/password: Authentication credentials (required)name: Image name (required)namespace: Namespace (default: "default")state: Desired state (present, absent)url: URL to download the image fromdisplay_name: Display name for the imagedescription: Description of the imagesource_type: Source type (download, upload)storage_class: Storage class for the imagelabels: Labels to apply to the image
Manage persistent volumes in Harvester.
Parameters:
host: Harvester host URL (required)tokenorusername/password: Authentication credentials (required)name: Volume name (required)namespace: Namespace (default: "default")state: Desired state (present, absent)storage: Storage size (e.g., "10Gi")access_modes: Access modes (default: ["ReadWriteOnce"])storage_class: Storage class for the volumevolume_mode: Volume mode (Filesystem, Block)labels: Labels to apply to the volume
Manage network attachment definitions in Harvester.
Parameters:
host: Harvester host URL (required)tokenorusername/password: Authentication credentials (required)name: Network name (required)namespace: Namespace (default: "default")state: Desired state (present, absent)config: Network configuration (JSON string or dict)labels: Labels to apply to the network
This role has no dependencies on other Ansible roles. It will automatically install the harvesterpy Python library when tasks are executed.
---
- name: Create a VM in Harvester
hosts: localhost
gather_facts: false
tasks:
- name: Create virtual machine
bpmconsultag.harvester.harvester_vm:
host: "https://harvester.example.com"
token: "your-api-token"
name: "my-vm"
namespace: "default"
state: present
cpu_cores: 2
memory: "4Gi"---
- name: Deploy complete VM with dependencies
hosts: localhost
gather_facts: false
vars:
harvester_host: "https://harvester.example.com"
harvester_token: "your-api-token"
tasks:
- name: Create VM image
bpmconsultag.harvester.harvester_image:
host: "{{ harvester_host }}"
token: "{{ harvester_token }}"
name: "ubuntu-20.04"
state: present
url: "https://cloud-images.ubuntu.com/releases/focal/release/ubuntu-20.04-server-cloudimg-amd64.img"
display_name: "Ubuntu 20.04 LTS"
- name: Create VM volume
bpmconsultag.harvester.harvester_volume:
host: "{{ harvester_host }}"
token: "{{ harvester_token }}"
name: "my-vm-disk"
state: present
storage: "20Gi"
- name: Create virtual machine
bpmconsultag.harvester.harvester_vm:
host: "{{ harvester_host }}"
token: "{{ harvester_token }}"
name: "my-ubuntu-vm"
state: present
cpu_cores: 4
memory: "8Gi"
disks:
- name: disk0
volume_name: "my-vm-disk"
bus: virtio
labels:
environment: production---
- name: Manage VM lifecycle
hosts: localhost
gather_facts: false
vars:
harvester_host: "https://harvester.example.com"
harvester_token: "your-api-token"
vm_name: "my-vm"
tasks:
- name: Stop VM
bpmconsultag.harvester.harvester_vm:
host: "{{ harvester_host }}"
token: "{{ harvester_token }}"
name: "{{ vm_name }}"
state: stopped
- name: Start VM
bpmconsultag.harvester.harvester_vm:
host: "{{ harvester_host }}"
token: "{{ harvester_token }}"
name: "{{ vm_name }}"
state: started
- name: Restart VM
bpmconsultag.harvester.harvester_vm:
host: "{{ harvester_host }}"
token: "{{ harvester_token }}"
name: "{{ vm_name }}"
state: restarted---
- name: Use harvester role
hosts: localhost
roles:
- role: bpmconsultag.harvester
vars:
harvester_host: "https://harvester.example.com"
harvester_token: "your-api-token"
tasks:
- name: Create VM using role defaults
harvester_vm:
host: "{{ harvester_host }}"
token: "{{ harvester_token }}"
name: "test-vm"
state: presentWhen running the example playbooks, you must specify the custom module path so Ansible can find the harvester modules:
# If you are in the ansible/roles/harvesterpy directory:
ansible-playbook -i examples/inventory.ini examples/create_vm.yml --module-path=library -e "harvester_verify_ssl=false"
# Or from the project root:
ansible-playbook -i ansible/roles/harvesterpy/examples/inventory.ini ansible/roles/harvesterpy/examples/create_vm.yml --module-path=ansible/roles/harvesterpy/library -e "harvester_verify_ssl=false"This ensures Ansible loads the modules from the library/ directory in this role. If you see errors like couldn't resolve module/action 'harvester_image', make sure to use the --module-path option as shown above.
The role includes several example playbooks in the examples/ directory:
create_vm.yml: Complete VM creation with image and volumemanage_vm_lifecycle.yml: Start, stop, and restart operationscleanup.yml: Remove all created resourcesinventory.ini: Example inventory file
-
Use Ansible Vault for Credentials: Store sensitive information like tokens and passwords in Ansible Vault:
ansible-vault create group_vars/all/vault.yml
-
Idempotency: All modules are idempotent. Running the same playbook multiple times will not create duplicate resources.
-
Check Mode: All modules support Ansible's check mode (
--check) for dry runs. -
Tags: Use tags to organize your playbooks:
- name: Create VM harvester_vm: # ... tags: [harvester, vm, create]
-
Error Handling: Use
ignore_errorsandfailed_whenfor better error handling:- name: Delete VM (may not exist) harvester_vm: name: "my-vm" state: absent ignore_errors: true
If Ansible cannot find the modules, ensure the role is properly installed and the library path is correct:
export ANSIBLE_LIBRARY=/path/to/harvesterpy/ansible/roles/harvesterpy/library:$ANSIBLE_LIBRARYIf you encounter issues with the harvesterpy library not being found, ensure you have installed it as described above. For production or non-development use, you can install from PyPI:
pip install harvesterpyIf you're using self-signed certificates, you can disable SSL verification (not recommended for production):
harvester_verify_ssl: falseTo test the role locally:
- Set up your Harvester connection details in a vars file
- Run the example playbooks:
ansible-playbook -i examples/inventory.ini examples/create_vm.yml
Contributions are welcome! Please submit pull requests or issues to the GitHub repository.
MIT
This role was created by bpmconsultag as part of the harvesterpy project.