[Infrastructure as Code (IaC) Pulumi] Use Pulumi kubernetes (K8S) Helm Chart to deploy Sentry 9.x

Sentry

Sentry is a service that helps you monitor and fix crashes in realtime. The server is in Python, but it contains a full API for sending events from any language, in any application.

This article is about how to use Pulumi, kubernetes (K8S) provider, Helm Chart and TypeScript SDK to deploy Sentry 9.x within Kubernetes (K8S).

Prerequisites

Usage

Pulumi New

Create the workspace directory.

1
2
3
$ mkdir -p col-example-pulumi-typescript-sentry

$ cd col-example-pulumi-typescript-sentry

Pulumi login into local file system.

1
2
3
$ pulumi login file://.
Logged in to cloudolife as cloudolife (file://.)
or visit https://pulumi.com/docs/reference/install/ for manual instructions and release notes.

Pulumi new a project with kubernetes-typescript SDK.

1
$ pulumi new kubernetes-typescript

The above command will create some files within the current directory.

1
2
3
4
5
6
7
8
tree . -L 1
.
├── node_modules/
├── package.json
├── package.json.lock
├── Pulumi.dev.yaml
├── Pulumi.yaml
└── main.ts

Install js-yaml package to load and parse yaml file.

1
$ npm i js-yaml

Pulumi Configuration

Configure Kubernetes

By default, Pulumi will look for a kubeconfig file in the following locations, just like kubectl:

  • The environment variable: $KUBECONFIG,

  • Or in current user’s default kubeconfig directory: ~/.kube/config

If the kubeconfig file is not in either of these locations, Pulumi will not find it, and it will fail to authenticate against the cluster. Set one of these locations to a valid kubeconfig file, if you have not done so already.

Configure Values.yaml

Edit values.yaml and replace content within {{ }}.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# values.yaml

# charts/values.yaml at master · helm/charts
# https://github.com/helm/charts/blob/master/stable/sentry/values.yaml

# Admin user to create
user:
# Indicated to create the admin user or not,
# Default is true as the initial installation.
create: true
email: {{ .Values.user.email }}
password: {{ .Values.user.password }}

# Name of the service and what port to expose on the pod
# Don't change these unless you know what you're doing
service:
type: ClusterIP

# Configure the location of Sentry artifacts
filestore:

filesystem:

## Enable persistence using Persistent Volume Claims
## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/
##
persistence:
size: 10Gi

postgresql:
password: {{ .Values.postgresql.password }}
postgresqlPassword: {{ .Values.postgresql.password }}

redis:
password: {{ .Values.redis.password }}

## Prometheus Exporter / Metrics
##
metrics:
enabled: true

manifests

Edit manifests/Ingress.yaml and replace content within {{ }}.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# manifests/Ingress.yaml

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: "nginx"

name: sentry
namespace: sentry
spec:
rules:
- host: {{ .Values.host }}
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: sentry
port:
number: 9000

tls:
- hosts:
- {{ .Values.host }}
secretName: {{ .Values.tls.secretName }}

main.ts

See and modify main.ts file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// main.ts

import * as pulumi from "@pulumi/pulumi";

import * as k8s from "@pulumi/kubernetes";

const yaml = require('js-yaml');
const fs = require('fs');

const configGroup = new k8s.yaml.ConfigGroup(name, {
files: [`./manifests/*.yaml`],
});

const nameSentry = "sentry"

// kubernetes.core/v1.Namespace | Pulumi
// https://www.pulumi.com/docs/reference/pkg/kubernetes/core/v1/namespace/
const namespaceSentry = new k8s.core.v1.Namespace(nameSentry, {
metadata: {
name: nameSentry,
},
})

const values = yaml.safeLoad(fs.readFileSync("./values.yaml", 'utf8'))

const charNameSentry = "sentry"

// sentry 4.0.1 · kubernetes/sentry
// https://artifacthub.io/packages/helm/sentry/sentry
const charSentry = new k8s.helm.v3.Chart(charNameSentry, {
chart: charNameSentry,
version: "4.3.3",
fetchOpts:{
// repo: "https://charts.helm.sh/stable",
repo: "http://mirror.azure.cn/kubernetes/charts/",
},
namespace: namespaceSentry.metadata.name,
values: values,
});

Pulumi Up

Run pulumi up to create the namespace and pods.

1
$ pulumi up

See pods about sentry.

1
2
3
4
5
6
7
8
9
10
11
12
$ kubectl get pods -n sentry
sentry-cron-65567f8867-cbf89 1/1 Running 0 174m
sentry-db-init--1-lpg6q 0/1 Completed 0 174m
sentry-metrics-6d67cf6cbf-f5hgr 1/1 Running 0 6h44m
sentry-sentry-postgresql-0 1/1 Running 0 6h44m
sentry-sentry-redis-master-0 1/1 Running 0 6h44m
sentry-sentry-redis-slave-0 1/1 Running 12 (120m ago) 6h45m
sentry-sentry-redis-slave-1 1/1 Running 0 6h18m
sentry-user-create--1-cfqtw 0/1 Completed 0 174m
sentry-web-d54b4c4c5-xh4hj 1/1 Running 0 174m
sentry-worker-577757d4c7-5cdkn 1/1 Running 0 174m
sentry-worker-577757d4c7-6lh6c 1/1 Running 0 174m

Pulumi Destroy

Destroy all resources created by Pulumi.

1
$ pulumi destroy

FAQs

502 Bad Gateway

Sentry may fail to initialize or upgrade database since it will take too long. You can do it yoursef.

First, enter into Pod sentry-web bash.

1
$ kubectl exec -n sentry `kubectl get pods -n sentry | grep sentry-web | awk '{print $2}'` -it -- bash

Then, run sentry upgrade within container to run all migrations and create an admin account.

1
$ sentry upgrade

Finally, you can visit Web UI without any error.

References

[1] charts/stable/sentry at master · helm/charts - https://github.com/helm/charts/tree/master/stable/sentry

[2] Azure Helm mirror - http://mirror.azure.cn/kubernetes/charts/

[3] charts/.Values.yaml at master · helm/charts - https://github.com/helm/charts/blob/master/stable/sentry/.Values.yaml

[4] Sentry | Error Tracking Software — JavaScript, Python, PHP, Ruby, more - https://sentry.io/welcome/

[5] getsentry/sentry: Sentry is cross-platform application monitoring, with a focus on error reporting. - https://github.com/getsentry/sentry

[6] Kubernetes Getting Started | Pulumi - https://www.pulumi.com/docs/get-started/kubernetes/

[7] Pulumi - Modern Infrastructure as Code - https://www.pulumi.com/

[8] Kubernetes - https://kubernetes.io/

[9] TypeScript: Typed JavaScript at Any Scale. - https://www.typescriptlang.org/

[10] Helm - https://helm.sh/