ampbase

OPAMP CONTROL PLANE

Documentation

Routing

Routing decides "which configuration version does this agent receive?" A channel's rules make that decision per agent. An agent no rule above it serves gets the channel default, the last rule in the list: the version you deploy from a configuration's page, which every agent receives when there are no other rules at all.

To ship a new version gradually — a canary, a ramp by percentage, or env by env — use a rollout: it moves the rules that serve the version it replaces, judges each stage from what its agents report about the version and their own builds, and can roll back on its own. Author a rule yourself when the routing is the point rather than a step toward a new default: an A/B comparison of two configs, or a region or team kept on its own version for good.

Rules sync to each channel every few seconds and evaluate in-process — there's no extra hop in the agent connection path.

The first matching rule wins

A channel's rules are an ordered list, and the order is the one on the Routing page. For each agent, Ampbase walks the list from the top. The first rule that matches the agent and routes it a version serves it; the rules below are not consulted for that agent.

   an agent checks in
        │
        ▼
   rule 1 matches and routes it a version? ── yes ─▶ rule 1 serves it
        │ no
        ▼
   rule 2 matches and routes it a version? ── yes ─▶ rule 2 serves it
        │ no
        ▼
       ...
        │ no
        ▼
   the last rule, the channel default, serves it

So a rule's position is part of what it does. A broad rule above a narrow one takes the agents both match; move the narrow rule above it and it takes them back. When two rules could match the same agent, the lower one's row says so — Overlaps prod-canary above: an agent both match is served by the rule above — so you can see which one wins before you save.

Matches

A rule decides which agents it applies to with label matchers: a key and a value, matched against the agent's attributes — anything you set under agent.attributes in supervisor.yaml (see Agents). Matchers belong to the rule as a whole, not to one variant:

rule: collector-us-east
├── matches: region == "us-east-1", env == "production"
├── variant "stable": weight 50  →  config "otelcol"  version 01HJK...
└── variant "trial":  weight 50  →  config "otelcol"  version 01HJL...
  • An agent matches only if every matcher matches it. Here that is agents in us-east-1 and in production.
  • A matching agent is then split between the variants by their weights.
  • A rule with no matchers matches every agent in the channel.

A matcher compares one key against one value (==), or against a set of values, matching an agent holding any of them (∈): env ∈ {integration, staging}. That is how a rollout's cohort stages widen: a stage's matcher sits on the temporary variant the rollout adds to each rule it moves, beside the rule's own. There is no rule language beyond this: no or across different keys, no numeric comparisons, no regular expressions, and no matchers on a variant of your own. If two groups of agents need different routing, give each its own rule, and put the one that should win their overlap first.

Variants

Most rules route every agent they match to one target: a configuration version, a bundle version, or none. The Routing page shows such a rule as the target it routes to.

Add a split to divide a rule's agents between two or more variants. Each variant then has:

  • A variant key (a label like stable, canary, v3.5-beta) that names the branch.
  • A weight between 0 and 100. Weights across a rule's variants must sum to 100.
  • A target, as above.

Weight bucketing is deterministic per agent (a hash of the agent ID), so an agent stays in the same bucket across reconnects. You won't see an agent oscillate between v3 and v4 every poll.

A variant with no target is a marker: it routes no version, so an agent it picks falls through to the rules below it. Markers exist for features that read which variant an agent resolved rather than what it was sent.

Targets: configs and bundles

  • Config target — a configuration plus an optional version. Leave the version on Track latest version to follow the configuration's latest version: a new save reaches the rule's agents on their next check-in, with no separate deploy step.
  • Bundle target — a bundle plus an optional version, with the same semantics.

Pinning is useful for ramps where you want the canary to stay on an exact build even as stable advances.

Editing and saving

The Routing page edits the whole list and saves it at once. The channel default is its last row, pinned below your rules: the configuration or bundle the channel serves, at its version, and when it was deployed and by whom. It matches every agent, so it serves each one no rule above it does. You can't edit, move or delete it on this page; you change it by deploying from a configuration's page. When the configuration or bundle it serves has a newer version, the row offers Deploy the newer version, which opens the deploy sheet on that version. A save never includes it.

  • Add rule puts a new rule at the bottom of your rules. Edit opens a rule in place. Drag a rule by its handle, or use ↑ ↓, to change its place; ⤓ moves it to the bottom.
  • As you change the list, the page checks it: each rule your change affects shows what it needs before it can be saved, in place on its row, and how many of the channel's agents have a build that can run what it routes. Nothing is written until you press Save rules.
  • Delete marks a rule for the next save, and the save asks you to confirm the deletions.
  • Saving a list that someone else changed since you opened the page is refused rather than overwriting their change. Reload the page and apply your edit again.

A change affects more rules than the one you touched, and the page checks each of them:

  • Moving a rule changes what it wins, and what every rule it passed wins. Each of those rules is checked as though you had edited it.
  • Deleting a rule hands its agents to the rules below it that could match them. Each of those rules is checked too. Deleting a rule asks for no confirmation when no rule below it could take its agents and route an enforcing version. Deleting a rule that is disabled or routes nothing asks for none either.

For a rule that routes an enforcing version — a Tetragon policy that can kill a process, say — that check asks you to type a confirmation phrase before the save goes through, and shows what the version enforces, how its canary has done, and the dry-run evidence for it. See Tetragon policies.

Changes reach every connected agent within a few seconds. Every rule a save changes is recorded in the channel audit log as its own Rule Saved entry, naming the rule and what happened to it.

