VPN Data Models¶
Nautobot provides a set of models for representing Virtual Private Networks (VPNs), including reusable profiles, policies, tunnel endpoints, and service terminations. These models enable you to define IKE (Phase 1) and IPSec (Phase 2) policy parameters, manage tunnel endpoints, model overlay and service-style VPN attachments, and associate VPNs with roles and secrets. Additionally, VPNs may optionally be associated with tenants so that administrators can indicate ownership of related model instances.
Nautobot's VPN models support two complementary approaches:
- Tunnel-based VPNs — Use VPN Tunnels and VPN Tunnel Endpoints to model point-to-point or hub-and-spoke tunnels (e.g. IPSec, GRE, WireGuard).
- Overlay and service-style VPNs — Use VPN Terminations to bind a VPN service (e.g. VXLAN-EVPN, VPLS, E-Line) to local attachment points such as VLANs, device interfaces, or VM interfaces.
High-Level Architecture of VPN Models¶
The following diagrams represent the logic behind VPN Models at a high level.
Note
Two separate diagrams are shown to make it easier for the reader. The first covers tunnel-based VPNs (VPN Tunnels and Endpoints), while the second covers termination-based VPNs (VPN Terminations), introduced in Nautobot 3.1.
Tunnel-based VPN Architecture¶
Termination-based VPN Architecture¶
flowchart LR
subgraph vpn_models["<b>VPN Models</b>"]
VPN["<b>VPN</b>"]
VPNProfile["<b>VPN Profile</b>"]
VPNTermination["<b>VPN Termination</b>"]
VPN -- "many" --> VPNTermination
VPN -. "optional" .-> VPNProfile
end
subgraph attachment["<b>Attachment Points</b> (exactly one)"]
VLAN["VLAN"]
IF["Interface"]
VMIF["VM Interface"]
end
VPNTermination --> attachment
style vpn_models fill:#fef3cd,stroke:#d4a843,color:#000
style attachment fill:#f0f0f0,stroke:#999,color:#000
Entity Relationship Diagrams¶
The following schemas illustrate the connections between related models.
Note
Three separate diagrams are shown to make it easier for the reader. The first covers VPN Profiles and policies, the second covers VPN Tunnels and Tunnel Endpoints, and the third covers VPN Terminations. Several minor elements such as Status and Role are not shown for readability reasons.
VPN Profile Models Entity-Relationship Diagram¶
erDiagram
"extras.Role"[Role] {}
"extras.SecretsGroup"[SecretsGroup] {}
"nautobot_vpn_models.VPN"[VPN] {}
"nautobot_vpn_models.VPNTunnel"[VPNTunnel] {}
"nautobot_vpn_models.VPNTunnelEndpoint"[VPNTunnelEndpoint] {}
"nautobot_vpn_models.VPNProfile"[VPNProfile] {
string name
string description
boolean keepalive_enabled
integer keepalive_interval
integer keepalive_retries
boolean nat_traversal
json extra_options
}
"nautobot_vpn_models.VPNPhase1Policy"[VPNPhase1Policy] {
string name
string description
choices ike_version
boolean aggressive_mode
choices encryption_algorithm
choices integrity_algorithm
choices dh_group
integer lifetime_seconds
integer lifetime_kb
choices authentication_method
}
"nautobot_vpn_models.VPNPhase2Policy"[VPNPhase2Policy] {
string name
string description
choices encryption_algorithm
choices integrity_algorithm
choices pfs_group
integer lifetime
}
"nautobot_vpn_models.VPNProfile" }o--o{ "nautobot_vpn_models.VPNPhase1Policy" : "may have"
"nautobot_vpn_models.VPNProfile" }o--o{ "nautobot_vpn_models.VPNPhase2Policy" : "may have"
"nautobot_vpn_models.VPNProfile" }o--o| "extras.Role" : "may have"
"nautobot_vpn_models.VPNProfile" }o--o| "extras.SecretsGroup" : "may have"
"nautobot_vpn_models.VPN" }o--o| "nautobot_vpn_models.VPNProfile" : "may have"
"nautobot_vpn_models.VPNTunnel" }o--o| "nautobot_vpn_models.VPNProfile" : "may have"
"nautobot_vpn_models.VPNTunnelEndpoint" }o--o| "nautobot_vpn_models.VPNProfile" : "may have"
VPN Tunnels and Endpoints Entity-Relationship Diagram¶
erDiagram
"nautobot_vpn_models.VPN"[VPN] {
VPNProfile vpn_profile
string name
string description
string vpn_id
choices service_type
Status status
json extra_attributes
Role role
}
"nautobot_vpn_models.VPNTunnel"[VPNTunnel] {
VPNProfile vpn_profile
VPN vpn
string name
string description
string tunnel_id
choices encapsulation
Status status
Role role
}
"nautobot_vpn_models.VPNTunnelEndpoint"[VPNTunnelEndpoint] {
VPNProfile vpn_profile
string source_fqdn
Role role
}
"tenancy.Tenant"[Tenant] {}
"extras.SecretsGroup"[SecretsGroup] {}
"dcim.Interface"[Interface] {}
"ipam.IPAddress"[IPAddress] {}
"ipam.Prefix"[Prefix] {}
"extras.DynamicGroup"[DynamicGroup] {}
"nautobot_vpn_models.VPN" ||--o{ "nautobot_vpn_models.VPNTunnel" : "has"
"nautobot_vpn_models.VPN" }o--o| "tenancy.Tenant" : "may have"
"nautobot_vpn_models.VPNTunnel" }o--o| "nautobot_vpn_models.VPNTunnelEndpoint" : "endpoint_a"
"nautobot_vpn_models.VPNTunnel" }o--o| "nautobot_vpn_models.VPNTunnelEndpoint" : "endpoint_z"
"nautobot_vpn_models.VPNTunnel" }o--o| "extras.SecretsGroup" : "may have"
"nautobot_vpn_models.VPNTunnel" }o--o| "tenancy.Tenant" : "may have"
"nautobot_vpn_models.VPNTunnelEndpoint" }o--o| "dcim.Interface" : "source_interface"
"nautobot_vpn_models.VPNTunnelEndpoint" |o--o| "dcim.Interface" : "tunnel_interface"
"nautobot_vpn_models.VPNTunnelEndpoint" }o--o| "ipam.IPAddress" : "source_ipaddress"
"nautobot_vpn_models.VPNTunnelEndpoint" }o--o{ "ipam.Prefix" : "protected_prefixes"
"nautobot_vpn_models.VPNTunnelEndpoint" }o--o{ "extras.DynamicGroup" : "protected_prefixes_dg"
VPN Terminations Entity-Relationship Diagram¶
erDiagram
"nautobot_vpn_models.VPN"[VPN] {
VPNProfile vpn_profile
string name
string description
string vpn_id
choices service_type
Status status
json extra_attributes
Tenant tenant
Role role
}
"nautobot_vpn_models.VPNTermination"[VPNTermination] {}
"ipam.VLAN"[VLAN] {}
"dcim.Interface"[Interface] {}
"virtualization.VMInterface"[VMInterface] {}
"nautobot_vpn_models.VPN" ||--o{ "nautobot_vpn_models.VPNTermination" : "has"
"nautobot_vpn_models.VPNTermination" |o--o| "ipam.VLAN" : "may have"
"nautobot_vpn_models.VPNTermination" |o--o| "dcim.Interface" : "may have"
"nautobot_vpn_models.VPNTermination" |o--o| "virtualization.VMInterface" : "may have"
Use Cases¶
Site-to-site IPSec VPN tunnel (transport mode)¶
Probably the simplest scenario for creating an IPSec VPN tunnel between two endpoints. No tunnel interface is assumed in this scenario.
flowchart LR
RTR01_lan((" "))
subgraph RTR01["<b><u>RTR01</u></b>"]
RTR01_ep["<b>Source IP:</b> 1.1.1.1<br/><b>Destination IP:</b> 2.2.2.2"]
end
subgraph RTR02["<b><u>RTR02</u></b>"]
RTR02_ep["<b>Source IP:</b> 2.2.2.2<br/><b>Destination IP:</b> 1.1.1.1"]
end
RTR02_lan((" "))
cloud(("☁ Internet"))
RTR01_lan -- "10.10.1.0/24" --- RTR01
RTR01 --- cloud --- RTR02
RTR01_ep <== "VPN Tunnel" ==> RTR02_ep
RTR02 -- "10.10.2.0/24" --- RTR02_lan
Site-to-site IPSec VPN tunnel (tunnel mode)¶
Another scenario with an IPSec VPN tunnel between two endpoints but this time a tunnel interface is used.
flowchart LR
RTR01_lan((" "))
subgraph RTR01["<b><u>RTR01</u></b>"]
RTR01_ep["<b>Source IP:</b> 1.1.1.1<br/><b>Destination IP:</b> 2.2.2.2<br/><b>Tunnel Interface:</b> Tu01<br/><b>Tunnel IP:</b> 192.168.0.1/30"]
end
subgraph RTR02["<b><u>RTR02</u></b>"]
RTR02_ep["<b>Source IP:</b> 2.2.2.2<br/><b>Destination IP:</b> 1.1.1.1<br/><b>Tunnel Interface:</b> Tu02<br/><b>Tunnel IP:</b> 192.168.0.2/30"]
end
RTR02_lan((" "))
cloud(("☁ Internet"))
RTR01_lan -- "10.10.1.0/24" --- RTR01
RTR01 --- cloud --- RTR02
RTR01_ep <== "VPN Tunnel" ==> RTR02_ep
RTR02 -- "10.10.2.0/24" --- RTR02_lan
Single hub-and-spoke VPN¶
Implementation of a hub-and-spoke topology (e.g. DMVPN) with RTR99 as the hub. The difference between this and site-to-site VPN tunnels is that, in this case, the hub only receives inbound VPN requests from the spokes. As such, its tunnel endpoint is re-used among tunnels and also does not need to define destination IP/FQDN.
flowchart LR
subgraph VPN_Blue["<span style='font-size:1.2em'><b>VPN Blue</b></span>"]
subgraph RTR01["<b><u>RTR01</u></b>"]
RTR01_ep["<b>Source IP:</b> 1.1.1.1<br/><b>Destination IP:</b> 99.99.99.99<br/><b>Tunnel Interface:</b> Tu01<br/><b>Tunnel IP:</b> 192.168.0.1/24"]
end
subgraph RTR99["<b><u>RTR99 (Hub)</u></b>"]
RTR99_ep["<b>Source IP:</b> 99.99.99.99<br/><b>Tunnel Interface:</b> Tu99<br/><b>Tunnel IP:</b> 192.168.0.99/24"]
end
subgraph RTR02["<b><u>RTR02</u></b>"]
RTR02_ep["<b>Source IP:</b> 2.2.2.2<br/><b>Destination IP:</b> 99.99.99.99<br/><b>Tunnel Interface:</b> Tu02<br/><b>Tunnel IP:</b> 192.168.0.2/24"]
end
RTR01_ep <== "VPN Tunnel 1" ==> RTR99_ep
RTR02_ep <== "VPN Tunnel 2" ==> RTR99_ep
end
style VPN_Blue fill:#eef4fb,stroke:#6ea8d9,color:#1e3a5f
style RTR01 fill:#e8e8e8,stroke:#999,color:#000
style RTR99 fill:#e8e8e8,stroke:#999,color:#000
style RTR02 fill:#e8e8e8,stroke:#999,color:#000
Multiple hub-and-spoke VPNs¶
Virtually the same as above, mentioned here to illustrate the separation between VPN groupings.
flowchart TB
subgraph VPN_Green["<span style='font-size:1.2em'><b>VPN Green</b></span>"]
direction LR
subgraph G_RTR01["<b><u>RTR01</u></b>"]
G_RTR01_ep["<b>Source IP:</b> 1.1.1.1<br/><b>Destination IP:</b> 99.99.99.99"]
end
subgraph G_RTR99["<b><u>RTR99 (Hub)</u></b>"]
G_RTR99_ep["<b>Source IP:</b> 99.99.99.99<br/><b>Tunnel Interface:</b> Tu99<br/><b>Tunnel IP:</b> 192.168.0.99/24"]
end
subgraph G_RTR02["<b><u>RTR02</u></b>"]
G_RTR02_ep["<b>Source IP:</b> 2.2.2.2<br/><b>Destination IP:</b> 99.99.99.99"]
end
G_RTR01_ep <== "Tunnel" ==> G_RTR99_ep
G_RTR02_ep <== "Tunnel" ==> G_RTR99_ep
end
subgraph VPN_Blue["<span style='font-size:1.2em'><b>VPN Blue</b></span>"]
direction LR
subgraph B_RTR01["<b><u>RTR01</u></b>"]
B_RTR01_ep["<b>Source IP:</b> 1.1.1.1<br/><b>Destination IP:</b> 99.99.99.99"]
end
subgraph B_RTR99["<b><u>RTR99 (Hub)</u></b>"]
B_RTR99_ep["<b>Source IP:</b> 99.99.99.99<br/><b>Tunnel Interface:</b> Tu99<br/><b>Tunnel IP:</b> 192.168.0.99/24"]
end
subgraph B_RTR02["<b><u>RTR02</u></b>"]
B_RTR02_ep["<b>Source IP:</b> 2.2.2.2<br/><b>Destination IP:</b> 99.99.99.99"]
end
B_RTR01_ep <== "Tunnel" ==> B_RTR99_ep
B_RTR02_ep <== "Tunnel" ==> B_RTR99_ep
end
style VPN_Blue fill:#eef4fb,stroke:#6ea8d9,color:#1e3a5f
style VPN_Green fill:#eefbf0,stroke:#6ec977,color:#14532d
style B_RTR01 fill:#e8e8e8,stroke:#999,color:#000
style B_RTR99 fill:#e8e8e8,stroke:#999,color:#000
style B_RTR02 fill:#e8e8e8,stroke:#999,color:#000
style G_RTR01 fill:#e8e8e8,stroke:#999,color:#000
style G_RTR99 fill:#e8e8e8,stroke:#999,color:#000
style G_RTR02 fill:#e8e8e8,stroke:#999,color:#000
Hub-and-spoke VPN using terminations¶
Added in version 3.1.0 — VPN Terminations and VPN service types were added.
The single hub-and-spoke use case above models each spoke-to-hub connection as a distinct VPN Tunnel with its own pair of VPN Tunnel Endpoints. This captures per-tunnel detail but requires more objects to manage.
As an alternative, the same topology can be represented with VPN Terminations — a flatter model introduced in Nautobot 3.1. Each participating router is attached to the VPN through a single termination on a device interface. There are no individual tunnel or endpoint objects; the VPN itself is the only grouping element. This trades per-tunnel granularity for a simpler model that is easier to create and maintain when tunnel-level detail is not needed.
flowchart LR
subgraph VPN["<b><u>VPN: AMER-DMVPN</u></b><br/>IPSec"]
direction TB
end
subgraph Term1["<b>VPN Termination</b>"]
IF1["<b>Interface:</b> GigabitEthernet0/0<br/><b>Device:</b> RTR01"]
end
subgraph Term2["<b>VPN Termination</b>"]
IF2["<b>Interface:</b> GigabitEthernet0/0<br/><b>Device:</b> RTR99 (Hub)"]
end
subgraph Term3["<b>VPN Termination</b>"]
IF3["<b>Interface:</b> GigabitEthernet0/0<br/><b>Device:</b> RTR02"]
end
VPN --- Term1
VPN --- Term2
VPN --- Term3
VXLAN-EVPN overlay mapped to VLANs¶
A VPN with service_type set to VXLAN-EVPN and a VNI identifier, with multiple VPN Terminations each binding the service to a VLAN. This represents a typical data center overlay where a single VXLAN service spans multiple switches and each switch maps the service to a local VLAN.
flowchart LR
subgraph VPN["<b><u>VPN: DC-Fabric-100</u></b><br/>VXLAN-EVPN, VNI: 10100"]
direction TB
end
subgraph Term1["<b>VPN Termination</b>"]
VLAN1["<b>VLAN:</b> 100<br/><b>Switch:</b> Switch-A"]
end
subgraph Term2["<b>VPN Termination</b>"]
VLAN2["<b>VLAN:</b> 100<br/><b>Switch:</b> Switch-B"]
end
subgraph Term3["<b>VPN Termination</b>"]
VLAN3["<b>VLAN:</b> 100<br/><b>Switch:</b> Switch-C"]
end
VPN --- Term1
VPN --- Term2
VPN --- Term3
Point-to-point E-Line service¶
A VPN with service_type set to EPL (Ethernet Private Line), with exactly two VPN Terminations — one per device interface. Point-to-point service types enforce a maximum of two terminations per VPN.
flowchart LR
subgraph VPN["<b><u>VPN: Customer-A-ELine</u></b><br/>EPL"]
direction TB
end
subgraph Term1["<b>VPN Termination</b>"]
IF1["<b>Interface:</b> GigabitEthernet0/1<br/><b>Device:</b> PE-Router-1"]
end
subgraph Term2["<b>VPN Termination</b>"]
IF2["<b>Interface:</b> GigabitEthernet0/1<br/><b>Device:</b> PE-Router-2"]
end
VPN --- Term1
VPN --- Term2
GraphQL Query Examples¶
The following GraphQL query examples show how an operator can query the information that is stored in the VPN models.
Querying VPN Attributes¶
{
vpns {
vpn_profile {
name
secrets_group {
name
}
vpn_phase1_policies {
name
encryption_algorithm
integrity_algorithm
}
vpn_phase2_policies {
name
encryption_algorithm
integrity_algorithm
}
}
vpn_tunnels {
name
vpn_profile {
name
}
}
}
}
Device-Level VPN Info¶
{
device (id: "ABC123") {
name
vpn_tunnel_endpoints {
endpoint_a_vpn_tunnels {
name
tunnel_id
vpn_profile {
name
}
}
endpoint_z_vpn_tunnels {
name
tunnel_id
vpn_profile {
name
}
}
}
}
}
Querying VPN Terminations¶
{
vpns {
name
service_type
status {
name
}
vpn_terminations {
vlan {
vid
name
}
interface {
name
device {
name
}
}
vm_interface {
name
virtual_machine {
name
}
}
}
}
}
Common Queries¶
The following are typical questions that can be answered using the VPN data model:
- Given a device, what tunnels are associated with it?
- Given a tunnel, what are the remote peers?
- Given a tunnel or device, what tunnel technology is in use (e.g. GRE vs DMVPN)?
- Given a DMVPN tunnel, is this device a hub or a spoke?
- Given a DMVPN tunnel, can spokes route directly to each other (i.e. DMVPN phase 3)?
- Given a tunnel, what subnets are protected by it?
- Given a tenant, what VPN tunnels are associated with it?
- Given a VLAN, which VPN service does it belong to?
- Given a VPN with a VXLAN service type, what VLANs and interfaces participate in it?
- Given a device interface, is it part of any overlay VPN service?
- Given a VPN, is it modeled as tunnel-based or termination-based?

