🎉 First commit

This commit is contained in:
2023-09-18 22:31:19 +02:00
commit 4c23ce19c3
9 changed files with 592 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
setup_env.sh
kubeconfig-k8s-projects.yaml
**/*.old
**/*.new

View File

@@ -0,0 +1,240 @@
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-carrramba
namespace: default
spec:
acme:
email: me@adrien.run
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-carrramba
solvers:
- http01:
ingress:
class: istio
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: carrramba-encore-rate-frontend
labels:
app: carrramba-encore-rate-frontend
spec:
replicas: 1
selector:
matchLabels:
app: carrramba-encore-rate-frontend
template:
metadata:
labels:
app: carrramba-encore-rate-frontend
spec:
containers:
- name: carrramba-encore-rate-frontend
image: rg.fr-par.scw.cloud/asr-projects/carrramba-encore-rate-frontend:latest
ports:
- name: web
containerPort: 80
imagePullSecrets:
- name: registry-secret
---
apiVersion: v1
kind: Service
metadata:
name: carrramba-encore-rate-frontend
labels:
app: carrramba-encore-rate-frontend
spec:
ports:
- name: web
port: 80
targetPort: web
selector:
app: carrramba-encore-rate-frontend
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: carrramba-encore-rate-frontend-ingress
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: carrramba-encore-rate-frontend
port:
name: web
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: strip-api-prefix
spec:
stripPrefix:
prefixes:
- /api
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: carrramba-encore-rate-api-ingress
annotations:
cert-manager.io/cluster-issuer: letsencrypt-carrramba
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.middlewares: default-strip-api-prefix@kubernetescrd
spec:
tls:
- hosts:
- carrramba.adrien.run
secretName: tls-carrramba-encore-rate-ingress
rules:
- http:
paths:
- path: /api/
pathType: Prefix
backend:
service:
name: carrramba-encore-rate-api
port:
name: web
---
# Service account to allow pod access to Vault via K8s auth
apiVersion: v1
kind: ServiceAccount
metadata:
name: carrramba-encore-rate-api
automountServiceAccountToken: true
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: carrramba-encore-rate-api
labels:
app: carrramba-encore-rate-api
spec:
replicas: 1
selector:
matchLabels:
app: carrramba-encore-rate-api
template:
metadata:
labels:
app: carrramba-encore-rate-api
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/agent-inject-secret-carrramba-encore-rate-api: "database/creds/carrramba-encore-rate-api"
vault.hashicorp.com/agent-inject-template-carrramba-encore-rate-api: |
{{ with secret "database/creds/carrramba-encore-rate-api" -}}
export CER__DB__NAME=carrramba_encore_rate
export CER__DB__HOST=postgres
export CER__DB__PORT=5432
export CER__DB__USER={{ .Data.username }}
export CER__DB__PASSWORD={{ .Data.password }}
{{- end }}
{{ with secret "carrramba-encore-rate-api/idfm-api-key" -}}
export CER__IDFM_API_KEY={{ .Data.key }}
{{- end}}
vault.hashicorp.com/role: "carrramba-encore-rate-api"
spec:
containers:
- name: carrramba-encore-rate-api
image: rg.fr-par.scw.cloud/asr-projects/carrramba-encore-rate-api:latest
command: ["/bin/bash"]
args: ["-c", "source ${BASH_ENV} ; python ./main.py "]
# args: ["-c", "while true; do echo hello; sleep 10;done"]
ports:
- name: web
containerPort: 8080
env:
- name: BASH_ENV
value: /vault/secrets/carrramba-encore-rate-api
- name: CONFIG_PATH
value: ./config.sample.yaml
- name: CER__TRACING__ENABLE
value: "true"
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "http://jaeger-all-in-one-collector.observability.svc.cluster.local:$(JAEGER_ALL_IN_ONE_COLLECTOR_SERVICE_PORT_HTTP_OTLP)"
imagePullPolicy: Always
imagePullSecrets:
- name: registry-secret
serviceAccountName: carrramba-encore-rate-api
---
apiVersion: v1
kind: Service
metadata:
name: carrramba-encore-rate-api
labels:
app: carrramba-encore-rate-api
spec:
ports:
- name: web
port: 8080
targetPort: web
selector:
app: carrramba-encore-rate-api
---
apiVersion: batch/v1
kind: CronJob
metadata:
name: db-update
spec:
schedule: "0 1 * * 5" # At 01:00 on Friday
jobTemplate:
spec:
template:
metadata:
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/agent-inject-secret-carrramba-encore-rate-admin: "database/creds/carrramba-encore-rate-admin"
vault.hashicorp.com/agent-inject-template-carrramba-encore-rate-admin: |
{{ with secret "database/creds/carrramba-encore-rate-admin" -}}
export CER__DB__NAME=carrramba_encore_rate
export CER__DB__HOST=postgres
export CER__DB__PORT=5432
export CER__DB__USER={{ .Data.username }}
export CER__DB__PASSWORD={{ .Data.password }}
{{- end }}
{{ with secret "carrramba-encore-rate-api/idfm-api-key" -}}
export CER__IDFM_API_KEY={{ .Data.key }}
{{- end}}
vault.hashicorp.com/role: "carrramba-encore-rate-admin"
spec:
containers:
- name: db-update
image: rg.fr-par.scw.cloud/asr-projects/carrramba-encore-rate-db-updater:latest
command: ["/bin/bash"]
args: ["-c", "source ${BASH_ENV} ; python -m db_updater.fill_db"]
imagePullPolicy: IfNotPresent
env:
- name: BASH_ENV
value: /vault/secrets/carrramba-encore-rate-admin
- name: CONFIG_PATH
value: ./config.sample.yaml
restartPolicy: Never
imagePullSecrets:
- name: registry-secret
serviceAccountName: carrramba-encore-rate-admin
---
# Service account to allow pod access to Vault via K8s auth
apiVersion: v1
kind: ServiceAccount
metadata:
name: carrramba-encore-rate-admin
automountServiceAccountToken: true

