diff --git a/.gitignore b/.gitignore index 144e145..862e660 100644 --- a/.gitignore +++ b/.gitignore @@ -48,8 +48,14 @@ Thumbs.db *.mov *.wmv +# Terraform +*.tfplan +tfplan +*.bak .terraform # Helm Charts charts/ *.tgz + + diff --git a/k8s/applications/templates/authelia.yaml b/k8s/applications/templates/authelia.yaml new file mode 100644 index 0000000..d1d9108 --- /dev/null +++ b/k8s/applications/templates/authelia.yaml @@ -0,0 +1,29 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: authelia +spec: + destination: + name: '' + namespace: authelia + server: 'https://kubernetes.default.svc' + source: + helm: + valueFiles: + - values-{{ .Values.environment }}.yaml + path: k8s/authelia + repoURL: 'git@bitbucket.org:jamkazam/video-iac.git' + targetRevision: {{ .Values.gitBranch }} + project: default + syncPolicy: + syncOptions: + - CreateNamespace=true + automated: + prune: true + allowEmpty: false + retry: + limit: 5 + backoff: + duration: 5s + factor: 2 + maxDuration: 3m diff --git a/k8s/applications/templates/console.yaml b/k8s/applications/templates/console.yaml new file mode 100644 index 0000000..f28bb35 --- /dev/null +++ b/k8s/applications/templates/console.yaml @@ -0,0 +1,29 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: console +spec: + destination: + name: '' + namespace: console + server: 'https://kubernetes.default.svc' + source: + helm: + valueFiles: + - values-{{ .Values.environment }}.yaml + path: k8s/console + repoURL: 'git@bitbucket.org:jamkazam/video-iac.git' + targetRevision: {{ .Values.gitBranch }} + project: default + syncPolicy: + syncOptions: + - CreateNamespace=true + automated: + prune: true + allowEmpty: false + retry: + limit: 5 + backoff: + duration: 5s + factor: 2 + maxDuration: 3m diff --git a/k8s/authelia/Chart.yaml b/k8s/authelia/Chart.yaml new file mode 100644 index 0000000..6194ee4 --- /dev/null +++ b/k8s/authelia/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: authelia +description: A Helm chart for Authelia IDP +type: application +version: 0.1.0 +appVersion: "4.39.15" diff --git a/k8s/authelia/templates/configmap.yaml b/k8s/authelia/templates/configmap.yaml new file mode 100644 index 0000000..e44531f --- /dev/null +++ b/k8s/authelia/templates/configmap.yaml @@ -0,0 +1,55 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: authelia-config +data: + configuration.yml: | + server: + address: "tcp://0.0.0.0:9091" + + log: + level: {{ .Values.config.log.level | default "info" }} + + identity_validation: + reset_password: + jwt_secret: "$JWT_SECRET" # Injected via env/file + + session: + name: authelia_session + secret: "$SESSION_SECRET" # Injected via env/file + expiration: 3600 + inactivity: 900 + cookies: + - domain: {{ .Values.domain | quote }} + authelia_url: {{ .Values.authelia_url | quote }} + + storage: + encryption_key: "$STORAGE_ENCRYPTION_KEY" # Injected via env/file + local: + path: /var/lib/authelia/db.sqlite3 + + authentication_backend: + file: + path: /config/users_database.yml + + access_control: + default_policy: deny + rules: + - domain: {{ .Values.domain | quote }} + policy: two_factor + + notifier: + smtp: + host: {{ .Values.config.notifier.smtp.host | quote }} + port: {{ .Values.config.notifier.smtp.port }} + sender: {{ .Values.config.notifier.smtp.sender | quote }} + username: {{ .Values.config.notifier.smtp.username | quote }} + password: "$SMTP_PASSWORD" # Injected via env/file + + webauthn: + display_name: {{ .Values.config.webauthn.display_name | quote }} + enable_passkey_login: {{ .Values.config.webauthn.enable_passkey_login }} + experimental_enable_passkey_uv_two_factors: {{ .Values.config.webauthn.experimental_enable_passkey_uv_two_factors }} + selection_criteria: + user_verification: {{ .Values.config.webauthn.selection_criteria.user_verification | quote }} + discoverability: {{ .Values.config.webauthn.selection_criteria.discoverability | quote }} diff --git a/k8s/authelia/templates/deployment.yaml b/k8s/authelia/templates/deployment.yaml new file mode 100644 index 0000000..b4f67d3 --- /dev/null +++ b/k8s/authelia/templates/deployment.yaml @@ -0,0 +1,69 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: authelia +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app: authelia + template: + metadata: + labels: + app: authelia + spec: + containers: + - name: authelia + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: 9091 + env: + - name: JWT_SECRET + valueFrom: + secretKeyRef: + name: authelia-secrets + key: jwt_secret + - name: SESSION_SECRET + valueFrom: + secretKeyRef: + name: authelia-secrets + key: session_secret + - name: STORAGE_ENCRYPTION_KEY + valueFrom: + secretKeyRef: + name: authelia-secrets + key: storage_encryption_key + - name: SMTP_PASSWORD + valueFrom: + secretKeyRef: + name: authelia-secrets + key: smtp_password + volumeMounts: + - name: config + mountPath: /config + - name: data + mountPath: /var/lib/authelia + livenessProbe: + httpGet: + path: /api/health + port: http + readinessProbe: + httpGet: + path: /api/health + port: http + volumes: + - name: config + projected: + sources: + - configMap: + name: authelia-config + - secret: + name: authelia-secrets + items: + - key: users_database.yml + path: users_database.yml + - name: data + persistentVolumeClaim: + claimName: authelia-data diff --git a/k8s/authelia/templates/ingress.yaml b/k8s/authelia/templates/ingress.yaml new file mode 100644 index 0000000..e2f9581 --- /dev/null +++ b/k8s/authelia/templates/ingress.yaml @@ -0,0 +1,27 @@ +{{- if .Values.ingress.enabled -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: authelia + annotations: + {{- toYaml .Values.ingress.annotations | nindent 4 }} +spec: + ingressClassName: {{ .Values.ingress.className | quote }} + tls: + {{- toYaml .Values.ingress.tls | nindent 4 }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + pathType: {{ .pathType }} + backend: + service: + name: authelia + port: + number: 9091 + {{- end }} + {{- end }} +{{- end -}} diff --git a/k8s/authelia/templates/pvc.yaml b/k8s/authelia/templates/pvc.yaml new file mode 100644 index 0000000..d317648 --- /dev/null +++ b/k8s/authelia/templates/pvc.yaml @@ -0,0 +1,13 @@ +{{- if .Values.persistence.enabled -}} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: authelia-data +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.persistence.size | quote }} + storageClassName: {{ .Values.persistence.storageClass | quote }} +{{- end -}} diff --git a/k8s/authelia/templates/secret.yaml b/k8s/authelia/templates/secret.yaml new file mode 100644 index 0000000..9084d44 --- /dev/null +++ b/k8s/authelia/templates/secret.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Secret +metadata: + name: authelia-secrets +type: Opaque +stringData: + jwt_secret: "q2vwzZUuzn2dzbxbnmaUtkdr/wB6S8bs/ok7izvLDv8=" + session_secret: "99r8UswZ7KK4eAK+HZxcn7BAbfVK6bpLuVPYef4lOR4=" + storage_encryption_key: "NwX+0+WggRpPyx+kdcCoanDyc5dIcGzXsv0038SBV6M=" + smtp_password: "BM6zKJUOWSc4XF+1dXZZlqAkbybGX+KbY+YciI7PIcsn" + users_database.yml: | + users: + jamadmin: + displayname: "JamKazam Administrator" + password: "$argon2id$v=19$m=65536,t=3,p=4$upTOgJS/rFd1kXusoxQzXA$IuaIDtOveVYsBncy8Aq4m2a9XV9GUofmP22Z1U+l18I" + email: "support@jamkazam.com" + groups: + - admins diff --git a/k8s/authelia/templates/service.yaml b/k8s/authelia/templates/service.yaml new file mode 100644 index 0000000..af61d4c --- /dev/null +++ b/k8s/authelia/templates/service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: authelia +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + app: authelia diff --git a/k8s/authelia/values-production.yaml b/k8s/authelia/values-production.yaml new file mode 100644 index 0000000..4d31407 --- /dev/null +++ b/k8s/authelia/values-production.yaml @@ -0,0 +1,9 @@ +ingress: + hosts: + - host: idp.jamkazam.com + paths: + - path: / + pathType: ImplementationSpecific + +authelia_url: https://idp.jamkazam.com +domain: jamkazam.com diff --git a/k8s/authelia/values-staging.yaml b/k8s/authelia/values-staging.yaml new file mode 100644 index 0000000..d794954 --- /dev/null +++ b/k8s/authelia/values-staging.yaml @@ -0,0 +1,9 @@ +ingress: + hosts: + - host: idp.staging.jamkazam.com + paths: + - path: / + pathType: ImplementationSpecific + +authelia_url: https://idp.staging.jamkazam.com +domain: staging.jamkazam.com diff --git a/k8s/authelia/values.yaml b/k8s/authelia/values.yaml new file mode 100644 index 0000000..c9a115e --- /dev/null +++ b/k8s/authelia/values.yaml @@ -0,0 +1,44 @@ +replicaCount: 1 + +image: + repository: authelia/authelia + pullPolicy: IfNotPresent + tag: "4.39.15" + +service: + type: ClusterIP + port: 9091 + +ingress: + enabled: true + className: nginx + annotations: + cert-manager.io/cluster-issuer: letsencrypt-nginx-production + tls: + - secretName: authelia-tls + hosts: + - idp.jamkazam.com + +config: + log: + level: debug + theme: light + default_2fa_method: webauthn + notifier: + smtp: + host: email-smtp.us-east-1.amazonaws.com + port: 587 + sender: support@jamkazam.com + username: AKIA2SXEHOQFM326T4WJ + webauthn: + display_name: "JamKazam IDP" + enable_passkey_login: true + experimental_enable_passkey_uv_two_factors: true + selection_criteria: + user_verification: required + discoverability: preferred + +persistence: + enabled: true + size: 1Gi + storageClass: linode-block-storage-retain diff --git a/k8s/console/Chart.yaml b/k8s/console/Chart.yaml new file mode 100644 index 0000000..7bcf080 --- /dev/null +++ b/k8s/console/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: console +description: JamKazam Console Static Site +type: application +version: 0.1.0 +appVersion: "1.0.0" diff --git a/k8s/console/templates/deployment.yaml b/k8s/console/templates/deployment.yaml new file mode 100644 index 0000000..700c289 --- /dev/null +++ b/k8s/console/templates/deployment.yaml @@ -0,0 +1,27 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: console +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app: console + template: + metadata: + labels: + app: console + spec: + containers: + - name: nginx + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + ports: + - containerPort: 80 + volumeMounts: + - name: html + mountPath: /usr/share/nginx/html/index.html + subPath: index.html + volumes: + - name: html + secret: + secretName: console-html diff --git a/k8s/console/templates/ingress.yaml b/k8s/console/templates/ingress.yaml new file mode 100644 index 0000000..c2b48b6 --- /dev/null +++ b/k8s/console/templates/ingress.yaml @@ -0,0 +1,25 @@ +{{- if .Values.ingress.enabled -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: console + annotations: + {{- toYaml .Values.ingress.annotations | nindent 4 }} +spec: + ingressClassName: {{ .Values.ingress.className | quote }} + tls: + {{- toYaml .Values.ingress.tls | nindent 4 }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ . | quote }} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: console + port: + number: 80 + {{- end }} +{{- end -}} diff --git a/k8s/console/templates/secret.yaml b/k8s/console/templates/secret.yaml new file mode 100644 index 0000000..3f67a18 --- /dev/null +++ b/k8s/console/templates/secret.yaml @@ -0,0 +1,32 @@ +apiVersion: v1 +kind: Secret +metadata: + name: console-html +type: Opaque +stringData: + index.html: | + + + + JamKazam Console + + + +
+

