equinix / terraform-provider-equinix

Terraform Equinix provider
https://deploy.equinix.com/labs/terraform-provider-equinix/
MIT License
47 stars 45 forks source link

[Bug]: equinix_metal_virtual_circuit for vrf on shared ports - nni_vlan #629

Open Fuxbert opened 5 months ago

Fuxbert commented 5 months ago

Terraform Version

Terraform v1.7.4

Equinix Provider Version

version = "1.33.0"

Effected Terraform Resources

equinix_metal_vrf equinix_metal_connection equinix_metal_virtual_circuit

Terraform Config Files

#-------------------------INTERCONNECTION----------------------------
resource "equinix_metal_connection" "am_vrf_to_rtr" {
  depends_on    = [ equinix_metal_vrf.am_vrf ]
  name          = "am_vrf_to_rtr"
  project_id    = var.project.id
  type          = "shared"
  redundancy    = "redundant"
  metro         = var.project.metro.secondary
  speed         = "10Gbps"
  service_token_type = "z_side"
  contact_email = var.user_email
  vrfs          = [ equinix_metal_vrf.am_vrf.id, equinix_metal_vrf.am_vrf.id ]
  }

#-------------------------VIRTUAL CIRCUITS---------------------------
#------------------------------TIMEOUT-------------------------------
# Wait for Interconnection to become accepted within Metal Portal

resource "null_resource" "countdown" {
  depends_on    = [ equinix_fabric_connection.am_rtr_vrf_prim, equinix_fabric_connection.am_rtr_vrf_sec ]
  provisioner "local-exec" {
    interpreter = ["/bin/sh", "-c"]
    command     = "sleep 300"
    }
  }

#------------------------------primary-------------------------------
resource "equinix_metal_virtual_circuit" "am_vrf_rtr_prim" {
  depends_on    = [ null_resource.countdown ]
  name          = "am_vrf_rtr_prim"
  description   = "Primary Virtual Circuit between VRF and Network Edge Router in Amsterdam"
  connection_id = equinix_metal_connection.am_vrf_to_rtr.id
  project_id    = var.project.id
  port_id       = equinix_metal_connection.am_vrf_to_rtr.ports[0].id
  vrf_id        = equinix_metal_vrf.am_vrf.id
  peer_asn      = var.asn.edge
  subnet        = var.subnet.am.vrf.vc_prim
  metal_ip      = cidrhost(var.subnet.am.vrf.vc_prim, 2)
  customer_ip   = cidrhost(var.subnet.am.vrf.vc_prim, 1)
  }
#-----------------------------secondary------------------------------
resource "equinix_metal_virtual_circuit" "am_vrf_rtr_sec" {
  depends_on    = [ null_resource.countdown ]
  name          = "am_vrf_rtr_sec"
  description   = "Secondary Virtual Circuit between VRF and Network Edge Router in Amsterdam"
  connection_id = equinix_metal_connection.am_vrf_to_rtr.id
  project_id    = var.project.id
  port_id       = equinix_metal_connection.am_vrf_to_rtr.ports[1].id
  vrf_id        = equinix_metal_vrf.am_vrf.id
  peer_asn      = var.asn.edge
  subnet        = var.subnet.am.vrf.vc_sec
  metal_ip      = cidrhost(var.subnet.am.vrf.vc_sec, 2)
  customer_ip   = cidrhost(var.subnet.am.vrf.vc_sec, 1)
  }

Debug Output

│ Error: POST https://api.equinix.com/metal/v1/projects/688ac43d-282d-415a-a349-b20a6e0a8947/connections/d5195803-24db-4cc5-a725-6399c15677cc/ports/86ff59f4-fff2-4db4-ae4d-38f1dfe9e9aa/virtual-circuits: 422 param is missing or the value is empty: nni_vlan
│
│   with equinix_metal_virtual_circuit.am_vrf_rtr_prim,
│   on metal.tf line 131, in resource "equinix_metal_virtual_circuit" "am_vrf_rtr_prim":
│  131: resource "equinix_metal_virtual_circuit" "am_vrf_rtr_prim" {

Panic Output

No response

Expected Behavior

Expectation is that TF provider will use the existing nni_vlan and just add the bgp details as provided in the resource config

Actual Behavior

Provisioning fails, provider requires the nni_vlan. If I provide this using

data "equinix_metal_virtual_circuit" "am_vrf_rtr_prim_prep" {
  virtual_circuit_id = equinix_metal_connection.am_vrf_to_rtr.ports[0].virtual_circuit_ids[0]
  }

data "equinix_metal_virtual_circuit" "am_vrf_rtr_sec_prep" {
  virtual_circuit_id = equinix_metal_connection.am_vrf_to_rtr.ports[1].virtual_circuit_ids[0]
  }

#------------------------------primary-------------------------------
resource "equinix_metal_virtual_circuit" "am_vrf_rtr_prim" {
  depends_on    = [ null_resource.countdown ]
  name          = "am_vrf_rtr_prim"
  description   = "Primary Virtual Circuit between VRF and Network Edge Router in Amsterdam"
  connection_id = equinix_metal_connection.am_vrf_to_rtr.id
  project_id    = var.project.id
  port_id       = equinix_metal_connection.am_vrf_to_rtr.ports[0].id
  vrf_id        = equinix_metal_vrf.am_vrf.id
  peer_asn      = var.asn.edge
  nni_vlan      = data.equinix_metal_virtual_circuit.am_vrf_rtr_prim_prep.nni_vlan
  subnet        = var.subnet.am.vrf.vc_prim
  metal_ip      = cidrhost(var.subnet.am.vrf.vc_prim, 2)
  customer_ip   = cidrhost(var.subnet.am.vrf.vc_prim, 1)
  }

the provider will ask for the vnid attribute. Again, providing this (with same reference as the nni_vlan), it fails with

│ Error: Value for unconfigurable attribute
│
│   with equinix_metal_virtual_circuit.am_vrf_rtr_prim,
│   on metal.tf line 141, in resource "equinix_metal_virtual_circuit" "am_vrf_rtr_prim":
│  141:   vnid          = data.equinix_metal_virtual_circuit.am_vrf_rtr_prim_prep.nni_vlan
│
│ Can't configure a value for "vnid": its value will be decided automatically based on the result of applying this configuration.

Steps to Reproduce

see above

ocobles commented 5 months ago

Not sure whether this is supported today. equinix_metal_virtual_circuitresource is just for creating new VCs on dedicated ports, but since shared ports autogenerate their VCs they cannot be updated that way. We would need to bypass the VRF configuration in the equinix_metal_connection as we do with vlans or create a new resource like equinix_metal_virtual_circuit_config

codinja1188 commented 5 months ago

vnid should be create earlier to create virtual-circuit

ocobles commented 5 months ago

It's not relevant to what's discussed here, but you should replace that null_resource with https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/sleep

displague commented 4 months ago

Related to https://github.com/equinix/terraform-provider-equinix/issues/363

ctreatma commented 1 month ago

v2.1.0 updated the metal_virtual_circuit resource so that it can be used with shared virtual circuits, so this nni_vlan error should not occur when using that version of the provider. However, note that for a shared virtual circuit you must specify the virtual_circuit_id attribute instead of the connection_id attribute.