Skip to content

Commit a9f6fc2

Browse files
committed
infra needed for bot
1 parent 885bed3 commit a9f6fc2

File tree

6 files changed

+203
-0
lines changed

6 files changed

+203
-0
lines changed

infra/k8s/README.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# miss-islington k8s infra
2+
3+
Kubernetes manifests for running miss-islington on cabotage instead of Heroku.
4+
5+
## What's here
6+
7+
`redis.yaml` and `cert.yaml` provision a standalone Redis instance in the `redis` namespace using the OpsTree Redis Operator (already running cluster-wide).
8+
The cert is issued by the internal `operators-ca-issuer` ClusterIssuer, ECDSA P-256, 90-day rotation.
9+
10+
`ingress.yaml` goes in the `python` namespace where cabotage deploys the app. It's a standard nginx ingress with backend-protocol
11+
HTTPS because cabotage serves on 8443/TLS behind a Service on port 443.
12+
13+
`generate-secrets.sh` creates the Redis password Secret and prints the full connection URI you need to set as `REDIS_URL` in cabotage.
14+
15+
## Setup
16+
17+
Generate the Redis password (once per cluster):
18+
19+
```
20+
./infra/k8s/generate-secrets.sh
21+
```
22+
23+
Apply the Redis CR and TLS cert:
24+
25+
```
26+
kubectl apply -k infra/k8s -n redis
27+
```
28+
29+
After cabotage has deployed the app and the Service exists, apply the ingress:
30+
31+
```
32+
kubectl apply -f infra/k8s/ingress.yaml
33+
```
34+
35+
## Cabotage env vars
36+
37+
Set these in the cabotage UI for the miss-islington application:
38+
39+
- `GH_SECRET` - GitHub webhook secret
40+
- `GH_APP_ID` - GitHub App ID
41+
- `GH_PRIVATE_KEY` - GitHub App private key
42+
- `GH_AUTH` - GitHub auth token (used by the celery worker to clone cpython)
43+
- `SENTRY_DSN` - Sentry DSN for error tracking
44+
- `REDIS_URL` - printed by `generate-secrets.sh`, looks
45+
like `rediss://:<password>@miss-islington.redis.svc.cluster.local:6379/0?ssl_ca_certs=/var/run/secrets/cabotage.io/ca.crt&ssl_cert_reqs=required`

infra/k8s/cert.yaml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
apiVersion: cert-manager.io/v1
2+
kind: Certificate
3+
metadata:
4+
name: miss-islington-certmanager
5+
spec:
6+
secretName: miss-islington-tls
7+
duration: 2160h # 90d
8+
renewBefore: 360h # 15d
9+
subject:
10+
organizations:
11+
- miss-islington-org
12+
commonName: miss-islington
13+
isCA: false
14+
privateKey:
15+
algorithm: ECDSA
16+
size: 256
17+
usages:
18+
- digital signature
19+
- key encipherment
20+
dnsNames:
21+
- miss-islington
22+
- miss-islington.redis
23+
- miss-islington.redis.svc
24+
- miss-islington.redis.svc.cluster.local
25+
- miss-islington-0
26+
- miss-islington-0.redis
27+
- miss-islington-0.redis.svc
28+
- miss-islington-0.redis.svc.cluster.local
29+
- miss-islington-1
30+
- miss-islington-1.redis
31+
- miss-islington-1.redis.svc
32+
- miss-islington-1.redis.svc.cluster.local
33+
- miss-islington-2
34+
- miss-islington-2.redis
35+
- miss-islington-2.redis.svc
36+
- miss-islington-2.redis.svc.cluster.local
37+
issuerRef:
38+
name: operators-ca-issuer
39+
kind: ClusterIssuer
40+
group: cert-manager.io

