Transform Manager
Skill: infrahub-managing-transforms
The Transform Manager produces, modifies, and debugs data transforms that convert Infrahub data into other formats (device configurations, JSON exports, CSV reports, and more). Transforms can be implemented as Python classes, Jinja2 templates, or a hybrid of both. The skill generates the transform code, GraphQL query, optional Jinja2 templates, and .infrahub.yml registration.
When to use
- Generating device configuration files from Infrahub data
- Exporting infrastructure data to JSON, CSV, or other formats
- Producing human-readable reports from graph data
- Any scenario where Infrahub data needs to be rendered into a different representation
- Changing what an existing transform or template renders, or working out why its output is wrong or an artifact fails to generate
What it produces
- GraphQL query file (
.gql): fetches the data the transform needs - Python transform class and/or Jinja2 template file(s)
.infrahub.ymlentry underpython_transformsorjinja2_transforms, including itswatchdependency declarationartifact_definitionsentry if the transform produces versioned artifacts
Example prompts
- "Create a Jinja2 transform that produces Cisco IOS configuration for each device, pulling interface and BGP data from Infrahub"
- "Write a Python transform that exports all IP addresses to a CSV file"
- "Build a hybrid transform that generates vendor-specific configs, Cisco IOS for routers, Juniper JunOS for switches"
- "The interface section of this config transform renders empty. Work out why and fix the template"
Key rules enforced
- Return type: Python transform must return
dictfor JSON output orstrfor text; wrong return type causes rendering failure datavariable: Jinja2 templates always receive the GraphQL response asdata; accessing the wrong key is a common mistake- Artifact definitions: if the transform output should be stored as a versioned artifact in Infrahub, an
artifact_definitionsentry is required in.infrahub.yml; the skill generates this when appropriate netutilsavailability:netutilsfilters are available in Jinja2 templates; the skill uses them where appropriate for IP and interface operationswatchdependencies: a Python transform always includes awatchblock naming every first-party module it imports and every file it reads at runtime (files: []when there are none); Infrahub never analyzes imports, so without the key the artifacts re-render on every commit, and with an incomplete list they silently go stale. A Jinja2 transform needs one only for a reference its parser cannot follow, such as a computed{% include %}
Common mistakes it catches
| Mistake | What the skill does instead |
|---|---|
Branching a Jinja2 template on __typename for the fragment's generic kind | Discriminates on field presence instead, since __typename resolves to the concrete kind, never the generic the fragment matched |
Returning a dict for a non-JSON/YAML content type (e.g. text/csv, image/svg+xml) | Returns a string for the six string content types; a dict there silently serializes as a Python repr |
Declaring watch: with nothing under it | Writes files: [] explicitly; a bare watch: parses to null and is indistinguishable from omitting the key |
Declaring an incomplete watch list that names some imports but not others | Names every first-party module and file the transform reads, since a partial list reads as complete while missing real dependencies |
A whole-directory watch entry | Names the specific modules, so an unrelated edit elsewhere in the directory doesn't re-render the artifact |
Missing .infrahub.yml registration under python_transforms or jinja2_transforms | Generates the registration entry alongside the transform |
Transform types
Python transform
Use when the output requires logic: conditional rendering, calculations, data reshaping.
- Implements
InfrahubTransformclass with atransform()method - Returns a
dictfor JSON output or astrfor text output
Jinja2 transform
Use when the output is primarily a template with variable substitution: device configs, structured text files.
- Template file receives the GraphQL query response in a
datavariable - Supports
netutilsfilters for network-specific operations (IP address manipulation, interface normalization)
Hybrid (Python + Jinja2)
Use when data needs preprocessing before rendering.
- Python class prepares and reshapes the data, Jinja2 template handles rendering
- Supports platform-specific templates (e.g., different configs per vendor) using
FileSystemLoader
Running it
Transforms run as part of the artifact generation pipeline or on demand:
infrahubctl transform <transform-name>
Not sure this is the right skill?
See Which skill do I use? for how the Transform Manager differs from the Data Analyzer and the Check Manager.