Stacks & Deployments
TeamsEnterpriseManage configuration stacks with Jinja2 templating, variable overrides, and a deployment state machine to track and roll out configurations across your network.
Overview
The Stacks & Deployments plugin provides configuration stack management with Jinja2 templating, stack instantiation, variable overrides, and a deployment state machine for tracking configuration rollouts across your network. A "stack" bundles multiple related configuration templates into a single deployable unit -- for example, a "Branch Office" stack might include router config, switch config, firewall rules, and DHCP settings, all parameterized with site-specific variables.
Key Concepts
| Concept | Description |
|---|---|
| Stack Template | A reusable blueprint containing one or more Jinja2 configuration templates with defined variables |
| Stack Instance | A concrete instantiation of a template with actual variable values (e.g., site name, IP ranges, VLAN IDs) |
| Deployment | The act of pushing a stack instance's rendered configurations to target devices, tracked through a state machine |
| Variable Overrides | Instance-level variable values that override template defaults, allowing per-site customization |
The plugin uses 7 database tables to track templates, instances, variables, deployments, and deployment history, providing a complete audit trail for all configuration changes.
How It Works
Stack Lifecycle
- Template Creation -- define a stack template with one or more Jinja2 config blocks, each targeting a device role (router, switch, firewall). Define template variables with types, defaults, and validation rules.
- Instantiation -- create an instance from a template by providing variable values. Variables can reference device properties (hostname, management IP) using mustache-style placeholders resolved at deployment time.
- Rendering -- the system renders Jinja2 templates with instance variables to produce final device configurations. Preview rendering before deployment to verify output.
- Deployment -- push rendered configs to target devices. The deployment state machine tracks the full lifecycle from draft to completion.
- History -- every deployment is recorded with timestamp, user, rendered configs, and success/failure status for audit and rollback.
Deployment State Machine
Each deployment progresses through a defined set of states, ensuring visibility and control over configuration rollouts:
| State | Description |
|---|---|
| Draft | Deployment created but not yet submitted. Configs can be previewed and edited. |
| Pending Approval | Submitted for review. One or more approvers must approve before deployment proceeds. |
| Approved | All required approvals received. Deployment is ready to execute. |
| Deploying | Configurations are actively being pushed to target devices. |
| Deployed | All configurations successfully applied to target devices. |
| Failed | One or more device configurations failed to apply. Review logs for details. |
| Rolled Back | Deployment was reverted to a previous configuration state. |
Step-by-Step Guide
Workflow 1: Create a Stack Template
- Navigate to Stacks plugin → Templates
- Click New Template
- Enter a template name and description (e.g., "Branch Office")
- Add one or more Jinja2 configuration blocks, each targeting a device role (router, switch, firewall)
- Define template variables with names, types, default values, and validation rules
- Click Save to create the template
Workflow 2: Instantiate a Stack
- Select an existing template from the Templates list
- Click Create Instance
- Enter an instance name (e.g., "NYC-Branch-01")
- Fill in variable values for this instance -- variables with defaults are pre-populated
- Click Preview to see the rendered configuration output for each device role
- Review the output and click Save
Workflow 3: Deploy a Stack Instance
- Select an instance from the Instances list
- Click Deploy
- Choose target devices for each configuration block
- Review the rendered configuration diff against current device configs
- Submit for approval (if approval workflows are enabled) or deploy immediately
- Monitor deployment progress in the deployment status view
Workflow 4: View Deployment History
- Navigate to the instance detail view
- Click the History tab
- View all past deployments with diffs, status, timestamp, and user information
- To roll back, select a previous deployment and click Rollback
Always use the Preview feature before deploying. It renders the full configuration output so you can verify variable substitution and Jinja2 logic before pushing to devices.
Terminal Integration
The Stacks & Deployments plugin integrates directly into the NetStacks Terminal through the StackDetailTab component. From the Terminal activity bar, you can:
- View stack templates and their variable definitions
- Browse stack instances with their current variable values
- See deployment status and history for each instance
- Open related devices directly in terminal sessions
StackDetailTab Views
| View | Description |
|---|---|
| Template View | Read-only view of the template definition including all Jinja2 config blocks and variable definitions with types and defaults |
| Instance View | Instance details including current variable values, rendered configuration output, deployment status, and deployment history |
From the Instance View, you can click any target device to open a terminal session directly to that device, making it easy to verify deployed configurations.
Code Examples
Create a Stack Template
curl -X POST https://netstacks.example.com/api/v1/plugins/stacks/templates \
-H "Authorization: Bearer your_token" \
-H "Content-Type: application/json" \
-d '{
"name": "Branch Office",
"description": "Complete branch office network configuration",
"config_blocks": [
{
"name": "Router Config",
"device_role": "router",
"template": "hostname {{ site_name }}-rtr01\n!\ninterface GigabitEthernet0/0\n ip address {{ wan_ip }} {{ wan_mask }}\n no shutdown\n!\ninterface GigabitEthernet0/1\n ip address {{ lan_gateway }} 255.255.255.0\n no shutdown\n!\nrouter ospf 1\n network {{ lan_subnet }} 0.0.0.255 area {{ ospf_area }}\n network {{ wan_subnet }} 0.0.0.3 area 0"
},
{
"name": "Switch Config",
"device_role": "switch",
"template": "hostname {{ site_name }}-sw01\n!\nvlan {{ data_vlan }}\n name DATA\nvlan {{ voice_vlan }}\n name VOICE\n!\ninterface Vlan{{ data_vlan }}\n ip address {{ data_gateway }} 255.255.255.0"
}
],
"variables": [
{"name": "site_name", "type": "string", "required": true},
{"name": "wan_ip", "type": "ip_address", "required": true},
{"name": "wan_mask", "type": "ip_address", "default": "255.255.255.252"},
{"name": "lan_gateway", "type": "ip_address", "required": true},
{"name": "lan_subnet", "type": "cidr", "required": true},
{"name": "wan_subnet", "type": "cidr", "required": true},
{"name": "ospf_area", "type": "number", "default": 0},
{"name": "data_vlan", "type": "number", "default": 100},
{"name": "voice_vlan", "type": "number", "default": 200},
{"name": "data_gateway", "type": "ip_address", "required": true}
]
}'Create an Instance with Variables
curl -X POST https://netstacks.example.com/api/v1/plugins/stacks/instances \
-H "Authorization: Bearer your_token" \
-H "Content-Type: application/json" \
-d '{
"template_id": "tmpl_abc123",
"name": "NYC-Branch-01",
"variables": {
"site_name": "NYC-BR01",
"wan_ip": "203.0.113.2",
"wan_mask": "255.255.255.252",
"lan_gateway": "10.10.1.1",
"lan_subnet": "10.10.1.0/24",
"wan_subnet": "203.0.113.0/30",
"ospf_area": 10,
"data_vlan": 100,
"voice_vlan": 200,
"data_gateway": "10.10.1.1"
}
}'Trigger a Deployment
curl -X POST https://netstacks.example.com/api/v1/plugins/stacks/deployments \
-H "Authorization: Bearer your_token" \
-H "Content-Type: application/json" \
-d '{
"instance_id": "inst_xyz789",
"target_devices": [
{"config_block": "Router Config", "device_id": "dev_rtr01"},
{"config_block": "Switch Config", "device_id": "dev_sw01"}
],
"require_approval": true,
"comment": "Initial branch office deployment for NYC-BR01"
}'
# Response
{
"deployment_id": "dep_001",
"instance_id": "inst_xyz789",
"status": "pending_approval",
"created_by": "admin@company.com",
"created_at": "2025-12-20T10:00:00Z",
"target_devices": [
{"config_block": "Router Config", "device_id": "dev_rtr01", "status": "pending"},
{"config_block": "Switch Config", "device_id": "dev_sw01", "status": "pending"}
],
"approvals_required": 1,
"approvals_received": 0
}Jinja2 Template Example: Branch Office Router
hostname {{ site_name }}-rtr01
!
interface GigabitEthernet0/0
ip address {{ wan_ip }} {{ wan_mask }}
no shutdown
!
interface GigabitEthernet0/1
ip address {{ lan_gateway }} 255.255.255.0
no shutdown
!
router ospf 1
network {{ lan_subnet }} 0.0.0.255 area {{ ospf_area }}
network {{ wan_subnet }} 0.0.0.3 area 0Jinja2 Template Example: Branch Office Switch
hostname {{ site_name }}-sw01
!
vlan {{ data_vlan }}
name DATA
vlan {{ voice_vlan }}
name VOICE
!
interface Vlan{{ data_vlan }}
ip address {{ data_gateway }} 255.255.255.0
no shutdown
!
{% for port in range(1, 24) %}
interface GigabitEthernet0/{{ port }}
switchport mode access
switchport access vlan {{ data_vlan }}
switchport voice vlan {{ voice_vlan }}
spanning-tree portfast
!
{% endfor %}
interface GigabitEthernet0/24
switchport mode trunk
switchport trunk allowed vlan {{ data_vlan }},{{ voice_vlan }}
no shutdownQ&A
- Q: How is this different from the Templates section?
- A: The Templates section covers individual Jinja2 templates. Stacks bundle multiple templates into deployable units with variable management and deployment tracking. Think of templates as building blocks and stacks as complete solutions -- a stack combines router, switch, and firewall templates into a single deployable package with shared variables.
- Q: Can I roll back a deployment?
- A: Yes. The deployment history preserves the previous configuration for each deployment. Navigate to the instance History tab, select a past deployment, and click Rollback to revert target devices to that configuration state.
- Q: Do deployments require approval?
- A: This is configurable. You can enable approval workflows that require one or more approvers before a deployment executes. When enabled, deployments enter the "Pending Approval" state and must be approved before they proceed. Approval can be configured globally or per-template.
- Q: What variable types are supported?
- A: The following variable types are supported, each with built-in validation:
- String -- free-text values
- Number -- integer or decimal values
- Boolean -- true/false values
- IP Address -- validated IPv4 or IPv6 addresses
- CIDR -- IP address with prefix length (e.g., 10.0.0.0/24)
- Select -- single choice from a defined list of options
- Multi-select -- multiple choices from a defined list of options
- Q: Can I preview a rendered config before deploying?
- A: Yes. When creating or editing an instance, click Preview to render all Jinja2 templates with the current variable values. The preview shows the complete output for each config block so you can verify the result before submitting a deployment.
- Q: Can variables reference device properties dynamically?
- A: Yes. Variables can use mustache-style placeholders like
{{device.hostname}}and{{device.mgmt_ip}}that are resolved at deployment time based on the target device's properties in NetStacks.
Troubleshooting
Template Rendering Errors
- Check Jinja2 syntax carefully -- common issues include undefined variables, missing closing tags (
{%- endif %}), and incorrect filter usage - Use the Preview feature to test rendering before deployment. Preview will display specific error messages with line numbers
- Ensure all required variables have values -- variables without defaults that are not filled in will cause rendering failures
Deployment Stuck in "Deploying"
- Check connectivity to target devices -- verify SSH or API access is working from the NetStacks server
- Review deployment logs for specific error messages, such as SSH timeout, authentication failure, or command rejection
- Verify that the credentials configured for target devices have write access (enable/configure mode)
- If a deployment is permanently stuck, it can be manually marked as Failed by an administrator
Variable Validation Failing
- Check variable type constraints -- IP address fields must contain valid IPv4 or IPv6 addresses
- CIDR fields must include the prefix length (e.g.,
10.0.0.0/24not10.0.0.0) - Number fields reject non-numeric input -- verify no extra spaces or characters are present
- Select and multi-select fields only accept values from the defined options list
Approval Workflow Issues
- If a deployment is stuck in "Pending Approval," verify that the required approvers have been notified and have access to the deployment
- Check that the approval workflow configuration specifies the correct number of required approvals
- Administrators can bypass approval in emergency situations through the admin override option
Rolling back a deployment pushes the previous configuration to target devices. Ensure the previous configuration is still valid and compatible with the current network state before initiating a rollback.
Related Features
- Template Basics -- learn the fundamentals of Jinja2 configuration templates used within stacks
- Jinja2 Syntax -- detailed reference for Jinja2 syntax, filters, and control structures
- Scheduled Tasks -- automate stack deployments on a schedule
- Incidents & ITSM -- integrate deployment events with your incident management workflow
- Plugin System -- understand the plugin architecture powering Stacks & Deployments