Description

Type: Configuration Help

Technology: Switching

Description: We are not seeing the expected VGA configuration deployed by the campus fabric wizard. The networks are configured and added to the CFW but are not being configured by Mist. As a workaround, we have added the additional CLI to the core switches until the issue is resolved. The device is configured with its own local IP but is not getting its VGA configuration via Mist.

 

Sample of expected configuration lines that needed to be added as additional CLI at the device level:

set interfaces irb unit 950 virtual-gateway-v4-mac 00:00:5e:00:00:01

set interfaces irb unit 950 virtual-gateway-accept-data

set interfaces irb unit 950 family inet address 10.10.10.249/24 virtual-gateway-address 10.10.10.250

Symptoms

Virtual-mac addresses not pushed from mist when using terraform project to configure the campus fabric


(temp-env) $ cat main.tf

terraform {

required_providers {

mist = {

source = "registry.terraform.io/juniper/mist"

version = "0.4.3"

}

}

}

provider "mist" {

host = var.host

}


resource "mist_site" "site_one" {

org_id = var.org_id

name = var.site_name

address = var.site_address

country_code = var.site_country_code

networktemplate_id = var.network_template_id

rftemplate_id = "xxxx"

}


resource "mist_org_inventory" "inventory" {

org_id = var.org_id

inventory = {

for switch in flatten([var.access_switches, [var.spineA, var.spineB]]) :

switch.mac => {

site_id = mist_site.site_one.id

unclaim_when_destroyed = false

}

}

}


resource "mist_site_evpn_topology" "evpn_one" {

depends_on = [

mist_device_switch.spineA,

mist_device_switch.spineB,

mist_device_switch.switch,

]

site_id = mist_site.site_one.id

name = "evpn_one"

evpn_options = {

routed_at = "core"

overlay = {

as = var.overlay_asn

}

core_as_border = true

per_vlan_vga_v4_mac = true

underlay = {

as_base = var.underlay_asn

use_ipv6 = false

subnet = var.underlay_subnet

}

auto_router_id_subnet = var.auto_router_id_subnet

}

switches = merge(

{ for switch in [var.spineA, var.spineB] : switch.mac => { role = "collapsed-core" } },

{ for switch in var.access_switches : switch.mac => { role = "esilag-access" } }

)

}


resource "mist_site_networktemplate" "networktemplate_one" {

site_id = mist_site.site_one.id

networks = {

for network in var.networks :

network.name => {

vlan_id = network.vlan_id

gateway = network.subnet != "" ? lookup(network, "gateway", null) : null

subnet = network.subnet != "" ? lookup(network, "subnet", null) : null

}

}

ospf_areas = {

0 = {

networks = {

for network in var.networks :

network.name => {

passive = true

} if network.subnet != null

}

}

}

port_usages = {

"core-to-access" = {

mode = "trunk"

all_networks = true

mtu = "9100"

ui_evpntopo_id = mist_site_evpn_topology.evpn_one.id

networks = [for network in var.networks : network.name]

}

}

}


resource "mist_device_switch" "spineA" {

device_id = provider::mist::search_inventory_by_mac(resource.mist_org_inventory.inventory, var.spineA.mac).id

site_id = provider::mist::search_inventory_by_mac(resource.mist_org_inventory.inventory, var.spineA.mac).site_id

managed = true

name = var.spineA.name

port_config = merge(

{

"et-0/1/0" = {

usage = "evpn_uplink"

},

"et-0/1/1" = {

usage = "evpn_downlink"

}

},

// Downlinks to access

{

for switch in var.access_switches :

switch.downlinkPort => {

usage = "core-to-access"

aggregated = true

esilag = true

ae_idx = switch.aei

}

}

)

other_ip_configs = {

for network in var.networks :

network.name => {

type = "static"

ip = network.spineAIP

netmask = cidrnetmask(network.subnet)

} if network.subnet != null

}

additional_config_cmds = length(var.spineA.additionalCLI) > 0 ? var.spineA.additionalCLI : [""]

// Staging configuration that is to be removed later.

dns_servers = [

"x.x.x.x"

]

switch_mgmt = {

local_accounts = {

tempadmin = {

role = "admin"

password = "password1"

}

}

protect_re = {

enabled = false

}

tacacs = {

enabled = false

}

}

}


resource "mist_device_switch" "spineB" {

device_id = provider::mist::search_inventory_by_mac(resource.mist_org_inventory.inventory, var.spineB.mac).id

site_id = provider::mist::search_inventory_by_mac(resource.mist_org_inventory.inventory, var.spineB.mac).site_id

managed = true

name = var.spineB.name

port_config = merge(

{

"et-0/1/0" = {

usage = "evpn_downlink"

},

"et-0/1/1" = {

usage = "evpn_uplink"

}

},

// Downlinks to access

{

for switch in var.access_switches :

switch.downlinkPort => {

usage = "core-to-access"

aggregated = true

esilag = true

ae_idx = switch.aei

}

}

)

other_ip_configs = {

for network in var.networks :

network.name => {

type = "static"

ip = network.spineBIP

netmask = cidrnetmask(network.subnet)

evpn_anycast = true

} if network.subnet != null

}

additional_config_cmds = length(var.spineB.additionalCLI) > 0 ? var.spineB.additionalCLI : [""]

// Staging configuration that is to be removed later.

dns_servers = [

"x.x.x.x"

]

switch_mgmt = {

local_accounts = {

tempadmin = {

role = "admin"

password = "password1"

}

}

protect_re = {

enabled = false

}

tacacs = {

enabled = false

}

}

}


resource "mist_device_switch" "switch" {

for_each = { for idx, switch in var.access_switches : switch.mac => switch }

//Management IP


device_id = provider::mist::search_inventory_by_mac(resource.mist_org_inventory.inventory, each.value.mac).id

site_id = provider::mist::search_inventory_by_mac(resource.mist_org_inventory.inventory, each.value.mac).site_id

managed = true

name = each.value.name

ip_config = {

type = "static"

ip = each.value.ip

netmask = "/22"

network = "MGMT"

gateway = var.mgmt_gateway

}

port_config = {

"${each.value.uplinkPortA},${each.value.uplinkPortB}" = {

usage = "core-to-access"

aggregated = true

esilag = false

ae_idx = each.value.aei

}

}

additional_config_cmds = length(each.value.additionalCLI) > 0 ? each.value.additionalCLI : [""]

// Staging configuration that is to be removed later.

dns_servers = [

"x.x.x.x"

]

switch_mgmt = {

local_accounts = {

tempadmin = {

role = "admin"

password = "password1"

}

}

protect_re = {

enabled = false

}

tacacs = {

enabled = false

}

}

}






Solution

Routed at value must be set to edge for the virtual-gateway-v4-mac to work.


"routed_at": "edge"


also needed to remove from terraform template: evpn_anycast = true from the options passed.

Modification History

2025-09-22 : Article Created

Related Information

https://registry.terraform.io/providers/Juniper/mist/latest/docs

https://registry.terraform.io/providers/Juniper/mist/latest/docs/resources/site_evpn_topology