Fuzzball Documentation
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Annotations and Selection

When a workflow uses an ephemeral volume without naming a specific provisioner, Fuzzball automatically selects a provisioner based on annotations and group access policies. Specifying size on a volume (without use or name) triggers this automatic selection, but the size value itself is not used as a selection criterion — provisioner selection is determined solely by annotation matching and group permissions.

This page describes how annotations work and how the selection algorithm resolves which provisioner to use.

How annotations work

Provisioner annotations are string key-value pairs that describe characteristics of the storage backend. Fuzzball treats annotation keys and values as opaque strings — the platform does not assign special meaning to any particular key or value. You define whatever annotations make sense for your organization (e.g., tier: fast, region: us-west, purpose: archive). Workflow volumes can request specific annotations, and Fuzzball will match them against provisioner annotations to find a compatible provisioner.

Setting annotations on a provisioner

Add annotations to a provisioner definition:

fast-storage:
  description: "Fast NVMe-backed NFS"
  driver:
    type: nfs
    target: "nfs-fast:/export/nvme"
  annotations:
    tier: fast
    region: us-west
  access: all
  ephemeral: all

Requesting annotations in a workflow

In a workflow definition, specify annotations: on a volume to request a provisioner with matching annotations:

volumes:
  scratch:
    annotations:
      tier: fast

Fuzzball will select a provisioner that has tier: fast in its annotations (among other checks).

Annotation matching rules

The matching logic follows these rules:

  1. Every annotation requested by the volume must exist on the provisioner with an exactly matching value
  2. Provisioners may have extra annotations — additional annotations on the provisioner that are not requested by the volume are ignored
  3. A volume with no annotations matches any provisioner — if the volume does not specify annotations, the annotation check is skipped
  4. Matching is exact — no wildcards, patterns, or partial matches. The key and value must be identical strings

Examples

Volume annotationsProvisioner annotationsMatch?Reason
tier: fasttier: fast, region: us-westYesAll requested annotations present
tier: fasttier: slowNoValue mismatch
tier: fastregion: us-westNoKey not found
(none)tier: fast, region: us-westYesNo annotations requested
tier: fast, region: us-westtier: fastNoMissing region key

The provisioner selection algorithm

When Fuzzball needs to select a provisioner (for ephemeral volumes or when the workflow does not specify a provisioner by name), it applies the following checks to each provisioner in the organization:

  1. Status check — skip provisioners that are not in Ready status
  2. Annotation match — skip provisioners that do not match the requested annotations
  3. Group permission check — skip provisioners where the user’s group does not have the required access for the operation type

The first provisioner that passes all three checks is selected.

If multiple provisioners match all criteria, the selection is non-deterministic — Fuzzball does not guarantee which one is chosen. Use annotations to distinguish provisioners when you need deterministic selection.

Volume resolution paths

Fuzzball resolves volumes differently depending on what the workflow specifies:

Direct provisioner name

When a workflow specifies use: my-provisioner, Fuzzball looks up the named provisioner directly. No selection algorithm runs — the provisioner must exist and the user’s group must have the required access.

volumes:
  data:
    use: my-nfs
    name: project-data

Ephemeral volume selection

When a workflow creates an ephemeral volume (no name:, with size: or annotations:), Fuzzball runs the selection algorithm with ephemeral operation type:

volumes:
  scratch:
    size: 10GB
    annotations:
      tier: fast

The selected provisioner must grant ephemeral access to the user’s group.

Persistent volume lookup

When a workflow references a persistent volume by name, Fuzzball searches across all provisioners for a volume with that name:

volumes:
  data:
    name: my-dataset

If the volume exists on exactly one accessible provisioner, that provisioner is selected. If the same volume name exists on multiple accessible provisioners, Fuzzball returns an error asking the user to specify the provisioner with use:.

Using annotations for multi-provisioner setups

Annotations are most useful when you have multiple provisioners and need workflows to select the right one without hardcoding provisioner names.

Separate provisioners by purpose

work-storage:
  driver:
    type: nfs
    target: "nfs-server:/export/work"
  annotations:
    purpose: work
  ephemeral: all

archive-storage:
  driver:
    type: nfs
    target: "nfs-server:/export/archive"
  annotations:
    purpose: archive
  access: all

Workflows select by purpose:

volumes:
  workspace:
    size: 50GB
    annotations:
      purpose: work

  results:
    name: my-archive
    annotations:
      purpose: archive

Separate provisioners by performance tier

fast-tier:
  driver:
    type: hostpath
    path: /mnt/nvme
    local: true
  annotations:
    tier: fast
  ephemeral: all

standard-tier:
  driver:
    type: nfs
    target: "nfs-server:/export/standard"
  annotations:
    tier: standard
  access: all
  ephemeral: all

Federated deployments

In federated deployments, each cluster has its own set of provisioners. The selection algorithm runs independently on each participating cluster. This means different clusters can have provisioners with the same annotations but different backends:

Cluster A:
  fast-storage:  hostpath /mnt/nvme (annotations: tier=fast)

Cluster B:
  fast-storage:  efs fs-12345678 (annotations: tier=fast)

A workflow requesting tier: fast will match the appropriate provisioner on whichever cluster it runs on, even though the underlying backends are different.