Allow multiple config templates attached to a device #10518

Closed
opened 2025-12-29 21:32:30 +01:00 by adam · 7 comments
Owner

Originally created by @rodvand on GitHub (Nov 26, 2024).

NetBox version

v4.1.7

Feature type

Data model extension

Triage priority

N/A

Proposed functionality

Extend the config template field on a device/virtual machine to allow for attaching multiple config templates.

Use case

We have multiple stages of a device lifespan, and one of the stages is the provisioning phase. In the first phase we create a file enabling the provisioning and enrollment to the management system. In the second phase we apply the actual configuration. Currently we use one config template for both. This is cumbersome as users then need to download the one file and manually split it into two. It would be useful to allow multiple config templates to be attached to a device in this case.

Database changes

I assume you would need to change the relationship of the RenderConfigMixin from many-to-one to many-to-many.

External dependencies

No response

Originally created by @rodvand on GitHub (Nov 26, 2024). ### NetBox version v4.1.7 ### Feature type Data model extension ### Triage priority N/A ### Proposed functionality Extend the config template field on a device/virtual machine to allow for attaching multiple config templates. ### Use case We have multiple stages of a device lifespan, and one of the stages is the provisioning phase. In the first phase we create a file enabling the provisioning and enrollment to the management system. In the second phase we apply the actual configuration. Currently we use one config template for both. This is cumbersome as users then need to download the one file and manually split it into two. It would be useful to allow multiple config templates to be attached to a device in this case. ### Database changes I assume you would need to change the relationship of the RenderConfigMixin from many-to-one to many-to-many. ### External dependencies _No response_
adam added the type: feature label 2025-12-29 21:32:30 +01:00
adam closed this issue 2025-12-29 21:32:30 +01:00
Author
Owner

@jeremystretch commented on GitHub (Dec 5, 2024):

Why not use the assigned platform or a tag to indicate which template to use? You could then use a single base template and render one or the other as needed automatically. This logic would be needed anyway: Even with multiple templates associated with a particular device, you would need to know which to render.

@jeremystretch commented on GitHub (Dec 5, 2024): Why not use the assigned platform or a tag to indicate which template to use? You could then use a single base template and render one or the other as needed automatically. This logic would be needed anyway: Even with multiple templates associated with a particular device, you would need to know which to render.
Author
Owner

@cybarox commented on GitHub (Dec 11, 2024):

We could also make good use of this functionality. We have devices that output the configuration in a different order when queried than the order that is required if this configuration is to be applied. If we use the template that is intended for the validity check, dependencies cannot be resolved cleanly and vice versa.

@cybarox commented on GitHub (Dec 11, 2024): We could also make good use of this functionality. We have devices that output the configuration in a different order when queried than the order that is required if this configuration is to be applied. If we use the template that is intended for the validity check, dependencies cannot be resolved cleanly and vice versa.
Author
Owner

@dmulyalin commented on GitHub (Feb 20, 2025):

I would like to suggest another option - config profiles.

Config profile is a collection of templates associated with Netbox entities - devices, interfaces, circuits etc. Devices, interfaces, circuits etc. can have more then one config profile associated with them render in the order defined by preference parameter.

For example, config profile named core-router can be associated with a set of templates that constitute base configuration for core routers, next we can associate core-router profile with a set of devices to render config accordingly.

Another example desk-plus-phone-port profile can be associated with a template to render configuration for interface that can have IP Phone and computer connected to it, next we can associate desk-plus-phone-port config profile to a set of ports on switches resulting in config properly rendered for device interfaces.

One more example, backbone-circuit profile can be associated with circuit object and a set of templates that will be inherited by device interfaces connected to the circuit to render appropriate config.

In all examples, Jinja2 templates will be using conditional of if platform xyz use this piece of config, but at the end we will end up with a set of reusable templates and capability to easily associate and trace templates usage across devices.

what do you think @jeremystretch ?

