← All posts
Deep Dive

Intent: Saying What You Mean and Proving the Network Agrees

Write a one-line statement of how the network should behave. The Intent engine compiles it into checks and tells you where reality diverges.

NAPT Team8 min read
Intent verificationBGP neighborsshould be upcompilePASSFAIL

Network configuration is full of accidental complexity. Engineers think in intent — "every spine must peer with every leaf in AS 65001" — and then translate that into hundreds of CLI lines spread across dozens of devices. The translation is where bugs live.

The Intent panel inverts the workflow. You declare the desired property in a small DSL; the engine compiles the declaration into a set of checks, executes them through the same script runner used by the console, and produces a pass/fail report keyed by device.

The DSL

The Intent DSL is intentionally tiny. Statements look like:

spines = group(role = "spine")
leaves = group(role = "leaf")

forall s in spines, l in leaves:
  bgp.peer(s, l).state == "Established"
  bgp.peer(s, l).remote_as == 65001

That is enough to express the majority of fabric-level invariants — full mesh, route presence, MTU uniformity, NTP reachability, AAA configuration, and dozens of others. The DSL deliberately stops at the point where it would become a general-purpose programming language; if you need that, write a script.

Compilation

Each statement compiles into a directed graph of checks. The compiler folds quantifiers, deduplicates shared lookups, and emits a plan you can preview before running. Previewing matters: a careless forall across thousands of devices can be wildly expensive, and seeing the plan first lets you reduce scope before pressing go.

Execution and evidence

The plan is executed by the standard run pipeline. Each check produces a finding, even when it passes — a successful intent run is a powerful artefact during change windows because it gives you a green baseline you can point to. Failed checks include the actual observed value side by side with the expected value, so remediation is unambiguous.

A failing intent run is not a bug in the engine; it is the engine doing its job. The signal you want is the delta between what you declared and what the network is doing.

Drift detection without polling

You can schedule intent runs on a cadence and the engine will only emit a finding when the result changes. That gives you the benefits of continuous verification without the noise of "still passing" alerts.

Composability

Intents can import other intents. A team can define a base fabric_health intent and a per-region overlay that adds locality-specific peering rules. Imports are versioned, so a global change to the base intent does not silently mutate every region's behaviour.

How intent relates to compliance

Compliance rules describe industry standards (PCI, CIS, internal hardening); intents describe your specific design. They cover different ground. A device can be fully compliant and still violate intent — and vice versa. Run both.

Authoring tips

  • Start with the smallest possible intent that you would notice if it broke. Grow from there.
  • Prefer many narrow intents over one giant one — the failure surface is easier to reason about and the run plan is cheaper.
  • Use named groups (spines, edge_routers) so intents read like English to the next engineer who opens them.

What to try first

Pick one rule that you currently verify by hand during change reviews — uplink MTU, NTP server list, SNMP community — and encode it as an intent. Run it. Watch the platform tell you about the three devices nobody remembered.

#intelligence#intent#verification

Was this helpful?

Generate scripts for the task covered in this post

Describe what you need and NAPT writes production-ready automation in Netmiko, NAPALM, or Nornir.

Open Script Generator →
New to NAPT? Start with the Setup Guide

Related posts