> ## Documentation Index
> Fetch the complete documentation index at: https://gcore.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a Bare Metal GPU cluster

export const MethodSection = ({children}) => children ?? null;

export const MethodSwitch = ({children}) => {
  const tabs = React.Children.toArray(children).map(c => {
    if (!c || !c.props) return null;
    if (c.props.id) return c;
    const inner = c.props.children;
    if (inner && inner.props && inner.props.id) return inner;
    return null;
  }).filter(Boolean);
  const firstId = tabs.length > 0 ? tabs[0].props.id : "";
  const [active, setActive] = React.useState(firstId);
  React.useEffect(() => {
    try {
      const saved = localStorage.getItem("gcore_docs_method");
      if (saved && tabs.find(t => t.props.id === saved)) {
        setActive(saved);
      }
    } catch (_) {}
  }, []);
  React.useEffect(() => {
    try {
      document.querySelectorAll("h2[id], h3[id]").forEach(heading => {
        const visible = heading.offsetParent !== null;
        document.querySelectorAll(`a[href="#${heading.id}"]`).forEach(link => {
          if (link.closest("h1,h2,h3,h4,h5,h6")) return;
          const li = link.closest("li");
          if (li) li.style.display = visible ? "" : "none";
        });
      });
    } catch (_) {}
    window.dispatchEvent(new Event("scroll"));
  }, [active]);
  const handleClick = id => {
    setActive(id);
    try {
      localStorage.setItem("gcore_docs_method", id);
    } catch (_) {}
  };
  return <div>
      <div className="not-prose flex gap-0 border-b border-zinc-200 dark:border-zinc-800 mb-8 mt-2" role="tablist">
        {tabs.map(tab => {
    const isActive = active === tab.props.id;
    return <button key={tab.props.id} role="tab" aria-selected={isActive} onClick={() => handleClick(tab.props.id)} className={["px-4 py-2 text-sm font-medium border-b-2 -mb-px transition-colors cursor-pointer", isActive ? "border-primary text-primary" : "border-transparent text-zinc-500 hover:text-zinc-800 dark:hover:text-zinc-200"].join(" ")}>
              {tab.props.label}
            </button>;
  })}
      </div>

      {tabs.map(tab => <div key={tab.props.id} style={{
    display: active === tab.props.id ? "" : "none"
  }}>
          {tab.props.children}
        </div>)}
    </div>;
};

