CiscoDevNet / terraform-provider-nxos

Terraform Cisco NX-OS Provider
https://registry.terraform.io/providers/netascode/nxos
Mozilla Public License 2.0
9 stars 10 forks source link

Problem with adding "no shutdown" to configuration #267

Open krzysztofmaciejewskiit opened 1 month ago

krzysztofmaciejewskiit commented 1 month ago

Having a "clean" terraform directory (main.tf, terraform.tfvars, variables.tf) executes the command "terraform init; terraform apply -auto-approve", everything passes fine, adds the first part of the code marked "part-1", all the commands along with "no shutdown" are added. When I add the code "part-2", coemend "terraform apply -auto-approve" usually all commands except "no shutdown" are added, relatively rarely all will be added, so it happens quite randomly. When I let go of the same terraform again without changes it will add the command "no shutdown" correctly. Below I paste the code of "part-1" and "part-2" and the output from terraform.

Terraform code: main.tf

  required_providers {
    nxos = {
      source  = "CiscoDevNet/nxos"
      version = "0.5.3"
    }
  }
}

provider "nxos" {
  username = var.nxos_username
  password = var.nxos_password
  url      = var.nxos_url
}

/*============================================ common ============================================*/

resource "nxos_feature_lldp" "lldp" {
  admin_state = "enabled"
}

/*=====================================*/

resource "nxos_rest" "cdpEntity" {
  dn         = "sys/cdp"
  class_name = "cdpEntity"
}

//============================================== part-1 ==============================================
//============================================== part-1 ==============================================
//============================================== part-1 ==============================================

/*============================================ description & L3 ============================================*/

resource "nxos_physical_interface" "desc-L3" {
  interface_id = "eth1/5"
  description  = "desc1"
  layer = "Layer3"
  admin_state  = "up"
  user_configured_flags = "admin_state"
}

/*============================================ lldp ============================================*/

resource "nxos_rest" "lldpInst" {
  depends_on = [nxos_feature_lldp.lldp]
  dn         = "sys/lldp/inst"
  class_name = "lldpInst"
  children = [
    {
      rn         = "if-[eth1/5]"
      class_name = "lldpIf"
      content = {
        adminRxSt = "disabled",
        adminTxSt = "disabled",
        id        = "eth1/5"
      }
    }
  ]
}

/*============================================ cdp ============================================*/

resource "nxos_rest" "cdpInst" {
  depends_on = [nxos_rest.cdpEntity]
  dn         = "sys/cdp/inst"
  class_name = "cdpInst"
  children = [
    {
      rn         = "if-[eth1/5]"
      class_name = "cdpIf"
      content = {
        adminSt = "disabled",
        id        = "eth1/5"
      }
    }
  ]
}

//============================================== part-2 ==============================================
//============================================== part-2 ==============================================
//============================================== part-2 ==============================================

/*============================================ description & L3 ============================================*/

resource "nxos_physical_interface" "desc-L3v2" {
  interface_id = "eth1/6"
  description = "desc2"
  layer = "Layer3"
  admin_state  = "up"
  user_configured_flags = "admin_state"
}

/*============================================ lldp ============================================*/

resource "nxos_rest" "lldpInstv2" {
  depends_on = [nxos_feature_lldp.lldp]
  dn         = "sys/lldp/inst"
  class_name = "lldpInst"
  children = [
    {
      rn         = "if-[eth1/6]"
      class_name = "lldpIf"
      content = {
        adminRxSt = "disabled",
        adminTxSt = "disabled",
        id        = "eth1/6"
      }
    }
  ]
}

/*============================================ cdp ============================================*/

resource "nxos_rest" "cdpInstv2" {
  depends_on = [nxos_rest.cdpEntity]
  dn         = "sys/cdp/inst"
  class_name = "cdpInst"
  children = [
    {
      rn         = "if-[eth1/6]"
      class_name = "cdpIf"
      content = {
        adminSt = "disabled",
        id        = "eth1/6"
      }
    }
  ]
}

Output:
Terraform will perform the following actions:

  # nxos_physical_interface.desc-L3v2 will be created
  + resource "nxos_physical_interface" "desc-L3v2" {
      + access_vlan              = "vlan-1"
      + admin_state              = "up"
      + auto_negotiation         = "on"
      + bandwidth                = 0
      + delay                    = 1
      + description              = "desc2"
      + duplex                   = "auto"
      + fec_mode                 = "auto"
      + id                       = (known after apply)
      + interface_id             = "eth1/6"
      + layer                    = "Layer3"
      + link_debounce_down       = 100
      + link_debounce_up         = 0
      + link_logging             = "default"
      + medium                   = "broadcast"
      + mode                     = "access"
      + mtu                      = 1500
      + native_vlan              = "vlan-1"
      + speed                    = "auto"
      + speed_group              = "auto"
      + trunk_vlans              = "1-4094"
      + uni_directional_ethernet = "disable"
      + user_configured_flags    = "admin_state"
    }

Output form Nexus9000: image

So as you can see on the second interface no shutdown was added. It can happen randomly, it is not a rule. I have a theory that this happens because after the “no switchport” command is executed, the interface flaps and, in my opinion, Terraform can't keep up with the “no shutdown” command afterwards.

The strangest thing is that the above result shows “+ admin_state = ‘up’

Link to Cisco Community discussion: https://community.cisco.com/t5/devnet-general-discussions/terraform-problem-with-adding-quot-no-shutdown-quot-to/td-p/5157845

danischm commented 3 hours ago

I believe this is a bug on NX-OS where the configuration does not get applied correctly with the first attempt (NX-OS REST API call). I have seen similar instances with other interface level configurations. I assume a subsequent "terraform apply" fixes the config, which would confirm that TF is doing the "right" thing. You can try adding the -parallelism=1 CLI argument and see if that improves the situation, which would suggest that NX-OS might have an issue with concurrent API calls.