Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for OpenStack By James Joyner IV · · 11 min read

Automating OpenStack Workflows with Mistral and AI

Mistral turns multi-step OpenStack operations into versioned, retryable workflows. Here is how I author, debug, and run them — with an AI pairing as my fast junior engineer.

  • #openstack
  • #mistral
  • #workflow
  • #automation
  • #devops

The first time I tried to “just script” a tenant onboarding — create a project, a network, a router, a default security group, and seed quotas — I ended up with a 200-line bash file that failed halfway through and left orphaned resources everywhere. Cleaning up that mess by hand at 2 a.m. is what finally sold me on OpenStack Mistral. Mistral is the workflow-as-a-service project: you describe a sequence (or DAG) of tasks in YAML, and the engine runs them with built-in retries, error handling, and state you can inspect after the fact. No more guessing where a half-finished script died.

These days I author Mistral workflows the same way I write everything else: I sketch the shape myself, hand the tedious YAML expansion to an AI assistant, then review every line before it touches a real cloud. Think of the model as a fast junior engineer — great at boilerplate, terrible at judgment.

Why Mistral Beats a Pile of Bash

A bash script is fire-and-forget. Mistral gives you durable execution: every task is recorded, you can see inputs and outputs, and you can rerun from where it failed. That matters most for the operations you only run occasionally and therefore never quite trust.

Confirm the service is alive before anything else:

openstack workflow service list
openstack workflow list

If those return cleanly, the Mistral API and at least one engine/executor are up. Empty workflow list just means nobody has uploaded definitions yet.

Anatomy of a Workflow

A Mistral workflow is YAML with a version tag, a name, inputs, and tasks. Here is a deliberately small one that creates a project and a network:

---
version: '2.0'

onboard_tenant:
  input:
    - project_name
    - network_name
  tasks:
    create_project:
      action: keystone.projects_create name=<% $.project_name %>
      publish:
        project_id: <% task().result.id %>
      on-success: create_network
    create_network:
      action: neutron.create_network body=<% {'network' => {'name' => $.network_name, 'tenant_id' => $.project_id}} %>

Notice the <% ... %> expressions — that is YAQL, Mistral’s data-query language. This is exactly where AI assistants earn their keep: YAQL syntax is fiddly and easy to get subtly wrong, and a model that has seen thousands of examples will produce a working <% task().result %> reference faster than I will from memory.

Pro Tip: Keep one canonical, working workflow in your prompt context when you ask an AI to write a new one. It anchors the model on your conventions — action names, naming, indentation — and dramatically cuts the rate of invented action arguments.

Uploading and Running

Create the workflow, then execute it with inputs:

openstack workflow create onboard_tenant.yaml
openstack workflow execution create onboard_tenant '{"project_name": "acme", "network_name": "acme-net"}'
openstack workflow execution list

Grab the execution ID and watch it progress:

openstack workflow execution show <execution-id>
openstack task list <execution-id>

Each task row shows state — SUCCESS, ERROR, RUNNING. When something breaks, that table is your first stop instead of scrolling through a thousand log lines.

Debugging Failed Executions

Failures are where Mistral shines, because the failed task keeps its inputs and the error result. Inspect the specific task:

openstack task show <task-id>

The output includes the published variables and the raw error. I paste that error, plus the task definition, into an AI session and ask: “Why did this Neutron action fail given these inputs?” The model is excellent at spotting a malformed YAQL dictionary or a missing required argument. It is not allowed to fix it against production — it suggests, I verify against the API reference, then I edit.

If you want a structured way to capture these incident-style failures, I run them through my incident response dashboard so the diagnosis and resolution get logged instead of evaporating in my terminal scrollback.

Error Handling and Retries

The thing that separates a Mistral workflow from a fancy script is what happens when a task fails. Each task can declare on-error transitions and a retry policy, so a transient Neutron timeout does not abort the whole onboarding run. A retry block looks like this:

    create_network:
      action: neutron.create_network body=<% ... %>
      retry:
        count: 3
        delay: 5
        continue-on: <% task().result.error contains 'timeout' %>
      on-error: cleanup_partial

That says: retry up to three times with a five-second delay, but only on timeout-style errors, and if it still fails, jump to a cleanup task. Encoding that policy by hand is exactly where people cut corners and end up with brittle workflows. I describe the retry intent in English — “retry network creation three times on transient errors, otherwise clean up and stop” — and the AI produces the YAML, retry policy and YAQL condition included. Then I confirm the continue-on expression actually matches the error string Neutron returns, because a model will guess at the error text. I sanity-check it against a real failure before trusting it.

Cron Triggers and Reverse Workflows

Mistral can run workflows on a schedule, which replaces a rat’s nest of crontabs:

openstack workflow cron trigger create nightly_cleanup cleanup_orphans \
  --pattern '0 3 * * *'
openstack workflow cron trigger list

For onboarding-style flows, I always pair them with a reverse workflow that tears down exactly what was created. Ask your AI assistant to generate the inverse: it reads the create workflow and produces matching delete tasks in reverse order. Review it carefully — a deletion workflow is precisely the thing you do not want an over-eager model to improvise.

Guardrails: Never Hand the Model Prod Creds

Everything above keeps a human in the loop on purpose. Mistral actions execute with real cloud credentials, and a workflow that deletes resources is one bad YAQL expression away from a very bad afternoon. My rules:

  • The AI drafts YAML; it never holds an openstack session or a clouds.yaml.
  • I test every new workflow against a sandbox project first.
  • Destructive tasks get an explicit input flag (confirm: true) the workflow checks before running.

I keep a small library of vetted Mistral prompts in my prompt workspace so I am not re-explaining my conventions every session, and the reusable starting points live in the OpenStack prompt pack. For the editor side of things, I usually drive this with Claude when I want longer reasoning about a DAG, or Cursor when I am editing the YAML files directly.

Putting It Together

A typical session: I describe the desired end state in plain English, the model emits a version: '2.0' workflow with named tasks and on-success/on-error transitions, I read it line by line, upload it to a test cloud, run one execution, inspect the task table, and only then promote it. The whole loop takes minutes instead of the hour it used to take to write defensive bash by hand.

The deeper win is composability. Once you have a library of small, vetted workflows — create-project, create-network, seed-quotas — you can reference them as sub-workflows from a larger orchestration. Mistral lets one workflow call another as an action, so the onboarding flow becomes a thin wrapper that calls four building blocks you already trust. I have the AI propose how to decompose a big workflow into reusable pieces; it is good at spotting the natural seams, and a modular workflow library is far easier to review than one 300-line monolith. That review discipline is what keeps the whole thing trustworthy as it grows.

Mistral changed how I think about cloud operations — from “scripts I hope finish” to “workflows I can observe and replay.” Adding an AI assistant to author the YAML just made the boring part fast. Keep the model in the junior-engineer lane, keep your hands on the credentials, and you get reliable automation without the 2 a.m. cleanup.

If you want a hand wiring Mistral into a real onboarding or teardown pipeline, work with me, or browse the rest of the OpenStack guides and prompt library to keep going.

Free download · 368-page PDF

Download the Free 500-Prompt DevOps AI Toolkit

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.