JamKazam Console

+

Welcome to the central management hub.

+ +
+ + diff --git a/k8s/console/templates/service.yaml b/k8s/console/templates/service.yaml new file mode 100644 index 0000000..978977e --- /dev/null +++ b/k8s/console/templates/service.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Service +metadata: + name: console +spec: + ports: + - port: {{ .Values.service.port }} + targetPort: 80 + selector: + app: console diff --git a/k8s/console/values-production.yaml b/k8s/console/values-production.yaml new file mode 100644 index 0000000..c2a7ccb --- /dev/null +++ b/k8s/console/values-production.yaml @@ -0,0 +1,27 @@ +replicaCount: 1 + +image: + repository: nginx + tag: alpine + pullPolicy: IfNotPresent + +service: + type: ClusterIP + port: 80 + +ingress: + enabled: true + className: nginx + annotations: + cert-manager.io/cluster-issuer: letsencrypt-nginx-production + tls: + - secretName: console-tls + hosts: + - console.jamkazam.com + hosts: + - console.jamkazam.com + +links: + authelia: https://idp.jamkazam.com + monitoring: https://monitoring.video.jamkazam.com + argocd: https://cd.video.jamkazam.com diff --git a/k8s/console/values-staging.yaml b/k8s/console/values-staging.yaml new file mode 100644 index 0000000..5d75c8f --- /dev/null +++ b/k8s/console/values-staging.yaml @@ -0,0 +1,27 @@ +replicaCount: 1 + +image: + repository: nginx + tag: alpine + pullPolicy: IfNotPresent + +service: + type: ClusterIP + port: 80 + +ingress: + enabled: true + className: nginx + annotations: + cert-manager.io/cluster-issuer: letsencrypt-nginx-production + tls: + - secretName: console-tls + hosts: + - console.staging.jamkazam.com + hosts: + - console.staging.jamkazam.com + +links: + authelia: https://idp.staging.jamkazam.com + monitoring: https://monitoring.video.jamkazam.com + argocd: https://cd.video.jamkazam.com