name: infrahub-managing-generators description: >- Creates Infrahub Generators — design-driven automation that builds infrastructure objects from templates and topology definitions. TRIGGER when: building design-to-implementation workflows, auto-creating objects from templates, topology-driven generation. DO NOT TRIGGER when: designing schemas, writing data transforms, querying live data, populating static data files. allowed-tools: - Read - Write - Edit - Bash - Grep argument-hint: "[generator-name] [description...]" metadata: version: 1.2.7 author: OpsMill
Infrahub Generator Creator
Overview
Expert guidance for creating Infrahub Generators. Generators query data from Infrahub via GraphQL and create new nodes and relationships based on the result -- enabling design-driven automation where a "design" object automatically creates downstream infrastructure.
Project Context
Infrahub config:
!cat .infrahub.yml 2>/dev/null || echo "No .infrahub.yml found"
Existing generators:
!find . -name "*.py" -path "*/generators/*" 2>/dev/null | head -20
When to Use
- Building design-driven automation (topology -> devices)
- Creating objects from templates or design definitions
- Implementing idempotent create-or-update workflows
- Auto-generating infrastructure from high-level designs
- Understanding the generator tracking system
Rule Categories
| Priority | Category | Prefix | Description |
|---|---|---|---|
| CRITICAL | Architecture | architecture- |
Components, groups |
| CRITICAL | Python Class | python- |
Generator, generate() |
| HIGH | Tracking | tracking- |
Upsert, idempotent |
| HIGH | API Ref | api- |
Constructor, props |
| HIGH | Registration | registration- |
.infrahub.yml config |
| MEDIUM | Patterns | patterns- |
Cleaning, batch, store |
| LOW | Testing | testing- |
infrahubctl commands |
Schema Features This Skill Depends On
Generators create real objects, so the schema must permit the shape they emit. Catch these gaps before the first run — re-running a buggy generator can delete data via the tracking cleanup.
| If the generator... | The schema must... | See |
|---|---|---|
| Creates objects of kind X | Have node X defined with the attributes the generator sets — extra attributes silently fail validation, missing required ones abort the create | ../infrahub-managing-schemas/rules/attribute-defaults-and-types.md |
| Links the created object to a parent | Have a Component/Parent relationship pair with matching identifiers and optional: false on the Parent side |
../infrahub-managing-schemas/rules/relationship-component-parent.md |
| Reads a "design" node to drive output | Define that node's human_friendly_id so the generator's tracking key stays stable across runs |
../infrahub-managing-schemas/rules/display-human-friendly-id.md |
| Is triggered by membership in a group | The target group must be a CoreGeneratorGroup (not CoreStandardGroup) — the dispatcher only recognizes the former |
rules/registration-config.md |
| Should be idempotent on re-run | Every save() uses allow_upsert=True; the run's tracking context deletes objects from prior runs that aren't recreated |
rules/tracking-idempotent.md |
Generator Basics
Every generator has three components:
- Target group -- objects that trigger the generator
- GraphQL query (
.gqlfile) -- fetches the design data - Python class -- inherits from
InfrahubGenerator, implementsgenerate()
from infrahub_sdk.generator import InfrahubGenerator
class MyGenerator(InfrahubGenerator):
async def generate(self, data: dict) -> None:
obj = await self.client.create(
kind="DcimDevice",
data={"name": "spine-01"},
)
await obj.save(allow_upsert=True)
Workflow
Follow these steps when creating a generator:
- Identify the design pattern — What "design" object triggers generation? What objects should be created from it? Read rules/architecture-components.md for the target group and generator components.
- Write the GraphQL query — Create a
.gqlfile that fetches the design data. Read ../infrahub-common/graphql-queries.md for query patterns. - Implement the Python class — Inherit from
InfrahubGenerator, implementgenerate(). Read rules/python-generate.md for the class pattern and rules/api-reference.md for available methods. - Make it idempotent — Use
allow_upsert=Trueso re-running creates or updates without duplicates. See rules/tracking-idempotent.md. - Check for
from_graphqladoption opportunity — ifgenerate()iterates response edges and callsself.client.get()to re-fetch typed peers, consider refactoring toInfrahubNode.from_graphql()to collapseO(N + 1)round trips toO(1). Read rules/patterns-hydration.md for the decision tree, detection heuristic, and refactor recipe. - Register in .infrahub.yml — Add under
generator_definitionswith the target group. See rules/registration-config.md. - Test — Run
infrahubctl generatorto validate. See rules/testing-commands.md.
Supporting References
- reference.md -- Class API,
lifecycle, idempotency contract,
.infrahub.ymlregistration (with thequery:-required shape that differs from check_definitions) - examples.md -- Complete Generator patterns (POP topology, network segment, minimal)
- ../infrahub-common/graphql-queries.md -- GraphQL query writing reference
- ../infrahub-common/infrahub-yml-reference.md -- .infrahub.yml project configuration
- ../infrahub-common/rules/ -- Shared rules (git integration, caching gotchas)
- ../infrahub-managing-schemas/SKILL.md -- Schema definitions Generators work with
- rules/ -- Individual rules organized by category prefix