# GCP

Sodot MPC Vertex is a self-hosted deployable service that represents an MPC party for MPC operations (e.g. keygen, sign or refresh).
It takes care of storing the secret shares, as well as running the MPC operations themselves. It can be used seamlessly with all Sodot MPC SDKs.
The Vertex exposes a REST API, documented [here](https://docs.sodot.dev/vertex-api-reference), that allows creating and managing secret shares easily.

## Architecture

The self-hosted solution comes in two forms: a dedicated [Terraform module](https://developer.hashicorp.com/terraform/intro) and a [Helm chart](https://helm.sh/docs/topics/charts/) (which the Terraform module uses internally). Both should be run on your organization's computing infrastructure.
We recommend you first look at our [example Terraform module](#obtaining-the-terraform-module) and modify it according to your organization's needs.

## Requirements

Before starting the installation process, make sure you have the done the following:

1. Install the `terraform` [CLI](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli).
2. Install the `gcloud` CLI tool for GCP.
3. Make sure you are **logged in** (i.e `gcloud auth application-default login`).
4. Make sure your account has permissions to **create resources** (e.g. clusters or load balancers).
5. Set up a Relay Server ([instructions](/relay-server/relay_gcp)).

:::note
This guide assumes you're running the provided example Terraform module as the root module (although most steps are applicable when running it as a submodule as well).
:::

## Installation Process

The installation process is made of the following steps:

1. [Collecting the installation parameters](#collecting-parameters)
2. [Obtaining a TLS certificate](#obtaining-a-tls-certificate)
3. [Obtaining the Terraform module](#obtaining-the-terraform-module)
4. [Applying the Terraform module to your cloud environment](#applying-the-terraform-module)
5. [Setting the DNS Record for `URL_ENDPOINT` to point to the Vertex](#setting-the-dns-record)

:::info
The steps below relate to the provided Terraform module as is.
Customizing the Helm chart deployment directly is possible as explained in the [Customizing Helm Chart Values](#customizing-helm-chart-values) section.
:::

### 1. Collecting Parameters

At this step you should collect the following pieces of information:
At the end of each bullet we put in parentheses a capitalized name which will be used to refer to the value being set throughout the rest of this guide.

1. The endpoint URL that you wish to host your Vertex at (`URL_ENDPOINT`).
2. The Sodot Docker registry user and token which provides access to all relevant Helm charts, Docker images and Terraform modules (`ARTIFACTORY_USER` and `ARTIFACTORY_TOKEN`). You can obtain these by following the [Obtaining Credentials](/vertex/deployment/obtaining-artifacts-credentials) guide.
3. The product you wish to deploy over the Vertex (`PRODUCT`).
   Currently, the supported products are `mpc-infra` and `exchange-api-vault`.

### 2. Obtaining a TLS Certificate

You should obtain a TLS certificate for the `URL_ENDPOINT` domain.
The certificate has to be loaded into the GCP Certificate Manager or created by GCP, as a Classic Certificate.
The `TLS_CERT_NAME` is the name of the certificate in the GCP Certificate Manager.

### 3. Obtaining the Terraform Module

You can consume the **Vertex** Terraform module from the Sodot private registry in one of two ways:

#### A. Use the module directly from the registry

First, you'll need to log in to the Sodot Docker registry using the credentials you obtained in the previous step.

```bash
terraform login repo.sodot.dev
```

Then, you can use the module directly from the registry by adding it to your Terraform configuration.
Add the following block to your `main.tf` (or similar) and run `terraform init`. Terraform will pull the module from your JFrog Artifactory registry at runtime.

```hcl
module "vertex" {
  source  = "repo.sodot.dev/sodot-terraform-modules__sodot/vertex/google"
  ...
}
```

#### B. Download the raw Terraform module to customize it

1. Fetch the desired release (replace `<VERSION>` with a tag such as `v1.10.1`):

```bash
curl -u "<ARTIFACTORY_USER>:<ARTIFACTORY_TOKEN>" \
  -O "https://repo.sodot.dev/artifactory/sodot-terraform-modules/sodot/vertex/google/<VERSION>.zip"
```

Alternatively, you can use the Artifactory GUI instead.<br /><br />

2. Unzip and make it your root module:

```bash
unzip <VERSION>.zip -d vertex
cd vertex
```

### 4. Applying the Terraform Module to Your Cloud Environment

Setting up the relevant infrastructure is performed by running `terraform init` followed by `terraform apply`.
Where you run those commands depends on the option you chose in [Obtaining the Terraform Module](#obtaining-the-terraform-module).
This will provision an GKE cluster, a Postgres DB for internal usage by the Vertex, and an additional KMS Keyring to hold the DB encryption keys.

#### Configuring Terraform

The module’s inputs are declared in `variables.tf` and have sensible defaults where appropriate.
You **must** supply the following variables when invoking **both** `terraform apply` and `terraform destroy`:

* `location` - the location to which the cluster and the rest of the resources will be provisioned.
* `project_id=<project_id>` - the GCP project ID under which resources are deployed.
* `artifactory_user=<ARTIFACTORY_USER>` - provides Terraform with permissions to pull the Helm chart and the Vertex Docker image.
* `artifactory_token=<ARTIFACTORY_TOKEN>` - provides Terraform with permissions to pull the Helm chart and the Vertex Docker image.
* `product_name=<PRODUCT>` - the Sodot product to deploy over the Vertex (e.g. `mpc-infra` or `exchange-api-vault`).
* `admin_access_token=<ADMIN_TOKEN>` - the secret admin token that will be used to set up all other users of the Vertex.
* `relay_address=<RELAY_URL>` - the URL for your organization's deployed Relay Server.
* `relay_api_key=<RELAY_API_KEY>` - an API key for accessing the Sodot Relay Server.
* `vertex_dns_address=<URL_ENDPOINT>` - equal to `URL_ENDPOINT`.
* `tls_cert_name=<TLS_CERT_NAME>` - the name of the TLS certificate in the GCP Certificate Manager.

Example for **option B** (inside the unzipped directory):

```bash
terraform init

terraform apply \
    -var "location=us-central1" \
    -var "project_id=my-project-id" \
    -var "artifactory_user=my-artifactory-user" \
    -var "artifactory_token=my-artifactory-token" \
    -var "product_name=mpc-infra" \
    -var "relay_api_key=ABEiM0RVZneImaq7zN3u8g==" \
    -var "relay_address=my-relay.XXXXX.com" \
    -var "admin_access_token=XXXXXXXXXXXXXXXXXX" \
    -var "vertex_dns_address=my-vertex.XXXXX.com" \
    -var "tls_cert_name=my-cert-name"
```

For **option A**, run the same command from the root module that references `module "vertex"`.

### 5. Setting the DNS Record for `URL_ENDPOINT` to Point to the Vertex

After running `terraform apply` there will be an IP address as an output with this title `vertex_public_ip_address`.
Copy it and create an `A` record for `URL_ENDPOINT` that points to that IP address.

Finally, test the deployment by running the following command:

```bash
curl https://URL_ENDPOINT/health -vvv
```

The request should result in an empty `200 OK` response from the Vertex, confirming it is indeed up and running.

## Customizing Helm Chart Values

While the Terraform module is the recommended way to deploy the Vertex, the underlying Helm chart can be customized directly for a finer-grained control over the deployment.
The Helm chart is available in the Sodot's Helm repository, and can be downloaded using the following commands:

```bash
helm registry login -u <ARTIFACTORY_USER> -p <ARTIFACTORY_TOKEN> repo.sodot.dev
helm pull oci://repo.sodot.dev/sodot-helm-charts/vertex-gcp
```

After pulling the chart, you can extract the chart files and modify them according to your needs.
After modifying the files, run the following command to install the chart:

:::note[Choosing Sodot Product]
The default values for the Helm chart deploys the Vertex configured for `mpc-infra`.
If you wish to deploy the Vertex for `exchange-api-vault`, you will need to set the `vertex.image.name` value to `vertex-exchange-api-vault` in the `values.yaml` file.
:::

```bash
helm install sodot-vertex oci://repo.sodot.dev/sodot-helm-charts/vertex-gcp -f values.yaml
```

### Example

You can use existing `cert-manager` and `external-dns` installations deployed on your cluster in order to manage the TLS certificate and DNS record respectively for the Vertex by making the following modifications to the `values.yaml` file:

* For `cert-manager` set:
  * `cert_manager.issuer = <Issuer name that is deployed on the cluster>`, or
  * `cert_manager.cluster_issuer = <ClusterIssuer name that is deployed on the cluster>`
* For `external-dns` set the `external_dns_hostname` value to the desired hostname for the Vertex (i.e. `ENDPOINT_URL`).

All configurable values, including the ones above, are documented in the `values.yaml` file.