A channel can hold up to 500 rules. Delete one to free a slot.

Build eligibility

Matchers are the condition you write. There is a second condition you don't: a variant reaches an agent only if that agent's build can actually run the configuration the variant targets.

You don't configure this. There's no component matcher and no picker to fill in. The requirement is derived from the config version a variant points at — every component that configuration names, whether it wires it into a pipeline or only defines it — and compared against the inventory each agent reports about its own build (see Supervisor reference, under Component inventory). Because it's derived rather than authored, it can't drift from the config it describes, and there's nothing to forget to add.

When an agent's build lacks something the variant's target needs, the variant is withheld from that agent. The agent falls through to the rules below, exactly as if this rule had not matched it, and to the channel default if none of them serves it. The default is never gated: an ineligible agent keeps running your stable config rather than being left without one. Withheld is not re-routed. Weight bucketing's choice still stands; it simply isn't delivered.

Where you see every decision it makes

  • The Routing page, when you change a rule. What each variant's target needs and how much of the channel can run it, before you save: needs exporter/kafka · 480 of 500 agents eligible · 12 missing exporter/kafka. It names the version it assessed, which matters for an unpinned target — that tracks its config's latest, so the readout tells you which version the numbers are about.
  • The Routing page, under Component eligibility on an opened rule. The decisions actually recorded at the last check-in, not a prediction: Of 500 targeted agents at last heartbeat: 460 eligible · 40 withheld. Withheld agents are grouped by reason, and each group names its remedy — add the component to the agent build, upgrade the supervisor so the build reports its inventory, review the target version's config.
  • The agent's rule trace. Open an agent and go to Rule evaluation: each rule it was evaluated against, in order, ending on the channel default, which is the one that served it whenever no rule above did. The gate is its own step in a rule's trace — variant "canary" withheld, then build missing exporter/kafka · falls through to the rules below, or the channel default, naming the version it was judged against.

What counts as eligible

  • A build that has never reported an inventory is unchecked, not fine. If the variant's target requires any components, the variant is withheld from that agent until its supervisor is upgraded to a release that reports an inventory and the first one arrives. Failing to prove a component is missing isn't evidence that it's there. On the rollout panel these agents appear as No manifest reported.
  • A target that requires no components runs on any build, so nothing is withheld from anyone — including agents that have never reported.
  • Agent types with no build-time components are always eligible. Refinery, Tetragon and AI coding agents have nothing a build of them could be missing.
  • If the target version's requirements can't be derived, the variant is withheld from everyone until you target a version whose requirements can be. An unreadable requirement is never treated as "requires nothing" — the readout says so in place, so you find out while editing rather than from a stalled rollout.

None of this blocks you from saving a rule or pointing a variant anywhere. An all-ineligible variant is simply inert: every agent it would have reached falls to the channel default, so there's nothing to acknowledge — only something to read. The one action that does carry friction is setting a channel default, which is ungated by design; see Configurations, under Build requirements and fleet coverage.

Renamed components are recognized

Eligibility is judged against what a build reports, and components are sometimes renamed upstream — a collector that used to list otlphttp may list otlp_http instead. Ampbase recognizes those as the same component: builds report the module each component comes from, and when the name your config uses and the name the build reports resolve to the same module, the build counts as having it.

You do not have to rewrite your config after an agent upgrade, and you do not have to keep two spellings in flight while a fleet upgrades — a config using either name is eligible on builds reporting either name.

Where a rename decided an outcome, it is stated rather than folded away. The coverage readouts count it separately (480 supported · 12 via a renamed component), the rule trace names the pair on the agent that received the variant, and the components card marks the row with the spelling that build reports.

A component that is genuinely absent is still missing — the recognition needs a matching module, not a similar name.

Typical patterns

Pattern How
Canary, then everyone A staged rollout by percentage — 10, 50, 100 — from Deploy this version. Each stage waits for its agents to report the version applied, and a rejection rolls it back. When the version needs build components, only agents that report their build are judged; see Rollouts.
Environment by environment A staged rollout by cohort through the values of a label, such as env: integration, staging, prod.
Rollback Roll back on the rollout's page returns every rule it moved to what it served before. After a rollout has finished, deploy the earlier version.
A/B experiment A rule you author: two equally-weighted variants pointing at different configs. Pair with metrics in your existing observability stack to compare.
Permanent targeting A rule you author with a matcher — region == "eu-west-1", say — and one variant at weight 100: those agents keep their own version, whatever the channel default is.
An exception inside a group Two rules, the narrower first: host == "db-7" above role == "db". The first rule wins the one host both match.

The rules a rollout moves

A staged rollout creates no rule of its own. It moves your rules that serve the version it replaces, the channel default among them, giving each a temporary variant for the agents each stage reaches. Each is marked Managed by rollout and is read-only while the rollout runs, and the channel's rules can't be saved until it ends, from the page and the API alike: the page says so in one banner naming the rollout, and every control that would save is disabled. See Rollouts, under What a rollout reaches.

When a rollout finishes, every rule it moved is handed back and can be edited again. A rule that tracked its latest version before the rollout may come back pinned instead, when tracking would serve a version no stage judged: after a rollback that leaves its latest at a version the rollback removed, or when its configuration or bundle moved on, or was deleted, during the rollout. Its row says Pinned by rollout with the rollout and the reason; set it back to Track latest version when you're ready.


Spotted a problem with these docs? Email support@ampbase.io.