# Deploy Feast with the feast template

Source: https://docs.quake.ai/resources/deployments/deploy-feast-template
Markdown: https://docs.quake.ai/resources/deployments/deploy-feast-template.md

---

# Deploy Feast with the feast template

Stand up [Feast](https://feast.dev), an open-source feature store, on a single Quake AI instance using the [validated OpenTofu template](/docs/platform/validation#how-infrastructure-templates-are-checked) `feast`. You apply the template, confirm the bundled Postgres and Redis containers start, and fetch online features from the sample driver view.

Feast is the feature layer for ML serving and training. You run it yourself; this is a self-hosted tool you operate, not a hosted feature platform.

<Figure size="md" caption="What you will build: a Feast host with bundled Postgres and Redis, serving online features on port 6566">

```d2
direction: right

dev: You {shape: person}
app: Inference app {shape: person}
fip: Floating IP
instance: Ubuntu instance {
  feast: Feast\nfeature server
  postgres: Postgres\noffline + registry
  redis: Redis\nonline store
  feast -> postgres: reads history
  feast -> redis: serves features
}

dev -> fip: SSH + feast CLI
app -> fip: gRPC 6566
fip -> instance.feast
```

</Figure>

<PricingCompanion
  components={[
    { kind: "template", slug: "feast", required: true },
  ]}
/>

## Prerequisites

You need:

- OpenTofu 1.6.0 or later installed locally.
- Your OpenStack credentials sourced into the shell (`source openrc.sh`). See [the OpenStack CLI guide](/docs/tools/openstack-cli).
- An SSH keypair that already exists in your project. Record its name for the `key_name` variable.
- A copy of the `feast` template directory from [the template reference page](/resources/iac-templates/feast).
- Your workstation public IP address for first-boot access to port 6566. Find it with `curl -sS https://api.ipify.org`.

## Step 1: Set the variables and apply the template

The feature server listens on port 6566. The template security group restricts 6566 to `server_allowed_cidr`, which defaults to the private network only. To reach the server from your workstation for first-boot checks, set `server_allowed_cidr` to your own address.

Copy the template example variables file and open it:

```bash
cp terraform.tfvars.example terraform.tfvars
```

Set `key_name` to the SSH keypair already in your project, and `server_allowed_cidr` to your workstation public IP with a `/32` suffix:

```hcl
key_name             = "YOUR_KEY_NAME"
server_allowed_cidr  = "YOUR_IP/32"
```

Initialize the working directory, preview the plan, and apply:

```bash
tofu init
tofu plan
tofu apply
```

OpenTofu provisions a private network, router, security group, block volume mounted at `/var/lib/docker`, an instance, and a floating IP. On first boot, cloud-init installs Docker Engine, starts bundled Postgres and Redis, runs `feast apply`, materializes sample driver features, and starts the feature server.

When the apply finishes, read the outputs:

```bash
tofu output
```

Record `floating_ip` and `feature_server_url`.

## Step 2: Confirm the containers are healthy

cloud-init takes several minutes after the instance reaches `ACTIVE`. SSH to the instance and watch the stack come up:

```bash
ssh ubuntu@YOUR_FLOATING_IP "sudo docker ps --format 'table {{.Names}}\t{{.Status}}'"
```

You should see `feast-server`, and in bundled mode also `postgres` and `redis`, in a running or healthy state. If `feast-init` exited with code 0, the registry and sample features are applied.

Inspect the generated password location (do not commit this file):

```bash
ssh ubuntu@YOUR_FLOATING_IP "sudo ls -l /opt/feast/.env"
```

Feast reads Postgres credentials from that file; no password ships in the template or tfvars.

## Step 3: Fetch online features

Install the Feast CLI locally or run it in a one-off container on the instance. From the instance:

```bash
ssh ubuntu@YOUR_FLOATING_IP
cd /opt/feast/feature_repo
sudo docker run --rm --network feast_feast-net \
  -v /opt/feast/feature_repo:/feature_repo -w /feature_repo \
  python:3.11-slim bash -c \
  "pip install -q 'feast[postgres,redis]==0.47.0' && \
   feast get-online-features \
   --entities driver_id:1001 \
   --features driver_hourly_stats:conv_rate driver_hourly_stats:acc_rate"
```

Feast returns the materialized feature values for driver `1001` from the Redis online store.



Leave `server_allowed_cidr` at its default and tunnel over SSH: `ssh -L 6566:localhost:6566 ubuntu@YOUR_FLOATING_IP`. Your inference client then targets `localhost:6566`.



## What you built

- **Applied the `feast` template** to provision network, security group, data volume, instance, and floating IP
- **Started bundled Postgres and Redis** as the offline store, SQL registry, and online store
- **Verified online feature retrieval** from the sample `driver_hourly_stats` feature view

## Scope of this deployment

This template runs a single-VM Feast host with bundled stores, not a hosted feature platform. The instance is CPU-only. You operate Docker, Postgres, Redis, and the data volume yourself: back them up, patch them, and watch resource use as feature volume grows. For production, point `store_mode` at `external` and wire Postgres and Redis from the dedicated templates, then size the instance up.

## Next steps

- [Feast template](/resources/iac-templates/feast): the template reference, parameters, and resource map
- [self-managed PostgreSQL template](/resources/iac-templates/self-managed-postgres): external offline store and registry
- [Redis cache template](/resources/iac-templates/redis-cache): external online store
- [How to store application secrets and inject them at runtime](/docs/security/how-to/inject-app-secrets): keep database passwords out of tfvars

## Clean up

When you no longer need the deployment, destroy everything the template created:

```bash
tofu destroy
```

Registry metadata, online features, and Postgres data all live on the instance and its attached volume, so `tofu destroy` removes them with the infrastructure.
