Modern Cloud Workflow with Pebl - Part 2
Tags: devops, cloud, infrastructureascode, pebl
Published: 2023-04-25 01:01:34

In part 1 we walked through setting up a pebl project, and the workflow for running and deploying our pebl apps.

In part 2 we are going to explore the [pebl sdk](https://docs.pebl.io/reference/SDK) more by looking at incorporating redis into our application.

## Adding Redis

Adding redis into our application is quite simple. In the same way that we used `pebl.service` to create a service, all we need for redis is `pebl.redis`. From the [pebl SDK reference](https://docs.pebl.io/reference/SDK#returns-1), it says:

> returns a dictionary containing two keys, `host` and `port`. These can be passed into your favorite redis client in order to connect with the resource.

So let's see what that looks like in practice. In the same `main.py` that we used in part 1, let's add a call to `pebl.redis` and print the result:

```python
import pebl
from flask import Flask

res = pebl.redis("redis-1")
print(res)

app = Flask(__name__)

@app.route("/")
def root():
  return "Hello!"

pebl.service(app, "your-subdomain.pebl.rocks")
```

Run this with the usual `pebl run` and check the results with `pebl info`.

```bash

  pebl cluster version: 0.0.8
  ctrl-C or q to exit the info pane
  (exiting will not stop the cluster)


══ logs ═════════════════════════════════════
[853e47] {'host': 'host.docker.internal', 'port': 32769}
```

## Connecting to Redis

While it's possible to connect to redis with a raw socket and manually send and parse the payloads, it's much easier and recommended to use a dedicated library. In this guide we will be using [redis-py](https://github.com/redis/redis-py) which is available as a [PyPI package](https://pypi.org/project/redis/).

First update the `Dockerfile` install redis-py while building our project:

```bash
FROM peblcloud/python:0.0.8
COPY main.py .
RUN pip install Flask redis
ENTRYPOINT python -u main.py
```

Then update `main.py` to utilize the new redis client, passing the `host` and `port` information that the pebl SDK provides:

```python
import pebl
import redis
from flask import Flask

conn = redis.Redis(**pebl.redis("redis-1"))
print(conn.ping())

app = Flask(__name__)

@app.route("/")
def root():
  return "Hello!"

pebl.service(app, "your-subdomain.pebl.rocks")
```

Note that `redis.Redis` takes two named parameters, `host` and `port`, which means that we can conveniently pass along the result of `pebl.redis` by unpacking the dictionary with `**`.

Run this and check the output! `conn.ping()` should return `True` if everything is wired up properly, which you should see printed on the info pane.

## A Simple Counter

Let's incorporate redis into our Flask application!

As an example we'll be creating a simple counter endpoint. A `POST` request to the endpoint will increment the counter, and `GET` request will return the current count.

```python
import pebl
import redis
from flask import Flask

conn = redis.Redis(**pebl.redis("redis-1"))

app = Flask(__name__)

@app.route("/")
def root():
  return "Hello!"

@app.route("/counter", methods=["POST"])
def increment():
  conn.incr("counter")
  return "success!"

@app.route("/counter", methods=["GET"])
def get_count():
  curr = conn.get("counter")
  return {
    "counter": int(curr) if curr else 0
  }

pebl.service(app, "your-subdomain.pebl.rocks")
```

Go ahead and run this with `pebl run` and play around with it! To use curl to send post requests make sure to supply the correct args. (Make sure to put in the correct port as shown by the info pane!)

```bash
$ curl -XPOST localhost:32770/counter
```

## Cloud Runtime

Try running this in the cloud! Just use `pebl deploy` like we did in part 1, and you should see your application update seamlessly. Once completed you'll be able to query the `/counter` endpoints as you were doing locally!

Make sure to use `https` when querying the cloud endpoints:

```bash
$ curl -XPOST https://hey.pebl.rocks/counter
```

### Tunnel

Previously when running this project on the local runtime, you might have noticed that the info pane shows
the local port for each redis instance:

```bash

  pebl cluster version: 0.0.8
  ctrl-C or q to exit the info pane
  (exiting will not stop the cluster)

      redis:redis-1 → localhost:12345
```

If you were curious, you might have already tried connecting to this local port. If you
haven't, simply invoke `redis-cli` with the `-p` argument, taking care to provide
the port that's shown on your info pane:

```bash
$ redis-cli -p 12345
```

In order to provide a seamless experience no matter which runtime you are running on,
we provide a `pebl tunnel` command that replicates this experience for the cloud runtime.
The command takes the name of a redis instance running in the cloud runtime, and it creates
a tunnel from a locally bound port. So if our redis instance was named `redis-1`, we would invoke:

```
$ pebl tunnel redis-1
tunnel established at: 127.0.0.1:12345
use redis-cli to connect:
redis-cli -p 12345
```

As you can see the output of the command gives the local port to connect to, in the same way that you had
with the local runtime.

Lastly, as a convenience, if you only have one redis instance in the cloud runtime, you can
omit the `name` argument to `pebl tunnel`, and it will automatically connect to the sole redis instance:

```
$ pebl tunnel
tunnel established at: 127.0.0.1:12345
use redis-cli to connect:
redis-cli -p 12345
```

## Next in Part 3

Feel free to play around with utilizing more [redis commands](https://redis.io/commands/) in this application. Afterwards head to part 3 in which we will cover pebl's object store interface which provides an intuitive way to manage storing blobs in the cloud.