Skip to content

Provisioning

Some resources aren't created or deleted through a direct REST endpoint. Their lifecycle runs through Waldur's marketplace order flow: you submit an order against an offering, Waldur processes it asynchronously, and a resource appears when it completes. The CLI exposes this as provision and terminate verbs.

There are two ways in:

  • Typed OpenStack commandsopenstack tenant, openstack instance, openstack volume get provision/terminate with a typed --generate-skeleton (flavor, image, ports, …), covered below.
  • Generic marketplace resource — provisions any offering type (SLURM, VMware, Azure, custom, …), with a free-form attributes body. See Provisioning other offerings.

The flow is the same either way: find an offering → submit an order → wait for it → get the resource.

1. Find an offering

Provisioning is always against an offering (a specific provider's OpenStack service). Browse them under marketplace offering, filtering by type:

1
2
waldur-cli marketplace offering list --filter type=OpenStack.Tenant --format json \
  --jmespath '[].{name: name, uuid: uuid, url: url}'

You'll need the offering's url, one of its plans' url, and the target project's url.

2. Build the order

provision takes the whole order body with the same --request / --request-file / --generate-skeleton options as create. The skeleton is the order envelopeoffering, project, plan, limits, accepting_terms_of_service — with the resource's typed attributes filled in under attributes, derived from that offering type's own schema (so an instance skeleton has flavor, image, ports, … and a volume skeleton has size, type, …):

1
waldur-cli openstack instance provision --generate-skeleton yaml > vm.yaml

Fill in offering, project, and the attributes you want. As with create, any field left null — including nested attributes fields — is omitted, so you only fill what you need. accepting_terms_of_service defaults to true in the skeleton.

Ambient project scope

If you've set a current project, you can leave project out of the order body entirely — it's filled in from the scope. An explicit project in the body still overrides it.

A tenant (VPC) order, for example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{
  "offering": "https://waldur.example.com/api/marketplace-public-offerings/<uuid>/",
  "project": "https://waldur.example.com/api/projects/<uuid>/",
  "plan": "https://waldur.example.com/api/marketplace-public-offerings/<uuid>/plans/<uuid>/",
  "attributes": {
    "name": "my-vpc",
    "skip_connection_extnet": true,
    "skip_creation_of_default_router": true
  },
  "limits": {"cores": 4, "ram": 4096, "storage": 51200},
  "accepting_terms_of_service": true
}

3. Provision

1
waldur-cli openstack tenant provision --request-file vpc.yaml

By default provision submits the order and polls it to completion, then prints the resulting resource. The order moves through pending/executing states to done; a failed order (erred, rejected, or canceled) surfaces its error_message as an error and a non-zero exit.

  • --no-wait — submit and return the order immediately, without polling. Useful in scripts that track orders themselves.
  • --timeout N — how long to wait for a terminal state before giving up, in seconds (default 600). Timing out doesn't cancel the order; it just stops waiting.
  • --interval N — how often to poll, in seconds (default 3). Raise it for an order you expect to take a while, to cut down on request volume; lower it if you want faster feedback on a quick one.
1
2
3
waldur-cli openstack tenant provision --request-file vpc.yaml --timeout 300
waldur-cli openstack instance provision --request-file vm.yaml --no-wait
waldur-cli openstack tenant provision --request-file vpc.yaml --interval 10

The provisioned resource object includes both resource_uuid (the OpenStack tenant/instance/ volume itself) and uuid — its marketplace resource UUID, which is what you'll need to terminate it.

Preview first

Add --dry-run to print the exact order that would be submitted (with the project and any defaults already filled in) without actually creating anything — see --dry-run.

Terminating

terminate tears a resource down through the same order flow. It takes the resource's marketplace_resource_uuid — the marketplace resource, not the plugin resource's own UUID. You'll find it as the uuid/marketplace_resource_uuid field on the provision result, or via get/list:

1
waldur-cli openstack instance terminate <marketplace_resource_uuid>

Some resources accept termination options as JSON:

1
2
waldur-cli openstack instance terminate <marketplace_resource_uuid> \
  --request '{"delete_volumes": true, "release_floating_ips": true}'

Like provision, terminate waits for the termination order to finish by default; --no-wait, --timeout N, and --interval N apply the same way.

Provisioning other offerings

marketplace resource provisions any offering type — SLURM allocations, VMware or Azure VMs, or a provider's custom offering — using the same order flow, just with a free-form attributes body instead of a typed one (the accepted attributes are offering-specific and not all modeled in the schema):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# find the offering
waldur-cli marketplace offering list --filter type=Marketplace.Slurm

# provision (offering + project + whatever attributes/limits that offering wants)
waldur-cli marketplace resource provision --request '{
  "offering": "https://waldur.example.com/api/marketplace-public-offerings/<uuid>/",
  "project":  "https://waldur.example.com/api/projects/<uuid>/",
  "plan":     "https://waldur.example.com/api/marketplace-public-offerings/<uuid>/plans/<uuid>/",
  "attributes": {"name": "my-allocation"},
  "limits":     {"cpu": 100, "ram": 200, "gpu": 4}
}'

marketplace resource provision --generate-skeleton gives the order envelope with a generic {name, description} attributes stub — fill in the offering-specific fields yourself (from the offering in the Waldur portal). Everything the typed commands support applies here too: --no-wait/--timeout/--interval, --dry-run, and the ambient --project (leave project out of the body and it's filled in).

marketplace resource list/get browse provisioned resources (handy for finding the marketplace_resource_uuid to terminate), and marketplace resource terminate <uuid> tears any of them down:

1
2
waldur-cli marketplace resource list --filter offering_uuid=<uuid>
waldur-cli marketplace resource terminate <marketplace_resource_uuid>

The typed openstack ... provision commands are just a convenience for the three OpenStack types — anything they can do, marketplace resource can do generically.

Waiting on anything, not just orders

Every command with a get also gets a wait — polling on an interval until a --jmespath condition against the fetched object is met, or timing out. Waldur's API has no server-side push/watch mechanism, so this is a client-side poll, not an instant notification -- but it saves you from writing your own poll loop.

The condition can be a boolean comparison:

1
waldur-cli openstack instance wait <uuid> --jmespath "state=='OK'"

or a plain presence check -- anything the expression returns other than false/null counts as met:

1
waldur-cli marketplace order wait <order-uuid> --jmespath "resource_uuid"

--timeout N (default 600s) and --interval N (default 3s) control how long to wait and how often to poll.

This is what makes --no-wait genuinely useful for fire-and-forget provisioning: submit without blocking, keep the printed order uuid, and wait on it later — from the same script, a different process, or a different machine entirely:

1
2
3
4
ORDER=$(waldur-cli openstack tenant provision --request-file vpc.yaml --no-wait \
  --format json --jmespath 'uuid')
# ... do other things ...
waldur-cli marketplace order wait "$ORDER" --jmespath "state=='done'" --format json

marketplace order get <uuid> is the one-shot version — no polling, just the current state (the same object provision's own polling already checks internally, exposed standalone for when you submitted with --no-wait and only have the order UUID, before any resource exists to check instead).

The bigger picture

An instance needs a tenant (and usually a network/subnet) to exist first, and its flavor and image are looked up within that tenant — so a from-scratch VM is a chain: provision a tenant, create a network and subnet in it, look up the tenant's flavor/image, then provision the instance referencing all of the above. Recipes & tips walks through a complete example.