{"id":27137174,"url":"https://github.com/cloudwithdan/infrastructure-as-code","last_synced_at":"2026-05-02T06:39:15.154Z","repository":{"id":260518898,"uuid":"868180942","full_name":"cloudwithdan/infrastructure-as-code","owner":"cloudwithdan","description":" GitOps Configuration and documentation of my Kubernetes homelab powered by Talos and FluxCD. ","archived":false,"fork":false,"pushed_at":"2025-03-23T18:30:28.000Z","size":313,"stargazers_count":1,"open_issues_count":8,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-23T18:35:39.065Z","etag":null,"topics":["devops","flux","gitops","homelab","homeops","kubernetes","talos"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cloudwithdan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-05T17:24:54.000Z","updated_at":"2025-03-23T18:30:31.000Z","dependencies_parsed_at":"2025-01-07T22:16:02.265Z","dependency_job_id":"1f42b3d4-97b5-490f-8c81-4c28094a997f","html_url":"https://github.com/cloudwithdan/infrastructure-as-code","commit_stats":null,"previous_names":["dnikoloski/infrastructure-as-code","cloudwithdan/infrastructure-as-code"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudwithdan%2Finfrastructure-as-code","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudwithdan%2Finfrastructure-as-code/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudwithdan%2Finfrastructure-as-code/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudwithdan%2Finfrastructure-as-code/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cloudwithdan","download_url":"https://codeload.github.com/cloudwithdan/infrastructure-as-code/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247773741,"owners_count":20993633,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["devops","flux","gitops","homelab","homeops","kubernetes","talos"],"created_at":"2025-04-08T03:47:18.782Z","updated_at":"2026-05-02T06:39:10.126Z","avatar_url":"https://github.com/cloudwithdan.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n\u003cimg src=\"https://raw.githubusercontent.com/prehor/home-ops/main/docs/assets/images/home-ops-kubernetes-logo.png\" align=\"center\" width=\"144px\" height=\"144px\"/\u003e\n\n### # Homelab Infrastructure :octocat:\n\n\u003c/div\u003e\n\nThis repo contains all of the configuration and documentation of my homelab.\n\n\nThe purpose of my homelab is to learn and to have fun. Being a DevOps Engineer by day, I work with Kubernetes every day, and my homelab is the place where I can try out and learn new things. On the other hand, by self-hosting some applications, it makes me feel responsible for the entire process of deploying and maintaining an application from A to Z. It forces me to think about backup strategies, security, scalability and the ease of deployment and maintenance.\n\n## Cluster Provisioning\n\nI use [Talos Linux](https://www.talos.dev/) for Kubernetes, because it's secure, immutable, and minimal.\n\n\n## Features\n\n- [Talos](https://www.talos.dev) bare-metal K8s OS\n- Lots of [self-hosted services](./kubernetes/main/apps)\n- [Flux](https://toolkit.fluxcd.io/) GitOps with this repository ([kubernetes directory](./kubernetes))\n- [MetalLB layer 4 loadbalancing](https://metallb.io/concepts/layer2/) \n- [SOPS](https://github.com/mozilla/sops) secrets stored in Git\n- [Cloudflared HTTP tunnel](https://github.com/cloudflare/cloudflared)\n- [K8s gateway](https://github.com/ori-edge/k8s_gateway) for local DNS resolution to the cluster and [NGINX ingress controller](https://kubernetes.github.io/ingress-nginx/)\n- Both internal \u0026 external services with a service [gateway](https://github.com/ori-edge/k8s_gateway/)\n- Automatic Cloudflare DNS updates with [external-dns](./kubernetes/main/apps/network/external-dns/app/helmrelease.yaml)\n- [CloudNative-PG](https://cloudnative-pg.io/) with automatic failover\n- [kube-prometheus-stack](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack) with various Grafana dashboards\n- [Longhorn](https://longhorn.io/) cluster storage\n\n## Mainfraime Configuration\n\n### Node Details\n\n- **Node Name**: `control-plane-1`\n- **Model**:  RasberryPi 4 B\n- **Specifications**:\n  - **CPU**: Cortex-A72 4 CPU Cores\n  - **RAM**: 8 GB\n  - **Storage**: 240 GB NVMe\n\n---\n\n- **Node Name**: `worker-1`\n- **Model**:  RasberryPi 4 B\n- **Specifications**:\n  - **CPU**: Cortex-A72 4 CPU Cores\n  - **RAM**: 8 GB\n  - **Storage**: 240 GB NVMe\n\n----\n\n- **Node Name**: `worker-2`\n- **Model**:  EliteDesk 800 G4 Desktop Mini\n- **Specifications**:\n  - **CPU**: i5-8500 6 CPU Cores\n  - **RAM**: 32 GB\n  - **Storage**: 500 GB NVMe\n\n#### Setup FluxCD\n\nBootstrap Flux\n\n```sh\nkubectl apply --server-side --kustomize kubernetes/main/flux-system/app.yaml\n```\n\nAdd SOPS key to Flux\n```sh\nkubectl create secret generic sops-age \\\n  --namespace=flux-system \\ \n  --from-file=danielnikoloski_sops.agekey\n```\n\n#### DNS and Tunnel\n\nSetup a Cloudflare Tunnel.\n\n```sh\ncloudflared tunnel login\ncloudflared tunnel create cluster\n```\n\nAdd the tunnel's `credentials.json` to the value in [`cloudflared-secret`](kubernetes/apps/network/cloudflared/app/secret.sops.yaml) and tunnel ID to `cluster-secrets.sops.yaml`.\n\nAdd a Cloudflare API token with these permissions to the value in [`external-dns-secret`](kubernetes/apps/network/external-dns/app/secret.sops.yaml).\n\n- `Zone - DNS - Edit`\n- `Zone - Zone - Edit`\n- `Account - Cloudflare Tunnel - Read`\n\n### Directories\n\nThis Git repository contains the following directories under [Kubernetes](./kubernetes/). Check out [cluster-template](https://github.com/onedr0p/flux-cluster-template) for more details on how this FluxCD setup works.\n\n```sh\n📁 kubernetes\n├── 📁 main # main cluster\n│   ├── 📁 apps # applications\n│   ├── 📁 flux # core flux configuration\n└── 📁 ...\n```\n\n### Storage\n\nUpgrade Talos nodes with custom Extensions in order to make Longhorn work\n\n- Create a new image -\n[Talos Linux Image Factory](https://factory.talos.de)\n```yaml\ncustomization:\n  systemExtensions:\n    officialExtensions:\n      - siderolabs/iscsi-tools\n      - siderolabs/util-linux-tools\n```\n\nUpgrade the node (example)\n```sh\ntalosctl upgrade --image factory.talos.dev/installer/f8a903f101ce10f686476024898734bb6b36353cc4d41f348514db9004ec0a9d:v1.9.4 -n 10.0.10.20\n```\n\nEdit machine and add Data Path Mounts\n\n```yaml\nmachine:\n  kubelet:\n    extraMounts:\n      - destination: /var/lib/longhorn\n        type: bind\n        source: /var/lib/longhorn\n        options:\n          - bind\n          - rshared\n          - rw\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudwithdan%2Finfrastructure-as-code","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcloudwithdan%2Finfrastructure-as-code","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudwithdan%2Finfrastructure-as-code/lists"}