> ## Documentation Index
> Fetch the complete documentation index at: https://gcore-doc-1256a.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Configuring file shares

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

export const MethodSwitch = ({children}) => {
  const tabs = React.Children.toArray(children).filter(c => c && c.props && c.props.id);
  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 (_) {}
  }, [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">
    Create NFS-based file shares and mount them to Linux virtual machines, bare metal servers, or GPU clusters.

    Two types of file shares are available:

    * **Standard** are general-purpose file shares using a Ceph-based backend.
    * **VAST** are high-performance type file shares, available in selected GPU-enabled regions.

    <Info>
      File share types are **mutually exclusive**, meaning each region has either Standard **or** VAST file shares, but not both.
    </Info>

    <Tip>
      The best practice is to create VAST shares **when** creating [GPU clusters](/edge-ai/ai-infrastructure/create-a-bare-metal-gpu-cluster) or **before** provisioning the corresponding [compute resources](/cloud/virtual-instances/types-of-virtual-machines) (such as VMs).
    </Tip>

    The creation flow for both types starts the same. Use the steps below and follow the instructions for the selected file share type.

    <Info>
      Please ensure that there are enough quotas to create the file share. To increase quotas, send us a request according to our guide. The quotas for File Shares are located on the Storage tab and include File Share count and File Share size (GiB).
    </Info>

    <Frame>
      <img src="https://mintcdn.com/gcore-doc-1256a/AL6TkMd7NPay-uo-/images/docs/cloud/file-shares/configure-file-shares/1.png?fit=max&auto=format&n=AL6TkMd7NPay-uo-&q=85&s=28faa3a5f320d0633c9e06bf28b43291" alt="Storage tab " width="2560" height="2260" data-path="images/docs/cloud/file-shares/configure-file-shares/1.png" />
    </Frame>

    ## Prepare the network for Bare Metal

    To mount the file share on a bare-metal server, the network must support bare-metal, and these servers require a dedicated VLAN.

    If needed, create a new network and enable the **Bare Metal Network** toggle during configuration.

    <Frame>
      <img src="https://mintcdn.com/gcore-doc-1256a/AL6TkMd7NPay-uo-/images/docs/cloud/file-shares/configure-file-shares/2-1.png?fit=max&auto=format&n=AL6TkMd7NPay-uo-&q=85&s=fe7208738ae32bd594ea0c7a4e0de1e5" alt="Bare Metal Network toggle" width="1812" height="974" data-path="images/docs/cloud/file-shares/configure-file-shares/2-1.png" />
    </Frame>

    <Info>
      Manually change the OS settings' existing Bare Metal network interface.
    </Info>

    ## Configure file shares for Linux VMs and Bare Metal

    This section describes creating and connecting a standard NFS-based file share using a private network. It can be used with Linux virtual machines or bare-metal servers.

    ### Step 1. Create a file share

    1. In the **Cloud** menu, click **Storage**, select **File Shares**, and click **Create File Share** on the right.

    <Frame>
      <img src="https://mintcdn.com/gcore-doc-1256a/AL6TkMd7NPay-uo-/images/docs/cloud/file-shares/configure-file-shares/3-1.png?fit=max&auto=format&n=AL6TkMd7NPay-uo-&q=85&s=af16d6980b90a5402609f30236765a5b" alt="File Shares" width="4744" height="2288" data-path="images/docs/cloud/file-shares/configure-file-shares/3-1.png" />
    </Frame>

    2. In the **Basic settings** panel, enter *File Share name*, specify *Size*, and select **Standard** as the *File Share type*.

           <img src="https://mintlify.s3.us-west-1.amazonaws.com/gcore-doc-1256a/images/file-shares-standard-4.png" alt="File Shares Standard 4 Pn" />

    3. In the **Network settings** panel, select the private *Network* and *Subnetwork* to use for the file share.

    4. In the **Access** panel, click **Add rule** and specify the IP addresses of the resources that should have access to the file share, and their access modes.

    5. Set **Additional options**, if required.

    ### Step 2. Set up NFS client support

    Connect to the server via the [Gcore Customer Portal](/cloud/virtual-instances/connect/connect-to-your-instance-via-control-panel) or SSH and set up NFS client support.

    For Ubuntu and Debian:

    ```bash theme={null}
    sudo apt -y install nfs-common
    ```

    For CentOS:

    ```bash theme={null}
    sudo yum install nfs-utils
    ```

    ### Step 3. Mount the file share

    1. Use an existing directory for mounting the share, or create a new one, for example:

       ```bash theme={null}
       sudo mkdir -p /mount/path
       ```

    2. Copy the mount command from the file share **Overview** tab.

    <Frame>
      <img src="https://mintcdn.com/gcore-doc-1256a/AL6TkMd7NPay-uo-/images/docs/cloud/file-shares/configure-file-shares/4-1.jpg?fit=max&auto=format&n=AL6TkMd7NPay-uo-&q=85&s=121f48ef8ddbe5ca0cb9a40ec8b24dc4" alt="Mount the file share" width="5120" height="2780" data-path="images/docs/cloud/file-shares/configure-file-shares/4-1.jpg" />
    </Frame>

    Mount the file share:

    ```bash theme={null}
    mount 0.0.0.0:/shares/share-d54589b8-132f-4de4-ae99-af5c6cdfdb9c /mount/path
    ```

    Replace `/mount/path` with the absolute local directory path where the file share should be mounted.

    ## VAST file shares

    <Info>
      VAST-based file shares are only available in regions with GPU support and use a high-performance backend designed for intensive data workloads.
    </Info>

    <Tip>
      The best practice is to create VAST shares **when** creating [GPU clusters](/edge-ai/ai-infrastructure/create-a-bare-metal-gpu-cluster) or **before** provisioning the corresponding [compute resources](/cloud/virtual-instances/types-of-virtual-machines) (such as VMs).
    </Tip>

    ### Step 1. Create a VAST share

    1. In the **Cloud** menu, click **Storage**, select **File Shares**, and click **Create File Share** on the right.
    2. In the **Basic settings** panel, enter *File Share name*, specify *Size*, and select **VAST** as the *File Share type*.
    3. Set **Additional options**, if required.

           <img src="https://mintlify.s3.us-west-1.amazonaws.com/gcore-doc-1256a/images/file-share-vast.png" alt="File Share Vast Pn" />

    When VAST share type is selected, controls in **Network settings** and **Access** panels are disabled, and the network is assigned automatically.

    The access rules cannot be configured manually - the VAST share is always available in read/write mode within its assigned network only. This network is not visible in the general **Network** tab. It is only available when attaching interfaces to a resource (VM, Bare Metal, or GPU cluster).

    VAST file shares always use read/write access; access rules are not supported.

    ### Step 2. Add VAST network interface to a compute resource

    Once the VAST file share is created, it is best to add the VAST network interface while provisioning the corresponding GPU cluster or compute resource.

    **Adding VAST interface while creating a compute resource**

    While provisioning a compute resource:

    1. Scroll down to the **Network settings** panel.
    2. Click **Add interface**.
    3. Click the interface to configure, and select the **VAST network**.
    4. Continue with provisioning the compute resource.

    The VAST network only becomes available after the file share has been created. It is a third, dedicated network, separate and distinct from public and private networks.

    <img src="https://mintlify.s3.us-west-1.amazonaws.com/gcore-doc-1256a/images/file-share-details.png" alt="File Share Details Pn" />

    **Adding VAST interface to an existing compute resource**

    While the VAST interface can be attached to an already-provisioned GPU cluster or compute resource, this requires additional manual network configuration and is not the standard workflow.

    <Tip>
      The best practice is to create VAST shares **when** creating [GPU clusters](/edge-ai/ai-infrastructure/create-a-bare-metal-gpu-cluster) or **before** provisioning the corresponding [compute resources](/cloud/virtual-instances/types-of-virtual-machines) (such as VMs).
    </Tip>

    **Attach VAST network interface**

    1. Go to server **Resource** settings ([VM](/cloud/virtual-instances/create-an-instance), [Bare Metal](/cloud/bare-metal-servers/create-a-bare-metal-server), or [GPU cluster](/edge-ai/ai-infrastructure/create-a-bare-metal-gpu-cluster)).
    2. Select the **Networking** tab and click **Add interface**.
    3. Click the **Network** drop-down and select the **VAST network**, then click **Add**.
    4. Once the interface is added, **note the following details** for use in subsequent steps:
       * **IP** address (such as `198.51.100.25`)
       * **MAC** address (such as `fa:16:3e:12:34:56`)
       * **CIDR** range (such as `198.51.102.0/22`)

    **Configure attached VAST network interface**

    <Info>
      This configuration is required only when adding an interface to an existing, already provisioned resource; for interfaces added during resource creation and provisioning, this configuration is performed automatically.
    </Info>

    **Automatic configuration with DHCP (recommended)**

    <Info>
      DHCP is now enabled on VAST subnets. This automatically provides IP address, CIDR, gateway, and route information when attaching a VAST subnet to a compute resource.
    </Info>

    When attaching a VAST subnet to an existing compute resource, use DHCP to automatically configure the network interface. This is the recommended method as it eliminates the need for manual network configuration.

    **DHCP configuration for VMs and GPU clusters**

    Run the DHCP client on the VAST interface. Replace `enp8s0` with the actual interface name:

    ```bash theme={null}
    sudo dhclient enp8s0
    ```

    **DHCP configuration for Bare Metal servers**

    <AccordionGroup>
      <Accordion title="Bluefield DPU">
        Run the DHCP client on the VAST interface. Replace `ens10f0v0` with the actual interface name:

        ```bash theme={null}
        sudo dhclient ens10f0v0
        ```
      </Accordion>

      <Accordion title="Standard (bond interface)">
        Create the VLAN interface and run the DHCP client. Replace `bond0.2998` with the actual VLAN interface name and VLAN ID:

        ```bash theme={null}
        ip link add link bond0 name bond0.2998 type vlan id 2998
        dhcpcd bond0.2998
        ```
      </Accordion>
    </AccordionGroup>

    The DHCP client automatically configures the IP address, subnet mask, gateway, and routing information, following the same [network configuration](/cloud/networking/ip-address/create-and-configure-a-reserved-ip-address) approach used across Gcore Cloud.

    **Manual configuration (alternative method)**

    If you prefer manual configuration or need custom network settings, you can configure the network interface manually.

    Connect to the server via the [Gcore Customer Portal](/cloud/virtual-instances/connect/connect-to-your-instance-via-control-panel) or SSH and configure the attached VAST network interface.

    1. Use `ip addr` to list all available interfaces.
    2. Identify the VAST interface using the MAC address from the previous step.
    3. Note the **interface name** (such as `enp8s0` or `enp4s0`) for use in the following steps.
    4. Configure the interface as described below for the relevant instance type.

    **Configuring VAST interface for VMs and GPU clusters**

    Replace `198.51.100.25` with the IP address from Step 2. Replace `enp8s0` with the interface name from above, if different.

    Set interface MTU:

    ```bash theme={null}
    sudo ip link set enp8s0 mtu 9000
    ```

    Activate the interface:

    ```bash theme={null}
    sudo ip link set enp8s0 up
    ```

    Set interface CIDR:

    ```bash theme={null}
    sudo ip addr add 198.51.100.25/22 dev enp8s0
    ```

    Add static route to the VAST network. Replace `198.51.100.1` with an address formed by the first three octets from the CIDR range in Step 2, keeping `1` as the last octet for the gateway IP.

    ```bash theme={null}
    sudo ip route add 172.19.252.0/22 via 198.51.100.1 dev enp8s0
    ```

    **Configuring VAST interface for Bare Metal servers**

    Bare Metal servers require different configuration depending on the network hardware.

    <AccordionGroup>
      <Accordion title="Bluefield DPU">
        In the commands below, replace `198.51.100.25` with the IP address from Step 2, and replace `ens10f0v0` with the interface name identified above.

        Set interface MTU:

        ```bash theme={null}
        sudo ip link set ens10f0v0 mtu 9000
        ```

        Activate the interface:

        ```bash theme={null}
        sudo ip link set ens10f0v0 up
        ```

        Set interface CIDR:

        ```bash theme={null}
        sudo ip addr add 198.51.100.25/22 dev ens10f0v0
        ```

        Add static route to the VAST network. Replace `198.51.100.1` with an address formed by the first three octets from the CIDR range in Step 2, keeping `1` as the last octet for the gateway IP.

        ```bash theme={null}
        sudo ip route add 172.19.252.0/22 via 198.51.100.1 dev ens10f0v0
        ```
      </Accordion>

      <Accordion title="Arista (Trunks)">
        For Bare Metal servers with Arista switches (Trunks), create a VLAN interface on the bond. A bond (link aggregation) combines multiple physical network interfaces into a single logical interface, providing higher throughput and redundancy.

        In the commands below, replace `100` with the VLAN ID shown in the **Networking** tab of the server details page, and replace `198.51.100.25` with the IP address from Step 2.

        Create VLAN interface on a bond:

        ```bash theme={null}
        sudo ip link add link bond0 name bond0.100 type vlan id 100
        ```

        Activate the interface:

        ```bash theme={null}
        sudo ip link set bond0.100 up
        ```

        Set interface CIDR:

        ```bash theme={null}
        sudo ip addr add 198.51.100.25/22 dev bond0.100
        ```

        Add static route to the VAST network. Replace `198.51.100.1` with an address formed by the first three octets from the CIDR range in Step 2, keeping `1` as the last octet for the gateway IP.

        ```bash theme={null}
        sudo ip route add 172.19.252.0/22 via 198.51.100.1 dev bond0.100
        ```
      </Accordion>
    </AccordionGroup>

    ### Step 3. Set up VAST NFS client support

    <Info>
      This step is **always required** for VAST file shares, regardless of whether they are added during or after resource provisioning.
    </Info>

    Connect to the server via the [Gcore Customer Portal](/cloud/virtual-instances/connect/connect-to-your-instance-via-control-panel) or SSH and set up VAST NFS client support.

    1. Install NFS client tools:

       ```bash theme={null}
       sudo apt-get update && sudo apt-get install nfs-common -y
       ```

    2. Install build tools and headers for kernel modules:

       ```bash theme={null}
       sudo apt install dkms debhelper dh-dkms build-essential linux-headers-$(uname -r) -y
       ```

    3. Install VAST NFS package:

       ```bash theme={null}
       curl -sSf https://vast-nfs.s3.amazonaws.com/download.sh | bash -s --
       ```

    ### Step 4. Mount the file share

    Use an existing directory for mounting the share, or create a new one, for example:

    ```bash theme={null}
    sudo mkdir -p /mount/path
    ```

    Mount the VAST file share:

    * Replace `ndp1-2-vast.cloud.gc.onl:/manila/manila-01234567-89ab-cdef-0123-456789abcdef` with the connection point from the VAST file share overview tab.
    * Replace `/mount/path` with the absolute local directory path where the file share should be mounted.

    ```bash theme={null}
    sudo mount -o vers=3,nconnect=56,remoteports=dns,spread_reads,spread_writes,noextend ndp1-2-vast.cloud.gc.onl:/manila/manila-01234567-89ab-cdef-0123-456789abcdef /mount/path
    ```

    The contents of the VAST file share are now accessible in the specified directory.

    <Info>
      Always use NFS version 3 (vers=3) when mounting VAST file shares. If the system does not support the `nconnect` option, install the [VAST Enhanced NFS Client](https://vastnfs.vastdata.com/docs/4.0/download.html).
    </Info>

    <img src="https://mintlify.s3.us-west-1.amazonaws.com/gcore-doc-1256a/images/file-share-mount.png" alt="File Share Mount Pn" />

    ## Resizing file shares

    <Info>
      * **VAST** shares can be resized directly, without being unmounted.
      * **Standard** shares must first be unmounted before they can be resized, for example:

        ```bash theme={null}
        umount -lf /mount/path
        ```

        Once resized, file shares can be remounted as described above for each share type.
    </Info>

    ### Resize file share

    This process is the same for both Standard and VAST-based file shares:

    1. In the **Cloud** menu, go to the **Storage** tab, select **File Shares**, and click the file share to be resized.
    2. In the **Overview** tab, click **Resize** and enter the new share size:

    <Frame>
      <img src="https://mintcdn.com/gcore-doc-1256a/AL6TkMd7NPay-uo-/images/docs/cloud/file-shares/configure-file-shares/5-1.png?fit=max&auto=format&n=AL6TkMd7NPay-uo-&q=85&s=cd88bb6b8550c816584d403ef5117e47" alt="Overview tab" width="3108" height="1420" data-path="images/docs/cloud/file-shares/configure-file-shares/5-1.png" />
    </Frame>
  </MethodSection>

  <MethodSection id="api" label="REST API">
    NFS file shares provide shared persistent storage accessible from any VM on the same private subnet. The steps below create a network, subnet, and NFS file share, then retrieve the connection point used to mount the share.

    <p>Before picking a region, check that file shares are available there — look for `has_sfs: true` in the regions response:</p>

    ```bash theme={null}
    curl "https://api.gcore.com/cloud/v1/regions" \
      -H "Authorization: APIKey $GCORE_API_KEY"
    ```

    <Info>
      A permanent [API token](/account-settings/api-tokens) is required, along with a [project ID](https://api.gcore.com/docs/cloud#tag/Projects/operation/GetProjectList.get) and [region ID](https://api.gcore.com/docs/cloud#tag/Regions/operation/GetRegionList.get).
    </Info>

    Open a bash terminal and set these as environment variables before running the examples:

    ```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}"
    ```

    ## Quickstart

    The scripts below create a private network, subnet, and 5 GiB NFS file share, then print the connection point for mounting.

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

        client = Gcore()

        # Step 1. Create a private network
        network = client.cloud.networks.create_and_poll(name="my-network", create_router=True)
        print(f"Network ID: {network.id}")

        # Step 2. Create a subnet
        subnet = client.cloud.networks.subnets.create_and_poll(
            network_id=network.id,
            name="my-subnet",
            cidr="192.168.100.0/24",
        )
        print(f"Subnet ID: {subnet.id}")

        # Step 3. Create the file share
        task_id_list = client.cloud.file_shares.create(
            name="my-share",
            protocol="NFS",
            size=5,
            network={"network_id": network.id, "subnet_id": subnet.id},
            access=[{"access_mode": "rw", "ip_address": "192.168.100.0/24"}],
        )
        task = client.cloud.tasks.poll(task_id_list.tasks[0])
        share_id = task.created_resources.file_shares[0]
        print(f"File share ID: {share_id}")

        # Step 4. Retrieve the connection point
        share = client.cloud.file_shares.get(file_share_id=share_id)
        print(f"Connection point: {share.connection_point}")
        print(f"Mount with: sudo mount -t nfs {share.connection_point} /mnt/share")
        ```
      </Tab>

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

        import (
            "context"
            "fmt"
            "log"

            gcore "github.com/G-Core/gcore-go"
            "github.com/G-Core/gcore-go/cloud"
            "github.com/G-Core/gcore-go/packages/param"
            "github.com/G-Core/gcore-go/shared/constant"
        )

        func main() {
            client := gcore.NewClient()
            ctx := context.Background()

            // Step 1. Create a private network
            network, err := client.Cloud.Networks.NewAndPoll(ctx, cloud.NetworkNewParams{
                Name:         "my-network",
                CreateRouter: param.NewOpt(true),
            })
            if err != nil {
                log.Fatal(err)
            }
            fmt.Printf("Network ID: %s\n", network.ID)

            // Step 2. Create a subnet
            subnet, err := client.Cloud.Networks.Subnets.NewAndPoll(ctx, cloud.NetworkSubnetNewParams{
                Name:      "my-subnet",
                Cidr:      "192.168.100.0/24",
                NetworkID: network.ID,
            })
            if err != nil {
                log.Fatal(err)
            }
            fmt.Printf("Subnet ID: %s\n", subnet.ID)

            // Step 3. Create the file share
            share, err := client.Cloud.FileShares.NewAndPoll(ctx, cloud.FileShareNewParams{
                OfCreateStandardFileShareSerializer: &cloud.FileShareNewParamsBodyCreateStandardFileShareSerializer{
                    Name: "my-share",
                    Network: cloud.FileShareNewParamsBodyCreateStandardFileShareSerializerNetwork{
                        NetworkID: network.ID,
                        SubnetID:  param.NewOpt(subnet.ID),
                    },
                    Size:     5,
                    Protocol: constant.ValueOf[constant.Nfs](),
                    Access: []cloud.FileShareNewParamsBodyCreateStandardFileShareSerializerAccess{
                        {AccessMode: "rw", IPAddress: "192.168.100.0/24"},
                    },
                },
            })
            if err != nil {
                log.Fatal(err)
            }
            fmt.Printf("File share ID: %s\n", share.ID)

            // Step 4. Retrieve the connection point
            details, err := client.Cloud.FileShares.Get(ctx, share.ID, cloud.FileShareGetParams{})
            if err != nil {
                log.Fatal(err)
            }
            fmt.Printf("Connection point: %s\n", details.ConnectionPoint)
            fmt.Printf("Mount with: sudo mount -t nfs %s /mnt/share\n", details.ConnectionPoint)
        }
        ```
      </Tab>
    </Tabs>

    ## Step-by-step

    <p>Each step below explains what the call does, which parameters matter, and what the response looks like. Use this section to understand the flow or to debug a specific step.</p>

    <Accordion title="Show all steps">
      ### Step 1. Create a private network

      A private network isolates traffic between the file share and the VMs that mount it.

      | Parameter       | Required | Description                                                                   |
      | --------------- | -------- | ----------------------------------------------------------------------------- |
      | `name`          | Yes      | Network name                                                                  |
      | `create_router` | No       | Set to `true` to attach a virtual router - required when adding subnets later |

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

          client = Gcore()
          network = client.cloud.networks.create_and_poll(name="my-network", create_router=True)
          print(network.id)  # save as NETWORK_ID
          ```
        </Tab>

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

          import (
              "context"
              "fmt"
              "log"

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

          func main() {
              client := gcore.NewClient()
              ctx := context.Background()

              network, err := client.Cloud.Networks.NewAndPoll(ctx, cloud.NetworkNewParams{
                  Name:         "my-network",
                  CreateRouter: param.NewOpt(true),
              })
              if err != nil {
                  log.Fatal(err)
              }
              fmt.Println(network.ID) // save as NETWORK_ID
          }
          ```
        </Tab>

        <Tab title="curl">
          ```bash theme={null}
          curl -s -X POST "https://api.gcore.com/cloud/v1/networks/$GCORE_CLOUD_PROJECT_ID/$GCORE_CLOUD_REGION_ID" \
            -H "Authorization: APIKey $GCORE_API_KEY" \
            -H "Content-Type: application/json" \
            -d '{
              "name": "my-network",
              "create_router": true
            }'
          ```

          Response:

          ```json theme={null}
          {
            "tasks": ["668e75b8-..."]
          }
          ```

          Poll <code>GET /cloud/v1/tasks/{task_id}</code> every 5 seconds until `state` is `FINISHED`, then read the network ID:

          ```json theme={null}
          {
            "state": "FINISHED",
            "created_resources": {
              "networks": ["6880a081-..."]
            }
          }
          ```
        </Tab>
      </Tabs>

      The full parameter list is in the [networks](https://api.gcore.com/docs/cloud#tag/Networks/operation/NetworkCreateV1.post) API reference.

      ### Step 2. Create a subnet

      A subnet assigns the address range that the file share and VMs will use. The file share and any VM that mounts it must share the same subnet.

      | Parameter     | Required | Description                                                                 |
      | ------------- | -------- | --------------------------------------------------------------------------- |
      | `network_id`  | Yes      | ID of the network from Step 1                                               |
      | `cidr`        | Yes      | IPv4 CIDR block for the subnet                                              |
      | `enable_dhcp` | No       | Enables automatic IP assignment for VMs on this subnet - defaults to `true` |

      <Tabs>
        <Tab title="Python SDK">
          ```python theme={null}
          # client initialized in Step 1
          subnet = client.cloud.networks.subnets.create_and_poll(
              network_id="{NETWORK_ID}",
              name="my-subnet",
              cidr="192.168.100.0/24",
          )
          print(subnet.id)  # save as SUBNET_ID
          ```
        </Tab>

        <Tab title="Go SDK">
          ```go theme={null}
          // client and ctx initialized in Step 1
          subnet, err := client.Cloud.Networks.Subnets.NewAndPoll(ctx, cloud.NetworkSubnetNewParams{
              Name:      "my-subnet",
              Cidr:      "192.168.100.0/24",
              NetworkID: "{NETWORK_ID}",
          })
          if err != nil {
              log.Fatal(err)
          }
          fmt.Println(subnet.ID) // save as SUBNET_ID
          ```
        </Tab>

        <Tab title="curl">
          ```bash theme={null}
          curl -s -X POST "https://api.gcore.com/cloud/v1/subnets/$GCORE_CLOUD_PROJECT_ID/$GCORE_CLOUD_REGION_ID" \
            -H "Authorization: APIKey $GCORE_API_KEY" \
            -H "Content-Type: application/json" \
            -d '{
              "name": "my-subnet",
              "cidr": "192.168.100.0/24",
              "network_id": "{NETWORK_ID}",
              "enable_dhcp": true
            }'
          ```

          Response:

          ```json theme={null}
          {
            "tasks": ["921b0e4d-..."]
          }
          ```

          Poll the task every 5 seconds until `FINISHED`, then save the subnet ID:

          ```json theme={null}
          {
            "state": "FINISHED",
            "created_resources": {
              "subnets": ["a87cedcc-..."]
            }
          }
          ```
        </Tab>
      </Tabs>

      The full parameter list is in the [subnets](https://api.gcore.com/docs/cloud#tag/Subnets/operation/SubnetCreateV1.post) API reference.

      ### Step 3. Create the file share

      A single create call provisions the NFS share on the private network and sets the initial access rules. File share creation typically takes 60-90 seconds.

      | Parameter              | Required | Description                                                |
      | ---------------------- | -------- | ---------------------------------------------------------- |
      | `name`                 | Yes      | Share name                                                 |
      | `protocol`             | Yes      | Must be `"NFS"` for Standard shares                        |
      | `size`                 | Yes      | Share size in GiB - minimum 1                              |
      | `network.network_id`   | Yes      | ID of the private network from Step 1                      |
      | `network.subnet_id`    | No       | Subnet ID - if omitted, a subnet is selected automatically |
      | `access[].access_mode` | Yes      | `"rw"` (read-write) or `"ro"` (read-only)                  |
      | `access[].ip_address`  | Yes      | Source IP address or CIDR that may mount the share         |

      <Tabs>
        <Tab title="Python SDK">
          ```python theme={null}
          # client initialized in Step 1
          task_id_list = client.cloud.file_shares.create(
              name="my-share",
              protocol="NFS",
              size=5,
              network={"network_id": "{NETWORK_ID}", "subnet_id": "{SUBNET_ID}"},
              access=[{"access_mode": "rw", "ip_address": "192.168.100.0/24"}],
          )
          task = client.cloud.tasks.poll(task_id_list.tasks[0])
          share_id = task.created_resources.file_shares[0]
          print(share_id)  # save as FILE_SHARE_ID
          ```
        </Tab>

        <Tab title="Go SDK">
          ```go theme={null}
          // client and ctx initialized in Step 1
          // param and constant are from github.com/G-Core/gcore-go/packages/param and shared/constant
          share, err := client.Cloud.FileShares.NewAndPoll(ctx, cloud.FileShareNewParams{
              OfCreateStandardFileShareSerializer: &cloud.FileShareNewParamsBodyCreateStandardFileShareSerializer{
                  Name: "my-share",
                  Network: cloud.FileShareNewParamsBodyCreateStandardFileShareSerializerNetwork{
                      NetworkID: "{NETWORK_ID}",
                      SubnetID:  param.NewOpt("{SUBNET_ID}"),
                  },
                  Size:     5,
                  Protocol: constant.ValueOf[constant.Nfs](),
                  Access: []cloud.FileShareNewParamsBodyCreateStandardFileShareSerializerAccess{
                      {AccessMode: "rw", IPAddress: "192.168.100.0/24"},
                  },
              },
          })
          if err != nil {
              log.Fatal(err)
          }
          fmt.Println(share.ID) // save as FILE_SHARE_ID
          ```
        </Tab>

        <Tab title="curl">
          ```bash theme={null}
          curl -s -X POST "https://api.gcore.com/cloud/v1/file_shares/$GCORE_CLOUD_PROJECT_ID/$GCORE_CLOUD_REGION_ID" \
            -H "Authorization: APIKey $GCORE_API_KEY" \
            -H "Content-Type: application/json" \
            -d '{
              "name": "my-share",
              "protocol": "NFS",
              "size": 5,
              "network": {
                "network_id": "{NETWORK_ID}",
                "subnet_id": "{SUBNET_ID}"
              },
              "access": [
                {"access_mode": "rw", "ip_address": "192.168.100.0/24"}
              ]
            }'
          ```

          Response:

          ```json theme={null}
          {
            "tasks": ["390170eb-..."]
          }
          ```

          Poll the task every 5 seconds until `FINISHED` (typically 60-90 seconds):

          ```json theme={null}
          {
            "state": "FINISHED",
            "created_resources": {
              "file_shares": ["6b3b713e-..."]
            }
          }
          ```
        </Tab>
      </Tabs>

      The full parameter list is in the [file shares](https://api.gcore.com/docs/cloud#tag/File-Shares/operation/FileShareCreate.post) API reference.

      ### Step 4. Retrieve the connection point

      The connection point is the NFS server address and share path used in the mount command. It becomes available once the share reaches `available` status.

      <Tabs>
        <Tab title="Python SDK">
          ```python theme={null}
          # client initialized in Step 1
          share = client.cloud.file_shares.get(file_share_id="{FILE_SHARE_ID}")
          print(share.connection_point)  # save as CONNECTION_POINT
          ```
        </Tab>

        <Tab title="Go SDK">
          ```go theme={null}
          // client and ctx initialized in Step 1
          details, err := client.Cloud.FileShares.Get(ctx, "{FILE_SHARE_ID}", cloud.FileShareGetParams{})
          if err != nil {
              log.Fatal(err)
          }
          fmt.Println(details.ConnectionPoint) // save as CONNECTION_POINT
          ```
        </Tab>

        <Tab title="curl">
          ```bash theme={null}
          curl -s "https://api.gcore.com/cloud/v1/file_shares/$GCORE_CLOUD_PROJECT_ID/$GCORE_CLOUD_REGION_ID/{FILE_SHARE_ID}" \
            -H "Authorization: APIKey $GCORE_API_KEY"
          ```

          Response:

          ```json theme={null}
          {
            "id": "6b3b713e-...",
            "status": "available",
            "connection_point": "192.168.100.58:/shares/share-416d581b-...",
            "size": 5,
            "protocol": "NFS",
            "network_id": "6880a081-...",
            "subnet_id": "a87cedcc-..."
          }
          ```
        </Tab>
      </Tabs>

      The `connection_point` value follows the format `{NFS_SERVER_IP}:/shares/{SHARE_PATH}`. Copy the full string - it is used verbatim in the mount command.

      ### Step 5. Create a VM on the same network

      The VM must join the private subnet to reach the file share NFS server IP. A [floating IP](/cloud/networking/ip-address/create-and-configure-a-floating-ip-address) is added so the instance is accessible via SSH from outside the private network.

      | Parameter                         | Required | Description                                                                                                               |
      | --------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------- |
      | `flavor`                          | Yes      | Instance [flavor](https://api.gcore.com/docs/cloud#tag/Flavors/operation/FlavorListV1.get) name - IDs are region-specific |
      | `interfaces[].type`               | Yes      | Use `"subnet"` to place the instance on the private subnet                                                                |
      | `interfaces[].network_id`         | Yes      | Must match the network used for the file share                                                                            |
      | `interfaces[].subnet_id`          | Yes      | Must match the subnet used for the file share                                                                             |
      | `interfaces[].floating_ip.source` | No       | Set to `"new"` to allocate and attach a floating IP automatically                                                         |
      | `keypair_name`                    | Yes      | Name of an SSH key pair registered in the project                                                                         |

      <Tabs>
        <Tab title="Python SDK">
          ```python theme={null}
          # client initialized in Step 1
          task_id_list = client.cloud.instances.create(
              flavor="{FLAVOR_NAME}",
              name="{INSTANCE_NAME}",
              interfaces=[
                  {
                      "type": "subnet",
                      "network_id": "{NETWORK_ID}",
                      "subnet_id": "{SUBNET_ID}",
                      "floating_ip": {"source": "new"},
                  }
              ],
              volumes=[
                  {
                      "source": "image",
                      "image_id": "{IMAGE_ID}",
                      "size": 20,
                      "boot_index": 0,
                      "delete_on_termination": True,
                  }
              ],
              keypair_name="{KEY_NAME}",
          )
          task = client.cloud.tasks.poll(task_id_list.tasks[0])
          instance_id = task.created_resources.instances[0]
          print(instance_id)  # save as INSTANCE_ID
          ```
        </Tab>

        <Tab title="Go SDK">
          ```go theme={null}
          // client and ctx initialized in Step 1
          // gcore is the root package: github.com/G-Core/gcore-go
          instanceResult, err := client.Cloud.Instances.NewAndPoll(ctx, cloud.InstanceNewParams{
              Name:   gcore.String("{INSTANCE_NAME}"),
              Flavor: "{FLAVOR_NAME}",
              Interfaces: []cloud.InstanceNewParamsInterfaceUnion{
                  {
                      OfSubnet: &cloud.InstanceNewParamsInterfaceSubnet{
                          NetworkID: "{NETWORK_ID}",
                          SubnetID:  "{SUBNET_ID}",
                          FloatingIP: cloud.InstanceNewParamsInterfaceSubnetFloatingIPUnion{
                              OfNew: &cloud.InstanceNewParamsInterfaceSubnetFloatingIPNew{},
                          },
                      },
                  },
              },
              Volumes: []cloud.InstanceNewParamsVolumeUnion{
                  {
                      OfImage: &cloud.InstanceNewParamsVolumeImage{
                          ImageID:             "{IMAGE_ID}",
                          BootIndex:           gcore.Int(0),
                          Size:                gcore.Int(20),
                          DeleteOnTermination: gcore.Bool(true),
                      },
                  },
              },
              SSHKeyName: gcore.String("{KEY_NAME}"),
          })
          if err != nil {
              log.Fatal(err)
          }
          fmt.Printf("Instance ID: %s\n", instanceResult.ID)
          ```
        </Tab>

        <Tab title="curl">
          ```bash theme={null}
          curl -s -X POST "https://api.gcore.com/cloud/v2/instances/$GCORE_CLOUD_PROJECT_ID/$GCORE_CLOUD_REGION_ID" \
            -H "Authorization: APIKey $GCORE_API_KEY" \
            -H "Content-Type: application/json" \
            -d '{
              "flavor": "{FLAVOR_NAME}",
              "name": "{INSTANCE_NAME}",
              "interfaces": [
                {
                  "type": "subnet",
                  "network_id": "{NETWORK_ID}",
                  "subnet_id": "{SUBNET_ID}",
                  "floating_ip": {"source": "new"}
                }
              ],
              "volumes": [
                {
                  "source": "image",
                  "image_id": "{IMAGE_ID}",
                  "size": 20,
                  "boot_index": 0,
                  "delete_on_termination": true
                }
              ],
              "keypair_name": "{KEY_NAME}"
            }'
          ```

          Response:

          ```json theme={null}
          {
            "tasks": ["f0b4df4f-..."]
          }
          ```

          Poll the task every 5 seconds until `FINISHED`, then read the instance ID from `created_resources.instances[0]`. Retrieve the floating IP:

          ```bash theme={null}
          curl -s "https://api.gcore.com/cloud/v1/instances/$GCORE_CLOUD_PROJECT_ID/$GCORE_CLOUD_REGION_ID/{INSTANCE_ID}" \
            -H "Authorization: APIKey $GCORE_API_KEY" \
            | grep -o '"addr":"[^"]*"'
          ```
        </Tab>
      </Tabs>

      Image selection, flavor lookup, and SSH key registration are covered in the [VM guide](/cloud/virtual-instances/create-an-instance).

      ### Step 6. Mount the file share

      Connect to the VM via SSH and mount the NFS share. The `nfs-common` package provides the NFS client utilities required to mount Standard file shares.

      Connect to the VM:

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

      Install the NFS client:

      For Ubuntu or Debian:

      ```bash theme={null}
      sudo apt-get install -y nfs-common
      ```

      For CentOS or Rocky Linux:

      ```bash theme={null}
      sudo yum install -y nfs-utils
      ```

      Create a mount point and mount the share:

      ```bash theme={null}
      sudo mkdir -p /mnt/share
      sudo mount -t nfs {CONNECTION_POINT} /mnt/share
      ```

      Replace `{CONNECTION_POINT}` with the full value from Step 4, for example:

      ```bash theme={null}
      sudo mount -t nfs 192.168.100.58:/shares/share-416d581b-1784-454c-adf8-d2dc75886625 /mnt/share
      ```

      Verify the share is mounted and accessible:

      ```bash theme={null}
      df -h /mnt/share
      echo "test" | sudo tee /mnt/share/test.txt && cat /mnt/share/test.txt
      ```

      ```
      Filesystem                                                         Size  Used Avail Use% Mounted on
      192.168.100.58:/shares/share-416d581b-1784-454c-adf8-d2dc75886625  4.9G     0  4.6G   0% /mnt/share
      test
      ```

      To make the mount persistent across reboots, add it to `/etc/fstab`:

      ```bash theme={null}
      echo "{CONNECTION_POINT} /mnt/share nfs defaults 0 0" | sudo tee -a /etc/fstab
      ```
    </Accordion>

    ## Resize the file share

    Standard file shares must be unmounted before resizing. The new size must be larger than the current size - downsizing is not supported.

    Unmount the share first:

    ```bash theme={null}
    sudo umount /mnt/share
    ```

    Then extend the share:

    <Tabs>
      <Tab title="Python SDK">
        ```python theme={null}
        # client initialized in Step 1
        resize_tasks = client.cloud.file_shares.resize(file_share_id="{FILE_SHARE_ID}", size=10)
        client.cloud.tasks.poll(resize_tasks.tasks[0])
        resized = client.cloud.file_shares.get(file_share_id="{FILE_SHARE_ID}")
        print(resized.size)  # 10
        ```
      </Tab>

      <Tab title="Go SDK">
        ```go theme={null}
        // client and ctx initialized in Step 1
        resized, err := client.Cloud.FileShares.ResizeAndPoll(ctx, "{FILE_SHARE_ID}", cloud.FileShareResizeParams{
            Size: 10,
        })
        if err != nil {
            log.Fatal(err)
        }
        fmt.Printf("New size: %d GiB\n", resized.Size)
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        curl -s -X POST "https://api.gcore.com/cloud/v1/file_shares/$GCORE_CLOUD_PROJECT_ID/$GCORE_CLOUD_REGION_ID/{FILE_SHARE_ID}/extend" \
          -H "Authorization: APIKey $GCORE_API_KEY" \
          -H "Content-Type: application/json" \
          -d '{"size": 10}'
        ```

        Response:

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

    Poll the task every 5 seconds until `FINISHED`, then remount the share:

    ```bash theme={null}
    sudo mount -t nfs {CONNECTION_POINT} /mnt/share
    df -h /mnt/share
    ```

    ```
    Filesystem                                                         Size  Used Avail Use% Mounted on
    192.168.100.58:/shares/share-416d581b-1784-454c-adf8-d2dc75886625  9.8G     0  9.3G   0% /mnt/share
    ```

    ## Clean up

    Delete the file share, subnet, and network when no longer needed:

    <Tabs>
      <Tab title="Python SDK">
        ```python theme={null}
        # client initialized in Step 1
        del_tasks = client.cloud.file_shares.delete(file_share_id="{FILE_SHARE_ID}")
        client.cloud.tasks.poll(del_tasks.tasks[0])

        del_subnet_tasks = client.cloud.networks.subnets.delete(subnet_id="{SUBNET_ID}")
        client.cloud.tasks.poll(del_subnet_tasks.tasks[0])

        del_net_tasks = client.cloud.networks.delete(network_id="{NETWORK_ID}")
        client.cloud.tasks.poll(del_net_tasks.tasks[0])
        ```
      </Tab>

      <Tab title="Go SDK">
        ```go theme={null}
        // client and ctx initialized in Step 1
        if err := client.Cloud.FileShares.DeleteAndPoll(ctx, "{FILE_SHARE_ID}", cloud.FileShareDeleteParams{}); err != nil {
            log.Fatal(err)
        }
        if _, err := client.Cloud.Networks.Subnets.Delete(ctx, "{SUBNET_ID}", cloud.NetworkSubnetDeleteParams{}); err != nil {
            log.Fatal(err)
        }
        if _, err := client.Cloud.Networks.Delete(ctx, "{NETWORK_ID}", cloud.NetworkDeleteParams{}); err != nil {
            log.Fatal(err)
        }
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        curl -s -X DELETE "https://api.gcore.com/cloud/v1/file_shares/$GCORE_CLOUD_PROJECT_ID/$GCORE_CLOUD_REGION_ID/{FILE_SHARE_ID}" \
          -H "Authorization: APIKey $GCORE_API_KEY"

        curl -s -X DELETE "https://api.gcore.com/cloud/v1/subnets/$GCORE_CLOUD_PROJECT_ID/$GCORE_CLOUD_REGION_ID/{SUBNET_ID}" \
          -H "Authorization: APIKey $GCORE_API_KEY"

        curl -s -X DELETE "https://api.gcore.com/cloud/v1/networks/$GCORE_CLOUD_PROJECT_ID/$GCORE_CLOUD_REGION_ID/{NETWORK_ID}" \
          -H "Authorization: APIKey $GCORE_API_KEY"
        ```
      </Tab>
    </Tabs>
  </MethodSection>
</MethodSwitch>
