Skip to content
Docs / dflux Runner
ContactGet started

Your first YAML flow

By the end of this tutorial you will have copied the shipped registration flow, modified one transition to fail on a different condition, and watched the resulting run land in failed instead of registered. The point is to put your hands on the YAML schema before reading the full reference.

Prerequisites

  • You completed the Quickstart and have d3x-run installed.
  • An AMF reachable from the lab — same as the previous tutorial.
  • Your clone of d3x-templates. The examples below assume it sits at ./d3x-templates, the same path the Quickstart used.

Step 1 — Copy the shipped flow

The shipped flows live in the templates repository, one YAML file per flow, grouped by network function. Copy the gNB registration flow into a working directory of your own so your edits don't touch the originals:

Bash

Open my-templates/registration_strict.yaml. Notice the shape: kind: flow, type: client, protocol: ngap, nf: gnb, initial_state: idle, final_states: [registered, failed]. Each entry under states: has transitions keyed by event:.

Step 2 — Rename the flow

The templates loader keys flows by name. Change the name: field so your edit doesn't collide with the shipped registration flow:

YAML

Step 3 — Tighten a check

In the wait_context_setup state, the shipped flow already asserts that security_key and ue.AmfUeNgapId are both not_empty before sending InitialContextSetupResponse. Add one more check that fails on purpose so you can watch the run land in failed — assert that ue.AmfUeNgapId equals 0, which a real AMF never returns:

YAML

When a check fails, the engine fails the flow immediately. It does not abort just the transition and wait — the run completes right away with a result of failed, in well under a second. The on_timeout on this state never fires.

Step 4 — Run your modified flow

Bash

Expected — the failing equals check ends the run almost instantly:

Code

The duration is a fraction of a second, not the 10s on_timeout window. The failed check fails the flow on the spot, so the timer on wait_context_setup is never given the chance to fire. Add -trace, as above, to see each check and send logged in order up to the one that fails.

Step 5 — Make it pass again

Change the check you added in Step 3 to one that holds — assert that ue.AmfUeNgapId is non-empty instead of equal to zero:

YAML

Re-run the same command. With every check passing, all four actions in the transition fire and the flow lands in registered with a result of PASS.

Step 6 — Inspect the catalog entry

Bash

This confirms the flow loaded, prints the YAML, and shows the high-level metadata fields (name, type, protocol, NF, category) that the daemon and web UI surface.

What you built

You wrote your first custom flow without writing Go. You've seen how a single check op (equals, not_empty, greater_than, and the rest) determines whether a transition fires and that a failed check fails the run on the spot. The full schema — every action type, every check op, the template syntax for {{...}} — is in the flow schema reference.

Where to go next