diff --git a/charts/home-assistant/Chart.yaml b/charts/home-assistant/Chart.yaml new file mode 100644 index 0000000..0a2d541 --- /dev/null +++ b/charts/home-assistant/Chart.yaml @@ -0,0 +1,12 @@ +apiVersion: v2 +name: home-assistant +version: 0.0.1 +description: Chart for Home Assistant +keywords: + - home-automation +sources: + - https://github.com/home-assistant +maintainers: + - name: alexlebens +icon: https://avatars.githubusercontent.com/u/13844975?s=200&v=4 +appVersion: 2024.2.1 diff --git a/charts/home-assistant/README.md b/charts/home-assistant/README.md new file mode 100644 index 0000000..c5df653 --- /dev/null +++ b/charts/home-assistant/README.md @@ -0,0 +1,17 @@ +## Introduction + +[Home Assistant](https://www.home-assistant.io/) + +Open source home automation that puts local control and privacy first. Powered by a worldwide community of tinkerers and DIY enthusiasts. Perfect to run on a Raspberry Pi or a local server. + +This chart bootstraps a [Home-Assistant](https://github.com/benphelps/homepage) deployment on a [Kubernetes](https://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +## Prerequisites + +- Kubernetes +- Helm +- Authentik / Auth + +## Parameters + +See the [values files](values.yaml). diff --git a/charts/home-assistant/templates/deployment.yaml b/charts/home-assistant/templates/deployment.yaml new file mode 100644 index 0000000..0abef9e --- /dev/null +++ b/charts/home-assistant/templates/deployment.yaml @@ -0,0 +1,97 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: home-assistant + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: home-assistant + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} + app.kubernetes.io/managed-by: helm +spec: + revisionHistoryLimit: 3 + replicas: {{ .Values.deployment.replicas }} + strategy: + type: {{ .Values.deployment.strategy }} + selector: + matchLabels: + app.kubernetes.io/name: home-assistant + app.kubernetes.io/instance: {{ .Release.Name }} + template: + metadata: + labels: + app.kubernetes.io/name: home-assistant + app.kubernetes.io/instance: {{ .Release.Name }} + spec: + serviceAccountName: home-assistant + automountServiceAccountToken: true + containers: + - name: {{ .Release.Name }} + image: "{{ .Values.deployment.image.repository }}:{{ .Values.deployment.image.tag }}" + imagePullPolicy: {{ .Values.deployment.image.imagePullPolicy }} + ports: + - name: http + containerPort: {{ .Values.service.http.port }} + protocol: TCP + env: + {{- range $k,$v := .Values.deployment.env }} + - name: {{ $k }} + value: {{ $v | quote }} + {{- end }} + {{- with .Values.deployment.envFrom }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - mountPath: /config + name: home-assistant-config + resources: + {{- toYaml .Values.deployment.resources | nindent 12 }} + livenessProbe: + tcpSocket: + port: {{ .Values.service.http.port }} + initialDelaySeconds: 0 + failureThreshold: 3 + timeoutSeconds: 1 + periodSeconds: 10 + readinessProbe: + tcpSocket: + port: {{ .Values.service.http.port }} + initialDelaySeconds: 0 + failureThreshold: 3 + timeoutSeconds: 1 + periodSeconds: 10 + startupProbe: + tcpSocket: + port: {{ .Values.service.http.port }} + initialDelaySeconds: 0 + failureThreshold: 30 + timeoutSeconds: 1 + periodSeconds: 5 + - name: codeserver + image: "{{ .Values.codeserver.image.repository }}:{{ .Values.codeserver.image.tag }}" + imagePullPolicy: {{ .Values.codeserver.image.imagePullPolicy }} + ports: + - containerPort: {{ .Values.codeserver.service.http.port }} + name: codeserver-http + protocol: TCP + env: + {{- range $k,$v := .Values.codeserver.env }} + - name: {{ $k }} + value: {{ $v | quote }} + {{- end }} + {{- with .Values.codeserver.envFrom }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.codeserver.securityContext | nindent 12 }} + volumeMounts: + - mountPath: /config/home-assistant + name: home-assistant-config + volumes: + - name: home-assistant-config + persistentVolumeClaim: + claimName: home-assistant-config diff --git a/charts/home-assistant/templates/ingress.yaml b/charts/home-assistant/templates/ingress.yaml new file mode 100644 index 0000000..c158fb9 --- /dev/null +++ b/charts/home-assistant/templates/ingress.yaml @@ -0,0 +1,82 @@ +{{- if .Values.ingress.enabled }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: home-assistant + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: home-assistant + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} + app.kubernetes.io/managed-by: helm + annotations: + cert-manager.io/cluster-issuer: letsencrypt-issuer + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" +spec: + ingressClassName: "{{ .Values.ingress.host }}" + tls: + - hosts: + - "{{ .Values.ingress.host }}" + secretName: "{{ .Release.Name }}-secret-tls" + rules: + - host: "{{ .Values.ingress.host }}" + http: + paths: + - path: /outpost.goauthentik.io/ + pathType: Prefix + backend: + service: + name: "{{ .Values.ingress.authentik.outpost }}" + port: + number: {{ .Values.ingress.authentik.port }} + - host: "{{ .Values.ingress.host }}" + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: http + port: + number: {{ .Values.service.http.port }} +{{- end }} + +--- +{{- if and .Values.codeserver.ingress.enabled Values.codeserver.enabled }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: codeserver-home-assistant + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: codeserver + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} + app.kubernetes.io/managed-by: helm + annotations: + cert-manager.io/cluster-issuer: letsencrypt-issuer + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" +spec: + ingressClassName: "{{ .Values.codeserver.ingress.host }}" + tls: + - hosts: + - "{{ .Values.codeserver.ingress.host }}" + secretName: "codeserver-{{ .Release.Name }}-secret-tls" + rules: + - host: "{{ .Values.codeserver.ingress.host }}" + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: codeserver-http + port: + number: {{ .Values.codeserver.service.http.port }} +{{- end }} diff --git a/charts/home-assistant/templates/middleware.yaml b/charts/home-assistant/templates/middleware.yaml new file mode 100644 index 0000000..ce7b669 --- /dev/null +++ b/charts/home-assistant/templates/middleware.yaml @@ -0,0 +1,30 @@ +{{- if .Values.ingress.enabled }} +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: authentik + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: home-assistant + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: auth + app.kubernetes.io/part-of: home-assistant + app.kubernetes.io/managed-by: helm +spec: + forwardAuth: + address: "http://{{ .Values.ingress.authentik.outpost }}.authentik:{{ .Values.ingress.authentik.port }}/outpost.goauthentik.io/auth/traefik" + trustForwardHeader: true + authResponseHeaders: + - X-authentik-username + - X-authentik-groups + - X-authentik-email + - X-authentik-name + - X-authentik-uid + - X-authentik-jwt + - X-authentik-meta-jwks + - X-authentik-meta-outpost + - X-authentik-meta-provider + - X-authentik-meta-app + - X-authentik-meta-version +{{- end }} diff --git a/charts/home-assistant/templates/persistant-volume-claim.yaml b/charts/home-assistant/templates/persistant-volume-claim.yaml new file mode 100644 index 0000000..fba578b --- /dev/null +++ b/charts/home-assistant/templates/persistant-volume-claim.yaml @@ -0,0 +1,20 @@ +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: home-assistant-config + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: home-assistant + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} + app.kubernetes.io/managed-by: helm +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.persistence.config.storageSize }} + storageClassName: {{ .Values.persistence.config.storageClassName }} + volumeMode: {{ .Values.persistence.config.volumeMode }} diff --git a/charts/home-assistant/templates/prometheus-rule.yaml b/charts/home-assistant/templates/prometheus-rule.yaml new file mode 100644 index 0000000..26db88a --- /dev/null +++ b/charts/home-assistant/templates/prometheus-rule.yaml @@ -0,0 +1,19 @@ +{{- if and .Values.metrics.enabled .Values.metrics.prometheusRule.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: home-assistant + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: home-assistant + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: home-assistant + app.kubernetes.io/managed-by: helm +spec: + groups: + - name: {{ .Release.Name }} + rules: + {{- toYaml .Values.prometheusRule.rules | nindent 8 }} +{{- end }} diff --git a/charts/home-assistant/templates/service-account.yaml b/charts/home-assistant/templates/service-account.yaml new file mode 100644 index 0000000..3344355 --- /dev/null +++ b/charts/home-assistant/templates/service-account.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: home-assistant + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: home-assistant + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: home-assistant + app.kubernetes.io/managed-by: helm diff --git a/charts/home-assistant/templates/service-monitor.yaml b/charts/home-assistant/templates/service-monitor.yaml new file mode 100644 index 0000000..ac169ad --- /dev/null +++ b/charts/home-assistant/templates/service-monitor.yaml @@ -0,0 +1,27 @@ +{{- if .Values.metrics.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: home-assistant + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: home-assistant + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: home-assistant + app.kubernetes.io/managed-by: helm +spec: + selector: + matchLabels: + app.kubernetes.io/name: home-assistant + app.kubernetes.io/instance: {{ .Release.Name }} + endpoints: + - port: http + interval: {{ .Values.metrics.serviceMonitor.interval }} + scrapeTimeout: {{ .Values.metrics.serviceMonitor.scrapeTimeout }} + path: /api/prometheus + bearerTokenSecret: + name: {{ .Values.metrics.serviceMonitor.bearerTokenSecret.name }} + key: {{ .Values.metrics.serviceMonitor.bearerTokenSecret.key }} +{{- end }} diff --git a/charts/home-assistant/templates/service.yaml b/charts/home-assistant/templates/service.yaml new file mode 100644 index 0000000..a97a8cc --- /dev/null +++ b/charts/home-assistant/templates/service.yaml @@ -0,0 +1,48 @@ +apiVersion: v1 +kind: Service +metadata: + name: home-assistant + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: home-assistant + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} + app.kubernetes.io/managed-by: helm +spec: + type: ClusterIP + ports: + - port: {{ .Values.service.http.port }} + targetPort: http + protocol: TCP + name: http + selector: + app.kubernetes.io/name: home-assistant + app.kubernetes.io/instance: {{ .Release.Name }} + +--- +{{- if Values.codeserver.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: home-assistant-codeserver + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: code-server + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} + app.kubernetes.io/managed-by: helm +spec: + type: ClusterIP + ports: + - port: {{ .Values.codeserver.service.http.port }} + targetPort: codeserver-http + protocol: TCP + name: codeserver-http + selector: + app.kubernetes.io/name: codeserver + app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/charts/home-assistant/values.yaml b/charts/home-assistant/values.yaml new file mode 100644 index 0000000..e587a86 --- /dev/null +++ b/charts/home-assistant/values.yaml @@ -0,0 +1,74 @@ +deployment: + replicas: 1 + strategy: Recreate + image: + repository: homeassistant/home-assistant + tag: 2024.2.1 + imagePullPolicy: IfNotPresent + env: + TZ: US/Mountain + envFrom: + resources: + requests: + memory: 512Mi + cpu: 50m + limits: + memory: 1Gi + cpu: 500m +service: + http: + port: 8123 +ingress: + enabled: true + host: homeassistant.alexlebens.net + authentik: + outpost: authentik-proxy-outpost + port: 9000 +metrics: + enabled: false + serviceMonitor: + interval: 1m + scrapeTimeout: 30s + ## See https://www.home-assistant.io/docs/authentication/ for where to find + ## long lived access token creation under your account profile, which is + ## needed to monitor Home Assistant + bearerTokenSecret: + name: "" + key: "" + prometheusRule: + enabled: false + rules: + - alert: HomeAssistantAbsent + annotations: + description: Home Assistant has disappeared from Prometheus service discovery. + summary: Home Assistant is down. + expr: | + absent(up{job=~".*home-assistant.*"} == 1) + for: 5m + labels: + severity: critical +persistence: + config: + storageClassName: ceph-block + storageSize: 1Gi + volumeMode: Filesystem +codeserver: + enabled: true + image: + repository: linuxserver/code-server + tag: 4.21.1 + imagePullPolicy: IfNotPresent + env: + TZ: US/Mountain + PUID: 1000 + PGID: 1000 + DEFAULT_WORKSPACE: /config + envFrom: + securityContext: + runAsUser: 0 + service: + http: + port: 8443 + ingress: + enabled: true + host: codeserver.homeassistant.alexlebens.net