infra/k8s/generate-secrets.sh

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/bin/bash
2+
# Generate Redis password secret for miss-islington
3+
# Run once per cluster setup
4+
set -e
5+
6+
NAMESPACE="redis"
7+
SECRET_NAME="miss-islington-password"
8+
9+
echo "=== Miss Islington Redis Secret ==="
10+
11+
if kubectl get secret -n "$NAMESPACE" "$SECRET_NAME" &>/dev/null; then
12+
echo "Secret '$SECRET_NAME' already exists in namespace '$NAMESPACE'."
13+
echo "Delete it first if you want to regenerate: kubectl delete secret -n $NAMESPACE $SECRET_NAME"
14+
exit 1
15+
fi
16+
17+
PASSWORD=$(openssl rand -hex 24)
18+
19+
kubectl create secret -n "$NAMESPACE" generic "$SECRET_NAME" --from-literal=password="$PASSWORD"
20+
21+
echo ""
22+
echo "Secret '$SECRET_NAME' created in namespace '$NAMESPACE'."
23+
echo ""
24+
echo "Redis connection URI (set as REDIS_URL in cabotage):"
25+
echo "rediss://:${PASSWORD}@miss-islington.redis.svc.cluster.local:6379/0?ssl_ca_certs=/var/run/secrets/cabotage.io/ca.crt&ssl_cert_reqs=required"
26+
echo ""
27+
echo "=== Done ==="

infra/k8s/ingress.yaml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Miss Islington - Cabotage Ingress
2+
# Apply manually: kubectl apply -f infra/k8s/ingress.yaml
3+
#
4+
# Exposes the Cabotage-deployed app via nginx-ingress
5+
# with Let's Encrypt TLS certificates via cert-manager.
6+
---
7+
apiVersion: networking.k8s.io/v1
8+
kind: Ingress
9+
metadata:
10+
name: python-miss-islington-miss-islington-web
11+
namespace: python
12+
annotations:
13+
cert-manager.io/cluster-issuer: letsencrypt
14+
nginx.ingress.kubernetes.io/backend-protocol: HTTPS
15+
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
16+
nginx.ingress.kubernetes.io/proxy-connect-timeout: 10s
17+
nginx.ingress.kubernetes.io/proxy-next-upstream: error
18+
nginx.ingress.kubernetes.io/proxy-read-timeout: 60s
19+
nginx.ingress.kubernetes.io/proxy-request-buffering: "on"
20+
nginx.ingress.kubernetes.io/proxy-send-timeout: 60s
21+
nginx.ingress.kubernetes.io/service-upstream: "true"
22+
labels:
23+
app: python-miss-islington-miss-islington
24+
process: web
25+
resident-service.cabotage.io: "true"
26+
spec:
27+
ingressClassName: nginx
28+
rules:
29+
- host: python-miss-islington-miss-islington-web.ingress.us-east-2.psfhosted.computer
30+
http:
31+
paths:
32+
- backend:
33+
service:
34+
name: python-miss-islington-miss-islington-web
35+
port:
36+
number: 443
37+
path: /
38+
pathType: Prefix
39+
tls:
40+
- hosts:
41+
- python-miss-islington-miss-islington-web.ingress.us-east-2.psfhosted.computer
42+
secretName: ingress-python-miss-islington-miss-islington-web

infra/k8s/kustomization.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
namespace: redis
2+
3+
resources:
4+
- cert.yaml
5+
- redis.yaml

infra/k8s/redis.yaml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
---
2+
apiVersion: redis.redis.opstreelabs.in/v1beta1
3+
kind: Redis
4+
metadata:
5+
name: miss-islington
6+
spec:
7+
TLS:
8+
secret:
9+
secretName: miss-islington-tls
10+
optional: false
11+
securityContext:
12+
runAsUser: 1000
13+
fsGroup: 1000
14+
kubernetesConfig:
15+
image: quay.io/opstree/redis:v7.0.15
16+
imagePullPolicy: IfNotPresent
17+
redisSecret:
18+
name: miss-islington-password
19+
key: password
20+
resources:
21+
requests:
22+
cpu: 100m
23+
memory: 128Mi
24+
limits:
25+
cpu: 100m
26+
memory: 128Mi
27+
redisExporter:
28+
enabled: false
29+
image: quay.io/opstree/redis-exporter:v1.44.0
30+
imagePullPolicy: Always
31+
resources:
32+
requests:
33+
cpu: 100m
34+
memory: 256Mi
35+
limits:
36+
cpu: 100m
37+
memory: 256Mi
38+
storage:
39+
volumeClaimTemplate:
40+
spec:
41+
accessModes: ["ReadWriteOnce"]
42+
resources:
43+
requests:
44+
storage: 1Gi

0 commit comments

Comments
 (0)