[Yandex Cloud documentation](../../index.md) > [Tutorials](../index.md) > [Serverless technologies](index.md) > Serverless-based backend > Connecting to a YDB database from a Node.js function in Cloud Functions

# Connecting to a Yandex Managed Service for YDB database from a Yandex Cloud Functions function in Node.js

{% note info %}

This tutorial is intended for Linux users. On Windows, you can follow it in [WSL](https://docs.microsoft.com/en-us/windows/wsl/about).

{% endnote %}

You will create a [function](../../functions/concepts/function.md) with a [Node.js app](https://ydb.tech/docs/en//reference/ydb-sdk/example/example-nodejs) that will run simple queries against a [YDB](https://ydb.tech/) database. You will deploy your app using Bash scripts and use the `tcs` command to compile it.

Use a metadata service to authorize your function with an associated [service account](../../iam/concepts/users/service-accounts.md) in YDB.

The application creates a YDB database connection driver, a session, and a transaction, and runs a query using the `ydb` library. This library is installed as a [dependency](../../functions/lang/nodejs/dependencies.md) when creating a [function version](../../functions/concepts/function.md#version). The database connection parameters are provided to the application using environment variables.

To set up a connection to a YDB database:
1. [Get your cloud ready](#before-begin).
1. [Set up your environment](#prepare-environment).
1. [Create a service account](#create-sa).
1. [Create an authorized key](#create-key).
1. [Create a YDB database](#create-database).
1. [Create a function](#create-function).
1. [Test the function](#test-function).

If you no longer need the resources you created, [delete them](#clear-out).

## Get your cloud ready {#before-begin}

Sign up for Yandex Cloud and create a [billing account](../../billing/concepts/billing-account.md):
1. Navigate to the [management console](https://console.yandex.cloud) and log in to Yandex Cloud or create a new account.
1. On the **[Yandex Cloud Billing](https://center.yandex.cloud/billing/accounts)** page, make sure you have a billing account linked and it has the `ACTIVE` or `TRIAL_ACTIVE` [status](../../billing/concepts/billing-account-statuses.md). If you do not have a billing account, [create one](../../billing/quickstart/index.md) and [link](../../billing/operations/pin-cloud.md) a cloud to it.

If you have an active billing account, you can create or select a [folder](../../resource-manager/concepts/resources-hierarchy.md#folder) for your infrastructure on the [cloud page](https://console.yandex.cloud/cloud).

[Learn more about clouds and folders here](../../resource-manager/concepts/resources-hierarchy.md).

### Required paid resources {#paid-resources}

The infrastructure support cost for this tutorial includes:
* Fee for using the function (see [Yandex Cloud Functions pricing](../../functions/pricing.md)).
* Fee for querying the database (see [Yandex Managed Service for YDB pricing](../../ydb/pricing/serverless.md)).

## Set up your environment {#prepare-environment}

1. Clone the [repository](https://github.com/yandex-cloud-examples/yc-ydb-connect-from-serverless-function) using Git:

   ```bash
   git clone https://github.com/yandex-cloud-examples/yc-ydb-connect-from-serverless-function.git
   ```

1. Install and initialize the [Yandex Cloud CLI](../../cli/quickstart.md).
1. Go to the project root directory:

   ```bash
   cd ~/yc-ydb-connect-from-serverless-function
   ```

   Make sure to run all further commands in this directory.
1. Install [jq](https://stedolan.github.io/jq/download/):

   ```bash
   sudo apt-get install jq
   ```

1. Install [Node.js](https://nodejs.org/en/download/package-manager/):

   ```bash
   curl --fail --silent --show-error --location https://deb.nodesource.com/setup_current.x | sudo -E bash - \
   sudo apt-get install -y nodejs
   ```

1. Install the dependencies:

   ```bash
   npm install
   ```

   Result:

   ```text
   up to date, audited 269 packages in 1s

   29 packages are looking for funding
      run `npm fund` for details

   found 0 vulnerabilities
   ```

## Create a service account {#create-sa}

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), select the [folder](../../resource-manager/concepts/resources-hierarchy.md#folder) where you want to create your service account.
  1. Navigate to **Identity and Access Management**.
  1. Click **Create service account**.
  1. Name the service account: `sa-function`.
  1. Click **Add role** and select `editor`.
  1. Click **Create**.

- CLI {#cli}

  1. [Create](../../iam/operations/sa/create.md#create-sa) a service account:

     ```bash
     yc iam service-account create --name sa-function
     ```

     Result:

     ```text
     id: aje028do8n9r********
     folder_id: b1g681qpemb4********
     created_at: "2023-08-23T06:24:49.759304161Z"
     name: sa-function
     ```

  1. [Assign](../../iam/operations/sa/set-access-bindings.md#assign-role-to-sa) the `editor` [role](../../iam/concepts/access-control/roles.md) to the service account:

     ```bash
     yc resource-manager folder add-access-binding <folder_ID> \
       --role editor \
       --subject serviceAccount:<service_account_ID>
     ```

     Result:

     ```text
     ...1s...done (4s)
     effective_deltas:
     - action: ADD
        access_binding:
           role_id: viewer
           subject:
           id: aje028do8n9r********
           type: serviceAccount
     ```

  For more information about the commands, see the [CLI reference](../../cli/cli-ref/iam/cli-ref/service-account/index.md).

- Terraform {#tf}

  If you do not have Terraform yet, [install it and configure the Yandex Cloud provider](../infrastructure-management/terraform-quickstart.md#install-terraform).
  
  
  To manage infrastructure using Terraform under a service account or user accounts (a Yandex account, a federated account, or a local user), [authenticate](../../terraform/authentication.md) using the appropriate method.

  1. In the configuration file, define the service account properties:

     ```hcl
     resource "yandex_iam_service_account" "sa" {
       name = "sa-function"
     }
     ```

     For more information about the resources you can create with Terraform, see [this provider guide](../../terraform/resources/iam_service_account.md).
  1. Make sure the configuration files are correct.
     1. In the terminal, navigate to the directory with your configuration file.
     1. Run a check using this command:

        ```bash
        terraform plan
        ```

     If the configuration is correct, the terminal will display a list of the resources and their settings. Otherwise, Terraform will show any detected errors.
  1. Deploy the cloud resources.
     1. If the configuration is correct, run this command:

        ```bash
        terraform apply
        ```

     1. To confirm resource creation, type `yes` and press **Enter**.

- API {#api}

  To create a service account and assign it a [role](../../iam/concepts/access-control/roles.md), use the [create](../../iam/api-ref/ServiceAccount/create.md) and [setAccessBindings](../../iam/api-ref/ServiceAccount/setAccessBindings.md) methods for the [ServiceAccount](../../iam/api-ref/ServiceAccount/index.md) resource.

{% endlist %}

## Create an authorized key {#create-key}

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), select the folder the service account belongs to.
  1. Navigate to **Identity and Access Management**.
  1. In the left-hand panel, select ![FaceRobot](../../_assets/console-icons/face-robot.svg) **Service accounts**.
  1. In the list that opens, select the `sa-function` service account.
  1. Click **Create new key** in the top panel.
  1. Select **Create authorized key**.
  1. Select the encryption algorithm.
  1. Enter a description for the [authorized key](../../iam/concepts/authorization/key.md) so you can easily find it in the management console.
  1. Save both the public and private parts of the authorized key to the `yc-ydb-connect-from-serverless-function/service_account_key_file.json` file:

     ```json
     {
       "service_account_id": "<sa-function_service_account_ID>",
       "key_algorithm": "RSA_2048",
       "public_key": "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----\n",
       "private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"
     }
     ```

- CLI {#cli}

  Run this command:

  ```bash
  yc iam key create --service-account-name sa-function -o service_account_key_file.json
  ```

  For more information about the `yc iam key create` command, see the [CLI reference](../../cli/cli-ref/iam/cli-ref/key/create.md).

  If successful, the private part of the authorized key (`privateKey`) and the ID of its public part (`id`) will be written to the `service_account_key_file.json` file.

- Terraform {#tf}

  1. In the configuration file, specify the authorized key properties:

     ```hcl
     resource "yandex_iam_service_account_key" "sa-auth-key" {
       service_account_id = "<sa-function_service_account_ID>"
       key_algorithm      = "RSA_2048"
     }
     ```

     For more information about the resources you can create with Terraform, see [this provider guide](../../terraform/resources/iam_service_account_key.md).
  1. Make sure the configuration files are correct.
     1. In the terminal, navigate to the directory with your configuration file.
     1. Run a check using this command:

        ```bash
        terraform plan
        ```

     If the configuration is correct, the terminal will display a list of the resources and their settings. Otherwise, Terraform will show any detected errors.
  1. Deploy the cloud resources.
     1. If the configuration is correct, run this command:

        ```bash
        terraform apply
        ```

     1. To confirm resource creation, type `yes` and press **Enter**.

- API {#api}

  To create an authorized access key, use the [create](../../iam/api-ref/Key/create.md) method for the [Key](../../iam/api-ref/Key/index.md) resource.

{% endlist %}

## Create a YDB database {#create-database}

{% 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 database.
  1. Navigate to **Managed Service for&nbsp;YDB**.
  1. Click **Create a database**.
  1. Name the database. The naming requirements are as follows:

     * Length: between 3 and 63 characters.
     * It can only contain lowercase Latin letters, numbers, and hyphens.
     * It must start with a letter and cannot end with a hyphen.

  1. Under **Database type**, select `Serverless`.
  1. Click **Create a database**.

     Wait for the database to start. While being created, the database will have the `Provisioning` status. Once it is ready for use, its status will change to `Running`.
  1. Click the name of the database you created.
  1. Save the value of the **Endpoint** field from the **Connection** section. You will need it in the next step.

{% endlist %}

## Create a function {#create-function}

{% note info %}

Before creating a function, make sure the `.env` file and the `create-func.sh` and `create-func-ver.sh` files from the `deploy` directory have the `LF` (line feed) character set.

{% endnote %}

1. Go to the project root directory:

   ```bash
   cd ~/yc-ydb-connect-from-serverless-function
   ```

1. Edit the `.env` file:
   * `ENDPOINT`: First part of the previously saved **Endpoint** field value (preceding `/?database=`), e.g., `grpcs://ydb.serverless.yandexcloud.net:2135`.
   * `DATABASE`: Second part of the previously saved **Endpoint** field value (following `/?database=`), e.g., `/ru-central1/r1gra875baom********/g5n22e7ejfr1********`.
   * `FUNCTION_NAME`: Function name, `func-test-ydb`.
   * `FOLDER_ID`: Folder ID.
   * `SERVICE_ACCOUNT_ID`: `sa-function` service account ID.

1. Create a function:

   ```bash
   ./deploy/create-func.sh
   ```

   This script creates a new function in your folder and makes it public.
1. Create a function version:

   ```bash
   ./deploy/create-func-ver.sh
   ```

   Result:

   ```text
   npx tsc --build tsconfig.json
   rm: Cannot delete '../build/func.zip': File or folder does not exist.
   adding: queries/ (stored 0%)
   adding: queries/clients-table.js (deflated 57%)
   adding: queries/helpers.js.map (deflated 43%)
   adding: queries/helpers.js (deflated 48%)
   adding: queries/clients-table.js.map (deflated 59%)
   adding: index.js (deflated 49%)
   adding: index.js.map (deflated 56%)
   adding: database.js.map (deflated 62%)
   adding: index-local.js (deflated 42%)
   adding: package.json (deflated 55%)
   adding: database.js (deflated 60%)
   adding: index-local.js.map (deflated 43%)
   yc function version create func-test-ydb
   done (27s)
   id: abcd2d363b4b********
   function_id: efghm9el0ja9********
   created_at: "2023-08-15T07:41:07.591Z"
   runtime: nodejs16
   entrypoint: index.handler
   resources:
         memory: "268435456"
   execution_timeout: 5s
   service_account_id: hijk3hlu8gqe********
   image_size: "33497088"
   status: ACTIVE
   tags:
         - $latest
   log_group_id: lmnoivbe341g********
   environment:
         DATABASE: /ru-central1/b1gia87mbaom********/etnilt3o6v9e********
         ENDPOINT: grpcs://ydb.serverless.yandexcloud.net:2135
   log_options:
         folder_id: pqrs81qpemb********
   ```

## Test the function {#test-function}

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), select the folder containing the function.
  1. Navigate to **Cloud Functions**.
  1. Select the `func-test-ydb` function.
  1. Navigate to the **Overview** tab.
  1. In the **Link to invoke** field, click the link.
  1. In your browser address bar, add the `api_key` parameter to the link, e.g., `?api_key=b95`:

      ```http request
      https://functions.yandexcloud.net/efghm9el0ja9********?api_key=b95
      ```

  1. If you database is connected, a table named `b95` with a single record will be created. A JSON message will appear on the page, e.g.:

     ```json
     {
       "info": "b95 table created, one record inserted"
     }
     ```

{% endlist %}

## How to delete the resources you created {#clear-out}

To stop paying for the resources you created:
1. [Delete the database](../../ydb/operations/manage-databases.md#delete-db).
1. [Delete the function](../../functions/operations/function/function-delete.md).