@dmulyalin commented on GitHub (Feb 20, 2025): I would like to suggest another option - config profiles. Config profile is a collection of templates associated with Netbox entities - devices, interfaces, circuits etc. Devices, interfaces, circuits etc. can have more then one config profile associated with them render in the order defined by preference parameter. For example, config profile named `core-router` can be associated with a set of templates that constitute base configuration for core routers, next we can associate `core-router` profile with a set of devices to render config accordingly. Another example `desk-plus-phone-port` profile can be associated with a template to render configuration for interface that can have IP Phone and computer connected to it, next we can associate `desk-plus-phone-port` config profile to a set of ports on switches resulting in config properly rendered for device interfaces. One more example, `backbone-circuit` profile can be associated with circuit object and a set of templates that will be inherited by device interfaces connected to the circuit to render appropriate config. In all examples, Jinja2 templates will be using conditional of if platform xyz use this piece of config, but at the end we will end up with a set of reusable templates and capability to easily associate and trace templates usage across devices. what do you think @jeremystretch ?
Author
Owner

@Zetoniakj commented on GitHub (Mar 17, 2025):

I think it would be good having them assigned on the platform section and make the device inherit from there would be the most effective way, tagging would also work while being more effective since we can assign tags to pretty much everything.

Think about like two different config files for OS /etc/network/interfaces and /etc/chrony.conf

Thinking about this use case, maybe having a json defining templates and out file in case its other than the template itself like

{
    "tags": [
        "linux_rhel",
        "centos",
        "almalinux"
    ]
    "ConfigTemplates": {
        "chrony.j2": "/etc/chrony.j2",
        "dns.j2": "/etc/resolv.conf"
    }
}
@Zetoniakj commented on GitHub (Mar 17, 2025): I think it would be good having them assigned on the `platform` section and make the device inherit from there would be the most effective way, tagging would also work while being more effective since we can assign tags to pretty much everything. Think about like two different config files for OS `/etc/network/interfaces` and `/etc/chrony.conf` Thinking about this use case, maybe having a json defining templates and out file in case its other than the template itself like ``` { "tags": [ "linux_rhel", "centos", "almalinux" ] "ConfigTemplates": { "chrony.j2": "/etc/chrony.j2", "dns.j2": "/etc/resolv.conf" } } ```
Author
Owner

@mhdask commented on GitHub (Apr 9, 2025):

This would also be useful for us
We have a case where a device is first provisioned through ZTP, where only the basic configuration needed to establish connection is loaded on the device, and then all the services comes after
it would be beneficial if we could render the configs independently

@mhdask commented on GitHub (Apr 9, 2025): This would also be useful for us We have a case where a device is first provisioned through ZTP, where only the basic configuration needed to establish connection is loaded on the device, and then all the services comes after it would be beneficial if we could render the configs independently
Author
Owner

@dannywade commented on GitHub (May 21, 2025):

@mhdask what if you use the device's status to determine which configuration to use? For example, a device that is going through initial provisioning via ZTP could have a 'Provisioning' status and transition to a 'Staged' status once the basic configuration to establish connectivity has been applied. Obviously, you can pick the status that makes the most sense, but I figure that field in making config decisions.

@dannywade commented on GitHub (May 21, 2025): @mhdask what if you use the device's status to determine which configuration to use? For example, a device that is going through initial provisioning via ZTP could have a 'Provisioning' status and transition to a 'Staged' status once the basic configuration to establish connectivity has been applied. Obviously, you can pick the status that makes the most sense, but I figure that field in making config decisions.
Author
Owner

@jeremystretch commented on GitHub (Jul 17, 2025):

As I noted above, associating multiple config templates to a device would require declaring conditional logic to determine which template to render. This can already be accomplished within a single base template by doing something like this:

{% if device.status == 'active' %}
  {% include 'template_a.jinja' %]
{% else %]
  {% include 'template_b.jinja' %}
{% endif %}

No one has presented an argument for why this doesn't work, so I'm going to close out the FR.

@jeremystretch commented on GitHub (Jul 17, 2025): As I noted [above](https://github.com/netbox-community/netbox/issues/18110#issuecomment-2521222713), associating multiple config templates to a device would require declaring conditional logic to determine _which_ template to render. This can already be accomplished within a single base template by doing something like this: ``` {% if device.status == 'active' %} {% include 'template_a.jinja' %] {% else %] {% include 'template_b.jinja' %} {% endif %} ``` No one has presented an argument for why this doesn't work, so I'm going to close out the FR.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#10518