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

# Manage 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>The cluster details page provides tools for monitoring nodes, managing lifecycle operations, configuring networking, and accessing administrative functions.</p>

    <p>Cluster management operates at two levels: cluster-wide operations (resize, reconfigure, delete) that affect all nodes at once, and per-node operations (rebuild, replace, power, apply settings) that target individual nodes independently.</p>

    ## Access cluster details

    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 a cluster name to open the details page.

    <p>The cluster details page shows the cluster name, current status badge, and cluster ID at the top. Below that, a header panel displays the following fields:</p>

    | Field     | Description                                                                                                  |
    | --------- | ------------------------------------------------------------------------------------------------------------ |
    | Pkey ID   | InfiniBand Partition Key ID. Displayed as "-" if InfiniBand is not configured or during cluster provisioning |
    | OS Distro | Operating system image installed on all nodes                                                                |
    | Region    | Data center location                                                                                         |
    | Plan      | Monthly pricing plan for the cluster                                                                         |

    <p>The page is organized into tabs: **Overview**, **Power**, **Networking**, **Tags**, **User Actions**, and **Delete**.</p>

    <Frame>
      <img src="https://mintcdn.com/gcore/IFamTPZ0eX9xxcmf/images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-overview.png?fit=max&auto=format&n=IFamTPZ0eX9xxcmf&q=85&s=4ead7489311890b3129d995d33099a96" alt="Cluster overview page showing header panel and tabs" width="1095" height="756" data-path="images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-overview.png" />
    </Frame>

    ## View cluster nodes

    <p>The **Overview** tab lists all nodes (servers) in the cluster. Each node entry shows the node name, flavor, assigned IP addresses, status, timestamps, cost, and other metadata. The table supports filtering by name, date range, and status.</p>

    <Info>
      Each node inherits its **cluster configuration** — image, SSH key, and user data — from the cluster. Network interfaces and file shares cannot be changed at the node level after creation. To update the cluster configuration, use **Reconfigure Cluster**; to sync a specific outdated node, use **Apply settings**.
    </Info>

    ## Cluster lifecycle

    ### Manage cluster size

    <p>Cluster size can be adjusted after creation by adding or removing nodes.</p>

    1. On the **Overview** tab, click **Resize Cluster**.
    2. Adjust the instance count using the **+** and **-** buttons.
    3. Click **Resize**.

    <Frame>
      <img src="https://mintcdn.com/gcore/IFamTPZ0eX9xxcmf/images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-resize-dialog.png?fit=max&auto=format&n=IFamTPZ0eX9xxcmf&q=85&s=7a4b3576a6a2358a0b4b7d56a5fc9aec" alt="Resize cluster dialog with instance count controls" width="624" height="495" data-path="images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-resize-dialog.png" />
    </Frame>

    <p>New nodes inherit the current cluster configuration. While resizing, most management actions are unavailable; Bare Metal H100 nodes may take 15–40 minutes to provision.</p>

    <Warning>
      Scaling down to zero nodes is not allowed. When scaling down, the system removes a random node — to target a specific node, use **Delete node** in [Node management](#node-management) instead.
    </Warning>

    ### Reconfigure cluster

    <p>Use **Reconfigure Cluster** to change the image, SSH key, or user data for the cluster and select how to apply the update.</p>

    1. Click **Reconfigure Cluster** in the top-right corner of the cluster details page.
    2. In the **Update settings** step, use the dropdowns next to **Image**, **SSH Key**, and **User data** to select new values, or leave them unchanged to keep the current settings. Click **Next**.
    3. In the **Select update method** step, select how to apply the changes:

    <Frame>
      <img src="https://mintcdn.com/gcore/IFamTPZ0eX9xxcmf/images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-reconfigure-step2.png?fit=max&auto=format&n=IFamTPZ0eX9xxcmf&q=85&s=604793b1f9da34a0441ba2e87f57331b" alt="Reconfigure cluster page step 2 showing update method options" width="1124" height="833" data-path="images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-reconfigure-step2.png" />
    </Frame>

    | Option                 | Description                                                                                                 |
    | ---------------------- | ----------------------------------------------------------------------------------------------------------- |
    | **Save only**          | The new configuration will be used for future scale-ups or the next rebuild. Existing nodes are unaffected. |
    | **Apply settings now** | Apply changes immediately to selected nodes or the entire cluster.                                          |
    | **Schedule for later** | Apply updates automatically at a specific time. Coming soon.                                                |

    4. If **Apply settings now** is selected, select **All Instances in Cluster** or **Selected Instances** under **Apply to**. Click **Reconfigure** to confirm.

    <Warning>
      Changes that require a node rebuild permanently delete all data on the system volume of affected nodes. IP addresses, hostname, and attached volumes are preserved.
    </Warning>

    ### Delete cluster

    <p>When a cluster is deleted, local NVMe storage is permanently erased; file shares and object storage remain intact.</p>

    1. Navigate to the **Delete** tab on the cluster details page.
    2. Click **Delete Cluster**.
    3. Confirm the deletion.

    <Frame>
      <img src="https://mintcdn.com/gcore/IFamTPZ0eX9xxcmf/images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-delete-tab.png?fit=max&auto=format&n=IFamTPZ0eX9xxcmf&q=85&s=fe68f6ab6c9d9d06651252791f794466" alt="Delete tab with warning message and delete button" width="1096" height="479" data-path="images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-delete-tab.png" />
    </Frame>

    <Warning>
      Cluster deletion is irreversible. Data on local NVMe storage cannot be recovered.
    </Warning>

    ## Node management

    <p>Node management operations target individual servers in the cluster independently — controlling power state, reinstalling the OS, swapping out failed nodes, and syncing updated cluster configuration to specific nodes.</p>

    ### Power actions

    <p>To control a single node:</p>

    1. Locate the node in the cluster list.
    2. Click the actions menu (three dots) on the node row.
    3. Select the desired action: **Power on**, **Power off**, **Soft reboot**, or **Hard reboot**.

    <Frame>
      <img src="https://mintcdn.com/gcore/IFamTPZ0eX9xxcmf/images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/node-actions-menu.png?fit=max&auto=format&n=IFamTPZ0eX9xxcmf&q=85&s=fd59e4f7fddc1cd03792b003b1e1ad64" alt="Node actions menu showing power and management options" width="1113" height="767" data-path="images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/node-actions-menu.png" />
    </Frame>

    <p>To apply power actions to multiple nodes at once, select them using the checkboxes, click **Group actions**, and select the action. Alternatively, use the **Power** tab to soft or hard reboot all cluster nodes simultaneously.</p>

    <Frame>
      <img src="https://mintcdn.com/gcore/IFamTPZ0eX9xxcmf/images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-power-tab.png?fit=max&auto=format&n=IFamTPZ0eX9xxcmf&q=85&s=1ab63e2919d82b2a7123454800a0db8b" alt="Power tab with soft and hard reboot options" width="1089" height="765" data-path="images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-power-tab.png" />
    </Frame>

    ### Rebuild node

    <p>Rebuild reinstalls the OS on a node. The dialog shows the current **Image**, **SSH Key**, and **User data**. Use the dropdown next to any field to select a new value for this rebuild, or leave it unchanged to keep the current setting. All data on local storage is deleted.</p>

    1. Click the actions menu (three dots) on the node row.
    2. Select **Rebuild**.
    3. In the dialog, change **Image**, **SSH Key**, or **User data** as needed, or leave them to keep current values.
    4. Type `Rebuild` to confirm and click **Rebuild**.

    <p>To rebuild multiple nodes at once, select them using checkboxes, click **Group actions**, and select **Rebuild**. The dialog offers two modes: **Apply same settings to all Instances** or **Per Instance configuration**.</p>

    <Warning>
      Rebuild deletes all data on the node's local storage. Node identity is preserved — IP addresses, hostname, and attached volumes remain unchanged.
    </Warning>

    ### Replace node

    <p>Replace deletes the current node and provisions a new one with the same configuration (flavor, image, network settings). Use this to recover a node stuck in a failed state without changing the cluster setup.</p>

    1. Click the actions menu (three dots) on the node row.
    2. Select **Replace**.
    3. Confirm the operation.

    ### Delete node

    <p>To permanently remove a single node from the cluster:</p>

    1. Locate the node in the cluster list.
    2. Click the actions menu (three dots) on the node row.
    3. Select **Delete**.
    4. Confirm the deletion.

    <Warning>
      Deleting the last node in a cluster automatically deletes the entire cluster. This applies to both UI and API/Terraform operations. When using the API or Terraform to delete nodes, no warning is displayed before the cluster is removed. Leave at least one node in the cluster to preserve it.
    </Warning>

    ### Apply settings

    <p>When a node's cluster configuration is outdated — because the cluster was reconfigured but that node was not yet updated — a warning appears in the node details panel.</p>

    1. Click a node name in the **Overview** tab to open its details panel.
    2. Click **Apply settings**.
    3. Review the diff table: each row shows the **Setting**, **Current** value, and **After Apply** value.
    4. Select or deselect nodes to include.
    5. Type `Apply` and click **Apply**.

    <p>To apply settings to multiple outdated nodes at once, select them using checkboxes in the **Overview** tab, click **Group actions**, and select **Apply settings**.</p>

    <Frame>
      <img src="https://mintcdn.com/gcore/IFamTPZ0eX9xxcmf/images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/node-details-panel.png?fit=max&auto=format&n=IFamTPZ0eX9xxcmf&q=85&s=fd6a19a2b7a6533dcd419282a4310e61" alt="Node details panel showing Apply settings and Rebuild buttons with outdated configuration warning" width="1440" height="900" data-path="images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/node-details-panel.png" />
    </Frame>

    ## Networking

    <p>Network interfaces are assigned to each node at cluster creation. Public and private interfaces can be added after creation. InfiniBand interfaces are managed automatically and cannot be modified.</p>

    ### View interfaces

    <p>The **Networking** tab displays network interfaces for each node. Click a node name to expand its interface details.</p>

    | Type       | Description                                                             |
    | ---------- | ----------------------------------------------------------------------- |
    | Public     | External IP address for internet access                                 |
    | Private    | Internal network for communication with other cloud resources           |
    | InfiniBand | High-speed, low-latency inter-node network for GPU-to-GPU communication |

    <Frame>
      <img src="https://mintcdn.com/gcore/IFamTPZ0eX9xxcmf/images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-networking-tab.png?fit=max&auto=format&n=IFamTPZ0eX9xxcmf&q=85&s=759ee49ceb7c20a1b3c9b039d238a86c" alt="Networking tab showing node and interface list" width="1089" height="502" data-path="images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-networking-tab.png" />
    </Frame>

    <p>For flavors with InfiniBand, multiple InfiniBand interfaces are created automatically (by default, eight for H100 configurations). These appear as "GPU-cluster ib-subnet" entries in the interface list. Click an interface to expand its details, including IP address and network configuration.</p>

    <Frame>
      <img src="https://mintcdn.com/gcore/IFamTPZ0eX9xxcmf/images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-network-interfaces.png?fit=max&auto=format&n=IFamTPZ0eX9xxcmf&q=85&s=02522c6a6b0e0cc1679cadd0dec3bde2" alt="Node with expanded interface showing network details" width="1086" height="830" data-path="images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-network-interfaces.png" />
    </Frame>

    ### Modify interfaces

    <p>To add network interfaces on a specific node:</p>

    1. Navigate to the **Networking** tab.
    2. Click a node to expand its details.
    3. Click **Add Interface** or **Add Sub-Interface**.
    4. Configure the interface type (public or private) and IP allocation settings as supported by the service.

    <Info>
      Only network interfaces can be modified on individual nodes after cluster creation. Image and storage configuration cannot be changed independently at the node level. InfiniBand interfaces are managed automatically and cannot be modified or deleted.
    </Info>

    ## Administration

    <p>Administrative tools for organizing clusters with tags, tracking operations through the audit log, and accessing nodes for troubleshooting via the browser console.</p>

    ### Tags

    <p>Tags are applied at the cluster level and inherited by all nodes.</p>

    1. Navigate to the **Tags** tab on the cluster details page.
    2. Enable the **Add custom tags** checkbox.
    3. Enter the key and value for each tag.
    4. Click **Save changes**.

    <Frame>
      <img src="https://mintcdn.com/gcore/IFamTPZ0eX9xxcmf/images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-tags-tab.png?fit=max&auto=format&n=IFamTPZ0eX9xxcmf&q=85&s=af7d7059e85f6ae13a964763df615331" alt="Tags tab with custom tags toggle" width="1091" height="490" data-path="images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-tags-tab.png" />
    </Frame>

    <p>Tags can be modified even while the cluster is in the Resizing state.</p>

    ### User actions

    <p>The **User Actions** tab displays a log of all operations performed on the cluster — creation, deletion, resize, power, and network actions. Use the date and action type filters to narrow results.</p>

    <Frame>
      <img src="https://mintcdn.com/gcore/IFamTPZ0eX9xxcmf/images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-user-actions-tab.png?fit=max&auto=format&n=IFamTPZ0eX9xxcmf&q=85&s=9069767d708bca503b5f80db4497cc3b" alt="User Actions tab showing audit log of cluster operations" width="1098" height="622" data-path="images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-user-actions-tab.png" />
    </Frame>

    ### Console

    <p>For troubleshooting or when SSH access is unavailable, use the browser-based console.</p>

    1. In the **Overview** tab, locate the target node.
    2. Click **Open Console** in the node row.
    3. The console opens in a new browser tab using noVNC.
    4. Log in using the operating system credentials.

    <Frame>
      <img src="https://mintcdn.com/gcore/IFamTPZ0eX9xxcmf/images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-console.png?fit=max&auto=format&n=IFamTPZ0eX9xxcmf&q=85&s=2a250b0afe0fc87400415e451d859095" alt="Browser-based noVNC console with login prompt" width="1366" height="328" data-path="images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-console.png" />
    </Frame>

    <p>The Customer Portal is suitable for managing individual clusters. For automated workflows — CI/CD pipelines, infrastructure-as-code, or batch provisioning — the [API](#api) and [Terraform](#terraform) tabs cover the same operations programmatically.</p>
  </MethodSection>

  <MethodSection id="api" label="REST API">
    <p>Use the REST API to inspect clusters, resize them, manage node lifecycle operations, and automate cluster administration workflows.</p>

    <Info>
      An [API token](/account-settings/api-tokens) is required, along with a
      [project ID](/api-reference/cloud/projects/list-projects)
      and a [region ID](/api-reference/cloud/regions/list-regions).
    </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}"
    ```

    <Info>
      Most write operations are asynchronous and return `{ "tasks": ["task-uuid"] }`. Poll <code>GET /cloud/v1/tasks/\{task\_id}</code> every five seconds until `state` is `FINISHED`. Bare Metal H100 nodes may take 15–40 minutes for provisioning operations.
    </Info>

    ## List bare metal GPU clusters

    <p>List all clusters in a project and region. Query string filters — by name, flavor, node count, tags, and timestamps — are documented in the [API reference](/api-reference/cloud/gpu-baremetal).</p>

    <Info>
      The Python and Go SDKs support `limit` and `offset` for pagination only. Name, flavor, node count, tag, image, and date filters are available via curl only.
    </Info>

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

        client = Gcore()

        page = client.cloud.gpu_baremetal.clusters.list()
        for cluster in page.results:
            print(cluster.id, cluster.name, cluster.servers_count, cluster.status)
        ```
      </Tab>

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

        import (
            "context"
            "fmt"
            "os"
            "strconv"

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

        func main() {
            projectID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_PROJECT_ID"), 10, 64)
            regionID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_REGION_ID"), 10, 64)

            client := gcore.NewClient()
            ctx := context.Background()

            page, err := client.Cloud.GPUBaremetal.Clusters.List(ctx,
                cloud.GPUBaremetalClusterListParams{
                    ProjectID: gcore.Int(projectID),
                    RegionID:  gcore.Int(regionID),
                })
            if err != nil {
                panic(err)
            }
            fmt.Printf("Total: %d\n", len(page.Results))
            for _, c := range page.Results {
                fmt.Printf("  %s  %s  nodes=%d\n", c.ID, c.Name, c.ServersCount)
            }
        }
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        curl -G "https://api.gcore.com/cloud/v3/gpu/baremetal/${GCORE_CLOUD_PROJECT_ID}/${GCORE_CLOUD_REGION_ID}/clusters" \
          -H "Authorization: APIKey ${GCORE_API_KEY}" \
          --data-urlencode "name[prefix]=prod-" \
          --data-urlencode "flavor[prefix]=bm3-" \
          --data-urlencode "servers_count[gte]=4" \
          --data-urlencode "tags[env]=production"
        ```

        Response:

        ```json theme={null}
        {
          "count": 1,
          "results": [
            {
              "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
              "name": "prod-bm-cluster-1",
              "status": "active",
              "flavor": "bm3-ai-1xlarge-h100-80-8",
              "tags": [
                { "key": "env", "value": "production", "read_only": false },
                { "key": "team", "value": "ml", "read_only": false }
              ],
              "servers_count": 4,
              "created_at": "2026-06-10T12:00:00Z",
              "updated_at": "2026-06-10T12:15:00Z",
              "servers_ids": [
                "server-uuid-1",
                "server-uuid-2",
                "server-uuid-3",
                "server-uuid-4"
              ],
              "has_pending_changes": false
            }
          ]
        }
        ```

        Use `limit` and `offset` for pagination. The default page size is 10; the maximum is 1000.
      </Tab>
    </Tabs>

    ## Get cluster details

    <p>Retrieve the full configuration and current status of a single cluster.</p>

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

        client = Gcore()

        cluster = client.cloud.gpu_baremetal.clusters.get(cluster_id="{CLUSTER_ID}")
        print(cluster.id, cluster.name, cluster.status, cluster.servers_count)
        ```
      </Tab>

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

        import (
            "context"
            "fmt"
            "os"
            "strconv"

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

        func main() {
            projectID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_PROJECT_ID"), 10, 64)
            regionID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_REGION_ID"), 10, 64)

            client := gcore.NewClient()
            ctx := context.Background()

            cluster, err := client.Cloud.GPUBaremetal.Clusters.Get(ctx,
                "{CLUSTER_ID}",
                cloud.GPUBaremetalClusterGetParams{
                    ProjectID: gcore.Int(projectID),
                    RegionID:  gcore.Int(regionID),
                })
            if err != nil {
                panic(err)
            }
            fmt.Printf("%s  %s  nodes=%d\n", cluster.ID, cluster.Name, cluster.ServersCount)
        }
        ```
      </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}" \
          -H "Authorization: APIKey ${GCORE_API_KEY}"
        ```

        Response:

        ```json theme={null}
        {
          "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
          "name": "prod-bm-cluster-1",
          "status": "active",
          "flavor": "bm3-ai-1xlarge-h100-80-8",
          "servers_count": 4,
          "servers_ids": ["server-uuid-1", "server-uuid-2", "server-uuid-3", "server-uuid-4"],
          "tags": [{ "key": "env", "value": "production" }],
          "created_at": "2026-06-10T12:00:00Z",
          "updated_at": "2026-06-10T12:15:00Z",
          "has_pending_changes": false
        }
        ```
      </Tab>
    </Tabs>

    ## Resize a cluster

    <p>Change the node count by specifying the new total number of nodes. Scaling down removes a random node; to target a specific node, the [delete node](#delete-a-specific-node) operation below handles per-node removal.</p>

    <Warning>
      Scaling down to zero is not allowed. A cluster must contain at least one node at all times.
    </Warning>

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

        client = Gcore()

        task_id_list = client.cloud.gpu_baremetal.clusters.resize(
            cluster_id="{CLUSTER_ID}",
            instances_count=4,
        )
        print(task_id_list.tasks)
        ```
      </Tab>

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

        import (
            "context"
            "fmt"
            "os"
            "strconv"

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

        func main() {
            projectID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_PROJECT_ID"), 10, 64)
            regionID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_REGION_ID"), 10, 64)

            client := gcore.NewClient()
            ctx := context.Background()

            taskIDList, err := client.Cloud.GPUBaremetal.Clusters.Resize(ctx,
                "{CLUSTER_ID}",
                cloud.GPUBaremetalClusterResizeParams{
                    ProjectID:      gcore.Int(projectID),
                    RegionID:       gcore.Int(regionID),
                    InstancesCount: 4,
                })
            if err != nil {
                panic(err)
            }
            fmt.Printf("%+v\n", taskIDList.Tasks)
        }
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        curl -X POST \
          "https://api.gcore.com/cloud/v1/ai/clusters/gpu/${GCORE_CLOUD_PROJECT_ID}/${GCORE_CLOUD_REGION_ID}/{CLUSTER_ID}/resize" \
          -H "Authorization: APIKey ${GCORE_API_KEY}" \
          -H "Content-Type: application/json" \
          -d '{"instances_count": 4}'
        ```

        Response:

        ```json theme={null}
        { "tasks": ["task-uuid"] }
        ```
      </Tab>
    </Tabs>

    ## Control cluster power state

    <p>The `action` endpoint applies a power operation to all nodes in the cluster simultaneously.</p>

    | Action        | Description                          |
    | ------------- | ------------------------------------ |
    | `start`       | Power on all nodes                   |
    | `stop`        | Power off all nodes                  |
    | `soft_reboot` | Send ACPI shutdown signal and reboot |
    | `hard_reboot` | Force-reset all nodes immediately    |

    <Info>
      The Python and Go SDKs (v0.48.0) do not expose the cluster action endpoint directly. Use the curl tab below.
    </Info>

    <Tabs>
      <Tab title="curl">
        ```bash theme={null}
        # Replace "soft_reboot" with "start", "stop", or "hard_reboot"
        curl -X POST \
          "https://api.gcore.com/cloud/v3/gpu/baremetal/${GCORE_CLOUD_PROJECT_ID}/${GCORE_CLOUD_REGION_ID}/clusters/{CLUSTER_ID}/action" \
          -H "Authorization: APIKey ${GCORE_API_KEY}" \
          -H "Content-Type: application/json" \
          -d '{"action": "soft_reboot"}'
        ```

        Response:

        ```json theme={null}
        { "tasks": ["task-uuid"] }
        ```
      </Tab>
    </Tabs>

    ## Rebuild a cluster

    <p>Reinstalls the OS on all nodes in the cluster using the cluster's current image, SSH key, and user data. All local storage data is erased.</p>

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

        client = Gcore()

        task_id_list = client.cloud.gpu_baremetal.clusters.rebuild(cluster_id="{CLUSTER_ID}")
        print(task_id_list.tasks)
        ```
      </Tab>

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

        import (
            "context"
            "fmt"
            "os"
            "strconv"

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

        func main() {
            projectID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_PROJECT_ID"), 10, 64)
            regionID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_REGION_ID"), 10, 64)

            client := gcore.NewClient()
            ctx := context.Background()

            taskIDList, err := client.Cloud.GPUBaremetal.Clusters.Rebuild(ctx,
                "{CLUSTER_ID}",
                cloud.GPUBaremetalClusterRebuildParams{
                    ProjectID: gcore.Int(projectID),
                    RegionID:  gcore.Int(regionID),
                })
            if err != nil {
                panic(err)
            }
            fmt.Printf("%+v\n", taskIDList.Tasks)
        }
        ```
      </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/{CLUSTER_ID}/rebuild" \
          -H "Authorization: APIKey ${GCORE_API_KEY}"
        ```

        Response:

        ```json theme={null}
        { "tasks": ["task-uuid"] }
        ```
      </Tab>
    </Tabs>

    ## Rebuild a specific node

    <p>Reinstalls the OS on a single node without affecting other nodes in the cluster. All local storage on the node is erased. The rebuild uses the image, SSH key, and user data currently configured in the cluster's server settings — to use different values, first update the server settings via <code>PATCH /cloud/v3/gpu/baremetal/\{project\_id}/\{region\_id}/clusters/\{cluster\_id}/servers\_settings</code>, then trigger the rebuild.</p>

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

        client = Gcore()

        task_id_list = client.cloud.gpu_baremetal.clusters.servers.rebuild(
            server_id="{SERVER_ID}",
            cluster_id="{CLUSTER_ID}",
        )
        print(task_id_list.tasks)
        ```
      </Tab>

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

        import (
            "context"
            "fmt"
            "os"
            "strconv"

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

        func main() {
            projectID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_PROJECT_ID"), 10, 64)
            regionID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_REGION_ID"), 10, 64)

            client := gcore.NewClient()
            ctx := context.Background()

            taskIDList, err := client.Cloud.GPUBaremetal.Clusters.Servers.Rebuild(ctx,
                "{SERVER_ID}",
                cloud.GPUBaremetalClusterServerRebuildParams{
                    ClusterID: "{CLUSTER_ID}",
                    ProjectID: gcore.Int(projectID),
                    RegionID:  gcore.Int(regionID),
                })
            if err != nil {
                panic(err)
            }
            fmt.Printf("%+v\n", taskIDList.Tasks)
        }
        ```
      </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/{CLUSTER_ID}/servers/{SERVER_ID}/rebuild" \
          -H "Authorization: APIKey ${GCORE_API_KEY}"
        ```

        Response:

        ```json theme={null}
        { "tasks": ["task-uuid"] }
        ```
      </Tab>
    </Tabs>

    ## Replace a specific node

    <p>Delete a node and provision a new one with the same configuration. Use this to recover a node stuck in a failed state without changing the cluster setup.</p>

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

        client = Gcore()

        task_id_list = client.cloud.gpu_baremetal.clusters.servers.replace(
            server_id="{SERVER_ID}",
            cluster_id="{CLUSTER_ID}",
        )
        print(task_id_list.tasks)
        ```
      </Tab>

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

        import (
            "context"
            "fmt"
            "os"
            "strconv"

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

        func main() {
            projectID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_PROJECT_ID"), 10, 64)
            regionID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_REGION_ID"), 10, 64)

            client := gcore.NewClient()
            ctx := context.Background()

            taskIDList, err := client.Cloud.GPUBaremetal.Clusters.Servers.Replace(ctx,
                "{SERVER_ID}",
                cloud.GPUBaremetalClusterServerReplaceParams{
                    ClusterID: "{CLUSTER_ID}",
                    ProjectID: gcore.Int(projectID),
                    RegionID:  gcore.Int(regionID),
                })
            if err != nil {
                panic(err)
            }
            fmt.Printf("%+v\n", taskIDList.Tasks)
        }
        ```
      </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/{CLUSTER_ID}/servers/{SERVER_ID}/replace" \
          -H "Authorization: APIKey ${GCORE_API_KEY}"
        ```

        Response:

        ```json theme={null}
        { "tasks": ["task-uuid"] }
        ```
      </Tab>
    </Tabs>

    ## Apply settings to a node

    <p>Syncs a specific node that has outdated cluster configuration. The node must have `has_pending_changes=true`. To apply settings to all nodes at once, use `POST /cloud/v3/gpu/baremetal/{project_id}/{region_id}/clusters/{cluster_id}/apply_settings` without specifying a server ID.</p>

    <Tabs>
      <Tab title="curl">
        ```bash theme={null}
        # Apply to a specific node
        curl -X POST \
          "https://api.gcore.com/cloud/v3/gpu/baremetal/${GCORE_CLOUD_PROJECT_ID}/${GCORE_CLOUD_REGION_ID}/clusters/{CLUSTER_ID}/servers/{SERVER_ID}/apply_settings" \
          -H "Authorization: APIKey ${GCORE_API_KEY}"

        # Apply to all nodes in the cluster
        curl -X POST \
          "https://api.gcore.com/cloud/v3/gpu/baremetal/${GCORE_CLOUD_PROJECT_ID}/${GCORE_CLOUD_REGION_ID}/clusters/{CLUSTER_ID}/apply_settings" \
          -H "Authorization: APIKey ${GCORE_API_KEY}"
        ```

        Response:

        ```json theme={null}
        { "tasks": ["task-uuid"] }
        ```
      </Tab>
    </Tabs>

    ## Delete a specific node

    <p>Remove a single node by ID. If this is the last node in the cluster, the entire cluster is deleted — no confirmation prompt is shown through the API.</p>

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

        client = Gcore()

        task_id_list = client.cloud.gpu_baremetal.clusters.servers.delete(
            instance_id="{SERVER_ID}",
            cluster_id="{CLUSTER_ID}",
        )
        print(task_id_list.tasks)
        ```
      </Tab>

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

        import (
            "context"
            "fmt"
            "os"
            "strconv"

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

        func main() {
            projectID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_PROJECT_ID"), 10, 64)
            regionID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_REGION_ID"), 10, 64)

            client := gcore.NewClient()
            ctx := context.Background()

            taskIDList, err := client.Cloud.GPUBaremetal.Clusters.Servers.Delete(ctx,
                "{SERVER_ID}",
                cloud.GPUBaremetalClusterServerDeleteParams{
                    ClusterID: "{CLUSTER_ID}",
                    ProjectID: gcore.Int(projectID),
                    RegionID:  gcore.Int(regionID),
                })
            if err != nil {
                panic(err)
            }
            fmt.Printf("%+v\n", taskIDList.Tasks)
        }
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        curl -X DELETE \
          "https://api.gcore.com/cloud/v1/ai/clusters/gpu/${GCORE_CLOUD_PROJECT_ID}/${GCORE_CLOUD_REGION_ID}/{CLUSTER_ID}/node/{SERVER_ID}" \
          -H "Authorization: APIKey ${GCORE_API_KEY}"
        ```

        Response:

        ```json theme={null}
        { "tasks": ["task-uuid"] }
        ```
      </Tab>
    </Tabs>

    ## Delete a cluster

    <p>Delete the cluster and all its nodes. Local NVMe storage is permanently erased. File shares and object storage remain intact. Pass `all_floating_ips=true` to release any floating IPs, and `all_reserved_fixed_ips=true` to release reserved fixed IPs.</p>

    <Warning>
      Cluster deletion is irreversible. Data on local NVMe storage cannot be recovered.
    </Warning>

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

        client = Gcore()

        task_id_list = client.cloud.gpu_baremetal.clusters.delete(
            cluster_id="{CLUSTER_ID}",
            all_floating_ips=True,
            all_reserved_fixed_ips=True,
        )
        print(task_id_list.tasks)
        ```
      </Tab>

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

        import (
            "context"
            "fmt"
            "os"
            "strconv"

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

        func main() {
            projectID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_PROJECT_ID"), 10, 64)
            regionID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_REGION_ID"), 10, 64)

            client := gcore.NewClient()
            ctx := context.Background()

            taskIDList, err := client.Cloud.GPUBaremetal.Clusters.Delete(ctx,
                "{CLUSTER_ID}",
                cloud.GPUBaremetalClusterDeleteParams{
                    ProjectID:           gcore.Int(projectID),
                    RegionID:            gcore.Int(regionID),
                    AllFloatingIPs:      gcore.Bool(true),
                    AllReservedFixedIPs: gcore.Bool(true),
                })
            if err != nil {
                panic(err)
            }
            fmt.Printf("%+v\n", taskIDList.Tasks)
        }
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        curl -X DELETE \
          "https://api.gcore.com/cloud/v3/gpu/baremetal/${GCORE_CLOUD_PROJECT_ID}/${GCORE_CLOUD_REGION_ID}/clusters/{CLUSTER_ID}?all_floating_ips=true&all_reserved_fixed_ips=true" \
          -H "Authorization: APIKey ${GCORE_API_KEY}"
        ```

        Response:

        ```json theme={null}
        { "tasks": ["task-uuid"] }
        ```
      </Tab>
    </Tabs>
  </MethodSection>

  <MethodSection id="terraform" label="Terraform">
    <p>Manage the lifecycle of an existing Bare Metal GPU cluster using the [`gcore_cloud_gpu_baremetal_cluster`](https://registry.terraform.io/providers/G-Core/gcore/latest/docs/resources/cloud_gpu_baremetal_cluster) resource from the [Terraform provider](/developer-tools/terraform/overview) v2 — rename it, scale the node count, update tags, and delete it when no longer needed. To bring an existing cluster under Terraform management without recreating it, use `terraform import`.</p>

    <Info>
      An [API token](/account-settings/api-tokens), a [project ID](/api-reference/cloud/projects/list-projects), and a [region ID](/api-reference/cloud/regions/list-regions) are required.
    </Info>

    ## Import an existing cluster

    <p>To manage an existing cluster with Terraform without recreating it, declare the resource block with values that match the live cluster, then run `terraform import`.</p>

    ```hcl theme={null}
    resource "gcore_cloud_gpu_baremetal_cluster" "my_cluster" {
      project_id    = var.project_id
      region_id     = var.region_id
      name          = "my-cluster"              # must match the current cluster name
      flavor        = "bm3-ai-1xlarge-a100-80-8"
      image_id      = "d9400449-0ee8-4c60-adb9-fc545a80325c"
      servers_count = 2

      servers_settings = {
        interfaces   = [{ type = "external" }]
        credentials  = { ssh_key_name = "my-ssh-key" }
      }
    }
    ```

    ```bash theme={null}
    terraform import gcore_cloud_gpu_baremetal_cluster.my_cluster '<project_id>/<region_id>/<cluster_id>'
    ```

    ## Rename the cluster

    <p>Change the `name` field and run `terraform apply`. The rename completes in seconds without node restarts.</p>

    ```hcl theme={null}
    resource "gcore_cloud_gpu_baremetal_cluster" "my_cluster" {
      project_id    = var.project_id
      region_id     = var.region_id
      name          = "my-cluster-renamed"      # updated name
      flavor        = "bm3-ai-1xlarge-a100-80-8"
      image_id      = "d9400449-0ee8-4c60-adb9-fc545a80325c"
      servers_count = 2

      servers_settings = {
        interfaces   = [{ type = "external" }]
        credentials  = { ssh_key_name = "my-ssh-key" }
      }
    }
    ```

    ## Scale the cluster

    <p>Change `servers_count` and run `terraform apply`. Scaling up adds nodes; scaling down removes a random node. Clusters must always contain at least one node.</p>

    <Warning>
      Bare Metal H100 nodes may take 15–40 minutes to provision. Keep the terminal open or use `terraform apply` in a persistent session.
    </Warning>

    ```hcl theme={null}
    resource "gcore_cloud_gpu_baremetal_cluster" "my_cluster" {
      project_id    = var.project_id
      region_id     = var.region_id
      name          = "my-cluster"
      flavor        = "bm3-ai-1xlarge-a100-80-8"
      image_id      = "d9400449-0ee8-4c60-adb9-fc545a80325c"
      servers_count = 4                         # updated node count

      servers_settings = {
        interfaces   = [{ type = "external" }]
        credentials  = { ssh_key_name = "my-ssh-key" }
      }
    }
    ```

    ## Manage tags

    <p>Tags are key-value pairs attached to the cluster. Update the `tags` map and run `terraform apply` — changes take effect immediately.</p>

    ```hcl theme={null}
    resource "gcore_cloud_gpu_baremetal_cluster" "my_cluster" {
      project_id    = var.project_id
      region_id     = var.region_id
      name          = "my-cluster"
      flavor        = "bm3-ai-1xlarge-a100-80-8"
      image_id      = "d9400449-0ee8-4c60-adb9-fc545a80325c"
      servers_count = 2

      servers_settings = {
        interfaces   = [{ type = "external" }]
        credentials  = { ssh_key_name = "my-ssh-key" }
      }

      tags = {
        env  = "production"
        team = "ml"
      }
    }
    ```

    ## Delete the cluster

    <p>Remove the resource block from the configuration and run `terraform apply`, or run `terraform destroy` to delete all resources at once.</p>

    <Warning>
      Cluster deletion is irreversible. Data on local NVMe storage cannot be recovered. File shares and object storage remain intact.
    </Warning>

    ```bash theme={null}
    terraform destroy
    ```
  </MethodSection>
</MethodSwitch>
