Introduction

Civo managed Kubernetes is currently in beta, and has a number of applications on the Kubernetes marketplace that can be easily installed on a cluster. At the time of me writing this guide, Hasura is not (yet) available on the marketplace, so I wrote this guide to set up Hasura in the Civo k3s service. I hope you find it useful!

If you are not yet a member of the Civo Kubernetes #KUBE100 beta, you can apply to join here. All testers get a monthly allowance of $70 for the duration of the beta in exchange for their feedback.

What is Hasura?

According to the official site:

Hasura is an open source engine that connects to your databases & microservices and instantly gives you a production-ready GraphQL API. Usable for new & existing applications, and auto-scalable.

So essentially, Hasura allows us to use GraphQL to query data in databases. That's handy!

Deployment

As mentioned above, you will need a Civo account with Kubernetes access. Once you are logged in, navigate to the Kubernetes menu to create a new cluster. In my case, I am creating a 3-node cluster of Medium-sized nodes (2 CPU, 4GB, 50GB storage each):

Hasura cluster creation

When you scroll down to the Marketplace section, select PostgreSQL with a 5GB storage option. Then you are ready to start your cluster!

Postgresql

Once the cluster is running, we will need to download the KUBECONFIG so we can create a user for Hasura and the database. You can do this from the web UI, or using the CLI. The web UI has this option, shown below. Save it and set kubectl to use it - if this is your only cluster you can save the resulting file as ~/.kube/config, or if you are running multiple clusters, follow these instructions.

Kubeconfig download

Next, connect to the Postgres server within k3s and activate it:

kubectl run tmp-shell --generator=run-pod/v1 --rm -i --tty --image alpine -- /bin/sh

Once inside the pod we will do this:

apk update
apk add postgresql-client
psql -U $user -h postgresql postgresdb

Please note that the $user in the above example is given to us by the Civo UI. You will need to substitute the generated value for the $user. This will ask us for a password which is given in the UI as well. Once connected to Postgres we run these commands to create a user for hasura in our database as well. We will then connect to our database and enable a cryptographic extension pgcrypt required by Hasura:

CREATE DATABASE todo;
CREATE USER hasura WITH ENCRYPTED PASSWORD 'hasuradb';
CREATE SCHEMA hdb_catalog;
CREATE SCHEMA hdb_views;
ALTER SCHEMA hdb_catalog OWNER TO hasura;
ALTER SCHEMA hdb_views OWNER TO hasura;
GRANT SELECT ON all tables IN SCHEMA information_schema TO hasura ;
GRANT SELECT ON all tables IN SCHEMA pg_catalog TO hasura ;
GRANT usage ON SCHEMA public TO hasura;
GRANT all ON all tables IN SCHEMA public TO hasura ;
GRANT all ON all sequences IN SCHEMA public TO hasura ;
grant all privileges on database todo to hasura ;
\c todo;
CREATE extension IF NOT EXISTS pgcrypto;

You can then exit from the Postgresql administrator by typing \q and Enter.

Once this is done, we will deploy Hasura in our k3s cluster. The full instructions are on the Hasura repository on GitHub. For default values, you can download the yaml file, but in our case I will put them below as I have made some modifications.

First, create a deployment.yaml that contains this:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: hasura
    hasuraService: custom
  name: hasura
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: hasura
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: hasura
    spec:
      containers:
      - image: hasura/graphql-engine:latest
        imagePullPolicy: Always
        name: hasura
        env:
        - name: HASURA_GRAPHQL_DATABASE_URL
          value: postgres://hasura:hasuradb@postgresql:5432/todo
        - name: HASURA_GRAPHQL_ENABLE_CONSOLE
          value: "true"
        - name: HASURA_GRAPHQL_ADMIN_SECRET
          value: supersecretpassword # Change this to your password!
        ports:
        - containerPort: 8080
          protocol: TCP
        resources: {}

then svc.yaml that will contain this:

apiVersion: v1
kind: Service
metadata:
  name: hasura-service
spec:
  type: ClusterIP
  ports:
    - name: hasura-port
      port: 8080
      targetPort: 8080
      protocol: TCP
  selector:
    app: hasura

and finally our ingress.yaml that will be along these lines. Please note that you will need to change the host line to reflect the DNS entry provided by the Civo Kubernetes UI for your cluster:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: hasura-ingress
  namespace: default
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
  - host: 64515915-f40a-460f-bea6-bcfa16af1752.k8s.civo.com # change this!
    http:
      paths:
      - path: /
        backend:
          serviceName: hasura-service
          servicePort: hasura-port

Hasura Usage

Now only that remains will be to visit our cluster URL (in the format 64515915-f40a-460f-bea6-bcfa16af1752.k8s.civo.com and displayed on the cluster administration page) at port 8080, as defined above. In this section, we will do some tests to see that everything is working as expected.

And if all went well then we will see this:

Hasura Login

This page will accept our password, the one we declared in the deployment.yaml file. Enter it and load the Hasura UI, which should look like this:

Hasura Dashboard

Now we go to the DATA tab and click on the SQL link. Then, in the raw SQL console that comes out we paste this and press Run!:

CREATE TABLE todo_list (id INTEGER PRIMARY KEY, item TEXT, minutes INTEGER);
INSERT INTO todo_list VALUES (1, 'Wash the dishes', 15);
INSERT INTO todo_list VALUES (2, 'vacuuming', 20);
INSERT INTO todo_list VALUES (3, 'Learn about k3s on Civo', 30);

After this we return to the GRAPHIQL tab and we will see that we can already create queries about our new table. Select all relevant items (id, item, and minutes) and hit Execute Query. The result should look like this:

hasura-4

Conclusion

While this is a simple example of what you can do with Hasura once deployed, it also works for existing databases. That means you can use the GraphQL API provided by Hasura to query any SQL database you may have. By adapting the above instructions, you could easily connect an existing database, or play with the one we have created in this exercise to get to grips with Hasura syntax. Let us know what you get up to!

Have you deployed Hasura to query your databases? Let me and @civocloud on Twitter know!