Template Versioning
TeamsEnterpriseHow NetStacks tracks every template change with immutable versions, and how to compare, diff, and roll back template versions.
Overview
Every edit to a template in NetStacks creates a new, immutable version. The template object tracks a current_version number that increments with each save. Previous versions are never deleted or overwritten — they form a complete audit trail of how the configuration evolved over time.
Versioning provides three key capabilities:
- History — See every version of the template with who created it and when
- Comparison — Diff any two versions side by side to see exactly what changed
- Rollback — Restore a previous version by copying its source into a new version, preserving the full history
This is especially important for network configurations where a small change can cause outages. Version history lets you trace issues back to the exact config change that caused them and quickly revert.
How It Works
The versioning model is built on two data structures from the Stacks plugin:
JinjaTemplate
The template object stores the current state including the current_version number, the latest template_source, and the list of extracted variables.
JinjaTemplateVersion
Each version is stored as a separate record containing:
version— Integer version number (1, 2, 3, ...)template_source— The complete template content at that versioncreated_by— The user ID who created the versioncreated_at— Timestamp when the version was created
Version Creation
When you update a template via PUT to /plugins/stacks/admin/templates/:id with a modified template_source, NetStacks:
- Creates a new
JinjaTemplateVersionwith the updated source - Increments the
current_versionnumber on the template - Re-extracts variables from the new source
- Updates the template's
updated_attimestamp
Versions are immutable once created. You cannot edit a historical version — you can only create new versions.
To fetch the full version history, use the ?include_versions=true query parameter on the GET template endpoint. Without this parameter, only the current template state is returned.
Step-by-Step Guide
Step 1: Edit a Template and Save
Open an existing template in the editor, make your changes, and click Save. NetStacks automatically creates a new version with the updated content. The version number increments from the previous value.
Step 2: View Version History
Open the template and navigate to the version history panel. You will see a chronological list of all versions with the version number, author, and timestamp.
Step 3: Compare Two Versions
Select any two versions to see a side-by-side diff. Lines added in the newer version are highlighted in green, removed lines in red. This makes it easy to identify exactly what changed between any two points in the template's history.
Step 4: Roll Back to a Previous Version
To revert to a previous version, select the version you want to restore and click Restore This Version. This copies the historical version's template source into a new version (incrementing the version number), so the full history is preserved. Rolling back does not delete any versions.
Rolling back a template does not automatically re-deploy to devices that are currently running a configuration from a newer version. You will need to trigger a new deployment on affected stack instances after rolling back.
Step 5: Verify the Rollback
After restoring, preview the template with test variables to confirm the output matches what you expect. Then check any stack instances using this template to decide whether re-deployment is needed.
Code Examples
Retrieve Template with Version History
GET /plugins/stacks/admin/templates/tmpl_8f3a2b1c?include_versions=true
Authorization: Bearer <token>Response with Version History
{
"id": "tmpl_8f3a2b1c",
"name": "interface-l3-ios",
"description": "Layer 3 interface configuration for Cisco IOS",
"template_source": "interface {{ interface_name }}\n description {{ description }}\n ip address {{ ip_address }} {{ subnet_mask }}\n ip ospf {{ ospf_process_id }} area {{ ospf_area }}\n no shutdown",
"current_version": 3,
"variables": ["interface_name", "description", "ip_address", "subnet_mask", "ospf_process_id", "ospf_area"],
"owner_id": "usr_a1b2c3d4",
"created_at": "2025-08-15T09:30:00Z",
"updated_at": "2025-09-02T14:15:00Z",
"versions": [
{
"version": 1,
"template_source": "interface {{ interface_name }}\n description {{ description }}\n ip address {{ ip_address }} {{ subnet_mask }}\n no shutdown",
"created_by": "usr_a1b2c3d4",
"created_at": "2025-08-15T09:30:00Z"
},
{
"version": 2,
"template_source": "interface {{ interface_name }}\n description {{ description }}\n ip address {{ ip_address }} {{ subnet_mask }}\n no ip proxy-arp\n no shutdown",
"created_by": "usr_a1b2c3d4",
"created_at": "2025-08-22T11:00:00Z"
},
{
"version": 3,
"template_source": "interface {{ interface_name }}\n description {{ description }}\n ip address {{ ip_address }} {{ subnet_mask }}\n ip ospf {{ ospf_process_id }} area {{ ospf_area }}\n no shutdown",
"created_by": "usr_e5f6g7h8",
"created_at": "2025-09-02T14:15:00Z"
}
]
}Version Diff Example
Comparing version 1 to version 3 of the template above shows the following changes:
interface {{ interface_name }}
description {{ description }}
ip address {{ ip_address }} {{ subnet_mask }}
+ ip ospf {{ ospf_process_id }} area {{ ospf_area }}
no shutdownVersion 2 added no ip proxy-arp (later removed in version 3), and version 3 added OSPF interface configuration. The diff between version 1 and 3 shows only the net change.
Update Template (Creates New Version)
PUT /plugins/stacks/admin/templates/tmpl_8f3a2b1c
Content-Type: application/json
Authorization: Bearer <token>
{
"template_source": "interface {{ interface_name }}\n description {{ description }}\n ip address {{ ip_address }} {{ subnet_mask }}\n ip ospf {{ ospf_process_id }} area {{ ospf_area }}\n ip ospf cost {{ ospf_cost | default(10) }}\n no shutdown"
}This creates version 4 with the added OSPF cost line.
Questions & Answers
- Q: Are template versions created automatically?
- A: Yes. Every time you save changes to a template (via the UI or the PUT API endpoint), a new version is created automatically. The version number increments sequentially and the previous version's content is preserved as an immutable record.
- Q: Can I delete old versions?
- A: No. Versions are immutable and cannot be deleted. This is by design — the complete version history serves as an audit trail for compliance and troubleshooting. If a template is no longer needed at all, you can delete the entire template, which removes all versions.
- Q: How do I compare two versions?
- A: Fetch the template with
?include_versions=trueto get all versions. In the UI, select any two versions to see a side-by-side diff. The diff highlights added lines (green) and removed lines (red) between the two selected versions. - Q: How do I roll back to a previous version?
- A: Select the version you want to restore and click "Restore This Version." This creates a new version (with the next version number) whose content matches the historical version. Rolling back never deletes intermediate versions — the full history is always preserved.
- Q: Does rolling back affect deployed stacks?
- A: Rolling back the template does not automatically re-deploy to devices. Any stack instances using this template will continue running the configuration they were last deployed with. To push the rolled-back version to devices, you need to trigger a new deployment on the affected stack instances.
- Q: Can I see who made each version?
- A: Yes. Each
JinjaTemplateVersionrecord includes acreated_byfield with the user ID of the person who saved that version, along with acreated_attimestamp.
Troubleshooting
Version history not appearing
Make sure you are requesting the template with the ?include_versions=true query parameter. Without this parameter, the API returns only the current template state and omits the versions array to reduce payload size.
Unexpected version numbering after rollback
Rolling back creates a new version with the next sequential number. For example, if you roll back from version 5 to version 2, the restored content becomes version 6. The version number always increments — it never reuses or resets previous numbers.
Concurrent edits creating unexpected versions
If two team members edit the same template simultaneously, both saves will create new versions. The second save becomes the current version and may overwrite the first person's changes in the active version. Review the version history to see both sets of changes and manually merge if needed.
NetStacks does not currently detect or merge conflicting edits. If multiple people edit the same template, the last save wins as the current version. Use version history to recover any overwritten changes.
Rollback did not change deployed devices
Rolling back a template only changes the template source. It does not automatically push the change to devices. After rolling back, navigate to the stack instances using this template and trigger a re-deployment to update device configurations.
Related Features
Related documentation for template versioning and deployment workflows:
- Template Basics — Introduction to templates and the authoring lifecycle
- Rendering & Preview — Preview rendered output after editing or rolling back a template
- Deployment History — Track which template version was deployed to each device and when
- Stack Instances — Manage deployments and trigger re-deployment after template changes