[skip-ci] Make unique name for each website deploy
Add function for replacing values in the beginning of a string. Add build secret.
This commit is contained in:
parent
76f5b87ec9
commit
de88a5d807
21 changed files with 126 additions and 121 deletions
|
@ -40,9 +40,9 @@ https://www.tecmint.com/deploy-nginx-on-a-kubernetes-cluster/
|
|||
Definition von Env-Vars im Deployment:
|
||||
AUTHTOKEN - muss konfigurierbar sein
|
||||
REPOZIPURL - muss konfigurierbar sein
|
||||
TARGETDIR - wird aus dem FQDN zusammengesetzt
|
||||
WEBSITEROOT - hardcoded, da containerspezifisch
|
||||
|
||||
Ingress, Service, Certificate, Deployment, Configmap und Volume Mount sollen durch eindeutige, auf FQDN basierenden Namen verbunden sein.
|
||||
Certificate, Ingress, Configmap, Deployment, Service, Volume Claim, Website-deployment sollen durch eindeutige, auf FQDN basierenden Namen verbunden sein.
|
||||
|
||||
## Getting started
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ FROM clojure:temurin-18-jammy
|
|||
ADD resources /tmp
|
||||
|
||||
ENV BUILDDIR="website"
|
||||
ENV WEBSITEROOT="/var/www/html/website/"
|
||||
|
||||
RUN /tmp/install.sh
|
||||
RUN /tmp/entrypoint.sh
|
|
@ -7,10 +7,14 @@
|
|||
(defn k8s-objects [config]
|
||||
(cm/concat-vec
|
||||
(map yaml/to-string
|
||||
[(website/generate-nginx-deployment)
|
||||
[(website/generate-nginx-deployment config)
|
||||
(website/generate-nginx-configmap config)
|
||||
(website/generate-nginx-service)
|
||||
(website/generate-nginx-service config)
|
||||
(website/generate-website-content-volume config)
|
||||
(website/generate-ingress config)
|
||||
(website/generate-certificate config)
|
||||
(website/generate-website-build-cron config)
|
||||
(website/generate-website-build-deployment config)
|
||||
(website/generate-website-build-secret config)
|
||||
|
||||
])))
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#?(:clj [clojure.edn :as edn]
|
||||
:cljs [cljs.reader :as edn])
|
||||
[dda.c4k-common.yaml :as yaml]
|
||||
[dda.c4k-common.common :as cm]
|
||||
[dda.c4k-common.common :as cm]
|
||||
[dda.c4k-common.predicate :as pred]))
|
||||
|
||||
(defn domain-list?
|
||||
|
@ -27,15 +27,29 @@
|
|||
(def config? (s/keys :req-un [::fqdn]
|
||||
:opt-un [::issuer]))
|
||||
|
||||
(def auth? (s/keys :req-un [::none]))
|
||||
(def auth? (s/keys :req-un [::token ::url]))
|
||||
|
||||
(def vol? (s/keys :req-un [::volume-total-storage-size
|
||||
::number-of-websites]))
|
||||
|
||||
(defn data-storage-by-volume-size
|
||||
(defn volume-size-by-total-available-space
|
||||
[total number-of-websites-on-node]
|
||||
(m/floor (/ total number-of-websites-on-node))) ; ToDo: This might be a terrible idea
|
||||
|
||||
(defn unique-name-from-fqdn
|
||||
[fqdn]
|
||||
(st/replace fqdn #"\." "-"))
|
||||
|
||||
; ToDo: Move to common
|
||||
(defn-spec replace-all-matching-subvalues-in-string-start pred/map-or-seq?
|
||||
[col string?
|
||||
value-to-partly-match string?
|
||||
value-to-inplace string?]
|
||||
(clojure.walk/postwalk #(if (and (= (type value-to-partly-match) (type %))
|
||||
(re-matches (re-pattern (str value-to-partly-match ".*")) %))
|
||||
(st/replace % value-to-partly-match value-to-inplace) %)
|
||||
col))
|
||||
|
||||
#?(:cljs
|
||||
(defmethod yaml/load-resource :website [resource-name]
|
||||
(case resource-name
|
||||
|
@ -45,6 +59,9 @@
|
|||
"website/nginx-deployment.yaml" (rc/inline "website/nginx-deployment.yaml")
|
||||
"website/nginx-service.yaml" (rc/inline "website/nginx-service.yaml")
|
||||
"website/website-content-volume.yaml" (rc/inline "website/website-content-volume.yaml")
|
||||
"website/website-build-cron.yaml" (rc/inline "website/website-build-cron.yaml")
|
||||
"website/website-build-deployment.yaml" (rc/inline "website/website-build-deployment.yaml")
|
||||
"website/website-build-secret.yaml" (rc/inline "website/website-build-secret.yaml")
|
||||
(throw (js/Error. "Undefined Resource!")))))
|
||||
|
||||
#?(:cljs
|
||||
|
@ -59,6 +76,7 @@
|
|||
(->
|
||||
(yaml/load-as-edn "website/certificate.yaml")
|
||||
(assoc-in [:spec :issuerRef :name] letsencrypt-issuer)
|
||||
(replace-all-matching-subvalues-in-string-start "NAME" (unique-name-from-fqdn fqdn))
|
||||
(cm/replace-all-matching-values-by-new-value "FQDN" fqdn))))
|
||||
|
||||
(defn-spec generate-ingress pred/map-or-seq?
|
||||
|
@ -66,30 +84,60 @@
|
|||
(let [{:keys [fqdn]} config]
|
||||
(->
|
||||
(yaml/load-as-edn "website/ingress.yaml")
|
||||
(replace-all-matching-subvalues-in-string-start "NAME" (unique-name-from-fqdn fqdn))
|
||||
(cm/replace-all-matching-values-by-new-value "FQDN" fqdn))))
|
||||
|
||||
(defn-spec generate-nginx-configmap pred/map-or-seq?
|
||||
(defn-spec generate-nginx-configmap pred/map-or-seq?
|
||||
[config config?]
|
||||
(let [{:keys [fqdn]} config
|
||||
configmap (yaml/load-as-edn "website/nginx-configmap.yaml")]
|
||||
(->
|
||||
configmap (yaml/load-as-edn "website/nginx-configmap.yaml")]
|
||||
(->
|
||||
configmap
|
||||
(assoc-in [:data :website.conf] (st/replace (-> configmap :data :website.conf) #"FQDN" (str fqdn ";")))
|
||||
)
|
||||
))
|
||||
(replace-all-matching-subvalues-in-string-start "NAME" (unique-name-from-fqdn fqdn)))))
|
||||
|
||||
(defn-spec generate-nginx-deployment pred/map-or-seq?
|
||||
[]
|
||||
(yaml/load-as-edn "website/nginx-deployment.yaml"))
|
||||
[config config?]
|
||||
(let [{:keys [fqdn]} config]
|
||||
(->
|
||||
(yaml/load-as-edn "website/nginx-deployment.yaml")
|
||||
(replace-all-matching-subvalues-in-string-start "NAME" (unique-name-from-fqdn fqdn)))))
|
||||
|
||||
(defn-spec generate-nginx-service pred/map-or-seq?
|
||||
[]
|
||||
(yaml/load-as-edn "website/nginx-service.yaml"))
|
||||
[config config?]
|
||||
(let [{:keys [fqdn]} config]
|
||||
(->
|
||||
(yaml/load-as-edn "website/nginx-service.yaml")
|
||||
(replace-all-matching-subvalues-in-string-start "NAME" (unique-name-from-fqdn fqdn)))))
|
||||
|
||||
(defn-spec generate-website-content-volume pred/map-or-seq?
|
||||
[config vol?]
|
||||
(let [{:keys [volume-total-storage-size number-of-websites]} config
|
||||
data-storage-size (data-storage-by-volume-size volume-total-storage-size number-of-websites)]
|
||||
(let [{:keys [volume-total-storage-size number-of-websites fqdn]} config
|
||||
data-storage-size (volume-size-by-total-available-space volume-total-storage-size number-of-websites)]
|
||||
(->
|
||||
(yaml/load-as-edn "website/website-content-volume.yaml")
|
||||
(replace-all-matching-subvalues-in-string-start "NAME" (unique-name-from-fqdn fqdn))
|
||||
(cm/replace-all-matching-values-by-new-value "WEBSITESTORAGESIZE" (str (str data-storage-size) "Gi")))))
|
||||
|
||||
(defn-spec generate-website-build-cron pred/map-or-seq?
|
||||
[config config?]
|
||||
(let [{:keys [fqdn]} config]
|
||||
(->
|
||||
(yaml/load-as-edn "website/website-build-cron.yaml")
|
||||
(replace-all-matching-subvalues-in-string-start "NAME" (unique-name-from-fqdn fqdn)))))
|
||||
|
||||
(defn-spec generate-website-build-deployment pred/map-or-seq?
|
||||
[config config?]
|
||||
(let [{:keys [fqdn]} config]
|
||||
(->
|
||||
(yaml/load-as-edn "website/website-build-deployment.yaml")
|
||||
(replace-all-matching-subvalues-in-string-start "NAME" (unique-name-from-fqdn fqdn)))))
|
||||
|
||||
(defn-spec generate-website-build-secret pred/map-or-seq?
|
||||
[auth auth?]
|
||||
(let [{:keys [fqdn token url]} config]
|
||||
(->
|
||||
(yaml/load-as-edn "website/website-build-secrets.yaml")
|
||||
(replace-all-matching-subvalues-in-string-start "NAME" (unique-name-from-fqdn fqdn))
|
||||
(cm/replace-all-matching-values-by-new-value "TOKEN" (b64/encode token))
|
||||
(cm/replace-all-matching-values-by-new-value "URL" (b64/encode url)))))
|
|
@ -1,10 +1,10 @@
|
|||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: website-cert
|
||||
name: NAME-cert
|
||||
namespace: default
|
||||
spec:
|
||||
secretName: website-cert
|
||||
secretName: NAME-cert
|
||||
commonName: FQDN
|
||||
duration: 2160h # 90d
|
||||
renewBefore: 360h # 15d
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: ingress-website
|
||||
name: NAME-ingress
|
||||
namespace: default
|
||||
annotations:
|
||||
ingress.kubernetes.io/ssl-redirect: "true"
|
||||
|
@ -10,7 +10,7 @@ spec:
|
|||
tls:
|
||||
- hosts:
|
||||
- FQDN
|
||||
secretName: website-cert
|
||||
secretName: NAME-cert
|
||||
rules:
|
||||
- host: FQDN
|
||||
http:
|
||||
|
@ -19,6 +19,6 @@ spec:
|
|||
path: "/"
|
||||
backend:
|
||||
service:
|
||||
name: nginx-service
|
||||
name: NAME-service
|
||||
port:
|
||||
number: 80
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: nginxconf
|
||||
name: NAME-configmap
|
||||
namespace: default
|
||||
data:
|
||||
nginx.conf: |
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx
|
||||
name: NAME-deployment
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
app: NAME-nginx
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
app: NAME-nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
- name: NAME-nginx
|
||||
image: nginx:latest
|
||||
imagePullPolicy: "Always"
|
||||
ports:
|
||||
|
@ -21,7 +21,7 @@ spec:
|
|||
volumeMounts:
|
||||
- mountPath: /etc/nginx
|
||||
readOnly: true
|
||||
name: nginxconfigvol
|
||||
name: nginx-config-volume
|
||||
- mountPath: /var/log/nginx
|
||||
name: log
|
||||
- mountPath: /var/www/html/website
|
||||
|
@ -30,9 +30,9 @@ spec:
|
|||
name: website-cert
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: nginxconfigvol
|
||||
- name: nginx-config-volume
|
||||
configMap:
|
||||
name: nginxconf
|
||||
name: NAME-configmap
|
||||
items:
|
||||
- key: nginx.conf
|
||||
path: nginx.conf
|
||||
|
@ -44,10 +44,10 @@ spec:
|
|||
emptyDir: {}
|
||||
- name: website-content-volume
|
||||
persistentVolumeClaim:
|
||||
claimName: website-content-pvc
|
||||
claimName: NAME-content-pvc
|
||||
- name: website-cert
|
||||
secret:
|
||||
secretName: website-cert
|
||||
secretName: NAME-cert
|
||||
items:
|
||||
- key: tls.crt
|
||||
path: tls.crt
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: nginx-service
|
||||
name: NAME-service
|
||||
labels:
|
||||
app: nginx
|
||||
app: NAME-nginx
|
||||
namespace: default
|
||||
spec:
|
||||
selector:
|
||||
app: nginx
|
||||
app: NAME-nginx
|
||||
ports:
|
||||
- name: nginx-http
|
||||
port: 80
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
apiVersion: batch/v1beta1
|
||||
kind: CronJob
|
||||
metadata:
|
||||
name: website-builder
|
||||
name: NAME-build-cron
|
||||
labels:
|
||||
app.kubernetes.part-of: website # correct name?
|
||||
spec:
|
||||
|
@ -13,35 +13,18 @@ spec:
|
|||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: backup-app
|
||||
image: domaindrivenarchitecture/c4k-gitea-backup
|
||||
- image: domaindrivenarchitecture/c4k-website-build
|
||||
name: NAME-build-app
|
||||
imagePullPolicy: IfNotPresent
|
||||
command: ["/entrypoint.sh"]
|
||||
env:
|
||||
- name: AWS_DEFAULT_REGION
|
||||
value: eu-central-1
|
||||
- name: AWS_ACCESS_KEY_ID_FILE
|
||||
value: /var/run/secrets/backup-secrets/aws-access-key-id
|
||||
- name: AWS_SECRET_ACCESS_KEY_FILE
|
||||
value: /var/run/secrets/backup-secrets/aws-secret-access-key
|
||||
- name: RESTIC_REPOSITORY
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: backup-config
|
||||
key: restic-repository
|
||||
- name: RESTIC_PASSWORD_FILE
|
||||
value: /var/run/secrets/backup-secrets/restic-password
|
||||
envFrom:
|
||||
- secretRef:
|
||||
name: NAME-secret
|
||||
volumeMounts:
|
||||
- name: gitea-data-volume
|
||||
mountPath: /var/backups
|
||||
- name: backup-secret-volume
|
||||
mountPath: /var/run/secrets/backup-secrets
|
||||
readOnly: true
|
||||
- name: content-volume
|
||||
mountPath: /var/www/html/website
|
||||
volumes:
|
||||
- name: gitea-data-volume
|
||||
- name: content-volume
|
||||
persistentVolumeClaim:
|
||||
claimName: gitea-data-pvc
|
||||
- name: backup-secret-volume
|
||||
secret:
|
||||
secretName: backup-secret
|
||||
claimName: NAME-content-pvc
|
||||
restartPolicy: OnFailure
|
|
@ -1,73 +1,33 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: backup-restore
|
||||
name: NAME-build-deployment
|
||||
spec:
|
||||
replicas: 0
|
||||
selector:
|
||||
matchLabels:
|
||||
app: backup-restore
|
||||
app: NAME-builder
|
||||
strategy:
|
||||
type: Recreate
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: backup-restore
|
||||
app.kubernetes.io/name: backup-restore
|
||||
app.kubernetes.io/part-of: gitea
|
||||
app: NAME-builder
|
||||
app.kubernetes.io/name: NAME-builder
|
||||
app.kubernetes.io/part-of: website
|
||||
spec:
|
||||
containers:
|
||||
- image: domaindrivenarchitecture/c4k-gitea-backup
|
||||
name: backup-app
|
||||
- image: domaindrivenarchitecture/c4k-website-build
|
||||
name: NAME-build-app
|
||||
imagePullPolicy: IfNotPresent
|
||||
command: ["/entrypoint-start-and-wait.sh"]
|
||||
env:
|
||||
- name: POSTGRES_USER
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: postgres-secret
|
||||
key: postgres-user
|
||||
- name: POSTGRES_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: postgres-secret
|
||||
key: postgres-password
|
||||
- name: POSTGRES_DB
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: postgres-config
|
||||
key: postgres-db
|
||||
- name: POSTGRES_HOST
|
||||
value: "postgresql-service:5432"
|
||||
- name: POSTGRES_SERVICE
|
||||
value: "postgresql-service"
|
||||
- name: POSTGRES_PORT
|
||||
value: "5432"
|
||||
- name: AWS_DEFAULT_REGION
|
||||
value: eu-central-1
|
||||
- name: AWS_ACCESS_KEY_ID_FILE
|
||||
value: /var/run/secrets/backup-secrets/aws-access-key-id
|
||||
- name: AWS_SECRET_ACCESS_KEY_FILE
|
||||
value: /var/run/secrets/backup-secrets/aws-secret-access-key
|
||||
- name: RESTIC_REPOSITORY
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: backup-config
|
||||
key: restic-repository
|
||||
- name: RESTIC_PASSWORD_FILE
|
||||
value: /var/run/secrets/backup-secrets/restic-password
|
||||
- name: CERTIFICATE_FILE
|
||||
value: ""
|
||||
command: ["/entrypoint.sh"]
|
||||
envFrom:
|
||||
- secretRef:
|
||||
name: NAME-secret
|
||||
volumeMounts:
|
||||
- name: gitea-data-volume
|
||||
mountPath: /var/backups
|
||||
- name: backup-secret-volume
|
||||
mountPath: /var/run/secrets/backup-secrets
|
||||
readOnly: true
|
||||
- name: content-volume
|
||||
mountPath: /var/www/html/website
|
||||
volumes:
|
||||
- name: gitea-data-volume
|
||||
- name: content-volume
|
||||
persistentVolumeClaim:
|
||||
claimName: gitea-data-pvc
|
||||
- name: backup-secret-volume
|
||||
secret:
|
||||
secretName: backup-secret
|
||||
claimName: NAME-content-pvc
|
||||
|
|
8
src/main/resources/website/website-build-secret.yaml
Normal file
8
src/main/resources/website/website-build-secret.yaml
Normal file
|
@ -0,0 +1,8 @@
|
|||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: NAME-secret
|
||||
data:
|
||||
AUTHTOKEN: TOKEN
|
||||
REPOZIPURL: URL
|
||||
|
|
@ -1,14 +1,15 @@
|
|||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: website-content-pvc
|
||||
name: NAME-content-volume
|
||||
namespace: default
|
||||
labels:
|
||||
app: nginx
|
||||
app: NAME-nginx
|
||||
spec:
|
||||
storageClassName: local-path
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: WEBSITESTORAGESIZE
|
||||
storage: WEBSITESTORAGESIZE
|
||||
|
Loading…
Reference in a new issue