[Yandex Cloud documentation](../../index.md) > [Yandex Managed Service for Sharded PostgreSQL](../index.md) > [Step-by-step guides](index.md) > Creating a cluster

# Creating a Sharded PostgreSQL cluster


## Creating a cluster {#create-cluster}

{% list tabs group=instructions %}

- Management console {#console}

    1. In the [management console](https://console.yandex.cloud), select the folder where you want to create a Sharded PostgreSQL cluster.
    1. Navigate to **Yandex Managed Service for Sharded&nbsp;PostgreSQL**.
    1. Click **Create cluster**.
    1. Under **Basic parameters**:

        1. Give the cluster a name. The name must be unique within the folder.
        1. Optionally, enter a description for the cluster.
        1. Optionally, create [labels](../../resource-manager/concepts/labels.md):

            1. Click **Add label**.
            1. Enter a label in `key: value` format.
            1. Press **Enter**.

        1. Select your cluster environment. Note that you cannot change the environment once the cluster is created:

            * `PRODUCTION`: For stable versions of your applications.
            * `PRESTABLE`: For testing purposes. The prestable environment is similar to the production environment and likewise covered by an SLA, but it is the first to get new features, improvements, and bug fixes. In the prestable environment, you can test new versions for compatibility with your application.

        1. Select the sharding type:

            * `Standard`: Cluster will consist only of infrastructure hosts.
            * `Advanced`: Cluster will consist only of router hosts and coordinator hosts.

    1. Under **Network settings**, select a [network](../../vpc/operations/network-create.md) and [security groups](../../vpc/concepts/security-groups.md) for the cluster.

        
        {% note warning %}
        
        For the router to be able to connect to your shard hosts, the Managed Service for Sharded PostgreSQL cluster and the shards and must be in the same [security group](../../vpc/concepts/security-groups.md) that allows incoming and outgoing TCP connections to port `6432`.
        
        {% endnote %}


    1. Specify the computing resource configuration:

        * For standard sharding, specify the infrastructure host configuration under **Infrastructure**.
        * For advanced sharding, specify the router host configuration under **Router**.

            Under **Coordinator**, configure the coordinator hosts.

        To specify your computing resource configuration:

        1. Select a platform in the **Platform** field.
        1. Specify the **Type** of virtual machine where you want to deploy the hosts:
        1. Select **Host class**.
        1. Under **Storage**, select the disk type and specify the [storage](../concepts/storage.md) size.
        1. Under **Hosts**:

            1. Click **Add host** to add the required number of hosts to create together with the Sharded PostgreSQL cluster.
            
            
            1. Click ![image](../../_assets/console-icons/pencil.svg) and specify the following for each host:
                * [Availability zone](../../overview/concepts/geo-scope.md).
                * [Subnet](../../vpc/concepts/network.md#subnet): By default, each host is created in a separate subnet.
                * **Public access** to make the host accessible from outside Yandex Cloud, if required.


            After creating a Sharded PostgreSQL cluster, you can add more hosts to it if your [folder resource](../concepts/limits.md) quotas allow.

    1. Under **Database**, specify parameters of the database in which you can run queries to tables in shards:

        * Database name. Acceptable length is from 1 to 63 characters. May contain lowercase and uppercase Latin letters, numbers, underscores, and hyphens.

        * Username. Acceptable length is from 1 to 63 characters. May contain lowercase and uppercase Latin letters, numbers, underscores, and hyphens, but cannot start with a hyphen.

        * Password. It may be from 8 to 128 characters long.

    1. Configure advanced cluster settings:

        * **Min. logging level**: Execution log will register logs of this or higher level. The available levels are `DEBUG`, `INFO`, `WARN`, `ERROR`, `FATAL`, and `PANIC`. The default is `INFO`.
        
        * **Backup start time (UTC)**: Time interval during which the cluster backup starts. Time is specified in 24-hour UTC format. The default time is `22:00 - 23:00` UTC.
        
        * **Retention period for automatic backups, days**: Automatic backups will be stored for this many days. The default value is seven days.
        
        * **Maintenance**: Maintenance window settings:
        
            * To enable maintenance at any time, select **At any time** (default).
            * To specify the preferred maintenance start time, select **By schedule** and specify the day of the week and the UTC time interval. For example, you can choose a time when the cluster is least loaded.
            
            Both active and stopped clusters are subject to maintenance. Maintenance operations include DBMS updates, patches, etc.
        
        
        * **Deletion protection**: Manages cluster protection against accidental deletion.
        
            Even with cluster deletion protection enabled, one can still delete a user or database or connect manually and delete the database contents.

    1. To configure [cluster-level DBMS settings](../concepts/settings-list.md), under **DBMS settings**, click **Settings**.

    1. Click **Create cluster**.

- REST API {#api}

  1. [Get an IAM token for API authentication](../api-ref/authentication.md) and put it into an environment variable:

     ```bash
     export IAM_TOKEN="<IAM_token>"
     ```

  1. Create a file named `body.json` and paste the following code into it:

     
     ```json
     {
       "folderId": "<folder_ID>",
       "name": "<cluster_name>",
       "description": "<description>",
       "environment": "<environment>",
       "securityGroupIds": [
         "<security_group_1_ID>",
         "<security_group_2_ID>",
         ...
         "<security_group_N_ID>"
       ],
       "networkId": "<network_ID>",
       "deletionProtection": <protect_cluster_from_deletion>,
       "configSpec": {
         "spqrSpec": {
           "router": {
             "config": {
               "showNoticeMessages": <show_information_notifications>,
               "timeQuantiles": [
                 <list_of_time_quantiles_for_displaying_statistics>
               ],
               "defaultRouteBehavior": "<allow_multishard_requests>",
               "preferSameAvailabilityZone": <routing_priority_to_router_availability_zone>
             },
             "resources": {
               "resourcePresetId": "<router_host_class>",
               "diskSize": "<storage_size_in_bytes>",
               "diskTypeId": "<disk_type>"
             }
           },
           "coordinator": {
             "resources": {
               "resourcePresetId": "<coordinator_host_class>",
               "diskSize": "<storage_size_in_bytes>",
               "diskTypeId": "<disk_type>"
             }
           },
           "infra": {
             "router": {
               "showNoticeMessages": <show_information_notifications>,
               "time_quantiles": [
                 <list_of_time_quantiles_for_displaying_statistics>
               ],
               "defaultRouteBehavior": "<allow_multishard_requests>",
               "preferSameAvailabilityZone": <routing_priority_to_router_availability_zone>
             },
             "resources": {
               "resourcePresetId": "<INFRA_host_class>",
               "diskSize": "<storage_size_in_bytes>",
               "diskTypeId": "<disk_type>"
             }
           },
           "consolePassword": "<Sharded_PostgreSQL_console_password>",
           "logLevel": "<logging_level>"
         },
         "backupWindowStart": {
           "hours": "<hours>",
           "minutes": "<minutes>",
           "seconds": "<seconds>",
           "nanos": "<nanoseconds>"
         },
         "backupRetainPeriodDays": "<number_of_days>",
       },
       "databaseSpecs": [
         {
           "name": "<DB_name>"
         },
         { <similar_settings_for_DB_2> },
         { ... },
         { <similar_settings_for_DB_N> }
       ],
       "userSpecs": [
         {
           "name": "<username>",
           "password": "<user_password>",
           "permissions": [
             {
               "databaseName": "<DB_name>"
             },
             { <database_2_name> },
             { ... },
             { <DB_N_name> }
           ],
           "settings": {
             "connectionLimit": "<number_of_user_connections>",
             "connectionRetries": "<number_of_retries_when_connecting>"
           },
           "grants": [
             "privilege_1",
             ...,
             "privilege_N"
           ]
         },
         { <similar_settings_for_user_2> },
         { ... },
         { <similar_settings_for_user_N> }
       ],
       "hostSpecs": [
         {
           "zoneId": "<availability_zone>",
           "subnetId": "<subnet_ID>",
           "assignPublicIp": <allow_public_access_to_host>,
           "type": "<host_type>"
         },
         { <similar_settings_for_host_2> },
         { ... },
         { <similar_settings_for_host_N> }
       ],
       "shardSpecs": [
         {
           "shardName": "<shard_name>",
           "mdbPostgresql": {
             "clusterId": "<cluster_ID>"
           }
         },
         { <similar_set_of_settings_for_shard_2> },
         { ... },
         { <similar_set_of_settings_for_shard_N> }
       ],
       "maintenanceWindow": {
         "weeklyMaintenanceWindow": {
           "day": "<day_of_week>",
           "hour": "<hour>"
         }
       }
     }
     ```


     Where:

     * `folderId`: Folder ID.  You can get it from the [list of your cloud folders](../../resource-manager/operations/folder/get-id.md).
     * `name`: Cluster name.
     * `environment`: Cluster environment, `PRODUCTION` or `PRESTABLE`.
     * `networkId`: ID of the [network](../../vpc/concepts/network.md#network) the cluster will be deployed in.

       {% note warning %}
       
       The cloud network selected for cluster deployment cannot be changed later. If you need to migrate your cluster to another cloud network in the future, use the [restore from a backup](../../managed-postgresql/operations/cluster-backups.md) feature and specify the required network for your new cluster copy.
       
       {% endnote %}

     
     * `securityGroupIds`: [Security group](../../vpc/concepts/security-groups.md) IDs.

        {% note warning %}
        
        For the router to be able to connect to your shard hosts, the Managed Service for Sharded PostgreSQL cluster and the shards and must be in the same [security group](../../vpc/concepts/security-groups.md) that allows incoming and outgoing TCP connections to port `6432`.
        
        {% endnote %}


     * `deletionProtection`: Cluster deletion protection, `true` or `false`.

        Even with deletion protection enabled, one can still connect to the cluster manually and delete the data.

     * `configSpec`: Cluster settings:

       * `spqrSpec`: Sharded PostgreSQL settings.

         * `router`: For [advanced sharding](../concepts/index.md#router), configure the following router settings:

           * `config`: Router configuration:

             * `showNoticeMessages`: Show information notifications, `true` or `false`.
             * `timeQuantiles`: Array of time quantile strings for displaying statistics. The default values are `"0.5"`, `"0.75"`, `"0.9"`, `"0.95"`, `"0.99"`, `"0.999"`, `"0.9999"`.
             * `defaultRouteBehavior`: Router's multishard request execution policy. Possible values: `BLOCK` or `ALLOW`.
             * `preferSameAvailabilityZone`: Enable priority routing of read requests to the router's availability zone, `true` or `false`.

           * `resources`: `ROUTER` host resource parameters:
             * `resourcePresetId`: [Host class](../concepts/instance-types.md).
             * `diskSize`: Disk size, in bytes.
             * `diskTypeId`: [Disk type](../concepts/storage.md).

         * `coordinator`: For advanced sharding, set the following coordinator resource parameters:
             * `resourcePresetId`: Host class.
             * `diskSize`: Disk size, in bytes.
             * `diskTypeId`: Disk type.

         * `infra`: For standard sharding, set the following `INFRA` host settings:

           * `resources`: Resource parameters:
              * `resourcePresetId`: Host class.
              * `diskSize`: Disk size, in bytes.
              * `diskTypeId`: Disk type.

           * `router`: Router configuration:

             * `showNoticeMessages`: Show information notifications, `true` or `false`.
             * `timeQuantiles`: Array of time quantiles for displaying statistics. The default values are `0.5`, `0.75`, `0.9`, `0.95`, `0.99`, `0.999`, `0.9999`.
             * `defaultRouteBehavior`: Router's multishard request execution policy. Possible values: `BLOCK` or `ALLOW`.
             * `preferSameAvailabilityZone`: Enable priority routing of read requests to the router's availability zone, `true` or `false`.

           * `consolePassword`: Sharded PostgreSQL console password.
           * `logLevel`: Query logging level: `DEBUG`, `INFO`, `WARNING`, `ERROR`, `FATAL`, `PANIC`.


       * `backupWindowStart`: Backup window settings.

           Here, specify the backup start time. Allowed values:

           * `hours`: Between `0` and `23` hours.
           * `minutes`: Between `0` and `59` minutes.
           * `seconds`: Between `0` and `59` seconds.
           * `nanos`: Between `0` and `999999999` nanoseconds.

       * `backupRetainPeriodDays`: Number of days to retain the cluster backup. Possible values: between `7` and `60` days.

     * `databaseSpecs`: Database settings as an array of elements, one per database. Each element has the following structure:

       * `name`: Database name.

     * `userSpecs`: User settings as an array of elements, one per user. Each element has the following structure:

       * `name`: Username.
       * `password`: User password. The password must be from 8 to 128 characters long.
       * `permissions.databaseName`: Name of the database the user can access.
       * `settings`: Database user connection parameters:

         * `connectionLimit`: Connection limit.
         * `connectionRetries`: Number of reconnect attempts.

       * `grants`: User privileges as an array of strings. The possible values are `reader`, `writer`, `admin`, or `transfer`.

     * `hostSpecs`: Cluster host settings as an array of elements, one per host. Each element has the following structure:

       * `zoneId`: [Availability zone](../../overview/concepts/geo-scope.md).

       
       * `subnetId`: [Subnet](../../vpc/concepts/network.md#subnet) ID.
       * `assignPublicIp`: Permission to [connect](connect.md) to the host from the internet, `true` or `false`.


       * `type`: Host type. The possible values are:
         * `ROUTER`: Router in a cluster with advanced sharding.
         * `COORDINATOR`: Coordinator in a cluster with advanced sharding.
         * `INFRA`: `INFRA` host in a cluster with standard sharding.

     * `shardSpecs`: Shard settings as an array of elements, one per shard. Each element has the following structure:

       * `shardName`: Shard name.
       * `mdbPostgresql.clusterId`: Managed Service for PostgreSQL cluster ID within the shard.

     * `maintenanceWindow`: Maintenance window settings:

       * `day`: Day of the week, in `DDD` format, for scheduled maintenance.
       * `hour`: Hour of day, in `HH` format, for scheduled maintenance. The valid values range from `1` to `24`.

  1. Call the [Cluster.Create](../api-ref/Cluster/create.md) method, e.g., via the following [cURL](https://curl.se/) request:

     ```bash
     curl \
       --request POST \
       --header "Authorization: Bearer $IAM_TOKEN" \
       --header "Content-Type: application/json" \
       --url 'https://mdb.api.cloud.yandex.net/managed-spqr/v1/clusters' \
       --data "@body.json"
     ```

  1. Check the [server response](../api-ref/Cluster/create.md#yandex.cloud.operation.Operation) to make sure your request was successful.

- gRPC API {#grpc-api}

  1. [Get an IAM token for API authentication](../api-ref/authentication.md) and put it into an environment variable:

     ```bash
     export IAM_TOKEN="<IAM_token>"
     ```

  1. Clone the [cloudapi](https://github.com/yandex-cloud/cloudapi) repository:
     
     ```bash
     cd ~/ && git clone --depth=1 https://github.com/yandex-cloud/cloudapi
     ```
     
     Below, we assume that the repository contents reside in the `~/cloudapi/` directory.
  1. Create a file named `body.json` and paste the following code into it:

     
     ```json
     {
       "folder_id": "<folder_ID>",
       "name": "<cluster_name>",
       "description": "<description>",
       "environment": "<environment>",
       "security_group_ids": [
         "<security_group_1_ID>",
         "<security_group_2_ID>",
         ...
         "<security_group_N_ID>"
       ],
       "network_id": "<network_ID>",
       "deletion_protection": <protect_cluster_from_deletion>,
       "config_spec": {
         "spqr_spec": {
           "router": {
             "config": {
               "show_notice_messages": {
                 "value": <show_information_notifications>
               },
               "time_quantiles": [
                 <list_of_time_quantiles_for_displaying_statistics>
               ],
               "default_route_behavior": "<allow_multishard_requests>",
               "prefer_same_availability_zone": {
                 "value": <routing_priority_to_router_availability_zone>
               }
             },
             "resources": {
               "resource_preset_id": "<router_host_class>",
               "disk_size": "<storage_size_in_bytes>",
               "disk_type_id": "<disk_type>" }
           },
           "coordinator": {
             "resources": {
               "resource_preset_id": "<coordinator_host_class>",
               "disk_size": "<storage_size_in_bytes>",
               "disk_type_id": "<disk_type>"
             }
           },
           "infra": {
             "resources": {
               "resource_preset_id": "INFRA_host_class",
               "disk_size": "<storage_size_in_bytes>",
               "disk_type_id": "<disk_type>"
             },
             "router": {
               "show_notice_messages": {
                 "value": <show_information_notifications>
               },
               "time_quantiles": [
                 <list_of_time_quantiles_for_displaying_statistics>
               ],
               "default_route_behavior": "<allow_multishard_requests>",
               "prefer_same_availability_zone": {
                 "value": <routing_priority_to_router_availability_zone>
               }
             },
           },
           "console_password": "<Sharded_PostgreSQL_console_password>",
           "log_level": "<logging_level>"
         },
         "backup_window_start": {
           "hours": "<hours>",
           "minutes": "<minutes>",
           "seconds": "<seconds>",
           "nanos": "<nanoseconds>"
         },
         "backup_retain_period_days": "<number_of_days>"
       },
       "database_specs": [
         {
           "name": "<DB_name>"
         },
         { <similar_settings_for_DB_2> },
         { ... },
         { <similar_settings_for_DB_N> }
       ],
       "user_specs": [
         {
           "name": "<username>",
           "password": "<user_password>",
           "permissions": [
             {
               "database_name": "<DB_name>"
             },
             { <database_2_name> },
             { ... },
             { <DB_N_name> }
           ],
           "settings": {
             "connection_limit": {
               "value": <number_of_user_connections>
             },
             "connection_retries": {
               "value": <number_of_retries_when_connecting>
             }
           },
           "grants": [
             "privilege_1",
             ...,
             "privilege_N"
           ]
         },
         { <similar_settings_for_user_2> },
         { ... },
         { <similar_settings_for_user_N> }
       ],
       "host_specs": [
         {
           "zone_id": "<availability_zone>",
           "subnet_id": "<subnet_ID>",
           "assign_public_ip": <allow_public_access_to_host>,
           "type": "<host_type>"
         },
         { <similar_settings_for_host_2> },
         { ... },
         { <similar_settings_for_host_N> }
       ],
       "shard_specs": [
         {
           "shard_name": "<shard_name>",
           "mdb_postgresql": {
             "cluster_id": "<cluster_ID>"
           }
         },
         { <similar_set_of_settings_for_shard_2> },
         { ... },
         { <similar_set_of_settings_for_shard_N> }
       ],
       "maintenance_window": {
         "weekly_maintenance_window": {
           "day": "<day_of_week>",
           "hour": "<hour>"
         }
       }
     }
     ```


     Where:

     * `folder_id`: Folder ID.  You can get it with the [list of folders in the cloud](../../resource-manager/operations/folder/get-id.md).
     * `name`: Cluster name.
     * `environment`: Cluster environment, `PRODUCTION` or `PRESTABLE`.
     * `network_id`: ID of the [network](../../vpc/concepts/network.md#network) the cluster will be deployed in.

       {% note warning %}
       
       The cloud network selected for cluster deployment cannot be changed later. If you need to migrate your cluster to another cloud network in the future, use the [restore from a backup](../../managed-postgresql/operations/cluster-backups.md) feature and specify the required network for your new cluster copy.
       
       {% endnote %}

     
     * `security_group_ids`: [Security group](../../vpc/concepts/security-groups.md) IDs.

        {% note warning %}
        
        For the router to be able to connect to your shard hosts, the Managed Service for Sharded PostgreSQL cluster and the shards and must be in the same [security group](../../vpc/concepts/security-groups.md) that allows incoming and outgoing TCP connections to port `6432`.
        
        {% endnote %}


     * `deletion_protection`: Cluster deletion protection, `true` or `false`.

        Even with deletion protection enabled, one can still connect to the cluster manually and delete the data.

     * `config_spec`: Cluster settings:

       * `spqr_spec`: Sharded PostgreSQL settings:

         * `router`: For [advanced sharding](../concepts/index.md#router), configure the following router settings:
           * `config`: Router configuration:

             * `show_notice_messages`: Show information notifications, `true` or `false`.
             * `time_quantiles`: Array of time quantiles for displaying statistics. The following values are used by default: `0.5`, `0.75`, `0.9`, `0.95`, `0.99`, `0.999`, `0.9999`.
             * `default_route_behavior`: Router's multishard request execution policy. Possible values: `BLOCK` or `ALLOW`.
             * `prefer_same_availability_zone`: Enable priority routing of read requests to the router's availability zone, `true` or `false`.

           * `resources`: `ROUTER` host resource parameters:
             * `resource_preset_id`: [Host class](../concepts/instance-types.md).
             * `disk_size`: Disk size, in bytes.
             * `disk_type_id`: [Disk type](../concepts/storage.md).

         * `coordinator`: For advanced sharding, set the following coordinator resource parameters:
             * `resource_preset_id`: Host class.
             * `disk_size`: Disk size, in bytes.
             * `disk_type_id`: Disk type.

         * `infra`: For standard sharding, set the following `INFRA` host settings:

           * `resources`: Resource parameters:
              * `resource_preset_id`: Host class.
              * `disk_size`: Disk size, in bytes.
              * `disk_type_id`: Disk type.

           * `router`: Router configuration:
               * `default_route_behavior`: Default router behavior. Possible values: `BLOCK` or `ALLOW` the request.
               * `prefer_same_availability_zone`: Enable priority routing to the router's availability zone, `true` or `false`.

           * `console_password`: Sharded PostgreSQL console password.
           * `log_level`: Query logging level: `DEBUG`, `INFO`, `WARNING`, `ERROR`, `FATAL`, `PANIC`.


       * `backup_window_start`: Backup window settings.

         Here, specify the backup start time. Allowed values:

         * `hours`: Between `0` and `23` hours.
         * `minutes`: Between `0` and `59` minutes.
         * `seconds`: Between `0` and `59` seconds.
         * `nanos`: Between `0` and `999999999` nanoseconds.

       * `backup_retain_period_days`: Number of days to retain the cluster backup. Possible values: between `7` and `60` days.

     * `database_specs`: Database settings as an array of elements, one for each DB. Each element has the following structure:

       * `name`: Database name.

     * `user_specs`: User settings as an array of elements, one per user. Each element has the following structure:

       * `name`: Username.
       * `password`: User password. The password must be from 8 to 128 characters long.
       * `permissions.database_name`: Name of the database the user can access.
       * `settings`: Database user connection parameters:

         * `connection_limit`: Connection limit.
         * `connection_retries`: Number of reconnect attempts.

       * `grants`: User privileges as an array of strings. The possible values are `reader`, `writer`, `admin`, or `transfer`.

     * `host_specs`: Cluster host settings as an array of elements, one per host. Each element has the following structure:

       * `zone_id`: [Availability zone](../../overview/concepts/geo-scope.md)

       
       * `subnet_id`: [Subnet](../../vpc/concepts/network.md#subnet) ID.
       * `assign_public_ip`: Permission to [connect](connect.md) to the host from the internet, `true` or `false`.


       * `type`: Host type. The possible values are:
         * `ROUTER`: Router in a cluster with advanced sharding.
         * `COORDINATOR`: Coordinator in a cluster with advanced sharding.
         * `INFRA`: `INFRA` host in a cluster with standard sharding.

     * `shard_specs`: Shard settings as an array of elements, one per shard. Each element has the following structure:

       * `shard_name`: Shard name.
       * `mdb_postgresql.cluster_id`: Managed Service for PostgreSQL cluster ID within the shard.

     * `maintenance_window`: Maintenance window settings:

       * `day`: Day of the week, in `DDD` format, for scheduled maintenance.
       * `hour`: Hour of day, in `HH` format, for scheduled maintenance. The valid values range from `1` to `24`.

  1. Call the [ClusterService.Create](../api-ref/grpc/Cluster/create.md) method, e.g., via the following [gRPCurl](https://github.com/fullstorydev/grpcurl) request:

     ```bash
     grpcurl \
       -format json \
       -import-path ~/cloudapi/ \
       -import-path ~/cloudapi/third_party/googleapis/ \
       -proto ~/cloudapi/yandex/cloud/mdb/spqr/v1/cluster_service.proto \
       -rpc-header "Authorization: Bearer $IAM_TOKEN" \
       -d @ \
       mdb.api.cloud.yandex.net:443 \
       yandex.cloud.mdb.spqr.v1.ClusterService.Create \
       < body.json
     ```

  1. Check the [server response](../api-ref/grpc/Cluster/create.md#yandex.cloud.operation.Operation) to make sure your request was successful.

{% endlist %}