<MethodSwitch>
  <MethodSection id="portal" label="Customer Portal">
    <p>GPU clusters are high-performance computing resources designed for AI/ML workloads, inference, and large-scale data processing. Each cluster consists of one or more GPU servers connected via high-speed networking.</p>

    <p>GPU clusters come in two types:</p>

    * **Bare Metal GPU**: Dedicated physical servers without virtualization, offering maximum performance and full hardware control.
    * **Spot Bare Metal GPU**: Discounted servers suitable for batch processing, experiments, and testing. [Spot clusters](/edge-ai/ai-infrastructure/spot-bare-metal-gpu) provide the same hardware access as standard Bare Metal GPUs and may be reclaimed with 24 hours' notice.

    <p>Cluster type and GPU model availability vary by region. The creation form displays only the options available in the selected region.</p>

    ## Cluster architecture

    <p>A cluster consists of one or more GPU servers with identical configuration.</p>

    <p>For multi-node clusters:</p>

    * Nodes share the same image and network settings.
    * InfiniBand networking is configured automatically when supported by the flavor.
    * File shares provide shared storage for datasets and checkpoints across all nodes.

    ## Create a GPU cluster

    <p>To create a Bare Metal GPU cluster, complete the following steps in the Gcore Customer Portal.</p>

    1. In the [Gcore Customer Portal](https://portal.gcore.com), navigate to **GPU Cloud**.
    2. In the sidebar, expand **GPU Clusters** and select **Bare Metal GPU Clusters**.
    3. Click **Create Cluster**.

    ### Step 1. Select region

    <p>In the **Region** section, select the data center location for the cluster.</p>

    <Frame>
      <img src="https://mintcdn.com/gcore/uiRa_jFs2CEr69p9/images/docs/edge-ai/ai-infrastructure/create-a-bare-metal-gpu-cluster/gpu-cluster-region.png?fit=max&auto=format&n=uiRa_jFs2CEr69p9&q=85&s=f2493fdc9c66defdd5576a6e137f6124" alt="Region selection section showing available regions grouped by geography" width="955" height="415" data-path="images/docs/edge-ai/ai-infrastructure/create-a-bare-metal-gpu-cluster/gpu-cluster-region.png" />
    </Frame>

    <p>Regions are grouped by geography (Asia-Pacific, EMEA). Each region card shows its availability status. File share integration, for example, is available only in select regions.</p>

    <Info>
      GPU model availability and pricing vary by region. Check other regions if a required GPU model is not available. For help with availability, contact the [sales team](https://gcore.com/contact-sales).
    </Info>

    ### Step 2. Configure cluster capacity

    <p>In this step, select the GPU model and flavor that define the hardware configuration for every node in the cluster. Available options depend on the selected region.</p>

    1. In the **Cluster capacity** section, select the **GPU Cluster type**:
       * **Bare Metal GPU** for dedicated physical servers
       * **Spot Bare Metal GPU** for discounted, interruptible instances (available in select regions)

    2. Select the **GPU Model**. Available models — A100, H100, or H200 — depend on the region.

    3. Enable or disable **Show out of stock** to filter available flavors.

    4. Select a flavor. Each flavor card displays GPU configuration, CPU type, RAM capacity, storage, network connectivity, pricing, and stock availability.

    <Frame>
      <img src="https://mintcdn.com/gcore/uiRa_jFs2CEr69p9/images/docs/edge-ai/ai-infrastructure/create-a-bare-metal-gpu-cluster/gpu-cluster-capacity.png?fit=max&auto=format&n=uiRa_jFs2CEr69p9&q=85&s=3fdf946de66b6fb56213209da7fae4cb" alt="Cluster capacity section showing GPU Cluster type, GPU Model selector, and flavor card with specifications" width="955" height="545" data-path="images/docs/edge-ai/ai-infrastructure/create-a-bare-metal-gpu-cluster/gpu-cluster-capacity.png" />
    </Frame>

    ### Step 3. Set the number of instances

    <p>In the **Number of Instances** section, specify how many servers to provision in the cluster.</p>

    <Frame>
      <img src="https://mintcdn.com/gcore/uiRa_jFs2CEr69p9/images/docs/edge-ai/ai-infrastructure/create-a-bare-metal-gpu-cluster/gpu-cluster-instances.png?fit=max&auto=format&n=uiRa_jFs2CEr69p9&q=85&s=bbd05b6cb49690942bc4c3e672a373ac" alt="Number of Instances section with instance counter" width="955" height="187" data-path="images/docs/edge-ai/ai-infrastructure/create-a-bare-metal-gpu-cluster/gpu-cluster-instances.png" />
    </Frame>

    <p>Each instance is a separate physical server with the selected flavor configuration. For single-node workloads, one instance is sufficient. For distributed training, provision multiple instances.</p>

    <p>The maximum number of instances is limited by the current stock availability in the region. There is no fixed per-cluster limit — clusters can scale to hundreds of nodes if capacity is available.</p>

    <Info>
      After creation, the cluster can be resized. Scaling up adds nodes with the same configuration used at creation. Scaling down removes a random node — to delete a specific node, use the per-node delete action in the cluster details. Deleting the last node in a cluster deletes the entire cluster.
    </Info>

    ### Step 4. Select image

    <p>The image defines the operating system and pre-installed software for cluster nodes.</p>

    <Frame>
      <img src="https://mintcdn.com/gcore/uiRa_jFs2CEr69p9/images/docs/edge-ai/ai-infrastructure/create-a-bare-metal-gpu-cluster/gpu-cluster-image.png?fit=max&auto=format&n=uiRa_jFs2CEr69p9&q=85&s=ba147f5c6ed6284492cb3c88ff673b15" alt="Image section with Public and Custom tabs and image selector" width="955" height="284" data-path="images/docs/edge-ai/ai-infrastructure/create-a-bare-metal-gpu-cluster/gpu-cluster-image.png" />
    </Frame>

    1. In the **Image** section, choose the operating system:
       * **Public**: Pre-configured images with NVIDIA drivers and CUDA toolkit (recommended)
       * **Custom**: Custom images uploaded to the account

    <p>The default Ubuntu images include pre-installed NVIDIA drivers and CUDA toolkit. Images with the `eni` suffix in the name are configured for InfiniBand interconnect.</p>

    2. Note the default login credentials displayed below the image selector: username `ubuntu`, SSH port `22`. These credentials are used to connect to the cluster after creation.

    ### Step 5. Configure file share integration

    <p>File shares provide shared storage accessible from all cluster nodes. GPU-enabled regions use VAST-backed high-performance shares. This option appears only in regions where file shares are available.</p>

    <p>For share types, sizing, access rules, and manual mounting, see [Configure file shares](/cloud/file-shares/configure-file-shares).</p>

    <Frame>
      <img src="https://mintcdn.com/gcore/uiRa_jFs2CEr69p9/images/docs/edge-ai/ai-infrastructure/create-a-bare-metal-gpu-cluster/gpu-cluster-file-share.png?fit=max&auto=format&n=uiRa_jFs2CEr69p9&q=85&s=96e9df9e43c70a7f7cd599e2b042af41" alt="File share integration section with Enable File Share checkbox" width="955" height="167" data-path="images/docs/edge-ai/ai-infrastructure/create-a-bare-metal-gpu-cluster/gpu-cluster-file-share.png" />
    </Frame>

    1. Enable the **File Share integration** checkbox.
    2. Select an existing file share or create a new one.
    3. Specify the mount path on cluster nodes (default: `/home/ubuntu/mnt/nfs`).

    <Info>
      When file share integration is enabled, the cluster automatically adds mount commands to the user data script. If **User data** is also configured in Additional options, do not remove these commands — they handle automatic mounting on first boot.
    </Info>

    ### Step 6. Configure network settings

    <p>Network settings define how the cluster communicates with external services and other resources. At least one interface is required.</p>

    <Frame>
      <img src="https://mintcdn.com/gcore/uiRa_jFs2CEr69p9/images/docs/edge-ai/ai-infrastructure/create-a-bare-metal-gpu-cluster/gpu-cluster-network.png?fit=max&auto=format&n=uiRa_jFs2CEr69p9&q=85&s=9f6d27a5dab54a9f2b77f8ac1ddf56a2" alt="Network settings section showing interface configuration" width="955" height="319" data-path="images/docs/edge-ai/ai-infrastructure/create-a-bare-metal-gpu-cluster/gpu-cluster-network.png" />
    </Frame>

    1. In the **Network settings** section, configure the network interface:

    | Type                 | Access                                        | Use case                                              |
    | -------------------- | --------------------------------------------- | ----------------------------------------------------- |
    | **Public**           | Direct internet access with dynamic public IP | Development, testing, quick access to cluster         |
    | **Private**          | Internal network only, no external access     | Production workloads, security-sensitive environments |
    | **Dedicated public** | Reserved static public IP                     | Production APIs, services requiring stable endpoints  |

    <p>For multi-node clusters, a private interface keeps internal traffic separate from internet-facing traffic.</p>

    <p>To add or configure interfaces, expand the interface card and adjust settings as needed. Additional interfaces can be attached by clicking **Add Interface**.</p>

    <p>All public interfaces include Basic DDoS Protection at no additional cost.</p>

    <p>Each interface can be expanded to configure security groups. In the **Security Groups** field, select one or more [security groups](/cloud/networking/add-and-configure-a-firewall) to control inbound and outbound traffic for that interface. The `default` security group is pre-selected. If no security group is selected, the default security group is attached automatically.</p>

    <Frame>
      <img src="https://mintcdn.com/gcore/7GoNDgB9fZnckEVg/images/docs/edge-ai/ai-infrastructure/create-a-bare-metal-gpu-cluster/network-settings-security-groups.png?fit=max&auto=format&n=7GoNDgB9fZnckEVg&q=85&s=dc07eff3768b4f230a4cc8f44aded43b" alt="Security Groups field with default group selected per interface" width="844" height="687" data-path="images/docs/edge-ai/ai-infrastructure/create-a-bare-metal-gpu-cluster/network-settings-security-groups.png" />
    </Frame>

    <p>To create a new security group, click **Add new Security Group** and configure inbound and outbound rules in the dialog.</p>

    ### Step 7. Configure SSH key

    <p>In the **SSH key** section, select an existing key from the dropdown or create a new one. Keys can be uploaded or generated directly in the Customer Portal. If generating a new key pair, save the private key immediately as it cannot be retrieved later.</p>

    <Frame>
      <img src="https://mintcdn.com/gcore/uiRa_jFs2CEr69p9/images/docs/edge-ai/ai-infrastructure/create-a-bare-metal-gpu-cluster/gpu-cluster-ssh-key.png?fit=max&auto=format&n=uiRa_jFs2CEr69p9&q=85&s=30867c1e1e78deba5cd6b5c2954fe724" alt="SSH key section with dropdown and options to add or generate keys" width="955" height="200" data-path="images/docs/edge-ai/ai-infrastructure/create-a-bare-metal-gpu-cluster/gpu-cluster-ssh-key.png" />
    </Frame>

    ### Step 8. Set additional options

    <p>The **Additional options** section provides optional settings: user data scripts for automated configuration and metadata tags for resource organization.</p>

    <Frame>
      <img src="https://mintcdn.com/gcore/uiRa_jFs2CEr69p9/images/docs/edge-ai/ai-infrastructure/create-a-bare-metal-gpu-cluster/gpu-cluster-additional-options.png?fit=max&auto=format&n=uiRa_jFs2CEr69p9&q=85&s=9db9427d23a8f4c1f0c7f5f9c821d84e" alt="Additional options section with User data and Add tags checkboxes" width="955" height="188" data-path="images/docs/edge-ai/ai-infrastructure/create-a-bare-metal-gpu-cluster/gpu-cluster-additional-options.png" />
    </Frame>

    ### Step 9. Name and create the cluster

    <p>The final step assigns a name to the cluster and initiates provisioning.</p>

    <Frame>
      <img src="https://mintcdn.com/gcore/uiRa_jFs2CEr69p9/images/docs/edge-ai/ai-infrastructure/create-a-bare-metal-gpu-cluster/gpu-cluster-name.png?fit=max&auto=format&n=uiRa_jFs2CEr69p9&q=85&s=92cadc871d3eb41fa01487b95bc9b017" alt="GPU Cluster Name section with name input field" width="955" height="166" data-path="images/docs/edge-ai/ai-infrastructure/create-a-bare-metal-gpu-cluster/gpu-cluster-name.png" />
    </Frame>

    1. In the **GPU Cluster Name** section, enter a name or use the auto-generated one.

    2. Review the **Estimated cost** panel on the right.

    3. Click **Create Cluster**.

    <p>Once all instances reach **Power on** status, the cluster is ready for use.</p>

    <Warning>
      Cluster-level settings (image, file share integration, default networks) cannot be changed after creation. New nodes added via scaling inherit the original configuration. To change these settings, create a new cluster.
    </Warning>

    ## Connect and verify the cluster

    <p>After the cluster is created, use SSH to connect to a node. The default username is `ubuntu`.</p>

    ```bash theme={null}
    ssh ubuntu@<instance-ip-address>
    ```

    <p>Replace `<instance-ip-address>` with the public or floating IP shown in the cluster details. For nodes with only private interfaces, connect through a bastion host or VPN, or use the [Gcore Customer Portal console](/cloud/virtual-instances/connect/connect-to-your-instance-via-control-panel).</p>

    <p>Verify that GPUs are available and drivers are loaded:</p>

    ```bash theme={null}
    nvidia-smi
    ```

    <p>The output displays all available GPUs, driver version, and CUDA version. If no GPUs appear, check that the image includes the correct NVIDIA drivers for the GPU model.</p>

    <p>If file share integration was enabled, verify the mount is accessible:</p>

    ```bash theme={null}
    ls /home/ubuntu/mnt/nfs
    ```

    <p>Clusters can also be created programmatically using the [GPU Bare Metal API](/api-reference/cloud/gpu-bare-metal).</p>
  </MethodSection>

  <MethodSection id="api" label="REST API">
    <p>Create a Bare Metal GPU cluster by selecting a flavor and image, then provisioning the cluster with a single API call.</p>

    <Info>
      An [API token](/account-settings/api-tokens) is required, along with a
      [project ID](/api-reference/cloud#tag/Projects/operation/ProjectsListV1.get)
      and a [region ID](/api-reference/cloud#tag/Regions/operation/RegionListV1.get).
      Bare Metal GPU clusters are available in select regions — use the [List flavors](#step-1-list-available-flavors) call to confirm availability.
    </Info>

    <p>Open a terminal and set these environment variables before running the examples:</p>

    ```bash theme={null}
    export GCORE_API_KEY="{YOUR_API_KEY}"
    export GCORE_CLOUD_PROJECT_ID="{YOUR_PROJECT_ID}"
    export GCORE_CLOUD_REGION_ID="{YOUR_REGION_ID}"
    export GCORE_SSH_KEY_NAME="{YOUR_SSH_KEY_NAME}"
    ```

    ## Quickstart

    <p>Complete scripts that list flavors and images, create a one-node cluster, wait for provisioning, and print the SSH command.</p>

    <Tabs>
      <Tab title="Python SDK">
        ```python theme={null}
        import os
        import time
        from gcore import Gcore

        client = Gcore(api_key=os.environ.get("GCORE_API_KEY"))
        project_id = int(os.environ["GCORE_CLOUD_PROJECT_ID"])
        region_id = int(os.environ["GCORE_CLOUD_REGION_ID"])
        ssh_key_name = os.environ["GCORE_SSH_KEY_NAME"]

        # Step 1. List flavors — select the one with the fewest GPUs
        flavors = client.cloud.gpu_baremetal.clusters.flavors.list(
            project_id=project_id,
            region_id=region_id,
        )
        flavor = min(
            flavors.results,
            key=lambda f: f.hardware_properties.gpu_count,
        )
        print(f"Flavor: {flavor.name}  ({flavor.hardware_properties.gpu_count} GPU(s))")

        # Step 2. List images — select the first (latest) image
        images = client.cloud.gpu_baremetal.clusters.images.list(
            project_id=project_id,
            region_id=region_id,
        )
        image = images.results[0]
        print(f"Image: {image.name}")

        # Step 3. Create the cluster
        task_id_list = client.cloud.gpu_baremetal.clusters.create(
            project_id=project_id,
            region_id=region_id,
            name="my-gpu-cluster",
            flavor=flavor.name,
            image_id=image.id,
            servers_count=1,
            servers_settings={
                "interfaces": [{"type": "external"}],
                "credentials": {"ssh_key_name": ssh_key_name},
            },
        )
        task_id = task_id_list.tasks[0]
        print(f"Provisioning — task: {task_id}")

        # Step 4. Poll task until FINISHED
        while True:
            task = client.cloud.tasks.get(task_id)
            if task.state == "FINISHED":
                cluster_id = task.created_resources.clusters[0]
                print(f"Cluster ID: {cluster_id}")
                break
            if task.state == "ERROR":
                raise RuntimeError(f"Cluster creation failed: {task.error}")
            print(f"  state={task.state} — retrying in 15s…")
            time.sleep(15)

        # Step 5. Get the public IP and print SSH command
        ifaces = client.cloud.gpu_baremetal.clusters.interfaces.list(
            cluster_id=cluster_id,
            project_id=project_id,
            region_id=region_id,
        )
        for iface in ifaces.results:
            if iface.network_details.external:
                ip = iface.ip_assignments[0].ip_address
                print(f"SSH: ssh ubuntu@{ip}")
        ```
      </Tab>

      <Tab title="Go SDK">
        ```go theme={null}
        package main

        import (
            "context"
            "fmt"
            "os"
            "sort"
            "strconv"
            "time"

            "github.com/G-Core/gcore-go"
            "github.com/G-Core/gcore-go/cloud"
            "github.com/G-Core/gcore-go/option"
        )

        func main() {
            projectIDInt, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_PROJECT_ID"), 10, 64)
            regionIDInt, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_REGION_ID"), 10, 64)
            sshKeyName := os.Getenv("GCORE_SSH_KEY_NAME")

            client := gcore.NewClient(option.WithAPIKey(os.Getenv("GCORE_API_KEY")))
            ctx := context.TODO()

            // Step 1. List flavors — select the one with fewest GPUs
            flavorList, err := client.Cloud.GPUBaremetal.Clusters.Flavors.List(ctx,
                cloud.GPUBaremetalClusterFlavorListParams{
                    ProjectID: gcore.Int(projectIDInt),
                    RegionID:  gcore.Int(regionIDInt),
                })
            if err != nil {
                panic(err)
            }
            sort.Slice(flavorList.Results, func(i, j int) bool {
                return flavorList.Results[i].HardwareProperties.GPUCount <
                    flavorList.Results[j].HardwareProperties.GPUCount
            })
            flavor := flavorList.Results[0]
            fmt.Printf("Flavor: %s  (%d GPU(s))\n", flavor.Name, flavor.HardwareProperties.GPUCount)

            // Step 2. List images — select the first (latest) image
            imageList, err := client.Cloud.GPUBaremetal.Clusters.Images.List(ctx,
                cloud.GPUBaremetalClusterImageListParams{
                    ProjectID: gcore.Int(projectIDInt),
                    RegionID:  gcore.Int(regionIDInt),
                })
            if err != nil {
                panic(err)
            }
            image := imageList.Results[0]
            fmt.Printf("Image: %s\n", image.Name)

            // Step 3. Create the cluster
            taskIDList, err := client.Cloud.GPUBaremetal.Clusters.New(ctx,
                cloud.GPUBaremetalClusterNewParams{
                    ProjectID:    gcore.Int(projectIDInt),
                    RegionID:     gcore.Int(regionIDInt),
                    Name:         "my-gpu-cluster",
                    Flavor:       flavor.Name,
                    ImageID:      image.ID,
                    ServersCount: 1,
                    ServersSettings: cloud.GPUBaremetalClusterNewParamsServersSettings{
                        Interfaces: []cloud.GPUBaremetalClusterNewParamsServersSettingsInterfaceUnion{{
                            OfExternal: &cloud.GPUBaremetalClusterNewParamsServersSettingsInterfaceExternal{},
                        }},
                        Credentials: cloud.GPUBaremetalClusterNewParamsServersSettingsCredentials{
                            SSHKeyName: gcore.String(sshKeyName),
                        },
                    },
                })
            if err != nil {
                panic(err)
            }
            taskID := taskIDList.Tasks[0]
            fmt.Printf("Provisioning — task: %s\n", taskID)

            // Step 4. Poll task until FINISHED
            var clusterID string
            for {
                task, err := client.Cloud.Tasks.Get(ctx, taskID)
                if err != nil {
                    panic(err)
                }
                if task.State == "FINISHED" {
                    clusterID = task.CreatedResources.Clusters[0]
                    fmt.Printf("Cluster ID: %s\n", clusterID)
                    break
                }
                if task.State == "ERROR" {
                    panic(fmt.Sprintf("Cluster creation failed: %v", task.Error))
                }
                fmt.Printf("  state=%s — retrying in 15s…\n", task.State)
                time.Sleep(15 * time.Second)
            }

            // Step 5. Get the public IP and print SSH command
            ifaces, err := client.Cloud.GPUBaremetal.Clusters.Interfaces.List(ctx,
                clusterID,
                cloud.GPUBaremetalClusterInterfaceListParams{
                    ProjectID: gcore.Int(projectIDInt),
                    RegionID:  gcore.Int(regionIDInt),
                })
            if err != nil {
                panic(err)
            }
            for _, iface := range ifaces.Results {
                if iface.NetworkDetails.External {
                    ip := iface.IPAssignments[0].IPAddress
                    fmt.Printf("SSH: ssh ubuntu@%s\n", ip)
                }
            }
        }
        ```
      </Tab>
    </Tabs>

    ## Step-by-step

    <p>Each step below explains the call, its key parameters, and what the response looks like.</p>

    <Accordion title="Show all steps">
      ### Step 1. List available flavors

      <p>Returns all Bare Metal GPU flavors available in the region. Use the response to pick a flavor name — required when creating the cluster.</p>

      | Field                           | Description                                                               |
      | ------------------------------- | ------------------------------------------------------------------------- |
      | `name`                          | Flavor identifier — pass this value as `flavor` when creating the cluster |
      | `hardware_description.gpu`      | GPU model name and VRAM                                                   |
      | `hardware_properties.gpu_count` | Number of GPUs per node                                                   |
      | `hardware_properties.nic_ib`    | InfiniBand configuration, if present                                      |
      | `capacity`                      | Available node count in the region (`0` means currently out of stock)     |

      <Tabs>
        <Tab title="Python SDK">
          ```python theme={null}
          import os
          from gcore import Gcore

          client = Gcore(api_key=os.environ.get("GCORE_API_KEY"))

          flavors = client.cloud.gpu_baremetal.clusters.flavors.list(
              project_id=int(os.environ["GCORE_CLOUD_PROJECT_ID"]),
              region_id=int(os.environ["GCORE_CLOUD_REGION_ID"]),
          )
          for f in flavors.results:
              print(f.name, f.hardware_description.gpu, f"GPUs={f.hardware_properties.gpu_count}")
          ```
        </Tab>

        <Tab title="Go SDK">
          ```go theme={null}
          flavorList, err := client.Cloud.GPUBaremetal.Clusters.Flavors.List(ctx,
              cloud.GPUBaremetalClusterFlavorListParams{
                  ProjectID: gcore.Int(projectID),
                  RegionID:  gcore.Int(regionID),
              })
          if err != nil {
              panic(err)
          }
          for _, f := range flavorList.Results {
              fmt.Printf("%s  gpu=%s  count=%d\n",
                  f.Name, f.HardwareDescription.GPU, f.HardwareProperties.GPUCount)
          }
          ```
        </Tab>

        <Tab title="curl">
          ```bash theme={null}
          curl "https://api.gcore.com/cloud/v3/gpu/baremetal/${GCORE_CLOUD_PROJECT_ID}/${GCORE_CLOUD_REGION_ID}/flavors" \
            -H "Authorization: APIKey ${GCORE_API_KEY}"
          ```
        </Tab>
      </Tabs>

      The API returns:

      ```json theme={null}
      {
        "count": 2,
        "results": [
          {
            "name": "bm3-ai-1xlarge-h100-80-8",
            "architecture": "x86_64",
            "disabled": false,
            "capacity": 0,
            "hardware_description": {
              "cpu": "2x Intel Xeon 8480+",
              "ram": "2TB RAM",
              "disk": "8 x 3.84 TB NVMe",
              "network": "3.2 Tbit/s Infiniband",
              "gpu": "NVIDIA H100-8GPU (80GB)"
            },
            "hardware_properties": {
              "gpu_model": "h100",
              "gpu_manufacturer": "nvidia",
              "gpu_count": 8,
              "nic_eth": "2x100",
              "nic_ib": "8x400"
            }
          }
        ]
      }
      ```

      ### Step 2. List available images

      <p>Returns all Bare Metal GPU cluster images available in the region. Use the response to pick an image ID — required when creating the cluster.</p>

      | Field  | Description                                                           |
      | ------ | --------------------------------------------------------------------- |
      | `id`   | Image UUID — pass this as `image_id` when creating the cluster        |
      | `name` | Image name; images with the `eni` suffix are optimized for InfiniBand |

      <Tabs>
        <Tab title="Python SDK">
          ```python theme={null}
          import os
          from gcore import Gcore

          client = Gcore(api_key=os.environ.get("GCORE_API_KEY"))

          images = client.cloud.gpu_baremetal.clusters.images.list(
              project_id=int(os.environ["GCORE_CLOUD_PROJECT_ID"]),
              region_id=int(os.environ["GCORE_CLOUD_REGION_ID"]),
          )
          for img in images.results:
              print(img.id, img.name)
          ```
        </Tab>

        <Tab title="Go SDK">
          ```go theme={null}
          imageList, err := client.Cloud.GPUBaremetal.Clusters.Images.List(ctx,
              cloud.GPUBaremetalClusterImageListParams{
                  ProjectID: gcore.Int(projectID),
                  RegionID:  gcore.Int(regionID),
              })
          if err != nil {
              panic(err)
          }
          for _, img := range imageList.Results {
              fmt.Printf("%s  %s\n", img.ID, img.Name)
          }
          ```
        </Tab>

        <Tab title="curl">
          ```bash theme={null}
          curl "https://api.gcore.com/cloud/v3/gpu/baremetal/${GCORE_CLOUD_PROJECT_ID}/${GCORE_CLOUD_REGION_ID}/images" \
            -H "Authorization: APIKey ${GCORE_API_KEY}"
          ```
        </Tab>
      </Tabs>

      The API returns:

      ```json theme={null}
      {
        "count": 9,
        "results": [
          {
            "id": "e975eac6-e81e-49b6-a0ca-967786907961",
            "name": "gcloud-ai-gpu-ubuntu-24.04-580.126.16-open-13.0.2-bm-v1.14.20"
          },
          {
            "id": "0e2600fe-df82-40bf-97f1-0b4b1f8bc9e0",
            "name": "ubuntu-22.04-x64-nvidia-a100/h100-eni"
          }
        ]
      }
      ```

      ### Step 3. Create the cluster

      <p>Submits the cluster creation request and returns a task ID for tracking provisioning progress.</p>

      | Parameter                                   | Required | Description                                                                  |
      | ------------------------------------------- | -------- | ---------------------------------------------------------------------------- |
      | `name`                                      | Yes      | Cluster name (2–63 chars, alphanumeric, hyphens, underscores)                |
      | `flavor`                                    | Yes      | Flavor name from Step 1                                                      |
      | `image_id`                                  | Yes      | Image UUID from Step 2                                                       |
      | `servers_count`                             | Yes      | Number of nodes to provision                                                 |
      | `servers_settings.interfaces`               | Yes      | At least one interface — use `"type": "external"` for public internet access |
      | `servers_settings.credentials.ssh_key_name` | Yes      | Name of an existing SSH key in the project                                   |
      | `tags`                                      | No       | Key-value metadata tags                                                      |

      <Tabs>
        <Tab title="Python SDK">
          ```python theme={null}
          import os
          from gcore import Gcore

          client = Gcore(api_key=os.environ.get("GCORE_API_KEY"))

          task_id_list = client.cloud.gpu_baremetal.clusters.create(
              project_id=int(os.environ["GCORE_CLOUD_PROJECT_ID"]),
              region_id=int(os.environ["GCORE_CLOUD_REGION_ID"]),
              name="my-gpu-cluster",
              flavor="{FLAVOR_NAME}",
              image_id="{IMAGE_ID}",
              servers_count=1,
              servers_settings={
                  "interfaces": [{"type": "external"}],
                  "credentials": {"ssh_key_name": os.environ["GCORE_SSH_KEY_NAME"]},
              },
              tags={"env": "production"},
          )
          print(task_id_list.tasks)  # save as TASK_ID
          ```
        </Tab>

        <Tab title="Go SDK">
          ```go theme={null}
          taskIDList, err := client.Cloud.GPUBaremetal.Clusters.New(ctx,
              cloud.GPUBaremetalClusterNewParams{
                  ProjectID:    gcore.Int(projectID),
                  RegionID:     gcore.Int(regionID),
                  Name:         "my-gpu-cluster",
                  Flavor:       "{FLAVOR_NAME}",
                  ImageID:      "{IMAGE_ID}",
                  ServersCount: 1,
                  ServersSettings: cloud.GPUBaremetalClusterNewParamsServersSettings{
                      Interfaces: []cloud.GPUBaremetalClusterNewParamsServersSettingsInterfaceUnion{{
                          OfExternal: &cloud.GPUBaremetalClusterNewParamsServersSettingsInterfaceExternal{},
                      }},
                      Credentials: cloud.GPUBaremetalClusterNewParamsServersSettingsCredentials{
                          SSHKeyName: gcore.String(os.Getenv("GCORE_SSH_KEY_NAME")),
                      },
                  },
              })
          if err != nil {
              panic(err)
          }
          fmt.Printf("%+v\n", taskIDList.Tasks)  // save as TASK_ID
          ```
        </Tab>

        <Tab title="curl">
          ```bash theme={null}
          curl -X POST \
            "https://api.gcore.com/cloud/v3/gpu/baremetal/${GCORE_CLOUD_PROJECT_ID}/${GCORE_CLOUD_REGION_ID}/clusters" \
            -H "Authorization: APIKey ${GCORE_API_KEY}" \
            -H "Content-Type: application/json" \
            -d '{
              "name": "my-gpu-cluster",
              "flavor": "{FLAVOR_NAME}",
              "image_id": "{IMAGE_ID}",
              "servers_count": 1,
              "servers_settings": {
                "interfaces": [{"type": "external"}],
                "credentials": {"ssh_key_name": "{YOUR_SSH_KEY_NAME}"}
              },
              "tags": {"env": "production"}
            }'
          ```
        </Tab>
      </Tabs>

      The API returns:

      ```json theme={null}
      { "tasks": ["e4cecbfc-5258-40bb-b78f-3cd92621c3b2"] }
      ```

      ### Step 4. Wait for provisioning

      <p>Poll the task endpoint every 15 seconds until `state` is `FINISHED`. Bare Metal GPU nodes typically provision in 15–20 minutes.</p>

      ```bash theme={null}
      curl "https://api.gcore.com/cloud/v1/tasks/e4cecbfc-5258-40bb-b78f-3cd92621c3b2" \
        -H "Authorization: APIKey ${GCORE_API_KEY}"
      ```

      <p>While provisioning:</p>

      ```json theme={null}
      {
        "id": "e4cecbfc-5258-40bb-b78f-3cd92621c3b2",
        "state": "RUNNING",
        "created_resources": null
      }
      ```

      <p>When complete:</p>

      ```json theme={null}
      {
        "id": "e4cecbfc-5258-40bb-b78f-3cd92621c3b2",
        "state": "FINISHED",
        "created_resources": {
          "clusters": ["4146c059-501a-409f-8fe1-04de091d917a"]
        }
      }
      ```

      <p>Read the cluster ID from `created_resources.clusters[0]`.</p>

      ### Step 5. Get the cluster public IP

      <p>Retrieve the network interfaces to find the node's public IP address for SSH access.</p>

      <Tabs>
        <Tab title="Python SDK">
          ```python theme={null}
          ifaces = client.cloud.gpu_baremetal.clusters.interfaces.list(
              cluster_id="{CLUSTER_ID}",
              project_id=int(os.environ["GCORE_CLOUD_PROJECT_ID"]),
              region_id=int(os.environ["GCORE_CLOUD_REGION_ID"]),
          )
          for iface in ifaces.results:
              if iface.network_details.external:
                  print("Public IP:", iface.ip_assignments[0].ip_address)
          ```
        </Tab>

        <Tab title="Go SDK">
          ```go theme={null}
          ifaces, err := client.Cloud.GPUBaremetal.Clusters.Interfaces.List(ctx,
              "{CLUSTER_ID}",
              cloud.GPUBaremetalClusterInterfaceListParams{
                  ProjectID: gcore.Int(projectID),
                  RegionID:  gcore.Int(regionID),
              })
          if err != nil {
              panic(err)
          }
          for _, iface := range ifaces.Results {
              if iface.NetworkDetails.External {
                  fmt.Println("Public IP:", iface.IPAssignments[0].IPAddress)
              }
          }
          ```
        </Tab>

        <Tab title="curl">
          ```bash theme={null}
          curl "https://api.gcore.com/cloud/v3/gpu/baremetal/${GCORE_CLOUD_PROJECT_ID}/${GCORE_CLOUD_REGION_ID}/clusters/{CLUSTER_ID}/interfaces" \
            -H "Authorization: APIKey ${GCORE_API_KEY}"
          ```
        </Tab>
      </Tabs>

      The API returns:

      ```json theme={null}
      {
        "count": 1,
        "results": [
          {
            "port_id": "302f6e9c-ff95-4d67-ac19-2d3473e2c3ee",
            "ip_assignments": [{ "ip_address": "85.234.84.39", "subnet_id": "351b0dd7-ca09-431c-be53-935db3785067" }],
            "network_details": { "name": "pub_net", "external": true }
          }
        ]
      }
      ```

      <p>The interface with `network_details.external: true` is the public network. Use its `ip_assignments[0].ip_address` for SSH.</p>
    </Accordion>

    ## Connect to the cluster

    <p>After the cluster reaches `active` status, connect to a node via SSH using the `ubuntu` user:</p>

    ```bash theme={null}
    ssh ubuntu@{NODE_PUBLIC_IP}
    ```

    <p>Verify that GPUs are detected:</p>

    ```bash theme={null}
    nvidia-smi
    ```

    <p>A successful output shows the list of GPUs, driver version, and CUDA version. For nodes with only private interfaces, connect through a bastion host or VPN.</p>
  </MethodSection>
</MethodSwitch>
