Part 6 - Apstra Racks in Terraform

Corporate Logo

What is a rack in Apstra?

A rack is a depiction of a physical Data Center rack abstracted in Apstra for use in a Blueprint. We use Racks as a component piece of the design. Racks connect to Spines in a Spine/Leaf topology, and usually contain Leaf nodes, and possibly Access nodes. It is necessary to create Racks first before we can build a Blueprint.

Create racks in Terraform.

Now let’s create the Rack Types inside of Apstra’s design system. To do this we will use another Terraform file.

You may want to refer to the following page in the step by step GUI based lab guide for reference: Lab Guide 1 - Juniper

The Rack Type resource is considerably larger than the ASN and IP pool resources we created earlier, but they’re not terribly complicated. If you take a moment to look them over you’ll find there’s a direct correlation between every line in the resource block below and the questions you’d be answering while creating a Rack Type in the web UI.
  1. Create a racks.tf file in the working directory.

  2. Populate the file with the following text content.

    # Look up details of a preconfigured logical device using its name. We'll use
    # data discovered in this lookup in the resource creation below.
    data "apstra_logical_device" "lab_guide_switch" {
      name = "virtual-7x10-1"
    }
    
    # Locals are variables available for use only within the project directory.
    # They're not available for use across Terraform Module boundaries. Here we
    # use "single_homed" and "dual_homed" as shorthand for Apstra Logical Device
    # IDs we need when creating Generic Systems (servers) in our Rack Types.
    locals {
      servers = {
        single_homed = "AOS-1x10-1"
        dual_homed   = "AOS-2x10-1"
      }
    }
    data "apstra_logical_device" "lab_guide_servers" {
      for_each = local.servers
      name = each.value
    }
    
    resource "apstra_rack_type" "lab_guide_single" {
      name                       = "apstra-single"
      fabric_connectivity_design = "l3clos"
      leaf_switches = {
        apstra-single = {
          logical_device_id = data.apstra_logical_device.lab_guide_switch.id
          spine_link_count  = 1
          spine_link_speed  = "10G"
        }
      }
      generic_systems = {
        single-server = {
          count             = 1
          logical_device_id = data.apstra_logical_device.lab_guide_servers["single_homed"].id
          links = {
            single-link = {
              target_switch_name = "apstra-single"
              links_per_switch   = 1
              speed              = "10G"
            }
          }
        }
      }
    }
    
    resource "apstra_rack_type" "lab_guide_esi" {
      name                       = "apstra-esi"
      fabric_connectivity_design = "l3clos"
      leaf_switches = {
        apstra-esi = {
          logical_device_id   = data.apstra_logical_device.lab_guide_switch.id
          spine_link_count    = 1
          spine_link_speed    = "10G"
          redundancy_protocol = "esi"
        }
      }
      generic_systems = {
        dual-server = {
          count             = 1
          logical_device_id = data.apstra_logical_device.lab_guide_servers["dual_homed"].id
          links = {
            single-link = {
              target_switch_name = "apstra-esi"
              links_per_switch   = 1
              speed              = "10G"
              lag_mode           = "lacp_active"
            }
          }
        }
        single-server-1 = {
          count             = 1
          logical_device_id = data.apstra_logical_device.lab_guide_servers["single_homed"].id
          links = {
            single-link = {
              target_switch_name = "apstra-esi"
              links_per_switch   = 1
              speed              = "10G"
              switch_peer        = "first"
            }
          }
        }
        single-server-2 = {
          count             = 1
          logical_device_id = data.apstra_logical_device.lab_guide_servers["single_homed"].id
          links = {
            single-link = {
              target_switch_name = "apstra-esi"
              links_per_switch   = 1
              speed              = "10G"
              switch_peer        = "second"
            }
          }
        }
      }
    }
  3. Now review what terraform wants to create with the terraform plan command, output follows.

    bwester@bwester-mbp playground % terraform plan
    
    
    data.apstra_logical_device.lab_guide_servers["single_homed"]: Reading...
    data.apstra_logical_device.lab_guide_switch: Reading...
    data.apstra_logical_device.lab_guide_servers["dual_homed"]: Reading...
    apstra_asn_pool.lab_guide: Refreshing state... [id=a93ff130-8aaf-4759-9dea-b71b62263df1]
    apstra_ipv4_pool.lab_guide: Refreshing state... [id=29a85b6c-3879-4b8c-8911-85d2116489ae]
    data.apstra_logical_device.lab_guide_servers["single_homed"]: Read complete after 1s [id=AOS-1x10-1]
    data.apstra_logical_device.lab_guide_servers["dual_homed"]: Read complete after 1s [id=AOS-2x10-1]
    data.apstra_logical_device.lab_guide_switch: Read complete after 1s [id=virtual-7x10-1]
    
    Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with
    the following symbols:
      + create
    
    Terraform will perform the following actions:
    
      # apstra_rack_type.lab_guide_esi will be created
      + resource "apstra_rack_type" "lab_guide_esi" {
          + fabric_connectivity_design = "l3clos"
          + generic_systems            = {
              + "dual-server" = {
                  + count               = 1
                  + links               = {
                      + "single-link" = {
                          + lag_mode           = "lacp_active"
                          + links_per_switch   = 1
                          + speed              = "10G"
                          + switch_peer        = (known after apply)
                          + tags               = (known after apply)
                          + target_switch_name = "apstra-esi"
                        },
                    }
                  + logical_device      = (known after apply)
                  + logical_device_id   = "AOS-2x10-1"
                  + port_channel_id_max = (known after apply)
                  + port_channel_id_min = (known after apply)
                  + tags                = (known after apply)
                },
              + "single-server-1" = {
                  + count               = 1
                  + links               = {
                      + "single-link" = {
                          + lag_mode           = (known after apply)
                          + links_per_switch   = 1
                          + speed              = "10G"
                          + switch_peer        = "first"
                          + tags               = (known after apply)
                          + target_switch_name = "apstra-esi"
                        },
                    }
                  + logical_device      = (known after apply)
                  + logical_device_id   = "AOS-1x10-1"
                  + port_channel_id_max = (known after apply)
                  + port_channel_id_min = (known after apply)
                  + tags                = (known after apply)
                },
              + "single-server-2" = {
                  + count               = 1
                  + links               = {
                      + "single-link" = {
                          + lag_mode           = (known after apply)
                          + links_per_switch   = 1
                          + speed              = "10G"
                          + switch_peer        = "second"
                          + tags               = (known after apply)
                          + target_switch_name = "apstra-esi"
                        },
                    }
                  + logical_device      = (known after apply)
                  + logical_device_id   = "AOS-1x10-1"
                  + port_channel_id_max = (known after apply)
                  + port_channel_id_min = (known after apply)
                  + tags                = (known after apply)
                },
            }
          + id                         = (known after apply)
          + leaf_switches              = {
              + "apstra-esi" = {
                  + logical_device      = (known after apply)
                  + logical_device_id   = "virtual-7x10-1"
                  + redundancy_protocol = "esi"
                  + spine_link_count    = 1
                  + spine_link_speed    = "10G"
                  + tags                = (known after apply)
                },
            }
          + name                       = "apstra-esi"
        }
    
      # apstra_rack_type.lab_guide_single will be created
      + resource "apstra_rack_type" "lab_guide_single" {
          + fabric_connectivity_design = "l3clos"
          + generic_systems            = {
              + "single-server" = {
                  + count               = 1
                  + links               = {
                      + "single-link" = {
                          + lag_mode           = (known after apply)
                          + links_per_switch   = 1
                          + speed              = "10G"
                          + switch_peer        = (known after apply)
                          + tags               = (known after apply)
                          + target_switch_name = "apstra-single"
                        },
                    }
                  + logical_device      = (known after apply)
                  + logical_device_id   = "AOS-1x10-1"
                  + port_channel_id_max = (known after apply)
                  + port_channel_id_min = (known after apply)
                  + tags                = (known after apply)
                },
            }
          + id                         = (known after apply)
          + leaf_switches              = {
              + "apstra-single" = {
                  + logical_device    = (known after apply)
                  + logical_device_id = "virtual-7x10-1"
                  + spine_link_count  = 1
                  + spine_link_speed  = "10G"
                  + tags              = (known after apply)
                },
            }
          + name                       = "apstra-single"
        }
    
    Plan: 2 to add, 0 to change, 0 to destroy.

    We can see that two racks will be added.

  4. Run terraform apply and make sure the output reflects successful execution

    bwester@bwester-mbp playground % terraform apply
    
    data.apstra_logical_device.lab_guide_switch: Reading...
    data.apstra_logical_device.lab_guide_servers["dual_homed"]: Reading...
    data.apstra_logical_device.lab_guide_servers["single_homed"]: Reading...
    apstra_asn_pool.lab_guide: Refreshing state... [id=a93ff130-8aaf-4759-9dea-b71b62263df1]
    apstra_ipv4_pool.lab_guide: Refreshing state... [id=29a85b6c-3879-4b8c-8911-85d2116489ae]
    data.apstra_logical_device.lab_guide_switch: Read complete after 1s [id=virtual-7x10-1]
    data.apstra_logical_device.lab_guide_servers["dual_homed"]: Read complete after 1s [id=AOS-2x10-1]
    data.apstra_logical_device.lab_guide_servers["single_homed"]: Read complete after 1s [id=AOS-1x10-1]
    
    Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with
    the following symbols:
      + create
    
    Terraform will perform the following actions:
    
      # apstra_rack_type.lab_guide_esi will be created
      + resource "apstra_rack_type" "lab_guide_esi" {
          + fabric_connectivity_design = "l3clos"
          + generic_systems            = {
              + "dual-server" = {
                  + count               = 1
                  + links               = {
                      + "single-link" = {
                          + lag_mode           = "lacp_active"
                          + links_per_switch   = 1
                          + speed              = "10G"
                          + switch_peer        = (known after apply)
                          + tags               = (known after apply)
                          + target_switch_name = "apstra-esi"
                        },
                    }
                  + logical_device      = (known after apply)
                  + logical_device_id   = "AOS-2x10-1"
                  + port_channel_id_max = (known after apply)
                  + port_channel_id_min = (known after apply)
                  + tags                = (known after apply)
                },
              + "single-server-1" = {
                  + count               = 1
                  + links               = {
                      + "single-link" = {
                          + lag_mode           = (known after apply)
                          + links_per_switch   = 1
                          + speed              = "10G"
                          + switch_peer        = "first"
                          + tags               = (known after apply)
                          + target_switch_name = "apstra-esi"
                        },
                    }
                  + logical_device      = (known after apply)
                  + logical_device_id   = "AOS-1x10-1"
                  + port_channel_id_max = (known after apply)
                  + port_channel_id_min = (known after apply)
                  + tags                = (known after apply)
                },
              + "single-server-2" = {
                  + count               = 1
                  + links               = {
                      + "single-link" = {
                          + lag_mode           = (known after apply)
                          + links_per_switch   = 1
                          + speed              = "10G"
                          + switch_peer        = "second"
                          + tags               = (known after apply)
                          + target_switch_name = "apstra-esi"
                        },
                    }
                  + logical_device      = (known after apply)
                  + logical_device_id   = "AOS-1x10-1"
                  + port_channel_id_max = (known after apply)
                  + port_channel_id_min = (known after apply)
                  + tags                = (known after apply)
                },
            }
          + id                         = (known after apply)
          + leaf_switches              = {
              + "apstra-esi" = {
                  + logical_device      = (known after apply)
                  + logical_device_id   = "virtual-7x10-1"
                  + redundancy_protocol = "esi"
                  + spine_link_count    = 1
                  + spine_link_speed    = "10G"
                  + tags                = (known after apply)
                },
            }
          + name                       = "apstra-esi"
        }
    
      # apstra_rack_type.lab_guide_single will be created
      + resource "apstra_rack_type" "lab_guide_single" {
          + fabric_connectivity_design = "l3clos"
          + generic_systems            = {
              + "single-server" = {
                  + count               = 1
                  + links               = {
                      + "single-link" = {
                          + lag_mode           = (known after apply)
                          + links_per_switch   = 1
                          + speed              = "10G"
                          + switch_peer        = (known after apply)
                          + tags               = (known after apply)
                          + target_switch_name = "apstra-single"
                        },
                    }
                  + logical_device      = (known after apply)
                  + logical_device_id   = "AOS-1x10-1"
                  + port_channel_id_max = (known after apply)
                  + port_channel_id_min = (known after apply)
                  + tags                = (known after apply)
                },
            }
          + id                         = (known after apply)
          + leaf_switches              = {
              + "apstra-single" = {
                  + logical_device    = (known after apply)
                  + logical_device_id = "virtual-7x10-1"
                  + spine_link_count  = 1
                  + spine_link_speed  = "10G"
                  + tags              = (known after apply)
                },
            }
          + name                       = "apstra-single"
        }
    
    Plan: 2 to add, 0 to change, 0 to destroy.
    
    Do you want to perform these actions?
      Terraform will perform the actions described above.
      Only 'yes' will be accepted to approve.
    
      Enter a value: yes
    
    apstra_rack_type.lab_guide_single: Creating...
    apstra_rack_type.lab_guide_esi: Creating...
    apstra_rack_type.lab_guide_single: Creation complete after 2s [id=trhgpkk7tu27mbdvtklh9a]
    apstra_rack_type.lab_guide_esi: Creation complete after 2s [id=h2-uvp1ftmuhr4cfsbkqrw]
    
    Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
  5. Now check the Apstra GUI to verify that we are really performing operations.

  6. Open the GUI for your lab and navigate to Design → Rack Types. You should see two new rack types called apstra-esi and apstra-single

    New Racks created

Congrats! You have finished this step.