Understanding the .infrahub.yml configuration file
The .infrahub.yml file serves as the central manifest that defines how Infrahub integrates with external Git repositories. This topic explains the role of this configuration file and the design philosophy behind its structure.
Why .infrahub.yml exists​
Infrastructure automation requires both structured data (device inventories, network topologies) and executable code (templates, validation scripts, Generators). The .infrahub.yml file solves the fundamental challenge of bridging these two worlds by:
- Declaring intent: Explicitly stating what resources from a Git repository should be imported into Infrahub
- Enabling selective integration: Allowing fine-grained control over which files and resources are processed
- Providing metadata: Supplying the necessary context for Infrahub to properly interpret and use repository contents
Design philosophy and structure​
The .infrahub.yml file follows a declarative approach where you specify what should happen rather than how it should happen. This design choice reflects several key principles:
Explicit over implicit​
Rather than scanning the entire repository and making assumptions about file purposes, the configuration file requires explicit declaration of all resources. This approach:
- Prevents unexpected imports of unintended files
- Makes the integration surface clear and auditable
- Allows for different file organizations across repositories
Resource types​
The configuration organizes resources into distinct categories based on their purpose and processing requirements:
- Executable code: Python transformations, Generators, and checks
- Templates: Jinja2 templates for configuration generation
- Schema definitions: Data models for infrastructure representation
- Data definitions: Object files for storing infrastructure data
- Query definitions: GraphQL queries for data retrieval
- Fragment definitions: Reusable GraphQL fragments for composing queries
- Menu definitions: UI navigation structure definitions
Each category has its own processing pipeline and validation requirements, reflecting the different ways Infrahub handles these resource types.
Metadata richness​
Beyond basic file paths, the configuration captures essential metadata about how resources should be used:
- Dependencies: Linking Transformations to their required GraphQL queries
- Targeting: Specifying which infrastructure groups a resource applies to
- Parameters: Defining the inputs required for executable resources
- Naming: Providing human-readable identifiers for UI and API access
Loading behavior and dependency management​
The .infrahub.yml file controls not only what gets loaded, but also how and when resources are processed:
Processing order​
Infrahub processes configuration sections in a specific order to handle dependencies:
- Schemas: Loaded first to establish the data model
- GraphQL queries: Loaded before resources that depend on them
- Objects: Loaded to populate initial data
- Python files: Check definitions, Python transformations, and Generators are loaded together
- Jinja2 transformations: Loaded after their required queries are available
- Artifact definitions: Loaded last to reference existing transformations
File vs. directory handling​
When you specify a directory in any resource list:
- Infrahub processes all relevant files within that directory
- Files are processed in alphabetical order
- Subdirectories are processed recursively
This behavior enables you to organize complex repositories while maintaining predictable loading order.
Dependency resolution​
The configuration enables Infrahub to resolve dependencies between resources:
- Transformations reference their required GraphQL queries by name
- Artifact definitions reference Transformations and target groups
- Generators specify their data dependencies through query requirements
This dependency management ensures that all resources have what they need when they execute.
Declaring extra dependencies with watch​
Infrahub automatically detects the files a Transformation reads: a Python Transformation's package directory, and the templates a Jinja2 Transformation statically includes, imports, or extends. When a file in that detected set changes in a proposed change, only the artifacts of the affected Transformation regenerate.
Some dependencies cannot be detected automatically, such as a template pulled in through a dynamic {% include some_variable %} or a helper module imported at runtime from another package. Declare these with the optional watch key on a jinja2_transforms or python_transforms entry. Watched files are added to the Transformation's auto-detected dependencies; they never replace them.
watch is a strict object. Today it accepts a single key, files:
filesis a list of file or directory paths, relative to the repository root.- A directory entry matches recursively: every tracked file beneath it joins the dependency set.
- Entries may be written with or without a trailing slash.
- Files ignored by Git,
.pycfiles,__pycache__/directories, and symlinks are never included.
A list at the watch key (watch: [a, b]), a bare string, or any unknown key is rejected when the repository is imported.
Future dependency-related keys (for example strict or exclude) will live under watch as additional keys alongside files.
Jinja2 example, where a template dynamically includes partials the parser cannot follow:
jinja2_transforms:
- name: DeviceConfig
query: device_config_query
template_path: templates/device_config.j2
watch:
files:
- templates/partials/
Python example, where a Transformation imports helpers from a sibling top-level package:
python_transforms:
- name: DeviceNameAttribute
class_name: DeviceNameAttribute
file_path: transforms/device_name_attribute.py
watch:
files:
- utils/
- shared/helpers.py
Declaring any watch.files entry also marks the Transformation's dependency closure as complete, which suppresses the conservative regenerate-on-any-change fallback that an incomplete auto-detection would otherwise trigger. See the proposed changes overview for what an incomplete closure means and how to resolve it.
Group targeting​
Many definitions in .infrahub.yml use groups to specify their targets:
- Artifact definitions - The
targetsfield references a group name to specify which objects should generate artifacts - Generator definitions - The
targetsfield specifies the group for generated objects - Check definitions - The
targetsfield indicates which group to validate
Groups provide a flexible way to target operations across multiple objects without hardcoding specific object lists. This design decouples resource definitions from infrastructure changes - you can add or remove objects from groups without modifying the configuration files.
Example targeting in .infrahub.yml:
artifact_definitions:
- name: "Router Configuration"
targets: "ProductionRouters" # References a group
transformation: "router_config_transform"
check_definitions:
- name: "Interface Validation"
targets: "NetworkDevices" # References a different group
class_name: "InterfaceCheck"
See organizing objects with groups for details on creating target groups.
Version control and branch behavior​
The .infrahub.yml file itself is version-controlled, enabling sophisticated integration patterns:
Branch-specific configuration​
Different Git branches can have different .infrahub.yml files:
- Development branches can include experimental resources
- Production branches can exclude debug or testing resources
- Feature branches can temporarily modify resource definitions
This flexibility allows teams to maintain different configurations for different environments or development stages.
Evolution and migration​
As your infrastructure automation evolves, the configuration file supports:
- Adding new resource types without affecting existing ones
- Deprecating old resources by removing them from the configuration
- Refactoring resource organization while maintaining functionality
This approach helps teams manage the lifecycle of infrastructure automation components with minimal disruption.
Future evolution and extensibility​
The .infrahub.yml format is designed to evolve with Infrahub's capabilities:
- New resource types can be added without breaking existing configurations
- Additional metadata fields can be introduced with backward compatibility
- Processing behavior can be enhanced while maintaining existing semantics
This future-proof design ensures that your automation investments remain valuable as Infrahub grows.
Conclusion​
The .infrahub.yml configuration file is a crucial bridge between Git repositories and Infrahub's infrastructure management capabilities. By understanding its design principles and structure, you can effectively organize your infrastructure automation resources and leverage Infrahub's full potential to manage your network infrastructure.
Further reading​
- Repository configuration file reference - Complete syntax and options reference
- How to connect external Git repositories - Step-by-step setup guide
- Understanding Git repositories in Infrahub - Repository integration concepts
- Understanding groups - Organizational concepts for targeting operations
- How to organize objects with groups - Creating and managing groups
- Schema development - Designing infrastructure data models
- Transformations - Data processing and template concepts
- Generators - Infrastructure provisioning automation
- Artifacts - Output generation and delivery