110
init.sh Executable file
View File

@@ -0,0 +1,110 @@
#!/bin/bash
source ./setup_env.sh
snap install kubectl --classic
snap install vault --classic
kubectl create secret docker-registry registry-secret \
--docker-server=rg.fr-par.scw.cloud \
--docker-username=asr-projects \
--docker-password=$SCW_SECRET_KEY
kubectl get secret registry-secret --output=yaml
# Install traefik
helm repo add traefik https://traefik.github.io/charts
helm repo update
kubectl create ns traefik
helm --kubeconfig ./kubeconfig-k8s-projects.yaml install -n traefik traefik traefik/traefik
# Install cert-manager
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm --kubeconfig ./kubeconfig-k8s-projects.yaml install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.12\
--set installCRDs=true
# Install vault
helm repo add hashicorp https://helm.releases.hashicorp.com
helm repo update
helm install vault hashicorp/vault
vault secrets enable database
# Install traefik
helm repo add traefik https://traefik.github.io/charts
helm repo update
helm install traefik traefik/traefik
# Install prometheus
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
kubectl create ns monitoring
helm --kubeconfig ./kubeconfig-k8s-projects.yaml \
-n monitoring install kube-prometheus-stack prometheus-community/kube-prometheus-stack
kubectl port-forward vault-0 8200:8200 &
export VAULT_ADDR='http://127.0.0.1:8200'
# Enable db passwords management by Vault
# Cf. https://www.hashicorp.com/blog/dynamic-database-credentials-with-vault-and-kubernetes
vault auth enable kubernetes
vault write auth/kubernetes/config \
kubernetes_host=https://5c3a37c1-03b3-4a9d-b36f-45566ece9847.api.k8s.fr-par.scw.cloud:6443 \
disable_local_ca_jwt=true
vault secrets enable database
vault write database/config/carrramba_encore_rate \
plugin_name=postgresql-database-plugin \
verify_connection=false \
allowed_roles="*" \
connection_url="postgresql://{{username}}:{{password}}@postgres:5432/carrramba_encore_rate?sslmode=disable" \
username="postgres" \
password="password"
vault policy write carrramba-encore-rate-api vault-carrramba-encore-rate-api-policy.hcl
vault write --force /database/rotate-root/carrramba_encore_rate
# TODO: Restore default_ttl and max_ttl once the api able to reload env variable on change.
vault write database/roles/carrramba-encore-rate-api \
db_name=carrramba_encore_rate \
creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \
GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
revocation_statements="ALTER ROLE \"{{name}}\" NOLOGIN;"\
default_ttl="768h" \
max_ttl="768h"
# default_ttl="1h" \
# max_ttl="24h"
vault write auth/kubernetes/role/carrramba_encore_rate_api \
bound_service_account_names=carrramba-encore-rate-api \
bound_service_account_namespaces=default \
policies=carrramba-encore-rate-api \
ttl=1h
vault policy write carrramba-encore-rate-admin vault-carrramba-encore-rate-admin-policy.hcl
vault write database/roles/carrramba-encore-rate-admin \
db_name=carrramba_encore_rate \
creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \
ALTER ROLE \"{{name}}\" SUPERUSER;" \
revocation_statements="ALTER ROLE \"{{name}}\" NOLOGIN;"\
default_ttl="1h" \
max_ttl="24h"
vault write auth/kubernetes/role/carrramba-encore-rate-admin \
bound_service_account_names=carrramba-encore-rate-admin \
bound_service_account_namespaces=default \
policies=carrramba-encore-rate-admin \
ttl=1h
vault secrets enable -path="carrramba-encore-rate-api" -description="carrramba-encore-rate secrets" kv
vault kv put carrramba-encore-rate-api/idfm-api-key key=$(pass dev/idfm_prim_api_token)
# Install tracing (cf. https://www.jaegertracing.io/docs/1.49/operator/)
kubectl create namespace observability
kubectl create -f https://github.com/jaegertracing/jaeger-operator/releases/download/v1.49.0/jaeger-operator.yaml -n observability
kubectl apply -f observability.yaml -n observability
kubectl apply -f carrramba-cert.yaml
kubectl apply -f carrramba-encore-rate-deployment.yaml

