YugabyteDB Managed API: provisioning a free DB from command line
Tags: yugabytedb, free, managed, service
Published: 2023-02-03 22:30:28

**YugabyteDB Managed** is the cloud service for YugabyteDB, PostgreSQL-compatible distributed SQL database. All actions can be done from http://cloud.yugabyte.com and can be **automated**. Here is an example of **provisioning** a DB on the free tier though the REST API.

## API Key, Account ID, Project ID

To interact in a secure way with the API endpoint you need a key, that you create in the web portal:

![Create API Key](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oi93z9t28mr9fchyu0h7.png)

You can retreive the key as well as the identifiers of your account and project:

![Generate Key](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dllitjkgcmghzhlpkxhc.png)

If you need to revoke the key, this where were you can do it here:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/972360tdgyvgf8bxre6a.png)

For further actions, you have all the necessary information to call the API. I set those in environment variables:

```sh
YBM_API_KEY="eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJBcGlKd3QiLCJzdWIiOiIyN2NmZTg4OS03YjdiLTQyYmMtYWU1Mi1hYWFkZTNkMzFiZjQiLCJpc3MiOiJmcGFjaG90QHl1Z2FieXRlLmNvbSIsImV4cCI6MTcwNjk0ODY1NiwiaWF0IjoxNjc1NDEyNjU2LCJqdGkiOiI5ZjI4YzE1MC05NTg4LTQxM2QtODc0MS1hZjAzMmI4NTM1ODkifQ.ftcVHaGBLwVgFVDoxQ03-dr9OTL0QKhgZ5AcIEEL-FY"

YBM_ACCOUNT_ID="8c17af53-3c7c-4e76-a530-768ccdfd75b1"

YBM_PROJECT_ID="684d1eeb-4c50-4678-a925-1e7d777d6bd8"

```

## Software Track

There are two software tracks, the "Preview" to test all new features, with odd release numbers, and the "Stable" one, for production, with even release numbers:

![Database Version](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ikp9ypxuqpi8wh3pp3wp.png)

Here, I'm creating a free database to test the latest features. 
I get the ID for the Preview track:

```sh
YBM_SOFTWARE="Preview"

YBM_SOFTWARE_TRACK_ID=$(
curl -s --request GET \
  --url https://cloud.yugabyte.com/api/public/v1/accounts/$YBM_ACCOUNT_ID/software-tracks \
  --header "Authorization: Bearer $YBM_API_KEY" \
  --header 'Content-Type: application/json' | \
  tee /dev/stderr |
  jq -r '.data[] | select(.spec.name=="'$YBM_SOFTWARE'") | .info.id '
)
echo ; set | grep ^YBM_ | cut -c1-80
```

## Allowed List

To access from the public internet I need to add my public IP to the "Allow List". I create an allow list with my public IP gathered from `http://ifconfig.me` and get its ID into an environment variable:

```sh
YBM_ALLOW_LIST="home"

curl -s --request POST \
  --url https://cloud.yugabyte.com/api/public/v1/accounts/$YBM_ACCOUNT_ID/projects/$YBM_PROJECT_ID/allow-lists  \
  --header "Authorization: Bearer $YBM_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "'${YBM_ALLOW_LIST}'",
  "description": "Gathered from http://ifconfig.me",
  "allow_list": [
    "'$(curl -s ifconfig.me)'/32"
  ]
}'

YBM_ALLOW_LIST_ID=$(
curl -s --request GET \
  --url https://cloud.yugabyte.com/api/public/v1/accounts/$YBM_ACCOUNT_ID/projects/$YBM_PROJECT_ID/allow-lists \
  --header "Authorization: Bearer $YBM_API_KEY" \
  --header 'Content-Type: application/json' |
  tee /dev/stderr |
  jq -r '.data[] | select(.spec.name=="'${YBM_ALLOW_LIST}'") | .info.id'
)
echo ; set | grep ^YBM_ | cut -c1-80
```

## Deploy

Now, I have all the necessary as environment variables:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nojjtfhrsg4dljq7qnuy.png)

I define a name for my cluster and a password for the `admin` user.
Then I call the cluster creation API with one node in Ireland AWS region `eu-west-1`. The `num_cores`, `memory_mb` and `disk_size_gb` settings are those of the free tier on AWS:

```sh
YBM_CLUSTER="my-free-yugabytedb"
YBM_ADMIN_PASSWORD="Password-5up3r53cr3t"

curl -s --request POST \
  --url https://cloud.yugabyte.com/api/public/v1/accounts/$YBM_ACCOUNT_ID/projects/$YBM_PROJECT_ID/clusters \
  --header "Authorization: Bearer $YBM_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "cluster_spec": {
    "name": "'$YBM_CLUSTER'",
    "cloud_info": {
      "code": "AWS",
      "region": "eu-west-1"
    },
    "cluster_info": {
      "cluster_tier": "FREE",
      "cluster_type": "SYNCHRONOUS",
      "num_nodes": 1,
      "fault_tolerance": "NONE",
      "node_info": {
        "num_cores": 2,
        "memory_mb": 4096,
        "disk_size_gb": 10
      },
      "is_production": false,
      "version": null
    },
    "network_info": {
      "single_tenant_vpc_id": null
    },
    "software_info": {
      "track_id": "'$YBM_SOFTWARE_TRACK_ID'"
    },
    "cluster_region_info": [
      {
        "placement_info": {
          "cloud_info": {
            "code": "AWS",
            "region": "eu-west-1"
          },
          "num_nodes": 1,
          "vpc_id": null,
          "num_replicas": 1,
          "multi_zone": false
        },
        "is_default": true,
        "is_affinitized": true,
        "accessibility_types": [
          "PUBLIC"
        ]
      }
    ]
  },
  "allow_list_info": [ "'"$YBM_ALLOW_LIST_ID"'" ],
  "db_credentials": {
    "ycql": {
      "username": "admin",
      "password": "'"$YBM_ADMIN_PASSWORD"'"
    },
    "ysql": {
      "username": "admin",
      "password": "'"$YBM_ADMIN_PASSWORD"'"
    }
  }
}'

```

I can check that the cluster is in Deploying state:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wtpkfgvqh3ormst629t6.png)


## List the clusters

I check the state from the list of clusters:

```sh
curl -s --request GET \
  --url https://cloud.yugabyte.com/api/public/v1/accounts/$YBM_ACCOUNT_ID/projects/$YBM_PROJECT_ID/clusters \
  --header "Authorization: Bearer $YBM_API_KEY" \
  --header 'Content-Type: application/json' \
  | jq -r '.data[] | .info.id +" "+ .spec.name +": "+ .info.state'

```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qpxtqmw6y4nefwe5cyni.png)

For further interaction, I get the ID of the one I'm currently creating:

```sh
YBM_CLUSTER_ID=$(
curl -s --request GET \
  --url https://cloud.yugabyte.com/api/public/v1/accounts/$YBM_ACCOUNT_ID/projects/$YBM_PROJECT_ID/clusters \
  --header "Authorization: Bearer $YBM_API_KEY" \
  --header 'Content-Type: application/json' | 
  tee /dev/stderr |
  jq -r '.data[] | select(.spec.name=="'$YBM_CLUSTER'") | .info.id'
)
echo ; set | grep ^YBM_ | cut -c1-80
```

I can wait in an automated way:
```sh
until curl -s --request GET   --url https://cloud.yugabyte.com/api/public/v1/accounts/$YBM_ACCOUNT_ID/projects/$YBM_PROJECT_ID/clusters/$YBM_CLUSTER_ID   --header "Authorization: Bearer $YBM_API_KEY" |
 grep '"state":"ACTIVE"' ; do sleep 1 ; done
```
This loop stops when the cluster is active

## Connect with PostgreSQL drivers

To connect to the default database `yugabyte` with the `admin` user I set the PostgreSQL environment variables, getting the host from the list of endpoints:

```sh
PGDATABASE=yugabyte
PGUSER="admin"
PGPASSWORD="$YBM_ADMIN_PASSWORD"
PGPORT="5433"
PGSSLMODE=require

PGHOST=$(
curl -s --request GET \
  --url https://cloud.yugabyte.com/api/public/v1/accounts/$YBM_ACCOUNT_ID/projects/$YBM_PROJECT_ID/clusters \
  --header "Authorization: Bearer $YBM_API_KEY" \
  --header 'Content-Type: application/json' | 
  tee /dev/stderr |
  jq -r '.data[] | select(.spec.name=="'$YBM_CLUSTER'") | .info.cluster_endpoints[0].host '
)
echo ; set | grep ^PG
export PGDATABASE PGUSER PGHOST PGPORT PGPASSWORD PGSSLMODE

```

I can now simply use any PostgreSQL tool or application:


![psqln](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gepa9cuz2xvcw7vjkppy.png)

## Terminate

The API is [documented](https://yugabyte.stoplight.io/docs/managed-apis), you have the link on the API key list as "Learn more about REST API".

I can pause a cluster when I don't need it:

```sh
curl -s --request POST \
  --url https://cloud.yugabyte.com/api/public/v1/accounts/$YBM_ACCOUNT_ID/projects/$YBM_PROJECT_ID/clusters/$YBM_CLUSTER_ID/pause \
  --header "Authorization: Bearer $YBM_API_KEY" --data ''

```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/11n859tu6alpkuwm82rz.png)

This one is free database, you don't pause it. 
You can consider it as serverless 😃

If you don't need it anymore, you can terminate the service:

```sh
curl -s --request DELETE \
  --url https://cloud.yugabyte.com/api/public/v1/accounts/$YBM_ACCOUNT_ID/projects/$YBM_PROJECT_ID/clusters/$YBM_CLUSTER_ID \
  --header "Authorization: Bearer $YBM_API_KEY"

```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u788j9liy4jufpbsbslr.png)

I've revoked my API key, so don't use those above IDs. You can sign up for your own free YugabyteDB: https://cloud.yugabyte.com/signup