├── .github ├── CODEOWNERS ├── dependabot.yaml ├── renovate.json └── workflows │ ├── deploy.yaml │ ├── release.yaml │ ├── sync-cluster-policies.yaml │ ├── sync-labels.yaml │ └── todos.yaml ├── .gitignore ├── .policyignore ├── .releaserc ├── .sops.yaml ├── .vscode ├── extensions.json └── homelab.code-workspace ├── README.md ├── docs └── images │ └── gitops-structure.drawio.png ├── hetzner ├── README.md ├── create-server.sh ├── create-snapshot.sh ├── delete-server.sh ├── talos-v1.10.3-amd64 │ └── hcloud.pkr.hcl └── talos-v1.10.3-arm64 │ └── hcloud.pkr.hcl ├── hosts ├── k8s ├── bases │ ├── README.md │ ├── apps │ │ ├── README.md │ │ ├── fleetdm │ │ │ ├── README.md │ │ │ ├── helm-release.yaml │ │ │ ├── helm-repository.yaml │ │ │ ├── kustomization.yaml │ │ │ ├── mysql-secret.yaml │ │ │ ├── namespace.yaml │ │ │ └── redis-secret.yaml │ │ ├── headlamp │ │ │ ├── README.md │ │ │ ├── helm-release.yaml │ │ │ ├── helm-repository.yaml │ │ │ ├── kustomization.yaml │ │ │ └── namespace.yaml │ │ ├── homepage │ │ │ ├── README.md │ │ │ ├── helm-release.yaml │ │ │ ├── helm-repository.yaml │ │ │ ├── kustomization.yaml │ │ │ └── namespace.yaml │ │ ├── kustomization.yaml │ │ ├── plantuml │ │ │ ├── README.md │ │ │ ├── helm-release.yaml │ │ │ ├── helm-repository.yaml │ │ │ ├── kustomization.yaml │ │ │ └── namespace.yaml │ │ └── whoami │ │ │ ├── helm-release.yaml │ │ │ ├── helm-repository.yaml │ │ │ ├── kustomization.yaml │ │ │ └── namespace.yaml │ ├── infrastructure │ │ ├── README.md │ │ ├── certificates │ │ │ ├── kustomization.yaml │ │ │ └── traefik-certificate.yaml │ │ ├── cluster-policies │ │ │ ├── flux │ │ │ │ ├── helm-release-enable-tests.yaml │ │ │ │ ├── helm-release-install-crds.yaml │ │ │ │ └── helm-release-remediation-retries.yaml │ │ │ ├── kustomization.yaml │ │ │ └── samples │ │ │ │ └── .gitkeep │ │ ├── controllers │ │ │ ├── cert-manager │ │ │ │ ├── README.md │ │ │ │ ├── helm-release.yaml │ │ │ │ ├── helm-repository.yaml │ │ │ │ ├── kustomization.yaml │ │ │ │ └── namespace.yaml │ │ │ ├── cilium │ │ │ │ ├── README.md │ │ │ │ ├── helm-release.yaml │ │ │ │ ├── helm-repository.yaml │ │ │ │ └── kustomization.yaml │ │ │ ├── dex │ │ │ │ ├── README.md │ │ │ │ ├── helm-release.yaml │ │ │ │ ├── helm-repository.yaml │ │ │ │ ├── kustomization.yaml │ │ │ │ └── namespace.yaml │ │ │ ├── goldilocks │ │ │ │ ├── README.md │ │ │ │ ├── helm-release.yaml │ │ │ │ ├── helm-repository.yaml │ │ │ │ ├── kustomization.yaml │ │ │ │ └── namespace.yaml │ │ │ ├── kustomization.yaml │ │ │ ├── kyverno │ │ │ │ ├── README.md │ │ │ │ ├── helm-release.yaml │ │ │ │ ├── helm-repository.yaml │ │ │ │ ├── kustomization.yaml │ │ │ │ └── namespace.yaml │ │ │ ├── oauth2-proxy │ │ │ │ ├── helm-release.yaml │ │ │ │ ├── helm-repository.yaml │ │ │ │ ├── kustomization.yaml │ │ │ │ └── namespace.yaml │ │ │ ├── reloader │ │ │ │ ├── README.md │ │ │ │ ├── helm-release.yaml │ │ │ │ ├── helm-repository.yaml │ │ │ │ ├── kustomization.yaml │ │ │ │ └── namespace.yaml │ │ │ ├── testkube │ │ │ │ ├── README.md │ │ │ │ ├── crds │ │ │ │ │ ├── executor.testkube.io_executors.yaml │ │ │ │ │ ├── executor.testkube.io_webhooks.yaml │ │ │ │ │ ├── kustomization.yaml │ │ │ │ │ ├── tests.testkube.io_scripts.yaml │ │ │ │ │ ├── tests.testkube.io_templates.yaml │ │ │ │ │ ├── tests.testkube.io_testexecutions.yaml │ │ │ │ │ ├── tests.testkube.io_tests.yaml │ │ │ │ │ ├── tests.testkube.io_testsources.yaml │ │ │ │ │ ├── tests.testkube.io_testsuiteexecutions.yaml │ │ │ │ │ ├── tests.testkube.io_testsuites.yaml │ │ │ │ │ ├── tests.testkube.io_testtriggers.yaml │ │ │ │ │ ├── testworkflows.testkube.io_testworkflowexecutions.yaml │ │ │ │ │ ├── testworkflows.testkube.io_testworkflows.yaml │ │ │ │ │ └── testworkflows.testkube.io_testworkflowtemplates.yaml │ │ │ │ ├── helm-release.yaml │ │ │ │ ├── helm-repository.yaml │ │ │ │ ├── kustomization.yaml │ │ │ │ └── namespace.yaml │ │ │ ├── traefik │ │ │ │ ├── README.md │ │ │ │ ├── helm-release.yaml │ │ │ │ ├── helm-repository.yaml │ │ │ │ ├── kustomization.yaml │ │ │ │ └── namespace.yaml │ │ │ ├── trivy-operator │ │ │ │ ├── README.md │ │ │ │ ├── helm-release.yaml │ │ │ │ ├── helm-repository.yaml │ │ │ │ ├── kustomization.yaml │ │ │ │ └── namespace.yaml │ │ │ └── vertical-pod-autoscaler │ │ │ │ ├── helm-release.yaml │ │ │ │ ├── helm-repository.yaml │ │ │ │ ├── kustomization.yaml │ │ │ │ └── namespace.yaml │ │ ├── kustomization.yaml │ │ ├── metrics-server │ │ │ ├── README.md │ │ │ ├── helm-release.yaml │ │ │ ├── helm-repository.yaml │ │ │ └── kustomization.yaml │ │ └── middlewares │ │ │ ├── forward-auth │ │ │ ├── README.md │ │ │ ├── forward-auth.yaml │ │ │ └── kustomization.yaml │ │ │ └── kustomization.yaml │ └── variables │ │ ├── kustomization.yaml │ │ ├── variables-base-config-map.yaml │ │ └── variables-base-secret.enc.yaml ├── clusters │ ├── README.md │ ├── dev │ │ ├── apps │ │ │ ├── flux-kustomization.yaml │ │ │ └── kustomization.yaml │ │ ├── infrastructure │ │ │ ├── controllers │ │ │ │ ├── flux-kustomization.yaml │ │ │ │ └── kustomization.yaml │ │ │ ├── flux-kustomization.yaml │ │ │ └── kustomization.yaml │ │ ├── kustomization.yaml │ │ └── variables │ │ │ ├── flux-kustomization.yaml │ │ │ ├── kustomization.yaml │ │ │ ├── variables-cluster-config-map.yaml │ │ │ └── variables-cluster-secret.enc.yaml │ ├── local │ │ ├── apps │ │ │ ├── flux-kustomization.yaml │ │ │ └── kustomization.yaml │ │ ├── infrastructure │ │ │ ├── controllers │ │ │ │ ├── flux-kustomization.yaml │ │ │ │ └── kustomization.yaml │ │ │ ├── flux-kustomization.yaml │ │ │ └── kustomization.yaml │ │ ├── kustomization.yaml │ │ └── variables │ │ │ ├── flux-kustomization.yaml │ │ │ ├── kustomization.yaml │ │ │ ├── variables-cluster-config-map.yaml │ │ │ └── variables-cluster-secret.enc.yaml │ └── prod │ │ ├── apps │ │ ├── flux-kustomization.yaml │ │ └── kustomization.yaml │ │ ├── infrastructure │ │ ├── controllers │ │ │ ├── flux-kustomization.yaml │ │ │ └── kustomization.yaml │ │ ├── flux-kustomization.yaml │ │ └── kustomization.yaml │ │ ├── kustomization.yaml │ │ └── variables │ │ ├── flux-kustomization.yaml │ │ ├── kustomization.yaml │ │ ├── variables-cluster-config-map.yaml │ │ └── variables-cluster-secret.enc.yaml └── distributions │ ├── README.md │ ├── kind │ ├── apps │ │ └── kustomization.yaml │ ├── infrastructure │ │ ├── cluster-issuers │ │ │ ├── kustomization.yaml │ │ │ └── selfsigned-cluster-issuer.yaml │ │ ├── controllers │ │ │ ├── kustomization.yaml │ │ │ └── traefik │ │ │ │ └── patches │ │ │ │ └── helm-release-patch.yaml │ │ ├── kustomization.yaml │ │ └── metrics-server │ │ │ └── patches │ │ │ └── helm-release-patch.yaml │ └── variables │ │ └── kustomization.yaml │ └── omni │ ├── apps │ └── kustomization.yaml │ ├── infrastructure │ ├── cloudflared │ │ ├── README.md │ │ ├── helm-release.yaml │ │ ├── helm-repository.yaml │ │ ├── kustomization.yaml │ │ └── namespace.yaml │ ├── cluster-issuers │ │ ├── cloudflare-origin-issuer.yaml │ │ └── kustomization.yaml │ ├── controllers │ │ ├── cilium │ │ │ └── patches │ │ │ │ └── helm-release-patch.yaml │ │ ├── hcloud-csi │ │ │ ├── hcloud-secret.yaml │ │ │ ├── helm-release.yaml │ │ │ ├── helm-repository.yaml │ │ │ ├── kustomization.yaml │ │ │ └── luks-encryption-secret.enc.yaml │ │ ├── kubelet-serving-cert-approver │ │ │ ├── README.md │ │ │ └── kustomization.yaml │ │ ├── kustomization.yaml │ │ └── origin-ca-issuer │ │ │ ├── helm-release.yaml │ │ │ ├── helm-repository.yaml │ │ │ └── kustomization.yaml │ └── kustomization.yaml │ └── variables │ └── kustomization.yaml ├── kind.yaml ├── ksail.yaml └── talos ├── cluster ├── allow-scheduling-on-control-planes.yaml ├── apparmor.yaml ├── cni.yaml ├── kubespan.yaml ├── mirror-registries.yaml ├── rotate-server-certificates.yaml ├── sysctls.yaml └── user-namespaces.yaml ├── control-planes └── .gitkeep └── workers └── .gitkeep /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @devantler 2 | -------------------------------------------------------------------------------- /.github/dependabot.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:recommended", 5 | ":disableDependencyDashboard", 6 | ":semanticCommitTypeAll(fix)" 7 | ], 8 | "assigneesFromCodeOwners": true, 9 | "flux": { 10 | "fileMatch": [ 11 | "^k8s/.+\\.ya?ml$" 12 | ] 13 | }, 14 | "argocd": { 15 | "fileMatch": [ 16 | "^k8s/.+\\.yaml$" 17 | ] 18 | }, 19 | "kubernetes": { 20 | "fileMatch": [ 21 | "^k8s/.+\\.ya?ml$" 22 | ] 23 | }, 24 | "github-actions": { 25 | "enabled": false 26 | }, 27 | "minor": { 28 | "automerge": true 29 | }, 30 | "patch": { 31 | "automerge": true 32 | }, 33 | "ignorePaths": [ 34 | "k8s/bases/infrastructure/cluster-policies/samples" 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yaml: -------------------------------------------------------------------------------- 1 | name: Deploy 2 | 3 | on: 4 | push: 5 | branches-ignore: 6 | - 'gh-readonly-queue/**' 7 | tags: 8 | - 'v*' 9 | workflow_dispatch: 10 | merge_group: 11 | 12 | permissions: 13 | contents: read 14 | packages: write 15 | 16 | concurrency: 17 | group: ${{ github.workflow }}-${{ github.ref }} 18 | cancel-in-progress: false 19 | 20 | jobs: 21 | wait-for-workflow: 22 | runs-on: ubuntu-latest 23 | steps: 24 | - name: Wait for previous job to finish 25 | uses: ahmadnassri/action-workflow-queue@v1 26 | with: 27 | timeout: 1800000 # 30 minutes 28 | 29 | deploy-dev: 30 | needs: wait-for-workflow 31 | uses: devantler-tech/workflows/.github/workflows/gitops-deploy.yaml@main 32 | secrets: inherit 33 | with: 34 | DEPLOYMENT_ENV: dev 35 | 36 | deploy-prod: 37 | if: startsWith(github.ref, 'refs/tags/v') 38 | needs: deploy-dev 39 | uses: devantler-tech/workflows/.github/workflows/gitops-deploy.yaml@main 40 | secrets: inherit 41 | with: 42 | DEPLOYMENT_ENV: prod 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: 3 | workflow_dispatch: 4 | push: 5 | branches: 6 | - main 7 | 8 | permissions: 9 | contents: write 10 | issues: write 11 | pull-requests: write 12 | id-token: write 13 | 14 | jobs: 15 | release: 16 | uses: devantler-tech/workflows/.github/workflows/release.yaml@main 17 | secrets: inherit 18 | -------------------------------------------------------------------------------- /.github/workflows/sync-cluster-policies.yaml: -------------------------------------------------------------------------------- 1 | # TODO: Move to https://github.com/devantler-tech/workflows as a reusable action. 2 | name: Sync Cluster Policies 3 | 4 | on: 5 | schedule: 6 | - cron: "0 0 * * *" # Runs daily at midnight 7 | workflow_dispatch: 8 | push: 9 | branches: 10 | - main 11 | paths: 12 | - 'k8s/bases/infrastructure/cluster-policies/samples/**' 13 | 14 | permissions: {} 15 | 16 | jobs: 17 | sync-policies: 18 | runs-on: ubuntu-latest 19 | env: 20 | KYVERNO_POLICIES_DIR: k8s/bases/infrastructure/cluster-policies/samples 21 | KYVERNO_POLICIES_TEMP_DIR: /tmp/cluster-policies 22 | 23 | steps: 24 | - name: Generate GitHub App Token 25 | uses: tibdex/github-app-token@v2 26 | id: generate-token 27 | with: 28 | app_id: ${{ vars.APP_ID }} 29 | private_key: ${{ secrets.APP_PRIVATE_KEY }} 30 | - name: Checkout repository 31 | uses: actions/checkout@v4 32 | with: 33 | token: ${{ steps.generate-token.outputs.token }} 34 | - name: Download latest Cluster Policies 35 | run: | 36 | git clone --filter=blob:none --sparse https://github.com/kyverno/policies ${{ env.KYVERNO_POLICIES_TEMP_DIR }} 37 | cd ${{ env.KYVERNO_POLICIES_TEMP_DIR }} 38 | git sparse-checkout set --no-cone '*/' ':!.*' 39 | - name: Remove blacklisted policies 40 | run: | 41 | while IFS= read -r pattern; do 42 | find ${{ env.KYVERNO_POLICIES_TEMP_DIR }} -path "${{ env.KYVERNO_POLICIES_TEMP_DIR }}/$pattern" -exec rm -rf {} + 43 | done < .policyignore 44 | - name: Copy Cluster Policies to the target directory 45 | run: | 46 | mkdir -p ${{ env.KYVERNO_POLICIES_DIR }} 47 | rm -rf ${{ env.KYVERNO_POLICIES_DIR }}/* 48 | cp -r ${{ env.KYVERNO_POLICIES_TEMP_DIR }}/* ${{ env.KYVERNO_POLICIES_DIR }} || echo "No policies found to copy." 49 | - name: Create PR with changes 50 | uses: peter-evans/create-pull-request@v7 51 | with: 52 | commit-message: "chore: sync cluster policies" 53 | title: "chore: sync cluster policies" 54 | body: "Sync Cluster Policies from " 55 | branch: sync-cluster-policies 56 | delete-branch: true 57 | signoff: true 58 | sign-commits: true 59 | reviewers: devantler 60 | assignees: devantler 61 | token: ${{ steps.generate-token.outputs.token }} 62 | branch-token: ${{ steps.generate-token.outputs.token }} 63 | -------------------------------------------------------------------------------- /.github/workflows/sync-labels.yaml: -------------------------------------------------------------------------------- 1 | name: Sync labels 2 | on: 3 | workflow_dispatch: 4 | schedule: 5 | - cron: "0 7 * * 1" 6 | 7 | permissions: 8 | issues: write 9 | 10 | jobs: 11 | sync-labels: 12 | uses: devantler-tech/workflows/.github/workflows/sync-labels.yaml@main 13 | -------------------------------------------------------------------------------- /.github/workflows/todos.yaml: -------------------------------------------------------------------------------- 1 | name: "TODOs" 2 | permissions: 3 | issues: write 4 | on: 5 | workflow_dispatch: 6 | push: 7 | branches: [main] 8 | 9 | jobs: 10 | todos: 11 | uses: devantler-tech/workflows/.github/workflows/todos.yaml@main 12 | secrets: inherit 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # MacOS 2 | .DS_Store 3 | 4 | # Linux 5 | 6 | # Windows 7 | 8 | # Temporary files 9 | *.tmp.* 10 | 11 | # hcloud 12 | hetzner/talos-*/*.raw.xz 13 | 14 | # SOPS 15 | 16 | .decrypted* 17 | -------------------------------------------------------------------------------- /.policyignore: -------------------------------------------------------------------------------- 1 | *.chainsaw-test* 2 | *.kyverno-test 3 | *artifact-hub.y*ml 4 | *artifacthub-pkg.y*ml 5 | *kustomization.yaml 6 | *README.md 7 | argo* 8 | aws* 9 | best-practices-cel* 10 | best-practices* 11 | castai* 12 | cert-manager* 13 | cleanup* 14 | consul* 15 | external-secret-operator* 16 | flux-cel* 17 | flux* 18 | istio* 19 | karpenter* 20 | kasten* 21 | kubecost-cel* 22 | kubecost* 23 | kubeops* 24 | kubevirt* 25 | linkerd* 26 | nginx* 27 | openshift* 28 | other-cel* 29 | other* 30 | pod-security-cel* 31 | pod-security* 32 | psa-cel* 33 | psa* 34 | psp-migration-cel* 35 | psp-migration* 36 | tekton* 37 | traefik-cel* 38 | traefik* 39 | velero* 40 | windows-security* 41 | -------------------------------------------------------------------------------- /.releaserc: -------------------------------------------------------------------------------- 1 | { 2 | "branches": [ 3 | "main" 4 | ], 5 | "plugins": [ 6 | "@semantic-release/commit-analyzer", 7 | "@semantic-release/release-notes-generator", 8 | "@semantic-release/github" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.sops.yaml: -------------------------------------------------------------------------------- 1 | creation_rules: 2 | - path_regex: ^k8s\/clusters\/local\/.+\.enc\.ya?ml$ 3 | encrypted_regex: ^(data|stringData)$ 4 | age: |- 5 | age14skmde00w0ps6u8asm4rdqwpktr5m5pq84070yzwvjjmcyfnl4ushfn5uq 6 | - path_regex: ^k8s\/clusters\/dev\/.+\.enc\.ya?ml$ 7 | encrypted_regex: ^(data|stringData)$ 8 | age: |- 9 | age188ez3ur89qj7pmnyyqhcp9nmxp7lvsa72plph0frkfh9tt7n5guqs0vz6c 10 | - path_regex: ^k8s\/clusters\/prod\/.+\.enc\.ya?ml$ 11 | encrypted_regex: ^(data|stringData)$ 12 | age: |- 13 | age1rk6fs67kly3h4zux5za429z3grjtvs8vcunav4sa28pxk738najsk8wgs6 14 | - path_regex: ^.+\.enc\.ya?ml$ 15 | encrypted_regex: ^(data|stringData)$ 16 | age: |- 17 | age14skmde00w0ps6u8asm4rdqwpktr5m5pq84070yzwvjjmcyfnl4ushfn5uq, 18 | age188ez3ur89qj7pmnyyqhcp9nmxp7lvsa72plph0frkfh9tt7n5guqs0vz6c, 19 | age1rk6fs67kly3h4zux5za429z3grjtvs8vcunav4sa28pxk738najsk8wgs6 20 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "inercia.vscode-k3d", 4 | "ms-azuretools.vscode-docker", 5 | "ms-kubernetes-tools.vscode-aks-tools", 6 | "redhat.vscode-yaml", 7 | "signageos.signageos-vscode-sops", 8 | "timonwong.shellcheck", 9 | "weaveworks.vscode-gitops-tools" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /.vscode/homelab.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "name": "🏠 Homelab", 5 | "path": ".." 6 | } 7 | ], 8 | "settings": { 9 | "markdownlint.config": { 10 | "MD024": false, 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Welcome to the DevantlerTech Platform ⛴️ 2 | 3 | Screenshot 2024-09-03 at 00 51 44 4 | 5 | This repo contains the deployment artifacts for the DevantlerTech Platform. The platform is a Kubernetes cluster that is highly automated with the use of Flux GitOps, CI/CD with Automated Testing, and much more. Feel free to look around. You might find some inspiration 🙌🏻 6 | 7 | ## Prerequisites 8 | 9 | For local development: 10 | 11 | - [Docker](https://docs.docker.com/get-docker/) - For running the cluster locally. 12 | - [KSail](https://github.com/devantler/ksail) - For developing the cluster locally, and for running the cluster in CI to ensure all changes are properly tested before being applied to the production cluster. 13 | 14 | For development and production clusters: 15 | 16 | - [Talos Omni](https://www.siderolabs.com/platform/saas-for-kubernetes/) - For provisioning the production cluster, and managing nodes, updates, and the Talos configuration. 17 | - [Hetzner](https://www.hetzner.com/cloud/) - For hosting servers for control plane and worker nodes. 18 | - [Cloudflare](https://www.cloudflare.com) - For etcd backups, DNS, and tunneling all traffic so my network stays private. 19 | - [Unifi](https://ui.com/) - For configuring a DMZ zone for my own nodes to run in, along with other security features. 20 | - [UTM](https://mac.getutm.app) - For running Kubernetes on Mac Mini via Apple Hypervisor. 21 | - [Flux GitOps](https://fluxcd.io) - For managing the kubernetes applications and infrastructure declaratively. 22 | - [SOPS](https://getsops.io) and [Age](https://github.com/FiloSottile/age) - For encrypting secrets at rest, allowing me to store them in this repository with confidence. 23 | 24 | ## Usage 25 | 26 | > [!IMPORTANT] 27 | > This setup uses SOPS to encrypt secrets at rest. If you want to run the platform locally, or on your own Omni instance, you will need to: 28 | > 29 | > 1. Fork this repo 30 | > 2. Create your own Age keys 31 | > 3. Update the `.sops.yaml` file in the root of the repository. 32 | > 4. Update GitHub secrets with your Age key. 33 | > 5. Replace all encoded `*.sops.yaml` files in the `k8s/` folder with new ones that are encrypted with your own keys. 34 | 35 | To run this cluster locally, simply run: 36 | 37 | ```bash 38 | ksail up 39 | ``` 40 | 41 | ## Clusters 42 | 43 | > [!TIP] 44 | > All clusters allow scheduling of workloads on control plane nodes. For homelab purposes, this is fine, but for enterprise use, it is recommended to separate control plane and worker nodes to ensure high availability and reliability. 45 | 46 | ### Production 47 | 48 | Hybrid Cloud cluster that runs on both Hetzner Cloud and on-prem. Used for production workloads. 49 | 50 | #### Control Plane Nodes 51 | 52 | - 2x [Hetzner CAX21 nodes](https://www.hetzner.com/cloud/) (QEMU ARM64 4 vCPU 8Gb RAM 80Gb SSD) 53 | - 1x [Hetzner CX32 node](https://www.hetzner.com/cloud/) (QEMU AMD64 4 vCPU 8Gb RAM 80Gb SSD) 54 | 55 | #### Worker Nodes 56 | 57 | - 1x UTM nodes (Apple Hypervisor ARM64 40 vCPU 32Gb RAM 350Gb SSD) 58 | 59 | ### Development 60 | 61 | Hybrid Cloud cluster that runs on both Hetzner Cloud and on-prem. Used to test and verify workloads before promoting them to production. 62 | 63 | #### Control Plane Nodes 64 | 65 | - 2x [Hetzner CAX21 nodes](https://www.hetzner.com/cloud/) (QEMU ARM64 4 vCPU 8Gb RAM 80Gb SSD) 66 | - 1x [Hetzner CX32 node](https://www.hetzner.com/cloud/) (QEMU AMD64 4 vCPU 8Gb RAM 80Gb SSD) 67 | 68 | #### Worker Nodes 69 | 70 | - 1x UTM nodes (Apple Hypervisor ARM64 32 vCPU 16Gb RAM 150Gb SSD) 71 | 72 | ## Hardware 73 | 74 | - [Unifi Cloud Gateway](https://eu.store.ui.com/eu/en/pro/products/ucg-ultra) 75 | - 1x Mac Mini M2 Pro (ARM64 10 CPU 32Gb RAM ~512Gb SSD) 76 | - 1x Mac Mini M1 (ARM64 8 CPU 16Gb RAM ~256Gb SSD) 77 | 78 | ## Structure 79 | 80 | The cluster uses Flux GitOps to reconcile the state of the cluster with single source of truth stored in this repository and published as an OCI image. For development, the cluster is spun up by `KSail` and for production, the cluster is provisioned by `Talos Omni`. 81 | 82 | The cluster configuration is stored in the `k8s/*` directories where the structure is as follows: 83 | 84 | - [`clusters/`](k8s/clusters): Contains the the cluster specific configuration for each environment. 85 | - [`local`](k8s/clusters/local): Contains the local cluster specific configuration. 86 | - [`prod`](k8s/clusters/prod): Contains the production cluster specific configuration.**** 87 | - [`distributions/`](k8s/distributions): Contains the distribution specific configuration. 88 | - [`kind`](k8s/distributions/kind): Contains the kind specific configuration. 89 | - [`talos`](k8s/distributions/omni): Contains the talos specific configuration. 90 | - [`bases/`](k8s/bases): Contains the different bases that are used for the different clusters and distributions. 91 | - [`infrastructure`](k8s/bases/common): Contains the different infrastructure components that are used for the different clusters and distributions. 92 | - [`apps`](k8s/bases/apps): Contains the different apps that are used for the different clusters and distributions. 93 | 94 | ### Kustomize and Flux Kustomization Flow 95 | 96 | > [!IMPORTANT] 97 | > If you know of a different way to manage kustomize and flux kustomizations that results in less boilerplate code, please let me know. I am always looking for ways to improve the structure and make it more maintainable. 98 | 99 | To support hooking into the kustomize flow for adding or modifying resources for a specific cluster, a specific distribution, or shared across all clusters, the following structure is used: 100 | 101 | ![Structure](docs/images/gitops-structure.drawio.png) 102 | 103 | This means that for every flux kustomization that is applied to the cluster, there should be a corresponding resource folder in `clusters//`, `distributions/`, or `bases/` that contains resources that should be applied to the cluster for that flux kustomization at the specific scope. For example, for the following flux kustomization `k8s/clusters//infrastructure.yaml`, the following resource folders should exist: 104 | 105 | - `k8s/clusters//infrastructure/` 106 | - `k8s/distributions//infrastructure/` 107 | - `k8s/bases/infrastructure/` 108 | 109 | This allows for a clean separation of concerns and allows for modification of the resources for a specific cluster, distribution, or shared across all clusters. 110 | 111 | ## Monthly Cost 112 | 113 | | Item | No. | Per unit | Total in Actual | Total in $ | 114 | | ------------------ | --- | -------- | --------------- | ---------- | 115 | | Talos Omni | 1 | $10 | $10 | $10 | 116 | | Cloudflare Domains | 3 | $0,87 | $2,61 | $2,61 | 117 | | Hetzner CAX21 | 4 | €7,49 | €29,96 | $34 | 118 | | Hetzner CX32 | 2 | €7,88 | €15,76 | $17,88 | 119 | | | | | | $64,49 | 120 | 121 | ## Star History 122 | 123 | [![Star History Chart](https://api.star-history.com/svg?repos=devantler/homelab&type=Date)](https://star-history.com/#devantler/homelab&Date) 124 | -------------------------------------------------------------------------------- /docs/images/gitops-structure.drawio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devantler-tech/platform/c920b5fa20f33d8ad4473bdb7b23f994cbb91f64/docs/images/gitops-structure.drawio.png -------------------------------------------------------------------------------- /hetzner/README.md: -------------------------------------------------------------------------------- 1 | # Talos Hetzner Cloud Bootstrapping Scripts 2 | 3 | This directory contains scripts to bootstrap Talos Omni nodes on Hetzner Cloud. 4 | 5 | ## Usage 6 | 7 | Before you can create and delete servers, you need a Hetzner Cloud Account with a Hetzner Cloud API token and SSH key configured. 8 | 9 | 1. Create an account on Hetzner Cloud 10 | 2. Create a new project on Hetzner Cloud (manually) 11 | 3. Create a new network on Hetzner Cloud with a subnet, and call it `homelab` (manually) 12 | 4. Create a new API token on Hetzner Cloud with read/write access to the project (manually) 13 | 5. Create an SSH Key on Hetzner Cloud (manually) 14 | 15 | ### Creating a snapshot of the Talos installation media 16 | 17 | Now that Hetzner Cloud is configured, and is ready to spin up servers for you, you need to get the Talos installation media, so we can create a snapshot of it, and use it to create servers in the future. 18 | 19 | 1. Download the Talos installation media for Hetzner Cloud from the Talos Omni UI (manually) 20 | 2. Move the Talos installation media to the `talos--/` folder, and ensure it is referenced in the `hcloud.pkr.hcl` file 21 | 3. Run the `create-snapshot.sh` script to create a snapshot of the Talos image. 22 | 23 | That's it! Now you can create and delete servers! 24 | 25 | ### Creating a Server 26 | 27 | To create a server, you need to run the `create-server.sh` script. This script will create a new server with the Talos image, and will configure the server to use the `homelab` network. 28 | 29 | ### Deleting a Server 30 | 31 | > [!WARNING] 32 | > Before deleting a server, ensure you have drained it, and destroyed it from your cluster. You can do this manually in the Talos Omni UI. 33 | 34 | To delete a server, you need to run the `delete-server.sh` script. This script will delete the server, and all of its resources. 35 | -------------------------------------------------------------------------------- /hetzner/create-server.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Set default values 3 | token="" 4 | server_name="" 5 | image_id="" 6 | server_type="cax21" 7 | location="fsn1" 8 | 9 | usage() { 10 | echo "Usage: $0 --token --server-name --server-type --location --placement-group --image-id --ssh-key-name " 11 | echo "" 12 | echo "Where:" 13 | echo " --token is the Hetzner Cloud API token for a Hetzner Cloud project" 14 | echo " --server-name is the name of the server to create" 15 | echo " --server-type is the type of server to create e.g. cx11" 16 | echo " --location is the location to create the server in e.g. fsn1" 17 | echo " --image-id is the ID of the snapshot image to use for the server" 18 | exit 1 19 | } 20 | 21 | while [[ "$#" -gt 0 ]]; do 22 | case $1 in 23 | --token) 24 | token="$2" 25 | shift 26 | ;; 27 | --server-name) 28 | server_name="$2" 29 | shift 30 | ;; 31 | --server-type) 32 | server_type="$2" 33 | shift 34 | ;; 35 | --location) 36 | location="$2" 37 | shift 38 | ;; 39 | --placement-group) 40 | placement_group="$2" 41 | shift 42 | ;; 43 | --image-id) 44 | image_id="$2" 45 | shift 46 | ;; 47 | --ssh-key-name) 48 | ssh_key_name="$2" 49 | shift 50 | ;; 51 | *) usage ;; 52 | esac 53 | shift 54 | done 55 | 56 | if [ -z "$token" ] || [ -z "$server_name" ] || [ -z "$server_type" ] || [ -z "$location" ] || [ -z "$placement_group" ] || [ -z "$image_id" ] || [ -z "$ssh_key_name" ]; then 57 | usage 58 | fi 59 | 60 | export HCLOUD_TOKEN=$1 61 | 62 | hcloud context create default 63 | 64 | hcloud network create --name default --ip-range 10.0.0.0/16 65 | 66 | if [ "$(hcloud network describe default | yq -e '.Subnets[]')" == "null" ]; then 67 | hcloud network add-subnet default --type server --network-zone eu-central 68 | fi 69 | 70 | hcloud firewall create --name talos-firewall --rules-file - <<<'[ 71 | { 72 | "description": "Allow KubeSpan Traffic", 73 | "direction": "in", 74 | "port": "51820", 75 | "protocol": "udp", 76 | "source_ips": [ 77 | "0.0.0.0/0", 78 | "::/0" 79 | ] 80 | } 81 | ]' 82 | 83 | hcloud server create --name "$server_name" \ 84 | --type "$server_type" \ 85 | --location "$location" \ 86 | --placement-group "$placement_group" \ 87 | --image "$image_id" \ 88 | --network default \ 89 | --firewall talos-firewall \ 90 | --ssh-key ssh-key 91 | -------------------------------------------------------------------------------- /hetzner/create-snapshot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Set default values 3 | token="" 4 | media_path="" 5 | 6 | usage() { 7 | echo "Usage: $0 --media-path --token " 8 | echo "" 9 | echo "Where:" 10 | echo " --token is the Hetzner Cloud API token for a Hetzner Cloud project" 11 | echo " --media-path is the path to the media file" 12 | exit 1 13 | } 14 | 15 | while [[ "$#" -gt 0 ]]; do 16 | case $1 in 17 | --token) 18 | token="$2" 19 | shift 20 | ;; 21 | --media-path) 22 | media_path="$2" 23 | shift 24 | ;; 25 | *) usage ;; 26 | esac 27 | shift 28 | done 29 | 30 | if [ -z "$media_path" ] || [ -z "$token" ]; then 31 | usage 32 | fi 33 | 34 | export HCLOUD_TOKEN=$token 35 | packer init "$media_path" 36 | packer build "$media_path" 37 | -------------------------------------------------------------------------------- /hetzner/delete-server.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | usage() { 3 | echo "Usage: $0 --token --server-name " 4 | echo "" 5 | echo "Where:" 6 | echo " --token is the Hetzner Cloud API token for a Hetzner Cloud project" 7 | echo " --server-name is the name of the server to delete" 8 | exit 1 9 | } 10 | 11 | while [[ "$#" -gt 0 ]]; do 12 | case $1 in 13 | --token) 14 | token="$2" 15 | shift 16 | ;; 17 | --server-name) 18 | server_name="$2" 19 | shift 20 | ;; 21 | *) usage ;; 22 | esac 23 | shift 24 | done 25 | 26 | if [ -z "$token" ] || [ -z "$server_name" ]; then 27 | usage 28 | fi 29 | 30 | export HCLOUD_TOKEN=$token 31 | 32 | hcloud context create talos 33 | 34 | hcloud server delete "$server_name" 35 | -------------------------------------------------------------------------------- /hetzner/talos-v1.10.3-amd64/hcloud.pkr.hcl: -------------------------------------------------------------------------------- 1 | packer { 2 | required_plugins { 3 | hcloud = { 4 | version = ">= 1.5.3" 5 | source = "github.com/hetznercloud/hcloud" 6 | } 7 | } 8 | } 9 | 10 | locals { 11 | image = "talos-v1.10.3-amd64/hcloud-amd64-omni-devantler-v1.10.3.raw.xz" 12 | } 13 | 14 | source "hcloud" "talos" { 15 | rescue = "linux64" 16 | image = "debian-12" # 17 | location = "fsn1" # https://docs.hetzner.com/cloud/general/locations 18 | server_type = "cx22" # https://docs.hetzner.com/cloud/servers/overview 19 | ssh_username = "root" 20 | snapshot_name = "talos-v1.10.3-amd64" 21 | server_name = "packer-talos-v1.10.3-amd64" 22 | } 23 | 24 | build { 25 | sources = ["source.hcloud.talos"] 26 | 27 | provisioner "file" { 28 | source = "${local.image}" 29 | destination = "/tmp/talos.raw.xz" 30 | } 31 | 32 | provisioner "shell" { 33 | inline = [ 34 | "xz -d -c /tmp/talos.raw.xz | dd of=/dev/sda && sync", 35 | ] 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /hetzner/talos-v1.10.3-arm64/hcloud.pkr.hcl: -------------------------------------------------------------------------------- 1 | packer { 2 | required_plugins { 3 | hcloud = { 4 | version = ">= 1.5.3" 5 | source = "github.com/hetznercloud/hcloud" 6 | } 7 | } 8 | } 9 | 10 | locals { 11 | image = "talos-v1.10.3-arm64/hcloud-arm64-omni-devantler-v1.10.3.raw.xz" 12 | } 13 | 14 | source "hcloud" "talos" { 15 | rescue = "linux64" 16 | image = "debian-12" # 17 | location = "fsn1" # https://docs.hetzner.com/cloud/general/locations 18 | server_type = "cax11" # https://docs.hetzner.com/cloud/servers/overview 19 | ssh_username = "root" 20 | snapshot_name = "talos-v1.10.3-arm64" 21 | server_name = "packer-talos-v1.10.3-arm64" 22 | } 23 | 24 | build { 25 | sources = ["source.hcloud.talos"] 26 | 27 | provisioner "file" { 28 | source = "${local.image}" 29 | destination = "/tmp/talos.raw.xz" 30 | } 31 | 32 | provisioner "shell" { 33 | inline = [ 34 | "xz -d -c /tmp/talos.raw.xz | dd of=/dev/sda && sync", 35 | ] 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /hosts: -------------------------------------------------------------------------------- 1 | 127.0.0.1 dex.local.platform.devantler.tech 2 | 127.0.0.1 goldilocks.local.platform.devantler.tech 3 | 127.0.0.1 local.platform.devantler.tech 4 | 127.0.0.1 oauth2-proxy.local.platform.devantler.tech 5 | 127.0.0.1 traefik.local.platform.devantler.tech 6 | 127.0.0.1 whoami.local.platform.devantler.tech 7 | -------------------------------------------------------------------------------- /k8s/bases/README.md: -------------------------------------------------------------------------------- 1 | # Bases 2 | 3 | This directory contains the base resources for the Kubernetes platform. These resources are used by all clusters and distributions in the platform. 4 | -------------------------------------------------------------------------------- /k8s/bases/apps/README.md: -------------------------------------------------------------------------------- 1 | # Apps 2 | 3 | These are the applications that I run on my Kubernetes cluster. They differ from infrastructure as they all are either web applications, services, or APIs that do not provide any infrastructural capabilities. 4 | -------------------------------------------------------------------------------- /k8s/bases/apps/fleetdm/README.md: -------------------------------------------------------------------------------- 1 | # Fleet Device Management 2 | 3 | Fleet Device Management is a free and open source device management solution for teams of any size. It supports all major operating systems, while still allowing low-level access to OS-specific features. 4 | 5 | - [Documentation](https://fleetdm.com/docs/) 6 | - [Helm Chart](https://github.com/fleetdm/fleet/tree/main/charts/fleet) 7 | -------------------------------------------------------------------------------- /k8s/bases/apps/fleetdm/helm-release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2 2 | kind: HelmRelease 3 | metadata: 4 | name: fleetdm 5 | namespace: fleetdm 6 | labels: 7 | helm.toolkit.fluxcd.io/helm-test: enabled 8 | helm.toolkit.fluxcd.io/remediation: enabled 9 | spec: 10 | interval: 10m 11 | chart: 12 | spec: 13 | chart: fleet 14 | version: v6.6.4 15 | sourceRef: 16 | kind: HelmRepository 17 | name: fleetdm 18 | # https://github.com/fleetdm/fleet/blob/main/charts/fleet/values.yaml 19 | values: 20 | resources: {} 21 | hostName: fleetdm.${domain} 22 | ingress: 23 | enabled: true 24 | hosts: 25 | - host: fleetdm.${domain} 26 | paths: 27 | - path: / 28 | pathType: ImplementationSpecific 29 | tls: {} 30 | annotations: 31 | gethomepage.dev/enabled: "true" 32 | gethomepage.dev/name: Fleet Device Management 33 | gethomepage.dev/description: Open-source device management platform. 34 | gethomepage.dev/group: Provisioning 35 | gethomepage.dev/icon: si-coderwall-#40B5A4 36 | fleet: 37 | tls: 38 | enabled: false 39 | database: 40 | address: fleetdm-mysql.fleetdm:3306 41 | cache: 42 | address: fleetdm-redis-master.fleetdm:6379 43 | usePassword: true 44 | # https://github.com/bitnami/charts/blob/main/bitnami/mysql/values.yaml 45 | mysql: 46 | enabled: true 47 | auth: 48 | createDatabase: true 49 | database: fleet 50 | username: fleet 51 | existingSecret: mysql 52 | # https://github.com/bitnami/charts/blob/main/bitnami/redis/values.yaml 53 | redis: 54 | enabled: true 55 | auth: 56 | existingSecret: redis 57 | existingSecretPasswordKey: redis-password 58 | -------------------------------------------------------------------------------- /k8s/bases/apps/fleetdm/helm-repository.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1 2 | kind: HelmRepository 3 | metadata: 4 | name: fleetdm 5 | namespace: fleetdm 6 | spec: 7 | url: https://fleetdm.github.io/fleet/charts 8 | -------------------------------------------------------------------------------- /k8s/bases/apps/fleetdm/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - mysql-secret.yaml 5 | - namespace.yaml 6 | - redis-secret.yaml 7 | - helm-release.yaml 8 | - helm-repository.yaml 9 | -------------------------------------------------------------------------------- /k8s/bases/apps/fleetdm/mysql-secret.yaml: -------------------------------------------------------------------------------- 1 | kind: Secret 2 | apiVersion: v1 3 | metadata: 4 | name: mysql 5 | namespace: fleetdm 6 | stringData: 7 | mysql-root-password: ${fleetdm_mysql_password:=fleetdm} 8 | mysql-replication-password: ${fleetdm_mysql_password:=fleetdm} 9 | mysql-password: ${fleetdm_mysql_password:=fleetdm} 10 | -------------------------------------------------------------------------------- /k8s/bases/apps/fleetdm/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: fleetdm 5 | labels: 6 | goldilocks.fairwinds.com/vpa-update-mode: "auto" 7 | goldilocks.fairwinds.com/vpa-min-replicas: "2" 8 | 9 | -------------------------------------------------------------------------------- /k8s/bases/apps/fleetdm/redis-secret.yaml: -------------------------------------------------------------------------------- 1 | kind: Secret 2 | apiVersion: v1 3 | metadata: 4 | name: redis 5 | namespace: fleetdm 6 | stringData: 7 | redis-password: ${fleetdm_redis_password:=fleetdm} 8 | -------------------------------------------------------------------------------- /k8s/bases/apps/headlamp/README.md: -------------------------------------------------------------------------------- 1 | # Headlamp 2 | 3 | Headlamp is a lightweight Kubernetes UI which supports multiple clusters and is extensible at its core. 4 | 5 | - [Documentation](https://headlamp.dev/docs/latest/) 6 | - [Helm Chart](https://github.com/headlamp-k8s/headlamp/tree/main/charts/headlamp) 7 | -------------------------------------------------------------------------------- /k8s/bases/apps/headlamp/helm-release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2 2 | kind: HelmRelease 3 | metadata: 4 | name: headlamp 5 | namespace: headlamp 6 | labels: 7 | helm.toolkit.fluxcd.io/helm-test: enabled 8 | helm.toolkit.fluxcd.io/remediation: enabled 9 | spec: 10 | interval: 10m 11 | chart: 12 | spec: 13 | chart: headlamp 14 | version: 0.27.0 15 | sourceRef: 16 | kind: HelmRepository 17 | name: headlamp 18 | postRenderers: 19 | - kustomize: 20 | patches: 21 | - target: 22 | kind: Deployment 23 | name: headlamp 24 | patch: | 25 | - op: add 26 | path: /metadata/annotations/secret.reloader.stakater.com~1reload 27 | value: oidc 28 | # https://github.com/headlamp-k8s/headlamp/blob/main/charts/headlamp/values.yaml 29 | values: 30 | config: 31 | oidc: 32 | clientID: github 33 | clientSecret: ${dex_client_secret} 34 | issuerURL: https://dex.${domain} 35 | scopes: "profile,email,groups" 36 | ingress: 37 | enabled: true 38 | ingressClassName: ${ingress_class_name:=} 39 | hosts: 40 | - host: headlamp.${domain} 41 | paths: 42 | - path: / 43 | type: ImplementationSpecific 44 | annotations: 45 | gethomepage.dev/enabled: "true" 46 | gethomepage.dev/name: Headlamp 47 | gethomepage.dev/description: A web UI for managing Kubernetes clusters. 48 | gethomepage.dev/group: Management 49 | gethomepage.dev/icon: https://pbs.twimg.com/profile_images/1537480067227566080/waXG0X7n_400x400.jpg 50 | -------------------------------------------------------------------------------- /k8s/bases/apps/headlamp/helm-repository.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1 2 | kind: HelmRepository 3 | metadata: 4 | name: headlamp 5 | namespace: headlamp 6 | spec: 7 | url: https://headlamp-k8s.github.io/headlamp/ 8 | -------------------------------------------------------------------------------- /k8s/bases/apps/headlamp/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - namespace.yaml 5 | - helm-release.yaml 6 | - helm-repository.yaml 7 | -------------------------------------------------------------------------------- /k8s/bases/apps/headlamp/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: headlamp 5 | labels: 6 | goldilocks.fairwinds.com/vpa-update-mode: "auto" 7 | goldilocks.fairwinds.com/vpa-min-replicas: "2" 8 | -------------------------------------------------------------------------------- /k8s/bases/apps/homepage/README.md: -------------------------------------------------------------------------------- 1 | # Homepage 2 | 3 | A modern, fully static, fast, secure fully proxied, highly customizable application dashboard with integrations for over 100 services and translations into multiple languages. Easily configured via YAML files or through docker label discovery. 4 | 5 | - [Documentation](https://gethomepage.dev/latest/) 6 | - [Helm Chart](https://gethomepage.dev/latest/installation/k8s/) 7 | -------------------------------------------------------------------------------- /k8s/bases/apps/homepage/helm-release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2 2 | kind: HelmRelease 3 | metadata: 4 | name: homepage 5 | namespace: homepage 6 | labels: 7 | helm.toolkit.fluxcd.io/helm-test: enabled 8 | helm.toolkit.fluxcd.io/remediation: enabled 9 | spec: 10 | interval: 10m 11 | chart: 12 | spec: 13 | chart: homepage 14 | version: 2.1.0 15 | sourceRef: 16 | kind: HelmRepository 17 | name: homepage 18 | postRenderers: 19 | - kustomize: 20 | patches: 21 | - target: 22 | kind: Deployment 23 | name: homepage 24 | patch: | 25 | - op: add 26 | path: /metadata/annotations/configmap.reloader.stakater.com~1reload 27 | value: homepage 28 | # ICONS: 29 | # https://github.com/walkxcode/dashboard-icons 30 | # https://simpleicons.org 31 | # https://pictogrammers.com/library/mdi/ 32 | # --- 33 | # https://github.com/jameswynn/helm-charts/blob/main/charts/homepage/values.yaml 34 | values: 35 | enableRbac: true 36 | serviceaccount: 37 | create: true 38 | ingress: 39 | main: 40 | enabled: true 41 | hosts: 42 | - host: ${domain} 43 | paths: 44 | - path: / 45 | pathType: Prefix 46 | annotations: 47 | traefik.ingress.kubernetes.io/router.middlewares: traefik-forward-auth@kubernetescrd 48 | env: 49 | - name: HOMEPAGE_ALLOWED_HOSTS 50 | value: ${domain} 51 | config: 52 | kubernetes: 53 | mode: cluster 54 | settingsString: | 55 | title: Platform 56 | favicon: https://devantler.tech/assets/images/author.png 57 | theme: dark 58 | color: slate 59 | background: 60 | image: https://images.unsplash.com/photo-1478760329108-5c3ed9d495a0?q=80&w=1974&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D 61 | blur: sm 62 | opacity: 70 63 | layout: 64 | Kubernetes: 65 | Cloud: 66 | Network: 67 | Storage: 68 | Monitoring: 69 | Analytics: 70 | widgets: 71 | - logo: 72 | icon: https://devantler.tech/assets/images/author.png 73 | - greeting: 74 | text_size: xl 75 | text: Welcome home! 76 | - search: 77 | provider: google 78 | target: _blank 79 | - datetime: 80 | text_size: xl 81 | format: 82 | dateStyle: long 83 | timeStyle: short 84 | hourCycle: h23 85 | - openmeteo: 86 | units: metric 87 | cache: 5 88 | # - longhorn: 89 | # expanded: true 90 | # total: true 91 | # labels: false 92 | # nodes: false 93 | services: 94 | - Kubernetes: 95 | - Omni: 96 | icon: si-talos-#FF7300 97 | href: https://devantler.omni.siderolabs.io 98 | description: Platform for provisioning and managing Talos Linux clusters. 99 | - Cloud: 100 | - Hetzner Cloud: 101 | icon: hetzner 102 | href: https://console.hetzner.cloud/projects 103 | description: Cloud infrastructure provider. 104 | - Network: 105 | - Cloudflare: 106 | icon: cloudflare 107 | href: https://dash.cloudflare.com 108 | description: Central hub for managing public networking, e.g. FQDN, DNS and remote tunneling. 109 | widget: 110 | type: cloudflared 111 | accountid: ${cloudflare_account_id} 112 | tunnelid: ${cloudflared_tunnel_id} 113 | key: ${cloudflare_api_token} 114 | - UniFi: 115 | icon: unifi 116 | href: https://unifi.ui.com 117 | description: Central hub for managing on-prem UniFi network infrastructure. 118 | - Monitoring: 119 | - Grafana: 120 | icon: grafana 121 | href: https://devantler.grafana.net 122 | description: Central hub for monitoring my infrastructure. 123 | - Analytics: 124 | - Disqus: 125 | icon: si-disqus-#2E9FFF 126 | href: https://disqus.com 127 | description: Platform to track and moderate embedded comments on my sites. 128 | - Google Analytics: 129 | icon: google-analytics 130 | href: https://analytics.google.com 131 | description: Web analytics service. 132 | bookmarks: 133 | - Personal: 134 | - Personal Site: 135 | - icon: github-light 136 | href: https://devantler.tech 137 | - Developer Platforms: 138 | - GitHub: 139 | - icon: github-light 140 | href: https://github.com 141 | - Codecov: 142 | - icon: si-codecov-#F01F7A 143 | href: https://app.codecov.io 144 | - Renovate: 145 | - icon: si-renovatebot-#007fa0 146 | href: https://developer.mend.io 147 | - Kubernetes: 148 | - ArtifactHUB: 149 | - icon: si-artifacthub-#417598 150 | href: https://artifacthub.io 151 | - CRD Docs: 152 | - icon: si-kubernetes-#326CE5 153 | href: https://doc.crds.dev 154 | - Network Policy Editor: 155 | - icon: si-kubernetes-#326CE5 156 | href: https://editor.networkpolicy.io 157 | - Package Registries: 158 | - Docker Hub: 159 | - icon: docker 160 | href: https://hub.docker.com 161 | - NuGet: 162 | - icon: si-nuget-#1088d6 163 | href: https://www.nuget.org 164 | -------------------------------------------------------------------------------- /k8s/bases/apps/homepage/helm-repository.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1 2 | kind: HelmRepository 3 | metadata: 4 | name: homepage 5 | namespace: homepage 6 | spec: 7 | url: https://jameswynn.github.io/helm-charts/ 8 | -------------------------------------------------------------------------------- /k8s/bases/apps/homepage/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - namespace.yaml 5 | - helm-release.yaml 6 | - helm-repository.yaml 7 | -------------------------------------------------------------------------------- /k8s/bases/apps/homepage/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: homepage 5 | labels: 6 | goldilocks.fairwinds.com/vpa-update-mode: "auto" 7 | goldilocks.fairwinds.com/vpa-min-replicas: "2" 8 | -------------------------------------------------------------------------------- /k8s/bases/apps/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - homepage/ 6 | - whoami/ 7 | -------------------------------------------------------------------------------- /k8s/bases/apps/plantuml/README.md: -------------------------------------------------------------------------------- 1 | # PlantUML 2 | 3 | A highly versatile tool that facilitates the rapid and straightforward creation of a wide array of diagrams. 4 | 5 | - [Documentation](https://plantuml.com) 6 | - [Helm Chart](https://github.com/stevehipwell/helm-charts/tree/main/charts/plantuml) 7 | 8 | ## Post-build variables 9 | 10 | | Variable | Description | Default | Required | 11 | | ------------------------ | ---------------------------------------------------------- | :-----: | :------: | 12 | | domain | The domain of the cluster | - | ✓ | 13 | | plantuml_ingress_enabled | Whether to enable an ingress route to the PlantUML service | true | ✗ | 14 | -------------------------------------------------------------------------------- /k8s/bases/apps/plantuml/helm-release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2 2 | kind: HelmRelease 3 | metadata: 4 | name: plantuml 5 | namespace: plantuml 6 | labels: 7 | helm.toolkit.fluxcd.io/helm-test: enabled 8 | helm.toolkit.fluxcd.io/remediation: enabled 9 | spec: 10 | interval: 10m 11 | chart: 12 | spec: 13 | chart: plantuml 14 | version: 3.38.0 15 | sourceRef: 16 | kind: HelmRepository 17 | name: plantuml 18 | # https://github.com/stevehipwell/helm-charts/blob/main/charts/plantuml/values.yaml 19 | values: 20 | ingress: 21 | enabled: ${plantuml_ingress_enabled:=true} 22 | hosts: 23 | - plantuml.${domain} 24 | annotations: 25 | gethomepage.dev/enabled: "true" 26 | gethomepage.dev/name: PlantUML 27 | gethomepage.dev/description: Text-based UML diagramming tool. 28 | gethomepage.dev/icon: si-uml-#FABD14 29 | -------------------------------------------------------------------------------- /k8s/bases/apps/plantuml/helm-repository.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1 2 | kind: HelmRepository 3 | metadata: 4 | name: plantuml 5 | namespace: plantuml 6 | spec: 7 | url: oci://ghcr.io/stevehipwell/helm-charts 8 | type: oci 9 | -------------------------------------------------------------------------------- /k8s/bases/apps/plantuml/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - namespace.yaml 5 | - helm-release.yaml 6 | - helm-repository.yaml 7 | -------------------------------------------------------------------------------- /k8s/bases/apps/plantuml/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: plantuml 5 | labels: 6 | goldilocks.fairwinds.com/vpa-update-mode: "auto" 7 | goldilocks.fairwinds.com/vpa-min-replicas: "2" 8 | -------------------------------------------------------------------------------- /k8s/bases/apps/whoami/helm-release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2 2 | kind: HelmRelease 3 | metadata: 4 | name: whoami 5 | namespace: whoami 6 | labels: 7 | # helm.toolkit.fluxcd.io/helm-test: enabled 8 | helm.toolkit.fluxcd.io/remediation: enabled 9 | spec: 10 | interval: 10m 11 | chart: 12 | spec: 13 | chart: whoami 14 | version: 5.3.0 15 | sourceRef: 16 | kind: HelmRepository 17 | name: whoami 18 | # https://github.com/cowboysysop/charts/blob/master/charts/whoami/values.yaml 19 | values: 20 | ingress: 21 | enabled: true 22 | hosts: 23 | - host: whoami.${domain} 24 | paths: 25 | - / 26 | annotations: 27 | traefik.ingress.kubernetes.io/router.middlewares: traefik-forward-auth@kubernetescrd 28 | -------------------------------------------------------------------------------- /k8s/bases/apps/whoami/helm-repository.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1 2 | kind: HelmRepository 3 | metadata: 4 | name: whoami 5 | namespace: whoami 6 | spec: 7 | url: https://cowboysysop.github.io/charts/ 8 | -------------------------------------------------------------------------------- /k8s/bases/apps/whoami/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - namespace.yaml 5 | - helm-release.yaml 6 | - helm-repository.yaml 7 | -------------------------------------------------------------------------------- /k8s/bases/apps/whoami/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: whoami 5 | labels: 6 | goldilocks.fairwinds.com/vpa-update-mode: "auto" 7 | goldilocks.fairwinds.com/vpa-min-replicas: "2" 8 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/README.md: -------------------------------------------------------------------------------- 1 | # Infrastructure 2 | 3 | These are services that provide the underlying infrastructure for my homelab. Many provide custom resources or automate certain tasks to simplify the management of my homelab. 4 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/certificates/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - traefik-certificate.yaml 6 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/certificates/traefik-certificate.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1 2 | kind: Certificate 3 | metadata: 4 | name: certificate 5 | namespace: traefik 6 | spec: 7 | secretName: certificate-tls 8 | dnsNames: 9 | - "${domain}" 10 | - "*.${domain}" 11 | issuerRef: 12 | group: ${issuer_group} 13 | kind: ${issuer_kind} 14 | name: ${issuer_name} 15 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/cluster-policies/flux/helm-release-enable-tests.yaml: -------------------------------------------------------------------------------- 1 | # TODO: Upstream `helm-release-enable-tests.yaml` to Kyverno policies repository. 2 | apiVersion: kyverno.io/v1 3 | kind: ClusterPolicy 4 | metadata: 5 | name: helm-release-enable-tests 6 | annotations: 7 | policies.kyverno.io/title: Helm Release Enable Tests 8 | policies.kyverno.io/category: Flux 9 | policies.kyverno.io/severity: low 10 | policies.kyverno.io/subject: HelmRelease 11 | policies.kyverno.io/description: >- 12 | This policy enables Helm tests for HelmRelease resources. 13 | spec: 14 | rules: 15 | - name: enable-helm-tests 16 | match: 17 | resources: 18 | kinds: 19 | - HelmRelease 20 | selector: 21 | matchLabels: 22 | helm.toolkit.fluxcd.io/helm-test: "enabled" 23 | mutate: 24 | patchStrategicMerge: 25 | spec: 26 | test: 27 | enable: true 28 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/cluster-policies/flux/helm-release-install-crds.yaml: -------------------------------------------------------------------------------- 1 | # TODO: Upstream `helm-release-install-crds.yaml` to Kyverno policies repository. 2 | apiVersion: kyverno.io/v1 3 | kind: ClusterPolicy 4 | metadata: 5 | name: helm-release-install-crds 6 | annotations: 7 | policies.kyverno.io/title: Helm Release Install CRDs 8 | policies.kyverno.io/category: Flux 9 | policies.kyverno.io/severity: low 10 | policies.kyverno.io/subject: HelmRelease 11 | policies.kyverno.io/description: >- 12 | This policy sets the installation strategy for CRDs in HelmRelease resources 13 | to CreateReplace. This ensures that if a HelmRelease is installed or upgraded, 14 | the CRDs will be created or replaced as needed. 15 | spec: 16 | rules: 17 | - name: set-helm-release-install-crds 18 | match: 19 | resources: 20 | kinds: 21 | - HelmRelease 22 | selector: 23 | matchLabels: 24 | helm.toolkit.fluxcd.io/crds: "enabled" 25 | mutate: 26 | patchStrategicMerge: 27 | spec: 28 | install: 29 | crds: CreateReplace 30 | upgrade: 31 | crds: CreateReplace 32 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/cluster-policies/flux/helm-release-remediation-retries.yaml: -------------------------------------------------------------------------------- 1 | # TODO: Upstream `helm-release-remediation-retries.yaml` to Kyverno policies repository. 2 | apiVersion: kyverno.io/v1 3 | kind: ClusterPolicy 4 | metadata: 5 | name: helm-release-remediation-retries 6 | annotations: 7 | policies.kyverno.io/title: Helm Release Remediation Retries 8 | policies.kyverno.io/category: Flux 9 | policies.kyverno.io/severity: low 10 | policies.kyverno.io/subject: HelmRelease 11 | policies.kyverno.io/description: >- 12 | This policy sets the remediation retries for HelmRelease resources 13 | to 3. This ensures that if a HelmRelease fails to install or upgrade, 14 | it will retry up to 3 times before giving up. 15 | spec: 16 | rules: 17 | - name: set-remediation-retries 18 | match: 19 | resources: 20 | kinds: 21 | - HelmRelease 22 | selector: 23 | matchLabels: 24 | helm.toolkit.fluxcd.io/remediation: "enabled" 25 | mutate: 26 | patchStrategicMerge: 27 | spec: 28 | install: 29 | remediation: 30 | retries: 3 31 | upgrade: 32 | remediation: 33 | retries: 3 34 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/cluster-policies/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - flux/helm-release-enable-tests.yaml 6 | - flux/helm-release-install-crds.yaml 7 | - flux/helm-release-remediation-retries.yaml 8 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/cluster-policies/samples/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devantler-tech/platform/c920b5fa20f33d8ad4473bdb7b23f994cbb91f64/k8s/bases/infrastructure/cluster-policies/samples/.gitkeep -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/cert-manager/README.md: -------------------------------------------------------------------------------- 1 | # Cert Manager 2 | 3 | Cert Manager is a Kubernetes add-on to automate the management and issuance of TLS certificates from various issuing sources. 4 | 5 | - [Documentation](https://cert-manager.io/docs/) 6 | - [Helm Chart](https://github.com/cert-manager/cert-manager/tree/master/deploy/charts/cert-manager) 7 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/cert-manager/helm-release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2 2 | kind: HelmRelease 3 | metadata: 4 | name: cert-manager 5 | namespace: cert-manager 6 | labels: 7 | helm.toolkit.fluxcd.io/crds: enabled 8 | helm.toolkit.fluxcd.io/helm-test: enabled 9 | helm.toolkit.fluxcd.io/remediation: enabled 10 | spec: 11 | interval: 10m 12 | chart: 13 | spec: 14 | chart: cert-manager 15 | version: v1.17.2 16 | sourceRef: 17 | kind: HelmRepository 18 | name: cert-manager 19 | install: 20 | crds: CreateReplace 21 | upgrade: 22 | crds: CreateReplace 23 | # https://github.com/cert-manager/cert-manager/blob/master/deploy/charts/cert-manager/values.yaml 24 | values: 25 | replicaCount: ${cert_manager_replicas:=2} 26 | webhook: 27 | replicaCount: ${cert_manager_replicas:=2} 28 | cainjector: 29 | replicaCount: ${cert_manager_replicas:=2} 30 | podDisruptionBudget: 31 | enabled: true 32 | crds: 33 | enabled: true 34 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/cert-manager/helm-repository.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1 2 | kind: HelmRepository 3 | metadata: 4 | name: cert-manager 5 | namespace: cert-manager 6 | spec: 7 | url: https://charts.jetstack.io 8 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/cert-manager/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - namespace.yaml 5 | - helm-release.yaml 6 | - helm-repository.yaml 7 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/cert-manager/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: cert-manager 5 | labels: 6 | goldilocks.fairwinds.com/vpa-update-mode: "auto" 7 | goldilocks.fairwinds.com/vpa-min-replicas: "2" 8 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/cilium/README.md: -------------------------------------------------------------------------------- 1 | # Cilium 2 | 3 | Cilium is ebpf-based CNI (Container Network Interface) for Kubernetes, providing advanced networking, security, and observability features. 4 | 5 | - [Documentation](https://docs.cilium.io/en/stable/) 6 | - [Helm Chart](https://github.com/cilium/cilium/blob/main/install/kubernetes/cilium) 7 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/cilium/helm-release.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: helm.toolkit.fluxcd.io/v2 3 | kind: HelmRelease 4 | metadata: 5 | name: cilium 6 | namespace: kube-system 7 | labels: 8 | helm.toolkit.fluxcd.io/crds: enabled 9 | helm.toolkit.fluxcd.io/helm-test: enabled 10 | helm.toolkit.fluxcd.io/remediation: enabled 11 | spec: 12 | chart: 13 | spec: 14 | chart: cilium 15 | version: 1.16.10 16 | sourceRef: 17 | kind: HelmRepository 18 | name: cilium 19 | interval: 10m0s 20 | # https://github.com/cilium/cilium/blob/main/install/kubernetes/cilium/values.yaml 21 | values: 22 | hubble: 23 | relay: 24 | replicas: ${cilium_replicas:=2} 25 | ui: 26 | replicas: ${cilium_replicas:=2} 27 | operator: 28 | replicas: ${cilium_replicas:=2} 29 | clustermesh: 30 | apiserver: 31 | replicas: ${cilium_replicas:=2} 32 | ipam: 33 | mode: kubernetes 34 | kubeProxyReplacement: true 35 | authentication: 36 | mutual: 37 | spire: 38 | enabled: true 39 | install: 40 | namespace: kube-system 41 | existingNamespace: true 42 | gatewayAPI: 43 | enabled: true 44 | enableAlpn: true 45 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/cilium/helm-repository.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: source.toolkit.fluxcd.io/v1 3 | kind: HelmRepository 4 | metadata: 5 | name: cilium 6 | namespace: kube-system 7 | spec: 8 | url: https://helm.cilium.io/ 9 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/cilium/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - helm-release.yaml 6 | - helm-repository.yaml 7 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/dex/README.md: -------------------------------------------------------------------------------- 1 | # Dex 2 | 3 | A federated OpenID Connect provider for Kubernetes. 4 | 5 | - [Documentation](https://dexidp.io/docs/) 6 | - [Helm Chart](https://github.com/dexidp/helm-charts/tree/master/charts/dex) 7 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/dex/helm-release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2 2 | kind: HelmRelease 3 | metadata: 4 | name: dex 5 | namespace: dex 6 | labels: 7 | helm.toolkit.fluxcd.io/crds: enabled 8 | helm.toolkit.fluxcd.io/helm-test: enabled 9 | helm.toolkit.fluxcd.io/remediation: enabled 10 | spec: 11 | interval: 10m 12 | chart: 13 | spec: 14 | chart: dex 15 | version: 0.23.0 16 | sourceRef: 17 | kind: HelmRepository 18 | name: dex 19 | # https://github.com/dexidp/helm-charts/blob/master/charts/dex/values.yaml 20 | values: 21 | replicaCount: ${dex_replicas:=2} 22 | ingress: 23 | enabled: true 24 | hosts: 25 | - host: dex.${domain} 26 | paths: 27 | - path: / 28 | pathType: ImplementationSpecific 29 | envVars: 30 | - name: CLIENT_ID 31 | value: ${github_app_client_id} 32 | - name: CLIENT_SECRET 33 | value: ${github_app_client_secret} 34 | config: 35 | issuer: https://dex.${domain} 36 | oauth2: 37 | skipApprovalScreen: true 38 | storage: 39 | type: kubernetes 40 | config: 41 | inCluster: true 42 | staticClients: 43 | - name: Public Client 44 | id: public-client 45 | secret: ${dex_client_secret} 46 | redirectURIs: ["https://oauth2-proxy.${domain}/oauth2/callback"] 47 | connectors: 48 | - type: github 49 | id: github 50 | name: GitHub 51 | config: 52 | clientID: $CLIENT_ID 53 | clientSecret: $CLIENT_SECRET 54 | redirectURI: https://dex.${domain}/callback 55 | teamNameField: slug 56 | useLoginAsID: false 57 | orgs: 58 | - name: devantler-tech 59 | teams: 60 | - platform 61 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/dex/helm-repository.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1 2 | kind: HelmRepository 3 | metadata: 4 | name: dex 5 | namespace: dex 6 | spec: 7 | url: https://charts.dexidp.io 8 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/dex/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - namespace.yaml 5 | - helm-release.yaml 6 | - helm-repository.yaml 7 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/dex/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: dex 5 | labels: 6 | goldilocks.fairwinds.com/vpa-update-mode: "auto" 7 | goldilocks.fairwinds.com/vpa-min-replicas: "2" 8 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/goldilocks/README.md: -------------------------------------------------------------------------------- 1 | # Goldilocks 2 | 3 | A utility that can help you identify a starting point for resource requests and limits. 4 | 5 | - [Documentation](https://goldilocks.docs.fairwinds.com) 6 | - [Helm Chart](https://github.com/FairwindsOps/charts/tree/master/stable/goldilocks) 7 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/goldilocks/helm-release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2 2 | kind: HelmRelease 3 | metadata: 4 | name: goldilocks 5 | namespace: goldilocks 6 | labels: 7 | helm.toolkit.fluxcd.io/crds: enabled 8 | helm.toolkit.fluxcd.io/helm-test: enabled 9 | helm.toolkit.fluxcd.io/remediation: enabled 10 | spec: 11 | interval: 10m 12 | chart: 13 | spec: 14 | chart: goldilocks 15 | version: 9.0.2 16 | sourceRef: 17 | kind: HelmRepository 18 | name: goldilocks 19 | # https://github.com/FairwindsOps/charts/blob/master/stable/goldilocks/values.yaml 20 | values: 21 | # https://github.com/FairwindsOps/charts/blob/master/stable/vpa/values.yaml 22 | controller: 23 | flags: 24 | on-by-default: true 25 | dashboard: 26 | flags: 27 | on-by-default: true 28 | ingress: 29 | enabled: true 30 | hosts: 31 | - host: goldilocks.${domain} 32 | paths: 33 | - path: / 34 | type: ImplementationSpecific 35 | annotations: 36 | traefik.ingress.kubernetes.io/router.middlewares: traefik-forward-auth@kubernetescrd 37 | gethomepage.dev/enabled: "true" 38 | gethomepage.dev/name: Goldilocks 39 | gethomepage.dev/description: Dashboard for automated vertical pod autoscaling recommendations. 40 | gethomepage.dev/group: Monitoring 41 | gethomepage.dev/icon: mdi-white-balance-sunny-#FFA500 42 | gethomepage.dev/app: goldilocks-dashboard 43 | gethomepage.dev/pod-selector: app.kubernetes.io/name=goldilocks 44 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/goldilocks/helm-repository.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1 2 | kind: HelmRepository 3 | metadata: 4 | name: goldilocks 5 | namespace: goldilocks 6 | spec: 7 | url: https://charts.fairwinds.com/stable 8 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/goldilocks/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - namespace.yaml 5 | - helm-release.yaml 6 | - helm-repository.yaml 7 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/goldilocks/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: goldilocks 5 | labels: 6 | goldilocks.fairwinds.com/vpa-update-mode: "auto" 7 | goldilocks.fairwinds.com/vpa-min-replicas: "2" 8 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - cert-manager/ 6 | - cilium/ 7 | - dex/ 8 | - goldilocks/ 9 | - kyverno/ 10 | - oauth2-proxy/ 11 | - reloader/ 12 | - traefik/ 13 | - vertical-pod-autoscaler/ 14 | # - trivy-operator/ 15 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/kyverno/README.md: -------------------------------------------------------------------------------- 1 | # Kyverno 2 | 3 | Kyverno is a policy engine designed for Kubernetes. It allows cluster administrators to enforce policies on resources in a Kubernetes cluster. Policies are created using Kubernetes resources and are automatically enforced by the Kyverno policy engine. 4 | 5 | - [Documentation](https://kyverno.io/docs/) 6 | - [Helm Chart](https://github.com/kyverno/kyverno/tree/main/charts/kyverno) 7 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/kyverno/helm-release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2 2 | kind: HelmRelease 3 | metadata: 4 | name: kyverno 5 | namespace: kyverno 6 | labels: 7 | helm.toolkit.fluxcd.io/crds: enabled 8 | helm.toolkit.fluxcd.io/helm-test: enabled 9 | helm.toolkit.fluxcd.io/remediation: enabled 10 | spec: 11 | interval: 10m 12 | chart: 13 | spec: 14 | chart: kyverno 15 | version: 3.4.2 16 | sourceRef: 17 | kind: HelmRepository 18 | name: kyverno 19 | # https://github.com/kyverno/kyverno/blob/main/charts/kyverno/values.yaml 20 | values: {} 21 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/kyverno/helm-repository.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1 2 | kind: HelmRepository 3 | metadata: 4 | name: kyverno 5 | namespace: kyverno 6 | spec: 7 | url: https://kyverno.github.io/kyverno/ 8 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/kyverno/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - namespace.yaml 5 | - helm-release.yaml 6 | - helm-repository.yaml 7 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/kyverno/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: kyverno 5 | labels: 6 | goldilocks.fairwinds.com/vpa-update-mode: "auto" 7 | goldilocks.fairwinds.com/vpa-min-replicas: "2" 8 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/oauth2-proxy/helm-release.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: helm.toolkit.fluxcd.io/v2 3 | kind: HelmRelease 4 | metadata: 5 | name: oauth2-proxy 6 | namespace: oauth2-proxy 7 | labels: 8 | helm.toolkit.fluxcd.io/helm-test: enabled 9 | helm.toolkit.fluxcd.io/remediation: enabled 10 | spec: 11 | interval: 10m 12 | chart: 13 | spec: 14 | chart: oauth2-proxy 15 | version: 7.12.17 16 | sourceRef: 17 | kind: HelmRepository 18 | name: oauth2-proxy 19 | # https://github.com/oauth2-proxy/manifests/blob/main/helm/oauth2-proxy/values.yaml 20 | values: 21 | deploymentAnnotations: 22 | configmap.reloader.stakater.com/reload: oauth2-proxy 23 | replicaCount: ${oauth2_proxy_replicas:=2} 24 | config: 25 | clientID: "${github_app_client_id}" 26 | clientSecret: "${github_app_client_secret}" 27 | cookieSecret: "${oauth2_proxy_cookie_secret}" 28 | configFile: |- 29 | provider = "github" 30 | github_users = ["devantler"] 31 | email_domains = [ "*" ] 32 | cookie_domains=[".${domain}"] 33 | upstreams = [ "static://202" ] 34 | skip_provider_button = true 35 | reverse_proxy = true 36 | ingress: 37 | enabled: true 38 | hosts: 39 | - oauth2-proxy.${domain} 40 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/oauth2-proxy/helm-repository.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: source.toolkit.fluxcd.io/v1 3 | kind: HelmRepository 4 | metadata: 5 | name: oauth2-proxy 6 | namespace: oauth2-proxy 7 | spec: 8 | url: https://oauth2-proxy.github.io/manifests 9 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/oauth2-proxy/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - helm-release.yaml 6 | - helm-repository.yaml 7 | - namespace.yaml 8 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/oauth2-proxy/namespace.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: oauth2-proxy 6 | labels: 7 | goldilocks.fairwinds.com/vpa-update-mode: "auto" 8 | goldilocks.fairwinds.com/vpa-min-replicas: "2" 9 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/reloader/README.md: -------------------------------------------------------------------------------- 1 | # Reloader 2 | 3 | A Kubernetes controller to watch changes in ConfigMap and Secrets and do rolling upgrades on Pods with their associated Deployment, StatefulSet, DaemonSet, and DeploymentConfig. 4 | 5 | - [Documentation](https://docs.stakater.com/reloader/) 6 | - [Helm Chart](https://github.com/stakater/Reloader/tree/master/deployments/kubernetes/chart/reloader) 7 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/reloader/helm-release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2 2 | kind: HelmRelease 3 | metadata: 4 | name: reloader 5 | namespace: reloader 6 | labels: 7 | helm.toolkit.fluxcd.io/helm-test: enabled 8 | helm.toolkit.fluxcd.io/remediation: enabled 9 | spec: 10 | interval: 10m 11 | chart: 12 | spec: 13 | chart: reloader 14 | version: 2.1.3 15 | sourceRef: 16 | kind: HelmRepository 17 | name: reloader 18 | # https://github.com/stakater/Reloader/blob/master/deployments/kubernetes/chart/reloader/values.yaml 19 | values: 20 | reloader: 21 | reloadStrategy: annotations 22 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/reloader/helm-repository.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1 2 | kind: HelmRepository 3 | metadata: 4 | name: reloader 5 | namespace: reloader 6 | spec: 7 | url: https://stakater.github.io/stakater-charts 8 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/reloader/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - namespace.yaml 5 | - helm-release.yaml 6 | - helm-repository.yaml 7 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/reloader/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: reloader 5 | labels: 6 | goldilocks.fairwinds.com/vpa-update-mode: "auto" 7 | goldilocks.fairwinds.com/vpa-min-replicas: "2" 8 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/testkube/README.md: -------------------------------------------------------------------------------- 1 | # Testkube 2 | 3 | A Kubernetes-native testing framework for testing Kubernetes applications. 4 | 5 | - [Documentation](https://docs.testkube.io) 6 | - [Helm Chart](https://github.com/kubeshop/helm-charts/tree/develop/charts/testkube) 7 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/testkube/crds/executor.testkube.io_executors.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | meta.helm.sh/release-name: testkube 7 | meta.helm.sh/release-namespace: testkube 8 | labels: 9 | app.kubernetes.io/managed-by: Helm 10 | name: executors.executor.testkube.io 11 | spec: 12 | group: executor.testkube.io 13 | names: 14 | kind: Executor 15 | listKind: ExecutorList 16 | plural: executors 17 | singular: executor 18 | scope: Namespaced 19 | versions: 20 | - name: v1 21 | schema: 22 | openAPIV3Schema: 23 | description: Executor is the Schema for the executors API 24 | properties: 25 | apiVersion: 26 | description: |- 27 | APIVersion defines the versioned schema of this representation of an object. 28 | Servers should convert recognized schemas to the latest internal value, and 29 | may reject unrecognized values. 30 | More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources 31 | type: string 32 | kind: 33 | description: |- 34 | Kind is a string value representing the REST resource this object represents. 35 | Servers may infer this from the endpoint the client submits requests to. 36 | Cannot be updated. 37 | In CamelCase. 38 | More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds 39 | type: string 40 | metadata: 41 | type: object 42 | spec: 43 | description: ExecutorSpec defines the desired state of Executor 44 | properties: 45 | args: 46 | description: executor binary arguments 47 | items: 48 | type: string 49 | type: array 50 | command: 51 | description: executor default binary command 52 | items: 53 | type: string 54 | type: array 55 | content_types: 56 | description: ContentTypes list of handled content types 57 | items: 58 | enum: 59 | - string 60 | - file-uri 61 | - git-file 62 | - git-dir 63 | - git 64 | type: string 65 | type: array 66 | executor_type: 67 | description: |- 68 | ExecutorType one of "rest" for rest openapi based executors or "job" which will be default runners for testkube 69 | or "container" for container executors 70 | enum: 71 | - job 72 | - container 73 | type: string 74 | features: 75 | description: Features list of possible features which executor handles 76 | items: 77 | enum: 78 | - artifacts 79 | - junit-report 80 | type: string 81 | type: array 82 | image: 83 | description: Image for kube-job 84 | type: string 85 | imagePullSecrets: 86 | description: container executor default image pull secrets 87 | items: 88 | description: |- 89 | LocalObjectReference contains enough information to let you locate the 90 | referenced object inside the same namespace. 91 | properties: 92 | name: 93 | description: |- 94 | Name of the referent. 95 | More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 96 | TODO: Add other useful fields. apiVersion, kind, uid? 97 | type: string 98 | type: object 99 | x-kubernetes-map-type: atomic 100 | type: array 101 | job_template: 102 | description: Job template to launch executor 103 | type: string 104 | jobTemplateReference: 105 | description: name of the template resource 106 | type: string 107 | meta: 108 | description: Meta data about executor 109 | properties: 110 | docsURI: 111 | description: URI for executor docs 112 | type: string 113 | iconURI: 114 | description: URI for executor icon 115 | type: string 116 | tooltips: 117 | additionalProperties: 118 | type: string 119 | description: executor tooltips 120 | type: object 121 | type: object 122 | slaves: 123 | description: Slaves data to run test in distributed environment 124 | properties: 125 | image: 126 | type: string 127 | required: 128 | - image 129 | type: object 130 | types: 131 | description: Types defines what types can be handled by executor e.g. 132 | "postman/collection", ":curl/command" etc 133 | items: 134 | type: string 135 | type: array 136 | uri: 137 | description: URI for rest based executors 138 | type: string 139 | useDataDirAsWorkingDir: 140 | description: use data dir as working dir for executor 141 | type: boolean 142 | type: object 143 | status: 144 | description: ExecutorStatus defines the observed state of Executor 145 | type: object 146 | type: object 147 | served: true 148 | storage: true 149 | subresources: 150 | status: {} 151 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/testkube/crds/executor.testkube.io_webhooks.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | meta.helm.sh/release-name: testkube 7 | meta.helm.sh/release-namespace: testkube 8 | labels: 9 | app.kubernetes.io/managed-by: Helm 10 | name: webhooks.executor.testkube.io 11 | spec: 12 | group: executor.testkube.io 13 | names: 14 | kind: Webhook 15 | listKind: WebhookList 16 | plural: webhooks 17 | singular: webhook 18 | scope: Namespaced 19 | versions: 20 | - name: v1 21 | schema: 22 | openAPIV3Schema: 23 | description: Webhook is the Schema for the webhooks API 24 | properties: 25 | apiVersion: 26 | description: |- 27 | APIVersion defines the versioned schema of this representation of an object. 28 | Servers should convert recognized schemas to the latest internal value, and 29 | may reject unrecognized values. 30 | More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources 31 | type: string 32 | kind: 33 | description: |- 34 | Kind is a string value representing the REST resource this object represents. 35 | Servers may infer this from the endpoint the client submits requests to. 36 | Cannot be updated. 37 | In CamelCase. 38 | More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds 39 | type: string 40 | metadata: 41 | type: object 42 | spec: 43 | description: WebhookSpec defines the desired state of Webhook 44 | properties: 45 | disabled: 46 | description: Disabled will disable the webhook 47 | type: boolean 48 | events: 49 | description: Events declare list if events on which webhook should 50 | be called 51 | items: 52 | enum: 53 | - start-test 54 | - end-test-success 55 | - end-test-failed 56 | - end-test-aborted 57 | - end-test-timeout 58 | - start-testsuite 59 | - end-testsuite-success 60 | - end-testsuite-failed 61 | - end-testsuite-aborted 62 | - end-testsuite-timeout 63 | - start-testworkflow 64 | - queue-testworkflow 65 | - end-testworkflow-success 66 | - end-testworkflow-failed 67 | - end-testworkflow-aborted 68 | type: string 69 | type: array 70 | headers: 71 | additionalProperties: 72 | type: string 73 | description: webhook headers (golang template supported) 74 | type: object 75 | onStateChange: 76 | description: OnStateChange will trigger the webhook only when the 77 | result of the current execution differs from the previous result 78 | of the same test/test suite/workflow 79 | type: boolean 80 | payloadObjectField: 81 | description: will load the generated payload for notification inside 82 | the object 83 | type: string 84 | payloadTemplate: 85 | description: golang based template for notification payload 86 | type: string 87 | payloadTemplateReference: 88 | description: name of the template resource 89 | type: string 90 | selector: 91 | description: Labels to filter for tests and test suites 92 | type: string 93 | uri: 94 | description: Uri is address where webhook should be made (golang template 95 | supported) 96 | type: string 97 | type: object 98 | status: 99 | description: WebhookStatus defines the observed state of Webhook 100 | type: object 101 | type: object 102 | served: true 103 | storage: true 104 | subresources: 105 | status: {} 106 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/testkube/crds/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - executor.testkube.io_executors.yaml 5 | - executor.testkube.io_webhooks.yaml 6 | - tests.testkube.io_scripts.yaml 7 | - tests.testkube.io_templates.yaml 8 | - tests.testkube.io_testexecutions.yaml 9 | - tests.testkube.io_tests.yaml 10 | - tests.testkube.io_testsources.yaml 11 | - tests.testkube.io_testsuiteexecutions.yaml 12 | - tests.testkube.io_testsuites.yaml 13 | - tests.testkube.io_testtriggers.yaml 14 | - testworkflows.testkube.io_testworkflowexecutions.yaml 15 | - testworkflows.testkube.io_testworkflows.yaml 16 | - testworkflows.testkube.io_testworkflowtemplates.yaml 17 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/testkube/crds/tests.testkube.io_scripts.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | meta.helm.sh/release-name: testkube 7 | meta.helm.sh/release-namespace: testkube 8 | labels: 9 | app.kubernetes.io/managed-by: Helm 10 | name: scripts.tests.testkube.io 11 | spec: 12 | group: tests.testkube.io 13 | names: 14 | kind: Script 15 | listKind: ScriptList 16 | plural: scripts 17 | singular: script 18 | scope: Namespaced 19 | versions: 20 | - name: v1 21 | schema: 22 | openAPIV3Schema: 23 | description: Script is the Schema for the scripts API 24 | properties: 25 | apiVersion: 26 | description: |- 27 | APIVersion defines the versioned schema of this representation of an object. 28 | Servers should convert recognized schemas to the latest internal value, and 29 | may reject unrecognized values. 30 | More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources 31 | type: string 32 | kind: 33 | description: |- 34 | Kind is a string value representing the REST resource this object represents. 35 | Servers may infer this from the endpoint the client submits requests to. 36 | Cannot be updated. 37 | In CamelCase. 38 | More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds 39 | type: string 40 | metadata: 41 | type: object 42 | spec: 43 | description: ScriptSpec defines the desired state of Script 44 | properties: 45 | content: 46 | description: script content as string (content depends from executor) 47 | type: string 48 | input-type: 49 | description: 'script content type can be: - direct content - created 50 | from file, - git repo directory checkout in case when test is some 51 | kind of project or have more than one file,' 52 | type: string 53 | name: 54 | description: script execution custom name 55 | type: string 56 | params: 57 | additionalProperties: 58 | type: string 59 | description: execution params passed to executor 60 | type: object 61 | repository: 62 | description: repository details if exists 63 | properties: 64 | branch: 65 | description: branch/tag name for checkout 66 | type: string 67 | path: 68 | description: if needed we can checkout particular path (dir or 69 | file) in case of BIG/mono repositories 70 | type: string 71 | token: 72 | description: git auth token for private repositories 73 | type: string 74 | type: 75 | description: Type_ repository type 76 | type: string 77 | uri: 78 | description: Uri of content file or git directory 79 | type: string 80 | username: 81 | description: git auth username for private repositories 82 | type: string 83 | required: 84 | - branch 85 | - type 86 | - uri 87 | type: object 88 | tags: 89 | items: 90 | type: string 91 | type: array 92 | type: 93 | description: script type 94 | type: string 95 | type: object 96 | status: 97 | description: ScriptStatus defines the observed state of Script 98 | properties: 99 | executions_count: 100 | type: integer 101 | last_execution: 102 | format: date-time 103 | type: string 104 | type: object 105 | type: object 106 | served: true 107 | storage: false 108 | subresources: 109 | status: {} 110 | - name: v2 111 | schema: 112 | openAPIV3Schema: 113 | description: Script is the Schema for the scripts API 114 | properties: 115 | apiVersion: 116 | description: |- 117 | APIVersion defines the versioned schema of this representation of an object. 118 | Servers should convert recognized schemas to the latest internal value, and 119 | may reject unrecognized values. 120 | More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources 121 | type: string 122 | kind: 123 | description: |- 124 | Kind is a string value representing the REST resource this object represents. 125 | Servers may infer this from the endpoint the client submits requests to. 126 | Cannot be updated. 127 | In CamelCase. 128 | More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds 129 | type: string 130 | metadata: 131 | type: object 132 | spec: 133 | description: ScriptSpec defines the desired state of Script 134 | properties: 135 | content: 136 | description: script content object 137 | properties: 138 | data: 139 | description: script content body 140 | type: string 141 | repository: 142 | description: repository of script content 143 | properties: 144 | branch: 145 | description: branch/tag name for checkout 146 | type: string 147 | path: 148 | description: if needed we can checkout particular path (dir 149 | or file) in case of BIG/mono repositories 150 | type: string 151 | token: 152 | description: git auth token for private repositories 153 | type: string 154 | type: 155 | description: VCS repository type 156 | type: string 157 | uri: 158 | description: uri of content file or git directory 159 | type: string 160 | username: 161 | description: git auth username for private repositories 162 | type: string 163 | required: 164 | - branch 165 | - type 166 | - uri 167 | type: object 168 | type: 169 | description: script type 170 | type: string 171 | uri: 172 | description: uri of script content 173 | type: string 174 | type: object 175 | name: 176 | description: script execution custom name 177 | type: string 178 | params: 179 | additionalProperties: 180 | type: string 181 | description: execution params passed to executor 182 | type: object 183 | tags: 184 | description: script tags 185 | items: 186 | type: string 187 | type: array 188 | type: 189 | description: script type 190 | type: string 191 | type: object 192 | status: 193 | description: ScriptStatus defines the observed state of Script 194 | properties: 195 | executions_count: 196 | type: integer 197 | last_execution: 198 | format: date-time 199 | type: string 200 | type: object 201 | type: object 202 | served: true 203 | storage: true 204 | subresources: 205 | status: {} 206 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/testkube/crds/tests.testkube.io_templates.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | meta.helm.sh/release-name: testkube 7 | meta.helm.sh/release-namespace: testkube 8 | labels: 9 | app.kubernetes.io/managed-by: Helm 10 | name: templates.tests.testkube.io 11 | spec: 12 | group: tests.testkube.io 13 | names: 14 | kind: Template 15 | listKind: TemplateList 16 | plural: templates 17 | singular: template 18 | scope: Namespaced 19 | versions: 20 | - name: v1 21 | schema: 22 | openAPIV3Schema: 23 | description: Template is the Schema for the Templates API 24 | properties: 25 | apiVersion: 26 | description: |- 27 | APIVersion defines the versioned schema of this representation of an object. 28 | Servers should convert recognized schemas to the latest internal value, and 29 | may reject unrecognized values. 30 | More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources 31 | type: string 32 | kind: 33 | description: |- 34 | Kind is a string value representing the REST resource this object represents. 35 | Servers may infer this from the endpoint the client submits requests to. 36 | Cannot be updated. 37 | In CamelCase. 38 | More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds 39 | type: string 40 | metadata: 41 | type: object 42 | spec: 43 | description: TemplateSpec defines the desired state of Template 44 | properties: 45 | body: 46 | description: template body to use 47 | type: string 48 | type: 49 | description: TemplateType defines template type by purpose 50 | enum: 51 | - job 52 | - container 53 | - cronjob 54 | - scraper 55 | - pvc 56 | - webhook 57 | - pod 58 | type: string 59 | required: 60 | - body 61 | - type 62 | type: object 63 | status: 64 | description: TemplateStatus defines the observed state of Template 65 | type: object 66 | type: object 67 | served: true 68 | storage: true 69 | subresources: 70 | status: {} 71 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/testkube/crds/tests.testkube.io_testsources.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | meta.helm.sh/release-name: testkube 7 | meta.helm.sh/release-namespace: testkube 8 | labels: 9 | app.kubernetes.io/managed-by: Helm 10 | name: testsources.tests.testkube.io 11 | spec: 12 | group: tests.testkube.io 13 | names: 14 | kind: TestSource 15 | listKind: TestSourceList 16 | plural: testsources 17 | singular: testsource 18 | scope: Namespaced 19 | versions: 20 | - name: v1 21 | schema: 22 | openAPIV3Schema: 23 | description: TestSource is the Schema for the testsources API 24 | properties: 25 | apiVersion: 26 | description: |- 27 | APIVersion defines the versioned schema of this representation of an object. 28 | Servers should convert recognized schemas to the latest internal value, and 29 | may reject unrecognized values. 30 | More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources 31 | type: string 32 | kind: 33 | description: |- 34 | Kind is a string value representing the REST resource this object represents. 35 | Servers may infer this from the endpoint the client submits requests to. 36 | Cannot be updated. 37 | In CamelCase. 38 | More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds 39 | type: string 40 | metadata: 41 | type: object 42 | spec: 43 | description: TestSourceSpec defines the desired state of TestSource 44 | properties: 45 | data: 46 | description: test content body 47 | type: string 48 | repository: 49 | description: repository of test content 50 | properties: 51 | authType: 52 | description: auth type for git requests 53 | enum: 54 | - basic 55 | - header 56 | type: string 57 | branch: 58 | description: branch/tag name for checkout 59 | type: string 60 | certificateSecret: 61 | description: git auth certificate secret for private repositories 62 | type: string 63 | commit: 64 | description: commit id (sha) for checkout 65 | type: string 66 | path: 67 | description: If specified, does a sparse checkout of the repository 68 | at the given path 69 | type: string 70 | tokenSecret: 71 | description: SecretRef is the Testkube internal reference for 72 | secret storage in Kubernetes secrets 73 | properties: 74 | key: 75 | description: object key 76 | type: string 77 | name: 78 | description: object name 79 | type: string 80 | required: 81 | - key 82 | - name 83 | type: object 84 | type: 85 | description: VCS repository type 86 | type: string 87 | uri: 88 | description: uri of content file or git directory 89 | type: string 90 | usernameSecret: 91 | description: SecretRef is the Testkube internal reference for 92 | secret storage in Kubernetes secrets 93 | properties: 94 | key: 95 | description: object key 96 | type: string 97 | name: 98 | description: object name 99 | type: string 100 | required: 101 | - key 102 | - name 103 | type: object 104 | workingDir: 105 | description: if provided we checkout the whole repository and 106 | run test from this directory 107 | type: string 108 | required: 109 | - type 110 | - uri 111 | type: object 112 | type: 113 | enum: 114 | - string 115 | - file-uri 116 | - git-file 117 | - git-dir 118 | - git 119 | type: string 120 | uri: 121 | description: uri of test content 122 | type: string 123 | type: object 124 | status: 125 | description: TestSourceStatus defines the observed state of TestSource 126 | type: object 127 | type: object 128 | served: true 129 | storage: true 130 | subresources: 131 | status: {} 132 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/testkube/crds/tests.testkube.io_testtriggers.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | meta.helm.sh/release-name: testkube 7 | meta.helm.sh/release-namespace: testkube 8 | labels: 9 | app.kubernetes.io/managed-by: Helm 10 | name: testtriggers.tests.testkube.io 11 | spec: 12 | group: tests.testkube.io 13 | names: 14 | kind: TestTrigger 15 | listKind: TestTriggerList 16 | plural: testtriggers 17 | singular: testtrigger 18 | scope: Namespaced 19 | versions: 20 | - additionalPrinterColumns: 21 | - jsonPath: .spec.resource 22 | name: Resource 23 | type: string 24 | - jsonPath: .spec.event 25 | name: Event 26 | type: string 27 | - jsonPath: .spec.execution 28 | name: Execution 29 | type: string 30 | - jsonPath: .metadata.creationTimestamp 31 | name: Age 32 | type: date 33 | name: v1 34 | schema: 35 | openAPIV3Schema: 36 | description: TestTrigger is the Schema for the testtriggers API 37 | properties: 38 | apiVersion: 39 | description: |- 40 | APIVersion defines the versioned schema of this representation of an object. 41 | Servers should convert recognized schemas to the latest internal value, and 42 | may reject unrecognized values. 43 | More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources 44 | type: string 45 | kind: 46 | description: |- 47 | Kind is a string value representing the REST resource this object represents. 48 | Servers may infer this from the endpoint the client submits requests to. 49 | Cannot be updated. 50 | In CamelCase. 51 | More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds 52 | type: string 53 | metadata: 54 | type: object 55 | spec: 56 | description: TestTriggerSpec defines the desired state of TestTrigger 57 | properties: 58 | action: 59 | description: Action represents what needs to be executed for selected 60 | Execution 61 | enum: 62 | - run 63 | type: string 64 | concurrencyPolicy: 65 | description: ConcurrencyPolicy defines concurrency policy for selected 66 | Execution 67 | enum: 68 | - allow 69 | - forbid 70 | - replace 71 | type: string 72 | conditionSpec: 73 | description: What resource conditions should be matched 74 | properties: 75 | conditions: 76 | description: list of test trigger conditions 77 | items: 78 | description: TestTriggerCondition is used for definition of 79 | the condition for test triggers 80 | properties: 81 | reason: 82 | description: test trigger condition reason 83 | type: string 84 | status: 85 | description: TestTriggerConditionStatuses defines condition 86 | statuses for test triggers 87 | enum: 88 | - "True" 89 | - "False" 90 | - Unknown 91 | type: string 92 | ttl: 93 | description: duration in seconds in the past from current 94 | time when the condition is still valid 95 | format: int32 96 | type: integer 97 | type: 98 | description: test trigger condition 99 | type: string 100 | required: 101 | - status 102 | - type 103 | type: object 104 | type: array 105 | delay: 106 | description: duration in seconds the test trigger waits between 107 | condition check 108 | format: int32 109 | type: integer 110 | timeout: 111 | description: duration in seconds the test trigger waits for conditions, 112 | until its stopped 113 | format: int32 114 | type: integer 115 | type: object 116 | delay: 117 | description: Delay is a duration string which specifies how long should 118 | the test be delayed after a trigger is matched 119 | format: duration 120 | type: string 121 | disabled: 122 | description: whether test trigger is disabled 123 | type: boolean 124 | event: 125 | description: On which Event for a Resource should an Action be triggered 126 | enum: 127 | - created 128 | - modified 129 | - deleted 130 | - deployment-scale-update 131 | - deployment-image-update 132 | - deployment-env-update 133 | - deployment-containers-modified 134 | - event-start-test 135 | - event-end-test-success 136 | - event-end-test-failed 137 | - event-end-test-aborted 138 | - event-end-test-timeout 139 | - event-start-testsuite 140 | - event-end-testsuite-success 141 | - event-end-testsuite-failed 142 | - event-end-testsuite-aborted 143 | - event-end-testsuite-timeout 144 | - event-queue-testworkflow 145 | - event-start-testworkflow 146 | - event-end-testworkflow-success 147 | - event-end-testworkflow-failed 148 | - event-end-testworkflow-aborted 149 | - event-created 150 | - event-updated 151 | - event-deleted 152 | type: string 153 | execution: 154 | description: Execution identifies for which test execution should 155 | an Action be executed 156 | enum: 157 | - test 158 | - testsuite 159 | - testworkflow 160 | type: string 161 | probeSpec: 162 | description: What resource probes should be matched 163 | properties: 164 | delay: 165 | description: duration in seconds the test trigger waits between 166 | probes 167 | format: int32 168 | type: integer 169 | probes: 170 | description: list of test trigger probes 171 | items: 172 | description: TestTriggerProbe is used for definition of the 173 | probe for test triggers 174 | properties: 175 | headers: 176 | additionalProperties: 177 | type: string 178 | description: test trigger condition probe headers to submit 179 | type: object 180 | host: 181 | description: test trigger condition probe host, default 182 | is pod ip or service name 183 | type: string 184 | path: 185 | description: test trigger condition probe path to check, 186 | default is / 187 | type: string 188 | port: 189 | description: test trigger condition probe port to connect 190 | format: int32 191 | type: integer 192 | scheme: 193 | description: test trigger condition probe scheme to connect 194 | to host, default is http 195 | type: string 196 | type: object 197 | type: array 198 | timeout: 199 | description: duration in seconds the test trigger waits for probes, 200 | until its stopped 201 | format: int32 202 | type: integer 203 | type: object 204 | resource: 205 | description: For which Resource do we monitor Event which triggers 206 | an Action on certain conditions 207 | enum: 208 | - pod 209 | - deployment 210 | - statefulset 211 | - daemonset 212 | - service 213 | - ingress 214 | - event 215 | - configmap 216 | type: string 217 | resourceSelector: 218 | description: ResourceSelector identifies which Kubernetes Objects 219 | should be watched 220 | properties: 221 | labelSelector: 222 | description: LabelSelector is used to identify a group of Kubernetes 223 | Objects based on their metadata labels 224 | properties: 225 | matchExpressions: 226 | description: matchExpressions is a list of label selector 227 | requirements. The requirements are ANDed. 228 | items: 229 | description: |- 230 | A label selector requirement is a selector that contains values, a key, and an operator that 231 | relates the key and values. 232 | properties: 233 | key: 234 | description: key is the label key that the selector 235 | applies to. 236 | type: string 237 | operator: 238 | description: |- 239 | operator represents a key's relationship to a set of values. 240 | Valid operators are In, NotIn, Exists and DoesNotExist. 241 | type: string 242 | values: 243 | description: |- 244 | values is an array of string values. If the operator is In or NotIn, 245 | the values array must be non-empty. If the operator is Exists or DoesNotExist, 246 | the values array must be empty. This array is replaced during a strategic 247 | merge patch. 248 | items: 249 | type: string 250 | type: array 251 | required: 252 | - key 253 | - operator 254 | type: object 255 | type: array 256 | matchLabels: 257 | additionalProperties: 258 | type: string 259 | description: |- 260 | matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels 261 | map is equivalent to an element of matchExpressions, whose key field is "key", the 262 | operator is "In", and the values array contains only "value". The requirements are ANDed. 263 | type: object 264 | type: object 265 | x-kubernetes-map-type: atomic 266 | name: 267 | description: Name selector is used to identify a Kubernetes Object 268 | based on the metadata name 269 | type: string 270 | nameRegex: 271 | description: kubernetes resource name regex 272 | type: string 273 | namespace: 274 | description: Namespace of the Kubernetes object 275 | type: string 276 | type: object 277 | testSelector: 278 | description: TestSelector identifies on which Testkube Kubernetes 279 | Objects an Action should be taken 280 | properties: 281 | labelSelector: 282 | description: LabelSelector is used to identify a group of Kubernetes 283 | Objects based on their metadata labels 284 | properties: 285 | matchExpressions: 286 | description: matchExpressions is a list of label selector 287 | requirements. The requirements are ANDed. 288 | items: 289 | description: |- 290 | A label selector requirement is a selector that contains values, a key, and an operator that 291 | relates the key and values. 292 | properties: 293 | key: 294 | description: key is the label key that the selector 295 | applies to. 296 | type: string 297 | operator: 298 | description: |- 299 | operator represents a key's relationship to a set of values. 300 | Valid operators are In, NotIn, Exists and DoesNotExist. 301 | type: string 302 | values: 303 | description: |- 304 | values is an array of string values. If the operator is In or NotIn, 305 | the values array must be non-empty. If the operator is Exists or DoesNotExist, 306 | the values array must be empty. This array is replaced during a strategic 307 | merge patch. 308 | items: 309 | type: string 310 | type: array 311 | required: 312 | - key 313 | - operator 314 | type: object 315 | type: array 316 | matchLabels: 317 | additionalProperties: 318 | type: string 319 | description: |- 320 | matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels 321 | map is equivalent to an element of matchExpressions, whose key field is "key", the 322 | operator is "In", and the values array contains only "value". The requirements are ANDed. 323 | type: object 324 | type: object 325 | x-kubernetes-map-type: atomic 326 | name: 327 | description: Name selector is used to identify a Kubernetes Object 328 | based on the metadata name 329 | type: string 330 | nameRegex: 331 | description: kubernetes resource name regex 332 | type: string 333 | namespace: 334 | description: Namespace of the Kubernetes object 335 | type: string 336 | type: object 337 | required: 338 | - action 339 | - event 340 | - execution 341 | - resource 342 | - resourceSelector 343 | - testSelector 344 | type: object 345 | status: 346 | description: TestTriggerStatus defines the observed state of TestTrigger 347 | type: object 348 | type: object 349 | served: true 350 | storage: true 351 | subresources: 352 | status: {} 353 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/testkube/crds/testworkflows.testkube.io_testworkflowexecutions.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | meta.helm.sh/release-name: testkube 7 | meta.helm.sh/release-namespace: testkube 8 | labels: 9 | app.kubernetes.io/managed-by: Helm 10 | name: testworkflowexecutions.testworkflows.testkube.io 11 | spec: 12 | group: testworkflows.testkube.io 13 | names: 14 | kind: TestWorkflowExecution 15 | listKind: TestWorkflowExecutionList 16 | plural: testworkflowexecutions 17 | singular: testworkflowexecution 18 | scope: Namespaced 19 | versions: 20 | - name: v1 21 | schema: 22 | openAPIV3Schema: 23 | description: TestWorkflowExecution is the Schema for the workflows API 24 | properties: 25 | apiVersion: 26 | description: |- 27 | APIVersion defines the versioned schema of this representation of an object. 28 | Servers should convert recognized schemas to the latest internal value, and 29 | may reject unrecognized values. 30 | More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources 31 | type: string 32 | kind: 33 | description: |- 34 | Kind is a string value representing the REST resource this object represents. 35 | Servers may infer this from the endpoint the client submits requests to. 36 | Cannot be updated. 37 | In CamelCase. 38 | More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds 39 | type: string 40 | metadata: 41 | type: object 42 | spec: 43 | description: TestWorkflowExecution specification 44 | properties: 45 | executionRequest: 46 | description: TestWorkflowExecutionRequest contains TestWorkflow execution parameters 47 | properties: 48 | config: 49 | additionalProperties: 50 | anyOf: 51 | - type: integer 52 | - type: string 53 | x-kubernetes-int-or-string: true 54 | type: object 55 | name: 56 | description: custom execution name 57 | type: string 58 | testWorkflowExecutionName: 59 | description: test workflow execution name started the test workflow execution 60 | type: string 61 | type: object 62 | testWorkflow: 63 | description: |- 64 | LocalObjectReference contains enough information to let you locate the 65 | referenced object inside the same namespace. 66 | properties: 67 | name: 68 | description: |- 69 | Name of the referent. 70 | More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 71 | TODO: Add other useful fields. apiVersion, kind, uid? 72 | type: string 73 | type: object 74 | x-kubernetes-map-type: atomic 75 | required: 76 | - testWorkflow 77 | type: object 78 | status: 79 | description: TestWorkflowExecutionStatus specification 80 | properties: 81 | generation: 82 | description: test workflow execution generation 83 | format: int64 84 | type: integer 85 | latestExecution: 86 | description: |- 87 | INSERT ADDITIONAL STATUS FIELD - define observed state of cluster 88 | Important: Run "make" to regenerate code after modifying this file 89 | properties: 90 | id: 91 | description: unique execution identifier 92 | type: string 93 | name: 94 | description: execution name 95 | type: string 96 | namespace: 97 | description: execution namespace 98 | type: string 99 | number: 100 | description: sequence number for the execution 101 | format: int32 102 | type: integer 103 | output: 104 | description: additional information from the steps, like referenced executed tests or artifacts 105 | items: 106 | description: TestWorkflowOutput defines output of TestWorkflow 107 | properties: 108 | name: 109 | description: output kind name 110 | type: string 111 | ref: 112 | description: step reference 113 | type: string 114 | value: 115 | description: value returned 116 | type: object 117 | x-kubernetes-preserve-unknown-fields: true 118 | type: object 119 | type: array 120 | reports: 121 | description: generated reports from the steps, like junit 122 | items: 123 | description: TestWorkflowStepReport contains report of TestWorkflow 124 | properties: 125 | file: 126 | description: file path to full report in artifact storage 127 | type: string 128 | kind: 129 | description: report kind/type 130 | type: string 131 | ref: 132 | description: step reference 133 | type: string 134 | summary: 135 | description: TestWorkflowStepReportSummary contains report summary of TestWorkflow 136 | properties: 137 | duration: 138 | description: total duration of all test cases in milliseconds 139 | format: int64 140 | type: integer 141 | errored: 142 | description: number of error test cases 143 | format: int32 144 | type: integer 145 | failed: 146 | description: number of failed test cases 147 | format: int32 148 | type: integer 149 | passed: 150 | description: number of passed test cases 151 | format: int32 152 | type: integer 153 | skipped: 154 | description: number of skipped test cases 155 | format: int32 156 | type: integer 157 | tests: 158 | description: total number of test cases 159 | format: int32 160 | type: integer 161 | type: object 162 | type: object 163 | type: array 164 | resolvedWorkflow: 165 | x-kubernetes-preserve-unknown-fields: true 166 | result: 167 | description: TestWorkflowResult contains result of TestWorkflow 168 | properties: 169 | duration: 170 | description: Go-formatted (human-readable) duration 171 | type: string 172 | durationMs: 173 | description: Duration in milliseconds 174 | format: int32 175 | type: integer 176 | finishedAt: 177 | description: when the pod has been completed 178 | format: date-time 179 | type: string 180 | initialization: 181 | description: TestWorkflowStepResult contains step result of TestWorkflow 182 | properties: 183 | errorMessage: 184 | type: string 185 | exitCode: 186 | format: int64 187 | type: integer 188 | finishedAt: 189 | description: when the container was finished 190 | format: date-time 191 | type: string 192 | queuedAt: 193 | description: when the container was created 194 | format: date-time 195 | type: string 196 | startedAt: 197 | description: when the container was started 198 | format: date-time 199 | type: string 200 | status: 201 | description: TestWorkfloStepwStatus has step status of TestWorkflow 202 | type: string 203 | type: object 204 | pausedMs: 205 | description: Pause duration in milliseconds 206 | format: int32 207 | type: integer 208 | pauses: 209 | items: 210 | description: TestWorkflowPause defines pause of TestWorkflow 211 | properties: 212 | pausedAt: 213 | description: when the pause has started 214 | format: date-time 215 | type: string 216 | ref: 217 | description: step at which it was paused 218 | type: string 219 | resumedAt: 220 | description: when the pause has ended 221 | format: date-time 222 | type: string 223 | required: 224 | - pausedAt 225 | - ref 226 | type: object 227 | type: array 228 | predictedStatus: 229 | description: TestWorkflowStatus has status of TestWorkflow 230 | enum: 231 | - queued 232 | - running 233 | - paused 234 | - passed 235 | - failed 236 | - aborted 237 | type: string 238 | queuedAt: 239 | description: when the pod was created 240 | format: date-time 241 | type: string 242 | startedAt: 243 | description: when the pod has been successfully assigned 244 | format: date-time 245 | type: string 246 | status: 247 | description: TestWorkflowStatus has status of TestWorkflow 248 | enum: 249 | - queued 250 | - running 251 | - paused 252 | - passed 253 | - failed 254 | - aborted 255 | type: string 256 | steps: 257 | additionalProperties: 258 | description: TestWorkflowStepResult contains step result of TestWorkflow 259 | properties: 260 | errorMessage: 261 | type: string 262 | exitCode: 263 | format: int64 264 | type: integer 265 | finishedAt: 266 | description: when the container was finished 267 | format: date-time 268 | type: string 269 | queuedAt: 270 | description: when the container was created 271 | format: date-time 272 | type: string 273 | startedAt: 274 | description: when the container was started 275 | format: date-time 276 | type: string 277 | status: 278 | description: TestWorkfloStepwStatus has step status of TestWorkflow 279 | type: string 280 | type: object 281 | type: object 282 | totalDuration: 283 | description: Go-formatted (human-readable) total duration (incl. pause) 284 | type: string 285 | totalDurationMs: 286 | description: Total duration in milliseconds (incl. pause) 287 | format: int32 288 | type: integer 289 | required: 290 | - predictedStatus 291 | - status 292 | type: object 293 | scheduledAt: 294 | description: when the execution has been scheduled to run 295 | format: date-time 296 | type: string 297 | signature: 298 | description: structured tree of steps 299 | items: 300 | description: TestWorkflowSignature has signature of TestWorkflow 301 | properties: 302 | category: 303 | description: step category, that may be used as name fallback 304 | type: string 305 | children: 306 | x-kubernetes-preserve-unknown-fields: true 307 | name: 308 | description: step name 309 | type: string 310 | negative: 311 | description: is the step/group meant to be negative 312 | type: boolean 313 | optional: 314 | description: is the step/group meant to be optional 315 | type: boolean 316 | ref: 317 | description: step reference 318 | type: string 319 | type: object 320 | type: array 321 | statusAt: 322 | description: when the execution result's status has changed last time (queued, passed, failed) 323 | format: date-time 324 | type: string 325 | testWorkflowExecutionName: 326 | description: test workflow execution name started the test workflow execution 327 | type: string 328 | workflow: 329 | x-kubernetes-preserve-unknown-fields: true 330 | required: 331 | - id 332 | - name 333 | - workflow 334 | type: object 335 | type: object 336 | required: 337 | - spec 338 | type: object 339 | served: true 340 | storage: true 341 | subresources: 342 | status: {} 343 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/testkube/helm-release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2 2 | kind: HelmRelease 3 | metadata: 4 | name: testkube 5 | namespace: testkube 6 | labels: 7 | helm.toolkit.fluxcd.io/crds: enabled 8 | helm.toolkit.fluxcd.io/helm-test: enabled 9 | helm.toolkit.fluxcd.io/remediation: enabled 10 | spec: 11 | interval: 10m 12 | chart: 13 | spec: 14 | chart: testkube 15 | version: 2.1.247 16 | sourceRef: 17 | kind: HelmRepository 18 | name: testkube 19 | # https://github.com/kubeshop/helm-charts/blob/develop/charts/testkube/values.yaml 20 | values: {} 21 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/testkube/helm-repository.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1 2 | kind: HelmRepository 3 | metadata: 4 | name: testkube 5 | namespace: testkube 6 | spec: 7 | url: https://kubeshop.github.io/helm-charts 8 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/testkube/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - crds 5 | - namespace.yaml 6 | - helm-release.yaml 7 | - helm-repository.yaml 8 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/testkube/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: testkube 5 | labels: 6 | goldilocks.fairwinds.com/vpa-update-mode: "auto" 7 | goldilocks.fairwinds.com/vpa-min-replicas: "2" 8 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/traefik/README.md: -------------------------------------------------------------------------------- 1 | # Traefik 2 | 3 | Traefik is a reverse proxy and load balancer that routes incoming requests to the correct backend service. It is used as an ingress controller in Kubernetes clusters. 4 | 5 | - [Documentation](https://doc.traefik.io/traefik/) 6 | - [Helm Chart](https://github.com/traefik/traefik-helm-chart) 7 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/traefik/helm-release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2 2 | kind: HelmRelease 3 | metadata: 4 | name: traefik 5 | namespace: traefik 6 | labels: 7 | helm.toolkit.fluxcd.io/crds: enabled 8 | helm.toolkit.fluxcd.io/helm-test: enabled 9 | helm.toolkit.fluxcd.io/remediation: enabled 10 | spec: 11 | interval: 10m 12 | chart: 13 | spec: 14 | chart: traefik 15 | version: 36.0.0 16 | sourceRef: 17 | kind: HelmRepository 18 | name: traefik 19 | # https://github.com/traefik/traefik-helm-chart/blob/master/traefik/values.yaml 20 | values: 21 | global: 22 | checkNewVersion: true 23 | deployment: 24 | replicas: ${traefik_replicas:=2} 25 | ports: 26 | web: 27 | redirections: 28 | entryPoint: 29 | to: websecure 30 | scheme: https 31 | service: 32 | type: ${traefik_service_type} 33 | ingressRoute: 34 | dashboard: 35 | enabled: true 36 | matchRule: Host(`traefik.${domain}`) 37 | entryPoints: 38 | - websecure 39 | middlewares: 40 | - name: forward-auth 41 | annotations: 42 | gethomepage.dev/enabled: "true" 43 | gethomepage.dev/name: Traefik 44 | gethomepage.dev/description: Dashboard for monitoring the traefik reverse proxy. 45 | gethomepage.dev/group: Monitoring 46 | gethomepage.dev/icon: traefik 47 | gethomepage.dev/href: "https://traefik.${domain}" 48 | tlsStore: 49 | default: 50 | defaultCertificate: 51 | secretName: certificate-tls 52 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/traefik/helm-repository.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1 2 | kind: HelmRepository 3 | metadata: 4 | name: traefik 5 | namespace: traefik 6 | spec: 7 | url: https://traefik.github.io/charts 8 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/traefik/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - helm-release.yaml 5 | - helm-repository.yaml 6 | - namespace.yaml 7 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/traefik/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: traefik 5 | labels: 6 | goldilocks.fairwinds.com/vpa-update-mode: "auto" 7 | goldilocks.fairwinds.com/vpa-min-replicas: "2" 8 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/trivy-operator/README.md: -------------------------------------------------------------------------------- 1 | # Trivy Operator 2 | 3 | The Trivy Operator leverages Trivy to continuously scan your Kubernetes cluster for security issues. The scans are summarised in security reports as Kubernetes Custom Resource Definitions, which become accessible through the Kubernetes API. The Operator does this by watching Kubernetes for state changes and automatically triggering security scans in response. 4 | 5 | - [Documentation](https://aquasecurity.github.io/trivy-operator/latest/) 6 | - [Helm Chart](https://github.com/aquasecurity/trivy-operator/tree/main/deploy/helm) 7 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/trivy-operator/helm-release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2 2 | kind: HelmRelease 3 | metadata: 4 | name: trivy-operator 5 | namespace: trivy-operator 6 | labels: 7 | helm.toolkit.fluxcd.io/helm-test: enabled 8 | helm.toolkit.fluxcd.io/remediation: enabled 9 | spec: 10 | interval: 10m 11 | chart: 12 | spec: 13 | chart: trivy-operator 14 | version: 0.28.1 15 | sourceRef: 16 | kind: HelmRepository 17 | name: trivy-operator 18 | # https://github.com/aquasecurity/trivy-operator/blob/main/deploy/helm/values.yaml 19 | values: {} 20 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/trivy-operator/helm-repository.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1 2 | kind: HelmRepository 3 | metadata: 4 | name: trivy-operator 5 | namespace: trivy-operator 6 | spec: 7 | url: https://aquasecurity.github.io/helm-charts/ 8 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/trivy-operator/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - namespace.yaml 5 | - helm-release.yaml 6 | - helm-repository.yaml 7 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/trivy-operator/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: trivy-operator 5 | labels: 6 | goldilocks.fairwinds.com/vpa-update-mode: "auto" 7 | goldilocks.fairwinds.com/vpa-min-replicas: "2" 8 | pod-security.kubernetes.io/enforce: privileged 9 | pod-security.kubernetes.io/audit: privileged 10 | pod-security.kubernetes.io/warn: privileged 11 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/vertical-pod-autoscaler/helm-release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2 2 | kind: HelmRelease 3 | metadata: 4 | name: vertical-pod-autoscaler 5 | namespace: vertical-pod-autoscaler 6 | labels: 7 | helm.toolkit.fluxcd.io/crds: enabled 8 | helm.toolkit.fluxcd.io/helm-test: enabled 9 | helm.toolkit.fluxcd.io/remediation: enabled 10 | spec: 11 | interval: 10m 12 | chart: 13 | spec: 14 | chart: vpa 15 | version: 4.7.2 16 | sourceRef: 17 | kind: HelmRepository 18 | name: vertical-pod-autoscaler 19 | # https://github.com/FairwindsOps/charts/blob/master/stable/goldilocks/values.yaml 20 | values: 21 | updater: 22 | enabled: true 23 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/vertical-pod-autoscaler/helm-repository.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1 2 | kind: HelmRepository 3 | metadata: 4 | name: vertical-pod-autoscaler 5 | namespace: vertical-pod-autoscaler 6 | spec: 7 | url: https://charts.fairwinds.com/stable 8 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/vertical-pod-autoscaler/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - namespace.yaml 5 | - helm-release.yaml 6 | - helm-repository.yaml 7 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/controllers/vertical-pod-autoscaler/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: vertical-pod-autoscaler 5 | labels: 6 | goldilocks.fairwinds.com/vpa-update-mode: "auto" 7 | goldilocks.fairwinds.com/vpa-min-replicas: "2" 8 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - certificates/ 6 | - cluster-policies/ 7 | - metrics-server/ 8 | - middlewares/ 9 | #- oauth2-proxy/ 10 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/metrics-server/README.md: -------------------------------------------------------------------------------- 1 | # Metrics Server 2 | 3 | Metrics Server is a scalable, efficient source of container resource metrics for Kubernetes built-in autoscaling pipelines. 4 | 5 | - [Documentation](https://kubernetes.io/docs/tasks/debug/debug-cluster/resource-metrics-pipeline/) 6 | - [Helm Chart](https://github.com/kubernetes-sigs/metrics-server/tree/master/charts/metrics-server) 7 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/metrics-server/helm-release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2 2 | kind: HelmRelease 3 | metadata: 4 | name: metrics-server 5 | namespace: kube-system 6 | labels: 7 | helm.toolkit.fluxcd.io/helm-test: enabled 8 | helm.toolkit.fluxcd.io/remediation: enabled 9 | spec: 10 | interval: 10m 11 | chart: 12 | spec: 13 | chart: metrics-server 14 | version: 3.12.2 15 | sourceRef: 16 | kind: HelmRepository 17 | name: metrics-server 18 | # https://github.com/kubernetes-sigs/metrics-server/blob/master/charts/metrics-server/values.yaml 19 | values: {} 20 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/metrics-server/helm-repository.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1 2 | kind: HelmRepository 3 | metadata: 4 | name: metrics-server 5 | namespace: kube-system 6 | spec: 7 | url: https://kubernetes-sigs.github.io/metrics-server/ 8 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/metrics-server/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - helm-release.yaml 5 | - helm-repository.yaml 6 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/middlewares/forward-auth/README.md: -------------------------------------------------------------------------------- 1 | # Traefik Middleware - Forward Auth 2 | 3 | This middleware adds forward authentication to requests. 4 | 5 | - [Documentation](https://doc.traefik.io/traefik/middlewares/http/forwardauth/) 6 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/middlewares/forward-auth/forward-auth.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: traefik.io/v1alpha1 2 | kind: Middleware 3 | metadata: 4 | name: forward-auth 5 | namespace: traefik 6 | spec: 7 | forwardAuth: 8 | address: https://oauth2-proxy.${domain} 9 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/middlewares/forward-auth/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - forward-auth.yaml 5 | -------------------------------------------------------------------------------- /k8s/bases/infrastructure/middlewares/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - forward-auth/ 6 | -------------------------------------------------------------------------------- /k8s/bases/variables/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - variables-base-config-map.yaml 6 | - variables-base-secret.enc.yaml 7 | -------------------------------------------------------------------------------- /k8s/bases/variables/variables-base-config-map.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: variables-base 6 | namespace: flux-system 7 | data: 8 | cloudflare_account_id: 634e9016d402443e427865dc35457728 9 | -------------------------------------------------------------------------------- /k8s/bases/variables/variables-base-secret.enc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: variables-base 5 | namespace: flux-system 6 | stringData: 7 | cloudflare_api_token: ENC[AES256_GCM,data:bteEJdVogGp5c2LkmByKu/lEHXlW9MrkwJ00rIQjzcFgFIq9/Z5vzA==,iv:asZMNSVoQ/LAHlQ8KcILQNK2cOakNPLujkWiUIkscBc=,tag:3t28xzyOLXO5BqhbpmokTQ==,type:str] 8 | sops: 9 | age: 10 | - recipient: age14skmde00w0ps6u8asm4rdqwpktr5m5pq84070yzwvjjmcyfnl4ushfn5uq 11 | enc: | 12 | -----BEGIN AGE ENCRYPTED FILE----- 13 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBR0l6UFQ1K3huVUhjZlJG 14 | SHFLU3hSWXN1bmt0eDdUOE1KTGN1QlpNQld3CjVzeFp4MWZ3OVpnaWNEU0hISVc2 15 | NFB6aVVFL3IwUTI0dS9PN1hHNVcyVlEKLS0tIFRFOWpDbGdWSGNPUU5CWUtISUFD 16 | WjJPRUEvOGJZVzg4ejhlUTJIaXpCcFUKbFKtBvK20m+q7vCdK7/1kamdwEQDhSgJ 17 | Bio7NZeyyovOueUit8yCMj8l/Y5tFKtONSyuWl4MF2DQNjvrwa/luw== 18 | -----END AGE ENCRYPTED FILE----- 19 | - recipient: age188ez3ur89qj7pmnyyqhcp9nmxp7lvsa72plph0frkfh9tt7n5guqs0vz6c 20 | enc: | 21 | -----BEGIN AGE ENCRYPTED FILE----- 22 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3eCtxc2tiWnhHQkZnQWdy 23 | VW5PN0d4Wm9WQW96elFMRXpCM1NTM3ZSb1dRClEvYVptUmRWS1BaQWJucCt0Qkl1 24 | SVdmdWtJZ1loVjZUelVQRG1RMUorMmsKLS0tIG5rWExuTG1FbHgyYlZLK0NwVUlW 25 | bGpJWlhpaGhRZzFSaDhNRzNGbUkxdFUKCYo8RfZ689ygP7NtJ7+7KVecO9UUKZoI 26 | 2VOdSpHEPr8l/Ych6d37foJIJHGKrbxkQh9Knaa4LoiLa2YcLUzEww== 27 | -----END AGE ENCRYPTED FILE----- 28 | - recipient: age1rk6fs67kly3h4zux5za429z3grjtvs8vcunav4sa28pxk738najsk8wgs6 29 | enc: | 30 | -----BEGIN AGE ENCRYPTED FILE----- 31 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVOGFRWE1tWFRLR0t5S2F0 32 | RitHTDcycGluUDhidTUrVUFzVW5WMElkNVVBCi9Hc2k4dTJGdis3UDgyMzZpKzgy 33 | UFdQc3YyOE9Hbm1LaFE0eVhXdTdxdE0KLS0tICtpQ3p2eisxZytQb0pkV2llVjBQ 34 | Y2pRQXFKbG9ZTGdDR1dQTDZyVlAxSDQKT1SYUmJf1Hqz7qgreB6Bg9OxJbeewLoi 35 | yXk9iodMC4ISDiuggKiUJonFdI/ltMAfyST7jDawrOHasbr/rZFIIw== 36 | -----END AGE ENCRYPTED FILE----- 37 | lastmodified: "2025-05-30T18:17:59Z" 38 | mac: ENC[AES256_GCM,data:WYa46ovo7Iu4YarwxczI9IB6XMZEk1478IQ0pPaQ7LX12msmpIWMPq3fiBLVNvLUCHiAO+NfCgWlt6woFw054mUj/iJPazbl78in/L34RjASsksiygFh2dNHhr4/MQtsbSI4edEZhMSendteiGP2jxkVL4i0dRHZ0Ip9YExIGeU=,iv:GzVCckhn7VGoYSp4ZDJkPIIOT9tWjivDDM5axITABw4=,tag:vRVkYFjDA3VNkQZIgdR33w==,type:str] 39 | encrypted_regex: ^(data|stringData)$ 40 | version: 3.10.2 41 | -------------------------------------------------------------------------------- /k8s/clusters/README.md: -------------------------------------------------------------------------------- 1 | # Clusters 2 | 3 | These are the different Kubernetes clusters that I run as part of my homelab. These serve as the index for the kustomization build and deployment process. 4 | 5 | Each cluster may contain its own set of resources, as that allows me to scope some deployments to specific clusters. 6 | -------------------------------------------------------------------------------- /k8s/clusters/dev/apps/flux-kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1 3 | kind: Kustomization 4 | metadata: 5 | name: apps 6 | namespace: flux-system 7 | spec: 8 | interval: 60m 9 | timeout: 3m 10 | retryInterval: 2m 11 | sourceRef: 12 | kind: OCIRepository 13 | name: flux-system 14 | dependsOn: 15 | - name: infrastructure 16 | decryption: 17 | provider: sops 18 | secretRef: 19 | name: sops-age 20 | postBuild: 21 | substituteFrom: 22 | - kind: ConfigMap 23 | name: variables-cluster 24 | - kind: Secret 25 | name: variables-cluster 26 | - kind: ConfigMap 27 | name: variables-base 28 | - kind: Secret 29 | name: variables-base 30 | path: clusters/dev/apps/ 31 | prune: true 32 | wait: true 33 | force: true 34 | -------------------------------------------------------------------------------- /k8s/clusters/dev/apps/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - ../../../distributions/omni/apps/ 6 | -------------------------------------------------------------------------------- /k8s/clusters/dev/infrastructure/controllers/flux-kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1 3 | kind: Kustomization 4 | metadata: 5 | name: infrastructure-controllers 6 | namespace: flux-system 7 | spec: 8 | interval: 60m 9 | timeout: 3m 10 | retryInterval: 2m 11 | path: clusters/dev/infrastructure/controllers/ 12 | sourceRef: 13 | kind: OCIRepository 14 | name: flux-system 15 | dependsOn: 16 | - name: variables 17 | decryption: 18 | provider: sops 19 | secretRef: 20 | name: sops-age 21 | postBuild: 22 | substituteFrom: 23 | - kind: ConfigMap 24 | name: variables-cluster 25 | - kind: Secret 26 | name: variables-cluster 27 | - kind: ConfigMap 28 | name: variables-base 29 | - kind: Secret 30 | name: variables-base 31 | wait: true 32 | prune: true 33 | force: true 34 | -------------------------------------------------------------------------------- /k8s/clusters/dev/infrastructure/controllers/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - ../../../../distributions/omni/infrastructure/controllers/ 6 | -------------------------------------------------------------------------------- /k8s/clusters/dev/infrastructure/flux-kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1 3 | kind: Kustomization 4 | metadata: 5 | name: infrastructure 6 | namespace: flux-system 7 | spec: 8 | interval: 60m 9 | timeout: 3m 10 | retryInterval: 2m 11 | path: clusters/dev/infrastructure/ 12 | sourceRef: 13 | kind: OCIRepository 14 | name: flux-system 15 | dependsOn: 16 | - name: infrastructure-controllers 17 | decryption: 18 | provider: sops 19 | secretRef: 20 | name: sops-age 21 | postBuild: 22 | substituteFrom: 23 | - kind: ConfigMap 24 | name: variables-cluster 25 | - kind: Secret 26 | name: variables-cluster 27 | - kind: ConfigMap 28 | name: variables-base 29 | - kind: Secret 30 | name: variables-base 31 | wait: true 32 | prune: true 33 | force: true 34 | -------------------------------------------------------------------------------- /k8s/clusters/dev/infrastructure/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - ../../../distributions/omni/infrastructure 6 | -------------------------------------------------------------------------------- /k8s/clusters/dev/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - apps/flux-kustomization.yaml 6 | - infrastructure/controllers/flux-kustomization.yaml 7 | - infrastructure/flux-kustomization.yaml 8 | - variables/flux-kustomization.yaml 9 | -------------------------------------------------------------------------------- /k8s/clusters/dev/variables/flux-kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.toolkit.fluxcd.io/v1 2 | kind: Kustomization 3 | metadata: 4 | name: variables 5 | namespace: flux-system 6 | spec: 7 | interval: 60m 8 | timeout: 3m 9 | retryInterval: 2m 10 | path: clusters/dev/variables/ 11 | sourceRef: 12 | kind: OCIRepository 13 | name: flux-system 14 | decryption: 15 | provider: sops 16 | secretRef: 17 | name: sops-age 18 | wait: true 19 | prune: true 20 | force: true 21 | -------------------------------------------------------------------------------- /k8s/clusters/dev/variables/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - ../../../distributions/omni/variables 6 | - variables-cluster-config-map.yaml 7 | - variables-cluster-secret.enc.yaml 8 | -------------------------------------------------------------------------------- /k8s/clusters/dev/variables/variables-cluster-config-map.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: variables-cluster 6 | namespace: flux-system 7 | data: 8 | cloudflared_tunnel_id: feb90d05-6569-4af1-8e79-13ecd147e39a 9 | domain: dev.platform.devantler.tech 10 | github_app_client_id: Iv23lidTbdsQoKttGTUI 11 | issuer_group: cert-manager.k8s.cloudflare.com 12 | issuer_kind: ClusterOriginIssuer 13 | issuer_name: cloudflare-origin 14 | traefik_service_type: ClusterIP 15 | -------------------------------------------------------------------------------- /k8s/clusters/dev/variables/variables-cluster-secret.enc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: variables-cluster 5 | namespace: flux-system 6 | stringData: 7 | cloudflared_tunnel_token: ENC[AES256_GCM,data:4tOBWKE1yyE8E/KDYs1WLEgc8G4vA8RblPjQIhwsyB2oDrAnjj2huhERYUrjjWYYGmqieBNEu6DkdjTTSkFhmJcZLkupQxfuAq61Pki8sVJEmCGEquLq371Id2b1RHhw+wKeYnrEL+cC1JFeD/aKX4K3OtVpGFQpZZhLU1BpNlnlauDz1rb7HYwsFuq2EG6w8atpa7d1Y/GaI0DPwEMMX0lt+5Ro3TYv3cGzxpHfom0Xd6f67pLAaQ==,iv:oaIENBgzjwSiI8fdcxmSRtnDMVb9neYAWDYX2yFb9nM=,tag:yoKHrocg+fP8Z7EvgYwoBA==,type:str] 8 | dex_client_secret: ENC[AES256_GCM,data:6D86xil65d0mqWyA6+293nSaD3M=,iv:NwnidZmqV1FEYoPzXiVuBFLea4yl1wquzx9mCP9QajI=,tag:gT4M6vauYFMJ8H0M2cyGvg==,type:str] 9 | github_app_client_secret: ENC[AES256_GCM,data:ZRl5HhAsRN0OWFrz9bwbyALETyV7rMUGB/C/98pUDoSDTxUsouKg1Q==,iv:p3ugJvnPiZgJOWnggBWFgXNAaNXRxTMCi3+86lHCgUU=,tag:mIOVh1KoONuJmjz67egYxw==,type:str] 10 | oauth2_proxy_cookie_secret: ENC[AES256_GCM,data:ju6ek+8TeEQWaHBgj88iTA6Ey7cvbeL3SdQykganKwdkk6GTsjj2VO/bKPs=,iv:me5/Zo90lBf0PEmVd//AfCF4RToj+dTvS2ayKZbVqbM=,tag:yKbBqNtnyD6lbtn5IUh5mg==,type:str] 11 | hcloud_token: ENC[AES256_GCM,data:0PCFWpWVHq2yODo1Owyjihj9qv/eckbWk4w8YVru+jG+p1mfgz5ipHHz+zUkv39v3pjUYvrPwRwJLJhMhY4ERQ==,iv:EndM1Zi8yo6AHokKMVjNiryLMx7oiKpND6UCtz/M4DI=,tag:aABKuGrrclZZKl4SvtjXAQ==,type:str] 12 | sops: 13 | age: 14 | - recipient: age188ez3ur89qj7pmnyyqhcp9nmxp7lvsa72plph0frkfh9tt7n5guqs0vz6c 15 | enc: | 16 | -----BEGIN AGE ENCRYPTED FILE----- 17 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJL1g5Z1FxWjZJNUxzQXE5 18 | NVlnTkE4WkNRSStyNlpvem9ZTHlyNDlEQ3dRCjZKaUF4bUNBZ1JDNHVCenpnM0pJ 19 | dzZRd3lFalZxcXdtdysvaWZCajFVT3MKLS0tIFZTMHo3S3A1eFI4SVBGQS9GMHA2 20 | bit4OGl5QVBJV2tMYTA4SjJHN1VkWVkKuOtlVdLXYA/Xhij3RttbU8crRx3brSVu 21 | MUfT1wTTowU3AkI2mX5AXO3v4IVqYmo6CNn60PeKUzOGfJdDjjzfOA== 22 | -----END AGE ENCRYPTED FILE----- 23 | lastmodified: "2025-05-31T18:00:02Z" 24 | mac: ENC[AES256_GCM,data:i4yQpAyd/X3E6TYsjzlOwDhoSXR1WLB96ACxbxpnLzW7o85uzX4yqrKosueZFEcKjGbWT4bivwgEa0FubpL6E43o3ZiGCtuS5z2vOJ8FWpBJUkgKoSoBqDr1o4xpq7Mq59UdRwnL0m1pBojCwyGjLypfri3jdd5UDqokO6WQvog=,iv:u3WhfMZ2ovlMuf+JkdWesUuL7sz79A/oKrixPGDP6zQ=,tag:HT1qGjfePzvmN9cQkLJCWw==,type:str] 25 | encrypted_regex: ^(data|stringData)$ 26 | version: 3.10.2 27 | -------------------------------------------------------------------------------- /k8s/clusters/local/apps/flux-kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1 3 | kind: Kustomization 4 | metadata: 5 | name: apps 6 | namespace: flux-system 7 | spec: 8 | interval: 60m 9 | timeout: 3m 10 | retryInterval: 2m 11 | sourceRef: 12 | kind: OCIRepository 13 | name: flux-system 14 | dependsOn: 15 | - name: infrastructure 16 | decryption: 17 | provider: sops 18 | secretRef: 19 | name: sops-age 20 | postBuild: 21 | substituteFrom: 22 | - kind: ConfigMap 23 | name: variables-cluster 24 | - kind: Secret 25 | name: variables-cluster 26 | - kind: ConfigMap 27 | name: variables-base 28 | - kind: Secret 29 | name: variables-base 30 | path: clusters/local/apps/ 31 | prune: true 32 | wait: true 33 | force: true 34 | -------------------------------------------------------------------------------- /k8s/clusters/local/apps/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - ../../../distributions/kind/apps/ 6 | -------------------------------------------------------------------------------- /k8s/clusters/local/infrastructure/controllers/flux-kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1 3 | kind: Kustomization 4 | metadata: 5 | name: infrastructure-controllers 6 | namespace: flux-system 7 | spec: 8 | interval: 60m 9 | timeout: 3m 10 | retryInterval: 2m 11 | path: clusters/local/infrastructure/controllers/ 12 | sourceRef: 13 | kind: OCIRepository 14 | name: flux-system 15 | dependsOn: 16 | - name: variables 17 | decryption: 18 | provider: sops 19 | secretRef: 20 | name: sops-age 21 | postBuild: 22 | substituteFrom: 23 | - kind: ConfigMap 24 | name: variables-cluster 25 | - kind: Secret 26 | name: variables-cluster 27 | - kind: ConfigMap 28 | name: variables-base 29 | - kind: Secret 30 | name: variables-base 31 | wait: true 32 | prune: true 33 | force: true 34 | -------------------------------------------------------------------------------- /k8s/clusters/local/infrastructure/controllers/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - ../../../../distributions/kind/infrastructure/controllers 6 | -------------------------------------------------------------------------------- /k8s/clusters/local/infrastructure/flux-kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1 3 | kind: Kustomization 4 | metadata: 5 | name: infrastructure 6 | namespace: flux-system 7 | spec: 8 | interval: 60m 9 | timeout: 3m 10 | retryInterval: 2m 11 | path: clusters/local/infrastructure/ 12 | sourceRef: 13 | kind: OCIRepository 14 | name: flux-system 15 | dependsOn: 16 | - name: infrastructure-controllers 17 | decryption: 18 | provider: sops 19 | secretRef: 20 | name: sops-age 21 | postBuild: 22 | substituteFrom: 23 | - kind: ConfigMap 24 | name: variables-cluster 25 | - kind: Secret 26 | name: variables-cluster 27 | - kind: ConfigMap 28 | name: variables-base 29 | - kind: Secret 30 | name: variables-base 31 | wait: true 32 | prune: true 33 | force: true 34 | -------------------------------------------------------------------------------- /k8s/clusters/local/infrastructure/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - ../../../distributions/kind/infrastructure 6 | -------------------------------------------------------------------------------- /k8s/clusters/local/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - apps/flux-kustomization.yaml 6 | - infrastructure/controllers/flux-kustomization.yaml 7 | - infrastructure/flux-kustomization.yaml 8 | - variables/flux-kustomization.yaml 9 | -------------------------------------------------------------------------------- /k8s/clusters/local/variables/flux-kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.toolkit.fluxcd.io/v1 2 | kind: Kustomization 3 | metadata: 4 | name: variables 5 | namespace: flux-system 6 | spec: 7 | interval: 60m 8 | timeout: 3m 9 | retryInterval: 2m 10 | path: clusters/local/variables/ 11 | sourceRef: 12 | kind: OCIRepository 13 | name: flux-system 14 | decryption: 15 | provider: sops 16 | secretRef: 17 | name: sops-age 18 | wait: true 19 | prune: true 20 | force: true 21 | -------------------------------------------------------------------------------- /k8s/clusters/local/variables/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - ../../../distributions/kind/variables 6 | - variables-cluster-config-map.yaml 7 | - variables-cluster-secret.enc.yaml 8 | -------------------------------------------------------------------------------- /k8s/clusters/local/variables/variables-cluster-config-map.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: variables-cluster 6 | namespace: flux-system 7 | data: 8 | cloudflared_tunnel_id: 16c0c1dc-388e-4ddc-bd5f-7fdb7710e499 9 | domain: local.platform.devantler.tech 10 | github_app_client_id: Iv23liZ8GHRgpx32Em2y 11 | issuer_group: cert-manager.io 12 | issuer_kind: ClusterIssuer 13 | issuer_name: selfsigned 14 | traefik_service_type: NodePort 15 | -------------------------------------------------------------------------------- /k8s/clusters/local/variables/variables-cluster-secret.enc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: variables-cluster 5 | namespace: flux-system 6 | stringData: 7 | cloudflared_tunnel_token: ENC[AES256_GCM,data:QvbFb2ujfi+JvwrDW2kWb9wap99RZBwVmaORHgI9aIpHGb8GiiUuaII3ClCvsaOlFGoo1E5Qn0+HbdfLJiDjo+FA/wR8G7Kii8uBtgfm8zCKo/gi3Fhd8Mq2OHCo+fgj4Mz4a6xXTPi/hp2UeorTPRENoL43e+kHzrky9QZ28Y9JEWfk8flB7lUnkZG77FerDxO0prdTt2eVP5Fscu7wYOo98Kb5nzo/MU6TX1POaa4rFk8sMPEoRw==,iv:8WnNo1aBrV3xwil8lnO1/AXp6NEuwAgjHDGiAIqxeTs=,tag:+6MwxKbzDtJQxXby1r59bQ==,type:str] 8 | dex_client_secret: ENC[AES256_GCM,data:o2clA8MTPFWC2s+bHnaMs6bdSSA=,iv:w/UZp5Bxc2pR2nyi+JxVaQNgEBfDpbcRluSeJ2UDgf8=,tag:l3kc8L3PB/90vHWMwxHfQQ==,type:str] 9 | github_app_client_secret: ENC[AES256_GCM,data:igknWcl7N/4SZ3zWjydmeAq+D9PIF9lFXIlPN5ng8Urj3lWg5d6zbA==,iv:arQQquJTBAMCPhoON0R5LzUYd//gV7LsLqOb6NqgOVo=,tag:MakOw2dXO9dXAarBpde21A==,type:str] 10 | oauth2_proxy_cookie_secret: ENC[AES256_GCM,data:useC+jN3YY76x6iOg+nLmnZeZOvEgT4BkWm1H+ossow57dge3j/nMjEme9s=,iv:dD3vGq5+yDc4SD9KOG1W1QaTvd73N5lDXUuYreqcSpg=,tag:FtBNJ8DsGkopNHhiUwxCvg==,type:str] 11 | sops: 12 | age: 13 | - recipient: age14skmde00w0ps6u8asm4rdqwpktr5m5pq84070yzwvjjmcyfnl4ushfn5uq 14 | enc: | 15 | -----BEGIN AGE ENCRYPTED FILE----- 16 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZQ0NqcDFoTklyUEhlTHZM 17 | ODBENHEzNTg4SnljbUwwWmV0UFNoZnlPaDJjCm1MNXdRdmdXSVIvWkdSM3h1Q2Y2 18 | YlVpU2dIblFWUFpVQ2IxNzNlNFVnSmsKLS0tIHF4SWdQYy9uSWFMTWVyK3dKL1l3 19 | OHBKalNlT09NYzdYc3RINUprL0ZqTW8KoTcrIHbkg3C3Gcq2GqMGiBE5j7QRXgjR 20 | Dksvvk875wmDUgBjK+4zwJtDwNFqi1w0ia4+rjpnwS2XkSiodwy6dQ== 21 | -----END AGE ENCRYPTED FILE----- 22 | lastmodified: "2025-05-30T20:53:40Z" 23 | mac: ENC[AES256_GCM,data:MbefTvLXwAy2M4bc+rq9zwPDd42VoTtVpzl5GPYLcgZmlnah0YQIvo8XygXO5JodTySiwTi1lqRuSSJR8bX2xdCI+r2M6ooAEMinX6Pwi0oMypvGjmSTQtzZbMuPP+SgLzLup1vSRvMXsOqLPIBqJuwVgJIB7UjMqDut4fS+/FM=,iv:EYXFddfxUIR40HKbbKxjeqRG/cBSzmsERehyPpqZmg4=,tag:ZCYoDti18UWoin0yw+Qydg==,type:str] 24 | encrypted_regex: ^(data|stringData)$ 25 | version: 3.10.2 26 | -------------------------------------------------------------------------------- /k8s/clusters/prod/apps/flux-kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1 3 | kind: Kustomization 4 | metadata: 5 | name: apps 6 | namespace: flux-system 7 | spec: 8 | interval: 60m 9 | timeout: 3m 10 | retryInterval: 2m 11 | sourceRef: 12 | kind: OCIRepository 13 | name: flux-system 14 | dependsOn: 15 | - name: infrastructure 16 | decryption: 17 | provider: sops 18 | secretRef: 19 | name: sops-age 20 | postBuild: 21 | substituteFrom: 22 | - kind: ConfigMap 23 | name: variables-cluster 24 | - kind: Secret 25 | name: variables-cluster 26 | - kind: ConfigMap 27 | name: variables-base 28 | - kind: Secret 29 | name: variables-base 30 | path: clusters/prod/apps/ 31 | prune: true 32 | wait: true 33 | force: true 34 | -------------------------------------------------------------------------------- /k8s/clusters/prod/apps/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - ../../../distributions/omni/apps/ 6 | -------------------------------------------------------------------------------- /k8s/clusters/prod/infrastructure/controllers/flux-kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1 3 | kind: Kustomization 4 | metadata: 5 | name: infrastructure-controllers 6 | namespace: flux-system 7 | spec: 8 | interval: 60m 9 | timeout: 3m 10 | retryInterval: 2m 11 | path: clusters/prod/infrastructure/controllers/ 12 | sourceRef: 13 | kind: OCIRepository 14 | name: flux-system 15 | dependsOn: 16 | - name: variables 17 | decryption: 18 | provider: sops 19 | secretRef: 20 | name: sops-age 21 | postBuild: 22 | substituteFrom: 23 | - kind: ConfigMap 24 | name: variables-cluster 25 | - kind: Secret 26 | name: variables-cluster 27 | - kind: ConfigMap 28 | name: variables-base 29 | - kind: Secret 30 | name: variables-base 31 | wait: true 32 | prune: true 33 | force: true 34 | -------------------------------------------------------------------------------- /k8s/clusters/prod/infrastructure/controllers/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - ../../../../distributions/omni/infrastructure/controllers/ 6 | -------------------------------------------------------------------------------- /k8s/clusters/prod/infrastructure/flux-kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1 3 | kind: Kustomization 4 | metadata: 5 | name: infrastructure 6 | namespace: flux-system 7 | spec: 8 | interval: 60m 9 | timeout: 3m 10 | retryInterval: 2m 11 | path: clusters/prod/infrastructure/ 12 | sourceRef: 13 | kind: OCIRepository 14 | name: flux-system 15 | dependsOn: 16 | - name: infrastructure-controllers 17 | decryption: 18 | provider: sops 19 | secretRef: 20 | name: sops-age 21 | postBuild: 22 | substituteFrom: 23 | - kind: ConfigMap 24 | name: variables-cluster 25 | - kind: Secret 26 | name: variables-cluster 27 | - kind: ConfigMap 28 | name: variables-base 29 | - kind: Secret 30 | name: variables-base 31 | wait: true 32 | prune: true 33 | force: true 34 | -------------------------------------------------------------------------------- /k8s/clusters/prod/infrastructure/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - ../../../distributions/omni/infrastructure 6 | -------------------------------------------------------------------------------- /k8s/clusters/prod/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - apps/flux-kustomization.yaml 6 | - infrastructure/controllers/flux-kustomization.yaml 7 | - infrastructure/flux-kustomization.yaml 8 | - variables/flux-kustomization.yaml 9 | -------------------------------------------------------------------------------- /k8s/clusters/prod/variables/flux-kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.toolkit.fluxcd.io/v1 2 | kind: Kustomization 3 | metadata: 4 | name: variables 5 | namespace: flux-system 6 | spec: 7 | interval: 60m 8 | timeout: 3m 9 | retryInterval: 2m 10 | path: clusters/prod/variables/ 11 | sourceRef: 12 | kind: OCIRepository 13 | name: flux-system 14 | decryption: 15 | provider: sops 16 | secretRef: 17 | name: sops-age 18 | wait: true 19 | prune: true 20 | force: true 21 | -------------------------------------------------------------------------------- /k8s/clusters/prod/variables/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - ../../../distributions/omni/variables 6 | - variables-cluster-config-map.yaml 7 | - variables-cluster-secret.enc.yaml 8 | -------------------------------------------------------------------------------- /k8s/clusters/prod/variables/variables-cluster-config-map.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: variables-cluster 6 | namespace: flux-system 7 | data: 8 | cloudflared_tunnel_id: 18508e52-a9d7-466c-b85e-1fa102b3542e 9 | domain: platform.devantler.tech 10 | github_app_client_id: Iv23limfvbk93bAXZI6b 11 | issuer_group: cert-manager.k8s.cloudflare.com 12 | issuer_kind: ClusterOriginIssuer 13 | issuer_name: cloudflare-origin 14 | traefik_service_type: ClusterIP 15 | -------------------------------------------------------------------------------- /k8s/clusters/prod/variables/variables-cluster-secret.enc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: variables-cluster 5 | namespace: flux-system 6 | stringData: 7 | cloudflared_tunnel_token: ENC[AES256_GCM,data:9wgfVd3Gdd0DfDFgTh0KMsuO4sAikjoXe36zZCjo2sPOVme394cEhmJDszcz0CcUoMgxbP98jA+DbMr/N8gEjXyaG5JOithxhWnZky7DsIdZqBlrqsQ9tm4pkHATspve5QQprW78UCOBDaUNp5+YxlrWcN5KqdbZCPWxlBO9daUhWio4N1EYyfUm0mGTghIH8hz72bhjUKxRv8yIoJR4tb7VDMDoE9l+QQnzn03QM2GWf5912hi8VQ==,iv:QRbbFUVvFZMXcoEsEAOKoc4it/WEOD4JZxICmRqJ2QM=,tag:CThESRc6svFszyFUyaelOg==,type:str] 8 | dex_client_secret: ENC[AES256_GCM,data:gVxwZqx8/LVQlRttnuMNIpVy89E=,iv:klCgOiWBp3k6HUOzs6KcpfM9KdxTUVRTdNqYevH0kZ8=,tag:Vc1AAeIZR61k/Crwe8uBxg==,type:str] 9 | github_app_client_secret: ENC[AES256_GCM,data:iTVC+ZemjyoxPthDHOAH1sE3JHvtI9pU4jyvcaU5Ec2L4dDolD/FBg==,iv:fl/QlG04RFi1//G7UUqS3duqTRYqc3feka6/jmp+chc=,tag:PwHi7b5MCk0qBDR2NairEQ==,type:str] 10 | hcloud_token: ENC[AES256_GCM,data:yhjuxpL/mVZ+yopyzXdncZXv0qzwaAs2Dad5ePoNqhP5wVhSu0aahbFAYXwGLXnI2A1KeF+ItrERVzXE0jOD3A==,iv:mD2ohoDGcti6z/d5WEXVDc+ftBKZOrxTlQykIWcaDcU=,tag:xq9p2FsdLEN+IOxbf73qxQ==,type:str] 11 | oauth2_proxy_cookie_secret: ENC[AES256_GCM,data:OcnWJyQfQ6OUdHr5YxYe2CmOSw8w7q0rit8CCP6Z9QlXqy4q1Yne1Ck3rU4=,iv:aReO3UrPimKuFEwkKeU+QLdXzTBALRWcFpHlVb+Cp6w=,tag:rMtxdbigYrbSn0GnoVkCAQ==,type:str] 12 | sops: 13 | age: 14 | - recipient: age1rk6fs67kly3h4zux5za429z3grjtvs8vcunav4sa28pxk738najsk8wgs6 15 | enc: | 16 | -----BEGIN AGE ENCRYPTED FILE----- 17 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSArc3VTczhFa2NrMFNqR2E1 18 | YXhNREpNdFVpcjhleGljSnJhVjczb0xPUzJZCitGZEdTdENUaUVOL1FGazV3RXQ2 19 | RzRrQnc2QlRLY0hMajc2aG9sWkdiMkUKLS0tIGM4YUVpQjh0RTBGaE5wZDJBbno5 20 | YTF5eFRrUGlvZkZGdmx5UzI3WWRvRTQKzSuBSfK89EvVDbT483Wgek2dZWWa2M2r 21 | qDk/Sua5xcRVPSG93fJPngVPSKeJK/HLArjDMbwueZrhCHx5mZIirA== 22 | -----END AGE ENCRYPTED FILE----- 23 | lastmodified: "2025-05-31T17:59:45Z" 24 | mac: ENC[AES256_GCM,data:PM/XDeTionbG/qnAYrrfNcTV22PdWBZVNd5ogrzKsmwYTpGShdabHvD1vow251uz15ksgNeuhyAFohkKl1NepFGhdrvoi2h11CjauWWBhYXE7YtU8XTyw3DEohJl53yEbyZI3Etn4RbtFqI99ekhjBHRW8SuAYpRoD2WjRSVKas=,iv:NsU9qBsJT0q9xs9ZSN0227GGUhqh0GIK82TsDYoiSi4=,tag:yE0h1D3bl8D+an5b8k4q3g==,type:str] 25 | encrypted_regex: ^(data|stringData)$ 26 | version: 3.10.2 27 | -------------------------------------------------------------------------------- /k8s/distributions/README.md: -------------------------------------------------------------------------------- 1 | # Distributions 2 | 3 | These are the different Kubernetes distributions that I run as part of my homelab. 4 | 5 | Each distribution may contain its own set of resources, as that allows me to scope some deployments to specific clusters. 6 | -------------------------------------------------------------------------------- /k8s/distributions/kind/apps/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - ../../../bases/apps/ 6 | -------------------------------------------------------------------------------- /k8s/distributions/kind/infrastructure/cluster-issuers/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - selfsigned-cluster-issuer.yaml 5 | -------------------------------------------------------------------------------- /k8s/distributions/kind/infrastructure/cluster-issuers/selfsigned-cluster-issuer.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1 2 | kind: ClusterIssuer 3 | metadata: 4 | name: selfsigned 5 | spec: 6 | ca: 7 | secretName: ca-key-pair 8 | --- 9 | apiVersion: v1 10 | kind: Secret 11 | metadata: 12 | name: ca-key-pair 13 | namespace: cert-manager 14 | data: 15 | tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZGekNDQTMrZ0F3SUJBZ0lRQ1FkKzdrdG95TXVWczcvbWlheFVCekFOQmdrcWhraUc5dzBCQVFzRkFEQ0IKb3pFZU1Cd0dBMVVFQ2hNVmJXdGpaWEowSUdSbGRtVnNiM0J0Wlc1MElFTkJNVHd3T2dZRFZRUUxERE51YVd0dgpiR0ZwWlcxcGJHUmhiVzFBVFdGakxteHZZMkZzWkc5dFlXbHVJQ2hPYVd0dmJHRnBJRVZ0YVd3Z1JHRnRiU2t4ClF6QkJCZ05WQkFNTU9tMXJZMlZ5ZENCdWFXdHZiR0ZwWlcxcGJHUmhiVzFBVFdGakxteHZZMkZzWkc5dFlXbHUKSUNoT2FXdHZiR0ZwSUVWdGFXd2dSR0Z0YlNrd0hoY05NalV3TlRJek1UY3hOelE0V2hjTk16VXdOVEl6TVRjeApOelE0V2pDQm96RWVNQndHQTFVRUNoTVZiV3RqWlhKMElHUmxkbVZzYjNCdFpXNTBJRU5CTVR3d09nWURWUVFMCkRETnVhV3R2YkdGcFpXMXBiR1JoYlcxQVRXRmpMbXh2WTJGc1pHOXRZV2x1SUNoT2FXdHZiR0ZwSUVWdGFXd2cKUkdGdGJTa3hRekJCQmdOVkJBTU1PbTFyWTJWeWRDQnVhV3R2YkdGcFpXMXBiR1JoYlcxQVRXRmpMbXh2WTJGcwpaRzl0WVdsdUlDaE9hV3R2YkdGcElFVnRhV3dnUkdGdGJTa3dnZ0dpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCCmp3QXdnZ0dLQW9JQmdRQzZwMlJOVHdqaERkRWh0ZlFrYWJTWlFRbld4L1JpZ21vNDFGamxzb2NEMmxLYnRnVmQKOXl6a2Fxd2JkNHZSTFdLSm0xY0ZyZGw0Uk9vV0RnbENHVkZCTDEwalN2a3NIWEc0djFkaXo0MDhUOXRHZUNzLwpjaitjbDlHN0J0ZktkQlVJanU4SXhkZjBEWVgxZTVGYVhFMThPUlNjUjU1ZElDamRhdDFabStld2EydnZNK05uCi9nZkxENDgvbUh1bEZhWURVK05pRmlBNUM0a2tXb1JMR0djT0tLYW9tb0JrQnlUbDlTeWNRTE9lZzJ0WkJmbDQKaWQvMXJPSXB1cEF2MjJESW9qbitZeVR4RUZXOXE1Vit6VlZHdlN6amw5UlRUVDc4QStFZ0hPQnlocXpLOFJPQgptZjJhTmF0bVhmbGFac1JqZEtURjQyQkQxbENiM0xwc0ZQT1R5VU9haGp5TWFUNUVJWVBhRXc1OXI5RXlNUEN5CndaVml3b0Nua1E0cnRmTkxIT2JwZDhWTnExVHZzSFVSbVdJVEZsRWpBbHdVMThKdU03aC9wUFlFUElxRTFoZzIKd2Q1bkZCZzE3cUhJYSs4T200aGFBTkNpS2Y1c093NVhXWEs0UDFNWTRnYnptMmFCSzIreTl5Rm9USkMvV1RKTgovcE1heWF1WXhENi9sWmtDQXdFQUFhTkZNRU13RGdZRFZSMFBBUUgvQkFRREFnSUVNQklHQTFVZEV3RUIvd1FJCk1BWUJBZjhDQVFBd0hRWURWUjBPQkJZRUZJc0JIck1aTGNtcithUEVZR3BFQ0lyTW5EQVpNQTBHQ1NxR1NJYjMKRFFFQkN3VUFBNElCZ1FDRUZtV1gwZW9Rd2hYZGN0Q1hteUxneWYvb3JZcEhNOCtkamdUOVZjRHZXU3djTWNRagpVVFRhZVhvTGtKVVBkK1Z4N1hWVVZrY0gxOUw0RUJlRXdNQTZqNDJtNFNualFiVHJ6VktORFNBT2laU1VDK3g4CkJ5dE5FVEpLR3FtRFhuTjltaGdqcVpzaTB0MENjZC9kSDJuSVpHTXV5cXI2Y3hxYkJURG1Sdmk3ejhoMEJYeisKcS9BL3N3bkhUKzBvMTBIYXpKalBScnowTUZQeDEyK3NRTVI2WHdEUkUxQWs1UUEyZ0F1VmI1Z1ZEUCtuZk5aMApFaDJUbXh3M3AvL1ZqUjkySzRDaHg4MThWVE8wWlJZQkV6bUhsSmx3VmpnTlFDYWF5Z291dUk5VHlhYU1yNk5hCnVKbzlsUjRGaklGOUxjU3E2TXdrSHFIM0o0NHNhMjRic1VSU1VBb0QyTG9WbXlSaThTc0tkR215OWRGQlEwTWgKcTQ1QUpKOTVaZFNWckwrNU5KVG5pclRVZ1g1Q3RZbGl6disreVFTYlVKblAxays1U29ZekVFZVVYUHBld3RGRAovU0xId2VtZEx4a296N1hsTkdVTzR2MTQ5SXNmeFdjaUZiN1pkZ2xtN2FnY3NqaWR5ZTAyei9uMEQ3clZDZnIvCnVuejZydE5aMk9IWWUrND0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQ== 16 | tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUcvZ0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQnVnd2dnYmtBZ0VBQW9JQmdRQzZwMlJOVHdqaERkRWgKdGZRa2FiU1pRUW5XeC9SaWdtbzQxRmpsc29jRDJsS2J0Z1ZkOXl6a2Fxd2JkNHZSTFdLSm0xY0ZyZGw0Uk9vVwpEZ2xDR1ZGQkwxMGpTdmtzSFhHNHYxZGl6NDA4VDl0R2VDcy9jaitjbDlHN0J0ZktkQlVJanU4SXhkZjBEWVgxCmU1RmFYRTE4T1JTY1I1NWRJQ2pkYXQxWm0rZXdhMnZ2TStObi9nZkxENDgvbUh1bEZhWURVK05pRmlBNUM0a2sKV29STEdHY09LS2FvbW9Ca0J5VGw5U3ljUUxPZWcydFpCZmw0aWQvMXJPSXB1cEF2MjJESW9qbitZeVR4RUZXOQpxNVYrelZWR3ZTempsOVJUVFQ3OEErRWdIT0J5aHF6SzhST0JtZjJhTmF0bVhmbGFac1JqZEtURjQyQkQxbENiCjNMcHNGUE9UeVVPYWhqeU1hVDVFSVlQYUV3NTlyOUV5TVBDeXdaVml3b0Nua1E0cnRmTkxIT2JwZDhWTnExVHYKc0hVUm1XSVRGbEVqQWx3VTE4SnVNN2gvcFBZRVBJcUUxaGcyd2Q1bkZCZzE3cUhJYSs4T200aGFBTkNpS2Y1cwpPdzVYV1hLNFAxTVk0Z2J6bTJhQksyK3k5eUZvVEpDL1dUSk4vcE1heWF1WXhENi9sWmtDQXdFQUFRS0NBWUJ1CkVRT09xd3A3VytCMDFvMFBZOTRCZVY3SjdzTm55NnZEczBSd3Z1UHJHN1VXNlRFbEJmck0vekphU0JhRTFSU0UKUEx3R04weEVKYTg4TGk2N2NaNStwK1Z1U0duQzMrSU5wWmRzUnlQcjZ0Tk5MTk9qNkVVbW5FZ3ExNUFzYkdOeQoxb2FTVDhoV3ZCckFkWXR6RTNjRng4c2xsUDRId0UwWXRFbXU2OGFtTzlJOERnY05iYmsrdndBajZsRVBPa0xaCk40Q2dlSmVyeStlbExsTlF6U1VJTG1TSWpBTWwrU2lEQ2g2eVRWMGVIalVSRy9yT1g4OVhXZ2xMdmg0RWVvSUgKNGcvWmdWV25HQUNiem5POC9paGY3UEdXVzc4TzNTTitMdVJmWTVaZGVEaEx0MlRUYzUzVlFPZWZhSVIwK0dzZwp4dVgyYXNTNWFkRUZMb0ZkNlRkTEFEVDZMU1pDYlpKd0VyT2ZobW4rVU84Q2k5MFFEbmR1elExYjRNL1B0ZVRzCjIrU1FNMTloZGlpdGc2b2MwMk1EYTlrSW9RcUxQekJWVU83Ni9BcksvakJOTFZLenZ2VTk2NCtyV2dsK2JCQm4KUFVMUlltU0dCOTh1QjVSdzZXeFpuSS9XNC9ua3F5UEFwQnJmaTBweXA3eGVTNkdLWjBuUEpuZ3VreWk3UkFFQwpnY0VBNW9tbzIwUzUza3BnYXFVZ3JHVUsrVjVVREJNZW1sbVlZR2d5ZkpIUnNPZjRhZXZ6dWNPMGFwbkI3UkRyCjNkZGdvZzZpdHNHdjZWUlpKODZHd1ZKWERreFhzbk5paDJRaWM4aWt3NnJwMXNWTTFUbFZQWDdTQVpTZStKdjMKT0ZOZ0t4ZXJvTTFnK0J2SDBCKysrQXBYcXl1dkZ6aXdBdW9YWGNRcHBocjRWR2J5TWtwRE5abWVjQjUxMDh0Ugo0dC8vdEprS1lrTk4xQXhxSXBZUGE5K1ZnOXZiaU1za1dxMk85MGY0UEtRLzBmWjNQeDNia0dtVDZ3STdVRGZkCjFtVlpBb0hCQU05RThCUVp1SHN6TGpwTDY4aVQ1U1pSakg3Z211UHFTNGQzeWRZSWlSS0dQOTlZbk1MUUhla20KR2RRaHFqUzhBb1JnT2hDY1R4ODBPTVpmRGJVYWQ1d2JQYUk5ZTNmWWNUNEdDMGhyWkdsNkVZNHhWVmtFcUdXNApZVUtMU2h6aGxWOVE3K1pGQzBKaFNXWTY5TjRuN2M5MTlzc1U4Uzl5bm9xRERzcHFiMEpRNnBZYVJGMHU2Nml1CnFqODBKVEdmU1JhSm5OdmU2VE1lZ3dudzNka3hyWmlZQnY2TEJCWFF3ai96Si9LQUgrOVROR1VqZ1lVRTAxNysKcGp6SndBRnFRUUtCd1FEZm5JYjhxQnpoVUtOVXpmWnpRVTd6c2xzem14Z0Qvd09kLzNONUFMZTBNRXp6OExubgpaYnlKNmJvQWlIbEFKTGpHZUF1NzJRTVgvNGk2NDhneG0veDFFZmUrVDgweUpoNkUwQW1CQVRidjYxQXJRZ0U4Ck5OYmVVWm9nNnFkUkt3NE12bGpyRUVzT1hXUGlxK2hBRDBnWjc3VlZnTmE0L1BiTkxJaDVaWStaem9EOTVxcHEKUXljNitWQ3dybll1NmJiTkplUzhpeXZpa21nZ1JBMlJSTDF4dUwrb1grSlRVaVZxRlpUaXZTNXFLZlpnY2tXVwpQZElNRVk0V3NSbXI2NEVDZ2NFQWd6bE9GaXZDbEoxdW94SDJFV014TFBWc1VkZTV1SnBaZjBianpsSlJGaDFRCnl3SzdITXZPWkJIdlFGS2dCQXNVUE9ML1lBeldPeGRBNnJhN1l2R0MwSjZlZ3QwU0VtcENKOWFEeGpIWHZMKy8KNVpwdVFwR2tXK0pFRVhGR1ZzcXJXMUZPMFNiZFhnVmlCd3RFaEhJYktjR3hvaGw4S1dJVDVmWGJvMk9IVlNFTgpwRUsxRFpuck1UeUVKTWZLMUlQWUxpQ3A0cnBhUWpjTEYzd2J1S3F2RVhFTzNKRCs0U0R1R3JiRGo5QjJaM3J5CkxTWXhsaG5jQ01TSVV1d1lWODBCQW9IQUh6TXFwQ1A4d2Vma0ZBYUN4N09mOEZ5SDQ0WGx3cVFTeG9HbTNUK1cKQUIxVGhucEdtQU82ZU5hVmE2Tkd4WGVhMnIycEtmcTJUSitVYnFnSE1sek53YXFrbTB3OFpqamtDbDlGMXRQQgp6RFBrTlNlMEc5UzM0OHFWRUQ4Sk5VakdEYWppK2QrWXNMZ3pUSDJnWGVQVVJkV0tvNy8ybVB3b2xqa29ZZDJ2ClpHcVRrNWpxRmZvaE9sNnZodmZVTEVDTHk3L3MxVTc4OHBGenB2ZS85OFhmd0JOMDBDZktsU2lkbFN4SmFLQm4Kc0tNTENpNStrcDB1R0lwZjA3OEFvTTZTCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0= 17 | -------------------------------------------------------------------------------- /k8s/distributions/kind/infrastructure/controllers/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - ../../../../bases/infrastructure/controllers/ 6 | -------------------------------------------------------------------------------- /k8s/distributions/kind/infrastructure/controllers/traefik/patches/helm-release-patch.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: helm.toolkit.fluxcd.io/v2 3 | kind: HelmRelease 4 | metadata: 5 | name: traefik 6 | namespace: traefik 7 | spec: 8 | # https://github.com/traefik/traefik-helm-chart/blob/master/traefik/values.yaml 9 | values: 10 | nodeSelector: 11 | ingress-ready: 'true' 12 | ports: 13 | web: 14 | nodePort: 30000 15 | websecure: 16 | nodePort: 30001 17 | -------------------------------------------------------------------------------- /k8s/distributions/kind/infrastructure/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - ../../../bases/infrastructure/ 6 | - cluster-issuers/ 7 | patches: 8 | - target: 9 | kind: HelmRelease 10 | name: metrics-server 11 | namespace: kube-system 12 | path: metrics-server/patches/helm-release-patch.yaml 13 | -------------------------------------------------------------------------------- /k8s/distributions/kind/infrastructure/metrics-server/patches/helm-release-patch.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: helm.toolkit.fluxcd.io/v2 3 | kind: HelmRelease 4 | metadata: 5 | name: metrics-server 6 | namespace: kube-system 7 | spec: 8 | # https://github.com/kubernetes-sigs/metrics-server/blob/master/charts/metrics-server/values.yaml 9 | values: 10 | args: 11 | - --kubelet-insecure-tls 12 | -------------------------------------------------------------------------------- /k8s/distributions/kind/variables/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - ../../../bases/variables 6 | -------------------------------------------------------------------------------- /k8s/distributions/omni/apps/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - ../../../bases/apps/ 6 | -------------------------------------------------------------------------------- /k8s/distributions/omni/infrastructure/cloudflared/README.md: -------------------------------------------------------------------------------- 1 | # Cloudflared 2 | 3 | Cloudflared is a tunneling daemon based on Wireguard that can proxy a local webserver through the Cloudflare network. It is used to make the local Kubernetes cluster available on the internet. 4 | 5 | - [Documentation](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/) 6 | - [Helm Chart](https://github.com/cloudflare/helm-charts) 7 | -------------------------------------------------------------------------------- /k8s/distributions/omni/infrastructure/cloudflared/helm-release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2 2 | kind: HelmRelease 3 | metadata: 4 | name: cloudflared 5 | namespace: cloudflared 6 | labels: 7 | helm.toolkit.fluxcd.io/helm-test: enabled 8 | helm.toolkit.fluxcd.io/remediation: enabled 9 | spec: 10 | interval: 10m 11 | chart: 12 | spec: 13 | chart: cloudflare-tunnel-remote 14 | version: 0.1.2 15 | sourceRef: 16 | kind: HelmRepository 17 | name: cloudflared 18 | # https://github.com/cloudflare/helm-charts/blob/main/charts/cloudflare-tunnel-remote/values.yaml 19 | values: 20 | cloudflare: 21 | tunnel_token: ${cloudflared_tunnel_token} 22 | -------------------------------------------------------------------------------- /k8s/distributions/omni/infrastructure/cloudflared/helm-repository.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1 2 | kind: HelmRepository 3 | metadata: 4 | name: cloudflared 5 | namespace: cloudflared 6 | spec: 7 | url: https://cloudflare.github.io/helm-charts 8 | -------------------------------------------------------------------------------- /k8s/distributions/omni/infrastructure/cloudflared/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - namespace.yaml 5 | - helm-release.yaml 6 | - helm-repository.yaml 7 | -------------------------------------------------------------------------------- /k8s/distributions/omni/infrastructure/cloudflared/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: cloudflared 5 | labels: 6 | goldilocks.fairwinds.com/vpa-update-mode: "auto" 7 | goldilocks.fairwinds.com/vpa-min-replicas: "2" 8 | -------------------------------------------------------------------------------- /k8s/distributions/omni/infrastructure/cluster-issuers/cloudflare-origin-issuer.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.k8s.cloudflare.com/v1 2 | kind: ClusterOriginIssuer 3 | metadata: 4 | name: cloudflare-origin 5 | spec: 6 | requestType: OriginECC 7 | auth: 8 | tokenRef: 9 | name: cloudflare-api-token 10 | key: api-token 11 | --- 12 | apiVersion: v1 13 | kind: Secret 14 | metadata: 15 | name: cloudflare-api-token 16 | namespace: cert-manager 17 | type: Opaque 18 | stringData: 19 | api-token: ${cloudflare_api_token} 20 | -------------------------------------------------------------------------------- /k8s/distributions/omni/infrastructure/cluster-issuers/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - cloudflare-origin-issuer.yaml 5 | -------------------------------------------------------------------------------- /k8s/distributions/omni/infrastructure/controllers/cilium/patches/helm-release-patch.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: helm.toolkit.fluxcd.io/v2 3 | kind: HelmRelease 4 | metadata: 5 | name: cilium 6 | namespace: kube-system 7 | spec: 8 | # https://github.com/cilium/cilium/blob/main/install/kubernetes/cilium/values.yaml 9 | values: 10 | securityContext: 11 | capabilities: 12 | ciliumAgent: 13 | - CHOWN 14 | - KILL 15 | - NET_ADMIN 16 | - NET_RAW 17 | - IPC_LOCK 18 | - SYS_ADMIN 19 | - SYS_RESOURCE 20 | - DAC_OVERRIDE 21 | - FOWNER 22 | - SETGID 23 | - SETUID 24 | cleanCiliumState: 25 | - NET_ADMIN 26 | - SYS_ADMIN 27 | - SYS_RESOURCE 28 | cgroup: 29 | autoMount: 30 | enabled: false 31 | hostRoot: /sys/fs/cgroup 32 | k8sServiceHost: localhost 33 | k8sServicePort: 7445 34 | -------------------------------------------------------------------------------- /k8s/distributions/omni/infrastructure/controllers/hcloud-csi/hcloud-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: hcloud 5 | namespace: kube-system 6 | stringData: 7 | token: ${hcloud_token} 8 | network: default 9 | -------------------------------------------------------------------------------- /k8s/distributions/omni/infrastructure/controllers/hcloud-csi/helm-release.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: helm.toolkit.fluxcd.io/v2 3 | kind: HelmRelease 4 | metadata: 5 | name: hcloud-csi 6 | namespace: kube-system 7 | labels: 8 | helm.toolkit.fluxcd.io/helm-test: enabled 9 | helm.toolkit.fluxcd.io/remediation: enabled 10 | spec: 11 | chart: 12 | spec: 13 | chart: hcloud-csi 14 | version: 2.15.0 15 | sourceRef: 16 | kind: HelmRepository 17 | name: hcloud 18 | interval: 10m0s 19 | # https://github.com/hetznercloud/csi-driver/blob/main/chart/values.yaml 20 | values: 21 | global: 22 | enableProvidedByTopology: true 23 | controller: 24 | hcloudVolumeDefaultLocation: fsn1 25 | node: 26 | affinity: 27 | nodeAffinity: 28 | requiredDuringSchedulingIgnoredDuringExecution: 29 | nodeSelectorTerms: 30 | - matchExpressions: 31 | - key: "instance.hetzner.cloud/is-root-server" 32 | operator: NotIn 33 | values: 34 | - "true" 35 | - key: "instance.hetzner.cloud/provided-by" 36 | operator: Exists 37 | - key: "instance.hetzner.cloud/provided-by" 38 | operator: NotIn 39 | values: 40 | - "robot" 41 | storageClasses: 42 | - name: hcloud 43 | defaultStorageClass: true 44 | reclaimPolicy: Delete 45 | extraParameters: 46 | csi.storage.k8s.io/node-publish-secret-name: luks-encryption 47 | csi.storage.k8s.io/node-publish-secret-namespace: kube-system 48 | -------------------------------------------------------------------------------- /k8s/distributions/omni/infrastructure/controllers/hcloud-csi/helm-repository.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: source.toolkit.fluxcd.io/v1 3 | kind: HelmRepository 4 | metadata: 5 | name: hcloud 6 | namespace: kube-system 7 | spec: 8 | url: https://charts.hetzner.cloud 9 | -------------------------------------------------------------------------------- /k8s/distributions/omni/infrastructure/controllers/hcloud-csi/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - hcloud-secret.yaml 6 | - helm-release.yaml 7 | - helm-repository.yaml 8 | - luks-encryption-secret.enc.yaml 9 | -------------------------------------------------------------------------------- /k8s/distributions/omni/infrastructure/controllers/hcloud-csi/luks-encryption-secret.enc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: luks-encryption 5 | namespace: kube-system 6 | stringData: 7 | encryption-passphrase: ENC[AES256_GCM,data:Qnxf9BPhb5DQuhNfd1+Wb9vqyUs=,iv:oX4VJ6B4Cf/Pl/z6JmU+LQ61lMXXUSHJr/fOdjed5qI=,tag:BBlpoeJWYxmAwmOudWxRvg==,type:str] 8 | sops: 9 | age: 10 | - recipient: age14skmde00w0ps6u8asm4rdqwpktr5m5pq84070yzwvjjmcyfnl4ushfn5uq 11 | enc: | 12 | -----BEGIN AGE ENCRYPTED FILE----- 13 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBIT0JWZUN5TWx4b2V1WGlY 14 | ejF2azBMVkVHclEzQ0Y3WDNRNlk0TVNZV0RRCllYYWxMaHZpVjEzZkJ1cGlNVGxX 15 | eXV3SEdyY0lGQm9ySkd1YnJ5Qk82cWsKLS0tIHRVMXVQTW1WeXJ5bnBuZ2N2bGlJ 16 | SXdDVG90eDlFdGxQYUNobFJ1SFJ4ZGMK2QNOneaLR6bMOeU2YSj9SRiw4fEHo9vk 17 | TL5pOf5ILI8kgN2mMspJZJU0PJyEQ6yznhj7B69yVwhFimVqA5fCdw== 18 | -----END AGE ENCRYPTED FILE----- 19 | - recipient: age188ez3ur89qj7pmnyyqhcp9nmxp7lvsa72plph0frkfh9tt7n5guqs0vz6c 20 | enc: | 21 | -----BEGIN AGE ENCRYPTED FILE----- 22 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNOHZ3NDZYUE1pRHZmYmF0 23 | VzQ5cE0ycWpKa25veFFXUHcxRm81TGFKemdJClF2OFVBVEUyK1RvU084Nk5kdWFn 24 | OGxQVXE3bzRkbStwa3JJbVZkbDN1WDQKLS0tIGtxUU1oN3dXL2hNSDBKNU1GUkRy 25 | KzdTQ1J5b3lyQXcrYTNMWjIwS2pxeVUK3Y5hMi03ange0fSas9axCc5sLFhfNEgr 26 | eDKojXF6/oQY2MIorF4I2L/h6qkQM02UENKc8Z9UlVO3yLRSyNSmVQ== 27 | -----END AGE ENCRYPTED FILE----- 28 | - recipient: age1rk6fs67kly3h4zux5za429z3grjtvs8vcunav4sa28pxk738najsk8wgs6 29 | enc: | 30 | -----BEGIN AGE ENCRYPTED FILE----- 31 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwMVlkQTlNdnpQNlEwZldh 32 | RDBHVjdDSVd5L2N5dVpTMnNlM2hjaEJQWG5ZCit4VzBSdGIya2pDMlY1akRnNG5u 33 | M0xRdC9TNkNpTUJxa1M0Q3g0T2tZNEUKLS0tIFVrRFZTN0gvNVlWVjBKN2l2SUZL 34 | b0tFQWg4a3g2b21RdUxNMEo1bnJ3Rk0Kouuqspfc4iIxowWWIVzG6XcrmazZK5cZ 35 | fPau3qU7rBFRwVtNA4YqtGlaFpp9IcATQCS8BcdwBghJNW19YKnTCg== 36 | -----END AGE ENCRYPTED FILE----- 37 | lastmodified: "2025-05-31T14:28:41Z" 38 | mac: ENC[AES256_GCM,data:speVnPX6Q9CR60IoGHFuhdMpPfg3D78CfGedEvkJzkE4ai+exUnXKe3J3004hc/PXcnUn2MS7NeI+R0Q8/PPloOSH3NqDH6YCuJr5wjzIPSysKpKIoEmfYGouwySnrzfdW4YVCOag+8OOWoWqZRpE1lK5cWNGa3gHcwLkxoekQo=,iv:f+/FIaD6EtknsPCcWvUCrO+GAQxxztFH0wvG4aaaEQE=,tag:rMbt1+reNfsP6l/7x55LuA==,type:str] 39 | encrypted_regex: ^(data|stringData)$ 40 | version: 3.10.2 41 | -------------------------------------------------------------------------------- /k8s/distributions/omni/infrastructure/controllers/kubelet-serving-cert-approver/README.md: -------------------------------------------------------------------------------- 1 | # Kubelet Serving Cert Approver 2 | 3 | A custom approving controller that approves `kubernetes.io/kubelet-serving` Certificate Signing Request that kubelet uses to serve TLS endpoints. 4 | 5 | - [Documentation](https://github.com/alex1989hu/kubelet-serving-cert-approver) 6 | -------------------------------------------------------------------------------- /k8s/distributions/omni/infrastructure/controllers/kubelet-serving-cert-approver/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - https://raw.githubusercontent.com/alex1989hu/kubelet-serving-cert-approver/main/deploy/standalone-install.yaml 5 | -------------------------------------------------------------------------------- /k8s/distributions/omni/infrastructure/controllers/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - ../../../../bases/infrastructure/controllers/ 6 | - hcloud-csi/ 7 | - kubelet-serving-cert-approver/ 8 | - origin-ca-issuer/ 9 | patches: 10 | - target: 11 | kind: HelmRelease 12 | name: cilium 13 | namespace: kube-system 14 | path: cilium/patches/helm-release-patch.yaml 15 | -------------------------------------------------------------------------------- /k8s/distributions/omni/infrastructure/controllers/origin-ca-issuer/helm-release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2 2 | kind: HelmRelease 3 | metadata: 4 | name: origin-ca-issuer 5 | namespace: cert-manager 6 | spec: 7 | interval: 10m 8 | chart: 9 | spec: 10 | chart: origin-ca-issuer 11 | version: 0.5.12 12 | sourceRef: 13 | kind: HelmRepository 14 | name: origin-ca-issuer 15 | # https://github.com/cloudflare/origin-ca-issuer/blob/trunk/deploy/charts/origin-ca-issuer/values.yaml 16 | values: {} 17 | -------------------------------------------------------------------------------- /k8s/distributions/omni/infrastructure/controllers/origin-ca-issuer/helm-repository.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1 2 | kind: HelmRepository 3 | metadata: 4 | name: origin-ca-issuer 5 | namespace: cert-manager 6 | spec: 7 | url: oci://ghcr.io/cloudflare/origin-ca-issuer-charts 8 | type: oci 9 | -------------------------------------------------------------------------------- /k8s/distributions/omni/infrastructure/controllers/origin-ca-issuer/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - helm-release.yaml 5 | - helm-repository.yaml 6 | - https://raw.githubusercontent.com/cloudflare/origin-ca-issuer/trunk/deploy/crds/cert-manager.k8s.cloudflare.com_clusteroriginissuers.yaml 7 | - https://raw.githubusercontent.com/cloudflare/origin-ca-issuer/trunk/deploy/crds/cert-manager.k8s.cloudflare.com_originissuers.yaml 8 | -------------------------------------------------------------------------------- /k8s/distributions/omni/infrastructure/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - ../../../bases/infrastructure/ 6 | - cloudflared/ 7 | - cluster-issuers/ 8 | -------------------------------------------------------------------------------- /k8s/distributions/omni/variables/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - ../../../bases/variables/ 6 | -------------------------------------------------------------------------------- /kind.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | kind: Cluster 3 | apiVersion: kind.x-k8s.io/v1alpha4 4 | name: local 5 | nodes: 6 | - role: control-plane 7 | - role: worker 8 | kubeadmConfigPatches: 9 | - | 10 | kind: InitConfiguration 11 | nodeRegistration: 12 | kubeletExtraArgs: 13 | node-labels: "ingress-ready=true" 14 | extraPortMappings: 15 | - containerPort: 30000 16 | hostPort: 80 17 | protocol: TCP 18 | - containerPort: 30001 19 | hostPort: 443 20 | protocol: TCP 21 | - role: worker 22 | - role: worker 23 | networking: 24 | disableDefaultCNI: true 25 | containerdConfigPatches: 26 | - >- 27 | [plugins."io.containerd.grpc.v1.cri".registry] 28 | config_path = "/etc/containerd/certs.d" 29 | -------------------------------------------------------------------------------- /ksail.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: ksail.io/v1alpha1 3 | kind: Cluster 4 | metadata: 5 | name: local 6 | spec: 7 | connection: 8 | context: kind-local 9 | timeout: 7m 10 | project: 11 | kustomizationPath: k8s/clusters/local 12 | deploymentTool: Flux 13 | cni: Cilium 14 | ingressController: Traefik 15 | secretManager: SOPS 16 | -------------------------------------------------------------------------------- /talos/cluster/allow-scheduling-on-control-planes.yaml: -------------------------------------------------------------------------------- 1 | cluster: 2 | allowSchedulingOnControlPlanes: true 3 | -------------------------------------------------------------------------------- /talos/cluster/apparmor.yaml: -------------------------------------------------------------------------------- 1 | machine: 2 | install: 3 | extraKernelArgs: 4 | - security=apparmor 5 | -------------------------------------------------------------------------------- /talos/cluster/cni.yaml: -------------------------------------------------------------------------------- 1 | cluster: 2 | network: 3 | cni: 4 | name: none 5 | proxy: 6 | disabled: true 7 | -------------------------------------------------------------------------------- /talos/cluster/kubespan.yaml: -------------------------------------------------------------------------------- 1 | machine: 2 | network: 3 | kubespan: 4 | enabled: true 5 | -------------------------------------------------------------------------------- /talos/cluster/mirror-registries.yaml: -------------------------------------------------------------------------------- 1 | machine: 2 | registries: 3 | mirrors: 4 | docker.io: 5 | endpoints: 6 | - https://harbor.devantler.tech/v2/docker.io-proxy 7 | - https://registry-1.docker.io 8 | overridePath: true 9 | gcr.io: 10 | endpoints: 11 | - https://harbor.devantler.tech/v2/gcr.io-proxy 12 | - https://gcr.io 13 | overridePath: true 14 | ghcr.io: 15 | endpoints: 16 | - https://harbor.devantler.tech/v2/ghcr.io-proxy 17 | - https://ghcr.io 18 | overridePath: true 19 | quay.io: 20 | endpoints: 21 | - https://harbor.devantler.tech/v2/quay.io-proxy 22 | - https://quay.io 23 | overridePath: true 24 | registry.k8s.io: 25 | endpoints: 26 | - https://harbor.devantler.tech/v2/registry.k8s.io-proxy 27 | - https://registry.k8s.io 28 | overridePath: true 29 | mcr.microsoft.com: 30 | endpoints: 31 | - https://harbor.devantler.tech/v2/mcr.microsoft.com-proxy 32 | - https://mcr.microsoft.com 33 | config: 34 | harbor.devantler.tech: 35 | auth: 36 | username: admin 37 | password: 38 | -------------------------------------------------------------------------------- /talos/cluster/rotate-server-certificates.yaml: -------------------------------------------------------------------------------- 1 | machine: 2 | kubelet: 3 | extraArgs: 4 | rotate-server-certificates: "true" 5 | -------------------------------------------------------------------------------- /talos/cluster/sysctls.yaml: -------------------------------------------------------------------------------- 1 | machine: 2 | sysctls: 3 | net.core.rmem_max: "7500000" 4 | net.core.wmem_max: "7500000" 5 | -------------------------------------------------------------------------------- /talos/cluster/user-namespaces.yaml: -------------------------------------------------------------------------------- 1 | cluster: 2 | apiServer: 3 | extraArgs: 4 | feature-gates: UserNamespacesSupport=true,UserNamespacesPodSecurityStandards=true 5 | machine: 6 | sysctls: 7 | user.max_user_namespaces: "11255" 8 | kubelet: 9 | extraConfig: 10 | featureGates: 11 | UserNamespacesSupport: true 12 | UserNamespacesPodSecurityStandards: true 13 | -------------------------------------------------------------------------------- /talos/control-planes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devantler-tech/platform/c920b5fa20f33d8ad4473bdb7b23f994cbb91f64/talos/control-planes/.gitkeep -------------------------------------------------------------------------------- /talos/workers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devantler-tech/platform/c920b5fa20f33d8ad4473bdb7b23f994cbb91f64/talos/workers/.gitkeep --------------------------------------------------------------------------------