25
observability.yaml Normal file
View File

@@ -0,0 +1,25 @@
---
apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
name: jaeger-all-in-one
spec:
strategy: allInOne
storage:
type: memory
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: jaeger-all-in-one
spec:
template:
spec:
containers:
- name: jaeger-all-in-one
image: jaegertracing/jaeger-operator:master
args: ["start"]
env:
- name: COLLECTOR_OTLP_ENABLED
value: "true"

114
postgres.yaml Normal file
View File

@@ -0,0 +1,114 @@
kind: PersistentVolume
apiVersion: v1
metadata:
name: postgres-pv-volume
labels:
type: local
app: postgres
spec:
storageClassName: manual
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
hostPath:
path: "/mnt/data"
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: postgres-pv-claim
labels:
app: postgres
spec:
storageClassName: manual
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
# apiVersion: v1
# kind: ConfigMap
# metadata:
# name: postgres-config
# labels:
# app: postgres
# data:
# POSTGRES_DB: carrramba_encore_rate
# POSTGRES_USER: postgres
# POSTGRES_PASSWORD: password
# ---
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
spec:
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
service: postgres
spec:
containers:
- name: postgres
image: postgres:15.3
# command: [ "sh", "-c"]
# args: ["while true; do echo 'yo' && sleep 5; done;"]
# imagePullPolicy: "IfNotPresent"
ports:
- containerPort: 5432
env:
- name: POSTGRES_DB
value: carrramba_encore_rate
- name: POSTGRES_USER
value: postgres
- name: POSTGRES_PASSWORD
value: password
# envFrom:
# - configMapRef:
# name: postgres-config
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: postgredb
- mountPath: /docker-entrypoint-initdb.d
name: initdb
volumes:
- name: postgredb
persistentVolumeClaim:
claimName: postgres-pv-claim
- name: initdb
configMap:
name: postgres-initdb-config
---
apiVersion: v1
kind: ConfigMap
metadata:
name: postgres-initdb-config
data:
initdb.sql: |
CREATE DATABASE carrramba_encore_rate;
CREATE EXTENSION IF NOT EXISTS pg_trgm;
---
apiVersion: v1
kind: Service
metadata:
name: postgres
labels:
app: postgres
spec:
type: ClusterIP
ports:
- port: 5432
targetPort: 5432
selector:
app: postgres

66
redis.yaml Normal file
View File

@@ -0,0 +1,66 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: redis-config
data:
redis-config: |
maxmemory 1gb
maxmemory-policy allkeys-lru
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:latest
command:
- redis-server
- "/redis-master/redis.conf"
env:
- name: MASTER
value: "true"
ports:
- containerPort: 6379
# resources:
# limits:
# cpu: "0.1"
volumeMounts:
- mountPath: /redis-master-data
name: data
- mountPath: /redis-master
name: config
volumes:
- name: data
emptyDir: {}
- name: config
configMap:
name: redis-config
items:
- key: redis-config
path: redis.conf
---
apiVersion: v1
kind: Service
metadata:
name: redis
labels:
app: redis
spec:
type: NodePort
ports:
- port: 6379
selector:
app: redis

View File

@@ -0,0 +1,7 @@
path "database/creds/carrramba-encore-rate-admin" {
capabilities = ["read"]
}
path "carrramba-encore-rate-api/idfm-api-key" {
capabilities = [ "read" ]
}

View File

@@ -0,0 +1,7 @@
path "database/creds/carrramba-encore-rate-api" {
capabilities = ["read"]
}
path "carrramba-encore-rate-api/idfm-api-key" {
capabilities = [ "read" ]
}

19
vault-postgres-policy.hcl Normal file
View File

@@ -0,0 +1,19 @@
# Mount secrets engines
path "sys/mounts/*" {
capabilities = [ "create", "read", "update", "delete", "list" ]
}
# Configure the database secrets engine and create roles
path "database/*" {
capabilities = [ "create", "read", "update", "delete", "list" ]
}
# Write ACL policies
path "sys/policies/acl/*" {
capabilities = [ "create", "read", "update", "delete", "list" ]
}
# Manage tokens for verification
path "auth/token/create" {
capabilities = [ "create", "read", "update", "delete", "list", "sudo" ]
}