Skip to content

Commit

Permalink
feat: switch to Telepresence based developer story (#37)
Browse files Browse the repository at this point in the history
This change changes the codebase to be Telepresence-friendly by:
- creating IntelliJ IDEA modules and run configurations
- moving the deployment manifests to the arikkfir/delivery repository
- removing Skaffold usage (replaced by Telepresence)
  • Loading branch information
arikkfir committed Sep 5, 2023
1 parent e16e9cd commit 198c44b
Show file tree
Hide file tree
Showing 31 changed files with 26 additions and 1,452 deletions.
135 changes: 26 additions & 109 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,135 +2,52 @@

GreenSTAR is an accounting application built for the new generation.

- https://app.admin.greenstar.kfirs.com
- https://app.greenstar.kfirs.com
- https://app.operations.greenstar.kfirs.com

(the above do not work yet)

## Local development environment

### Prerequisite tools

```shell
$ brew install jq yq # JSON and YAML manipulation
$ brew install go node # Programming languages
$ brew install kubernetes-cli kustomize helm kind # Kubernetes tools
$ brew install skaffold # Kubernetes development tool
$ brew install dnsmasq mkcert # For local TLS domains
$ brew install jq yq # Just useful tools for JSON and YAML manipulation
$ brew install go node # Programming languages
$ brew install kubernetes-cli # Kubernetes CLI
```

### Local testing domains

Given that the application has multiple components, and each needs to be addressable separately via a separate domain,
we need to use the same convention even when running locally.

To do that, we will utilize `dnsmasq` to resolve the `greenstar.test` domain to localhost. To do that, perform the
following actions (once):
### Telepresence setup

```shell
$ cat >> /opt/homebrew/etc/dnsmasq.conf <<EOF
address=/.greenstar.test/127.0.0.1
server=8.8.8.8
server=8.8.4.4
EOF
$ sudo brew services restart dnsmasq
$ dig @127.0.0.1 foobar.greenstar.test # sanity test
$ sudo mkdir /etc/resolver
$ cat <<EOF | sudo tee /etc/resolver/greenstar
domain greenstar.test
search greenstar.test
nameserver 127.0.0.1
EOF
$ sudo killall -HUP mDNSResponder
$ scutil --dns # sanity test; verify resolver for "greenstar.test" appears and working

... replace DNS server with 127.0.0.1 in macOS network manager...

$ dig foobar.greenstar.test # sanity test (notice it's not the same sanity as above)
```
Install Telepresence by following [this guide](https://www.getambassador.io/docs/telepresence-oss/latest/install).

See [this blog post](https://mjpitz.com/blog/2020/10/21/local-ingress-domains-kind/) for more information.
It's also possible you'll need to [apply these changes](https://www.getambassador.io/docs/telepresence-oss/latest/troubleshooting#volume-mounts-are-not-working-on-macos)
if you need to have volume mounts working on macOS.

### Local TLS

It is not sufficient to just resolve the `*.greenstar.test` domain to localhost, we also need it to work with TLS, since
we are utilizing Auth0 which uses cryptographic APIs, which require secure hosts. To do that, follow the following
actions:
You'll also need to connect to the cluster once with a durable connection, like so:

```shell
$ mkcert -install
$ cd deploy/local
$ mkcert '*.greenstar.test'
```

See [this blog post](https://web.dev/how-to-use-local-https/) for more information.

### Setup cluster

Replace the relevant values with something representing you, e.g. your local username, or something similar. The app
(when in dev mode) will create a few transient resources (e.g. Cloud Pub/Sub topics, subscriptions, etc) in the GCP
project associated with this ID, to differentiate it from similar resources used by other developers. Make sure you
don't use something secret - a name or nickname is perfectly fine here.

```shell
$ kind create cluster --name=greenstar --config=deploy/etc/kind-cluster-config.yaml
```

### Personal secrets & values

Some values needed during local development are not shared, and are personally related to the development team. To make
those available while running, perform the following (assuming you have access to the secrets, or use your own):

```shell
$ touch frontend/apply-patches.sh
$ cat > deploy/local/backend-secrets.env <<EOF
AUTH_DESCOPE_PROJECT_ID=descope_project_id
AUTH_DESCOPE_MANAGEMENT_KEY=descope_management_key
DEV_MODE_ID=your_own_made_up_id
EOF
$ cat > deploy/local/frontend-secrets.env <<EOF
EOF
$ telepresence connect
```

### Running

#### Traefik

Greenstar is relying on Traefik as an ingress controller, and thus needs it to be deployed in the cluster. Since there's
no need to redeploy it on every change, you can deploy it once to your local cluster and forget about it, like so:

```shell
$ skaffold run -f deploy/etc/skaffold-traefik.yaml
```
The developer story for GreenSTAR is architected on the following principals:

This will install Traefik to the `default` namespace of the `kind` cluster you just set up. It will start responding to
requests to `*.greenstar.test` though it will not have any backends to route to (see below).
1. Every change is done in a feature or bugfix branch
2. This branch is pushed to GitHub and a pull request is created for it (PR creation has been automated)
3. PR creation triggers a dedicated environment to be created for the PR
1. This environment is deployed to a dedicated namespace in the cluster
2. The environment is accessible via a dedicated URL
4. Telepresence is then used to run the backend or frontend locally yet replacing their counterpart in the remote
namespace. For instance, the backend can be run locally, but traffic arriving to the dedicated environment's backend
will reach the locally-running process of the backend (thanks to Telepresence).
5. Once the PR is merged, the dedicated environment is deleted

#### Application
The IntelliJ IDEA project is stored in the repository (the parts that should be shared across engineers) and it contains
run configurations for the backend and frontend. These run configurations are configured to run the application locally.

To run the application in a dev-loop mode, so that changes you make will get redeployed to the local cluster, simply
run this:
However, you need to first start a Telepresence intercept, like so:

```shell
$ skaffold dev
```

This will build all container images, deploy them to the `default` namespace of the `kind` cluster you just set up, and
then make the following URLs available:

- https://api.greenstar.test - application backend (tenant agnostic)
- https://neo4j.greenstar.test - neo4j console
- https://global.greenstar.test - administration frontend (no tenant)
- [https://*.greenstar.test](https://*.greenstar.test) - tenant frontend (replace `*` with the tenant ID)

#### Application & Traefik together
# If you want to intercept the backend locally:
$ telepresence intercept --namespace=MY-ENV greenstar-frontend --port 8080:http --env-file ./frontend/intercept.env

You can also deploy both Traefik and the application in one dev-loop command, so that they are both redeployed on
changes you make, like so:

```shell
$ skaffold dev -p traefik
# If you want to intercept the frontend locally:
$ telepresence intercept --namespace=MY-ENV greenstar-backend --port 8000:http --env-file ./backend/intercept.env
```

This activates the `traefik` Skaffold profile, which simply includes the Traefik skaffold module as a dependency.
114 changes: 0 additions & 114 deletions deploy/base/app/backend.yaml

This file was deleted.

97 changes: 0 additions & 97 deletions deploy/base/app/frontend.yaml

This file was deleted.

10 changes: 0 additions & 10 deletions deploy/base/app/kustomization.yaml

This file was deleted.

Loading

0 comments on commit 198c44b

Please sign in to comment.