| name | infrahub-managing-transforms |
| description | Creates Infrahub transforms that convert data into JSON, text, CSV, or device configs using Python or Jinja2 templates, with YAML-driven tests. TRIGGER when: building config generation, data export, format conversion, Jinja2 templates, artifact pipelines, writing or running tests for a transform. DO NOT TRIGGER when: designing schemas, writing validation checks, creating generators, querying live data. |
| allowed-tools | ["Read","Write","Edit","Bash","Grep"] |
| argument-hint | [transform-name] [format] |
| metadata | {"version":"1.2.7","author":"OpsMill"} |
Infrahub Transform Creator
Overview
Expert guidance for creating Infrahub transforms.
Transforms convert Infrahub data into different formats
-- JSON, text, CSV, device configs, or any text-based
output -- using Python classes or Jinja2 templates.
Project Context
Infrahub config:
!cat .infrahub.yml 2>/dev/null || echo "No .infrahub.yml found"
Existing transforms:
!find . -name "*.py" -path "*/transforms/*" -o -name "*.j2" -path "*/templates/*" 2>/dev/null | head -20
When to Use
- Building data transformations (Infrahub data -> another format)
- Generating device configurations from infrastructure data
- Creating CSV reports, cable matrices, or inventory exports
- Rendering Jinja2 templates with query data
- Combining Python logic with Jinja2 rendering
- Connecting transforms to artifacts for automated output
Rule Categories
| Priority | Category | Prefix | Description |
|---|
| CRITICAL | Types | types- | Python vs Jinja2 choice |
| CRITICAL | Python | python- | InfrahubTransform class |
| CRITICAL | Jinja2 | jinja2- | Template syntax, filters |
| HIGH | Hybrid | hybrid- | Python + Jinja2 combined |
| HIGH | Artifacts | artifacts- | Output files, targets |
| HIGH | API Ref | api- | Class attrs, methods |
| MEDIUM | Patterns | patterns- | Utilities, CSV, shared |
| HIGH | Testing | testing- | Resources Testing Framework, transform/render commands |
Schema Features This Skill Depends On
A transform reads schema-shaped data and produces a
file. Misalignment between the transform and the
schema fails late — at artifact-render time, when
someone is waiting for the output.
Before writing Python
If the transform body is string formatting — f-strings,
concatenation, conditional sections — Jinja2 expresses
the same output in fewer lines, renders directly in
the proposed-change UI, and lives under
jinja2_transforms in .infrahub.yml instead of
python_transforms. Walk this ladder before reaching
for InfrahubTransform:
| Signal | Cheaper layer | See rule |
|---|
Transform body is return f"..." or "\n".join([...]) built from query results | Jinja2 template file | yagni-python-transform-that-could-be-jinja2 |
| Transform copies query data verbatim without computation | The GraphQL query alone — no transform needed | Ladder step 1 (drop the requirement); judgment call, no rule |
Conditionals are if x: out += ...; else: out += ... and nothing else | Jinja2 {% if %} blocks | yagni-python-transform-that-could-be-jinja2 |
Use Python when the transform parses, computes, or
reshapes — IP/subnet math, hashing, ordered
aggregation, structural JSON re-shaping. See
rules/python-transform.md
for the legitimate cases.
Transform Basics
Two types of transforms:
| Type | Output | Entry Point |
|---|
| Python | JSON/dict or text | InfrahubTransform.transform() |
| Jinja2 | Text | .j2 template file |
from infrahub_sdk.transforms import InfrahubTransform
class MyTransform(InfrahubTransform):
query = "my_query"
async def transform(self, data: dict) -> dict:
device = data["DcimDevice"]["edges"][0]["node"]
return {"hostname": device["name"]["value"]}
Workflow
Follow these steps when creating a transform:
- Choose the transform type — Python for JSON/dict
or complex logic, Jinja2 for text templates, hybrid
for both. Read
rules/types-overview.md.
- Write the GraphQL query — Create a
.gql file
that fetches the data to transform. Read
../infrahub-common/graphql-queries.md
for query patterns.
- Implement the transform — For Python, inherit
from
InfrahubTransform and implement transform().
Read rules/python-transform.md.
For Jinja2, create a .j2 template. Read
rules/jinja2-template.md.
For hybrid, read
rules/hybrid-python-jinja2.md.
- Connect to artifacts — If the transform output
should be stored as a file, configure artifact
definitions. See
rules/artifacts-definitions.md.
- Register in .infrahub.yml — Add under
python_transforms or jinja2_transforms. See
rules/api-reference.md.
- Add tests — Create YAML-driven test definitions
(smoke, unit, integration) alongside the transform so
it is validated automatically in the proposed change
pipeline. Read
rules/testing-resource-framework.md.
- Test locally — Run
infrahubctl transform or
infrahubctl render to validate. See
rules/testing-commands.md.
Supporting References