From b82ff8a09f7e124b38c766fbf74e5ff97ef28be3 Mon Sep 17 00:00:00 2001 From: Moritz Graf Date: Sun, 17 May 2026 10:52:11 +0200 Subject: [PATCH] chore(hass): rename values to secret to encrypt token and add README --- k8s/home-assistant/README.md | 27 +++ k8s/home-assistant/home-assistant.secret.yaml | Bin 0 -> 7833 bytes k8s/home-assistant/home-assistant.yaml | 229 ------------------ 3 files changed, 27 insertions(+), 229 deletions(-) create mode 100644 k8s/home-assistant/README.md create mode 100644 k8s/home-assistant/home-assistant.secret.yaml delete mode 100644 k8s/home-assistant/home-assistant.yaml diff --git a/k8s/home-assistant/README.md b/k8s/home-assistant/README.md new file mode 100644 index 0000000..1778c86 --- /dev/null +++ b/k8s/home-assistant/README.md @@ -0,0 +1,27 @@ +# Home Assistant + +Deployment for Home Assistant via the `pajikos` Helm chart. + +## Deployment + +1. Ensure the Helm repository is added and updated: +```bash +helm repo add pajikos https://pajikos.github.io/home-assistant-helm-chart/ +helm repo update +``` + +2. Apply the raw secrets (if they haven't been applied yet): +```bash +kubectl apply -f hass-code-auth.secret.yml +``` + +3. Upgrade/Install the Helm release: +```bash +helm upgrade --install home-assistant pajikos/home-assistant -n home-assistant -f home-assistant.secret.yaml +``` + +## Architecture & Configuration +This setup perfectly balances **Infrastructure as Code (IaC)** with **Dynamic UI Configuration**: +- **Core Settings:** Network proxies, InfluxDB tokens, and Ingress routing are strictly enforced via `home-assistant.secret.yaml`. +- **Dynamic Config:** The helm chart utilizes an init-script to inject `!include` directives for `automations.yaml`, `scripts.yaml`, and `scenes.yaml` into the main config. This allows the Home Assistant UI to write dynamic automations without violating the IaC principles! +- **Code Server Addon:** For advanced manual tweaks, a VS Code instance (`hass-coder.moritzgraf.de`) runs alongside the pod, allowing direct manipulation of the `/config` directory. diff --git a/k8s/home-assistant/home-assistant.secret.yaml b/k8s/home-assistant/home-assistant.secret.yaml new file mode 100644 index 0000000000000000000000000000000000000000..cdff5dc3d2988a10770cf6ece2eeb34aafe3116c GIT binary patch literal 7833 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 literal 0 HcmV?d00001 diff --git a/k8s/home-assistant/home-assistant.yaml b/k8s/home-assistant/home-assistant.yaml deleted file mode 100644 index 971f3aa..0000000 --- a/k8s/home-assistant/home-assistant.yaml +++ /dev/null @@ -1,229 +0,0 @@ -# # helm show values pajikos/home-assistant | less - - -# Environment variables -env: -- name: TZ - value: Europe/Berlin -# - name: SOME_VAR_FROM_CONFIG_MAP -# valueFrom: -# configMapRef: -# name: configmap-name -# key: config-key -# - name: SOME_SECRET -# valueFrom: -# secretKeyRef: -# name: secret-name -# key: secret-key - -# Ingress settings -ingress: - # Enable ingress for home assistant - enabled: true - className: "nginx" - annotations: - kubernetes.io/ingress.class: "nginx" - nginx.ingress.kubernetes.io/force-ssl-redirect: "true" - nginx.ingress.kubernetes.io/ssl-redirect: "true" - cert-manager.io/cluster-issuer: "letsencrypt-prod" - kubernetes.io/tls-acme: "true" - hosts: - - host: hass.moritzgraf.de - paths: - - path: / - pathType: ImplementationSpecific - tls: - - hosts: - - "hass.moritzgraf.de" - secretName: hass-moritzgraf-de - -# Persistence values for the Home Assistant instance -persistence: - # Enable or disable persistence - enabled: true - # Access mode for the persistent volume claim - accessMode: ReadWriteOnce - # Size of the persistent volume claim - size: 10Gi - # Storage class for the persistent volume claim - storageClass: "" - -configuration: - # Enable or disable the configuration setup for Home Assistant - enabled: true - # Force init will merge the current configuration file with the default configuration on every start - # This is useful when you want to ensure that the configuration file is always up to date - forceInit: true - # List of trusted proxies in the format of CIDR notation in a case of using a reverse proxy - # Here is the list of the most common private IP ranges, use your list of possible trusted proxies, usually, it's the IP of the reverse proxy - trusted_proxies: - - 10.233.0.0/16 - # Template for the configuration.yaml file - # Used the `tpl` function to render the template, so you can use Go template functions - templateConfig: |- - # Loads default set of integrations. Do not remove. - default_config: - - {{- if .Values.ingress.enabled }} - http: - use_x_forwarded_for: true - trusted_proxies: - {{- range .Values.configuration.trusted_proxies }} - - {{ . }} - {{- end }} - {{- end}} - # Load frontend themes from the themes folder - frontend: - themes: !include_dir_merge_named themes - - automation: !include automations.yaml - script: !include scripts.yaml - scene: !include scenes.yaml - # # moritz custom config - influxdb: - host: influxdb-influxdb2.influxdb.svc.cluster.local - port: 80 - api_version: 2 - bucket: default - organization: influxdata - token: enaiY9yaiWi6ahv0phoph3FaiphoGh - ssl: false - verify_ssl: false - max_retries: 3 - - # Init script for the Home Assistant initialization, you can use Go template functions - # Script is executed before the Home Assistant container starts and is used to prepare the configuration - # Will be executed only if the configuration.enabled is set to true - initScript: |- - #!/bin/bash - set -e - - # Check if the configuration file exists - if [ ! -f /config/configuration.yaml ]; then - echo "Configuration file not found, creating a new one" - cp /config-templates/configuration.yaml /config/configuration.yaml - fi - - # Check if the force init is enabled - forceInit="{{ .Values.configuration.forceInit }}" - if [ "$forceInit" = "true" ]; then - echo "Force init is enabled, overwriting the configuration file" - current_time=$(date +%Y%m%d_%H%M%S) - echo "Backup the current configuration file to configuration.yaml.$current_time" - cp /config/configuration.yaml /config/configuration.yaml.$current_time - echo "The current configuration file will be merged with the default configuration file with this content:" - cat /config-templates/configuration.yaml - if [[ ! -s /config/configuration.yaml ]]; then - # If /config/configuration.yaml is empty, use the content of /config-templates/configuration.yaml - cat /config-templates/configuration.yaml > /config/configuration.yaml - else - # Perform the merge operation if /config/configuration.yaml is not empty - yq eval-all --inplace 'select(fileIndex == 0) *d select(fileIndex == 1)' /config/configuration.yaml /config-templates/configuration.yaml - fi - fi - - # Check if the automations file exists - if [ ! -f /config/automations.yaml ]; then - echo "Automations file not found, creating a new one" - touch /config/automations.yaml - echo "[]" >> /config/automations.yaml - fi - - # Check if the scripts file exists - if [ ! -f /config/scripts.yaml ]; then - echo "Scripts file not found, creating a new one" - touch /config/scripts.yaml - fi - - # Check if the scenes file exists - if [ ! -f /config/scenes.yaml ]; then - echo "Scenes file not found, creating a new one" - touch /config/scenes.yaml - fi - - # install hacs - see https://www.hacs.xyz/docs/use/download/download/#to-download-hacs - apk add --no-cache bash - wget -O - https://get.hacs.xyz | bash - - - initContainer: - name: setup-config - image: mikefarah/yq:4 - securityContext: - runAsUser: 0 - command: ["/bin/sh", "-c"] - args: - - /bin/sh /mnt/init/init.sh - # env: - # - name: FORCE_INIT - # valueFrom: - # configMapKeyRef: - # name: init-script - # key: forceInit - # Home Assistant configuration volume will be mounted to /config automatically - volumeMounts: - - name: init-volume - mountPath: /mnt/init/init.sh - subPath: init.sh - - name: config-volume - mountPath: /config-templates - -serviceMonitor: - # requires HA integration: https://www.home-assistant.io/integrations/prometheus/ - enabled: false - scrapeInterval: 30s - labels: - prometheus: haumdaucher - -# Addons configuration for additional services -addons: - # Code-server addon configuration - codeserver: - # Enable or disable the code-server addon - enabled: true - # # Resource settings for the code-server container - # resources: {} - # # Image settings for the code-server addon - # image: - # # Repository for the code-server image - # repository: ghcr.io/coder/code-server - # # Image pull policy for the code-server image - # pullPolicy: IfNotPresent - # # Tag for the code-server image - # tag: "4.92.2" - # Service settings - service: - # Service type (ClusterIP, NodePort, LoadBalancer, or ExternalName) - type: ClusterIP - # Service port - port: 12321 - # Ingress settings for the code-server addon - ingress: - # Enable or disable the ingress for the code-server addon - enabled: true - # Ingress class name - className: "nginx" - # Ingress annotations - annotations: - kubernetes.io/ingress.class: "nginx" - nginx.ingress.kubernetes.io/force-ssl-redirect: "true" - nginx.ingress.kubernetes.io/ssl-redirect: "true" - cert-manager.io/cluster-issuer: "letsencrypt-prod" - kubernetes.io/tls-acme: "true" - nginx.ingress.kubernetes.io/auth-type: basic - nginx.ingress.kubernetes.io/auth-secret: hass-coder-auth - nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - HASS Coder' - # Ingress hosts configuration - hosts: - - host: hass-coder.moritzgraf.de - paths: - - path: / - pathType: ImplementationSpecific - # Ingress TLS configuration - tls: - - hosts: - - "hass-coder.moritzgraf.de" - secretName: hass-coder-moritzgraf-de - # if you need any additional volume mounts, you can define them here - additionalMounts: [] - # - mountPath: /home/coder/.ssh/id_rsa - # name: id-rsa