{"id":21929184,"url":"https://github.com/achetronic/homelab-ops","last_synced_at":"2025-04-19T17:51:59.461Z","repository":{"id":196814695,"uuid":"612446533","full_name":"achetronic/homelab-ops","owner":"achetronic","description":"Mono repository to manage the super-pro infrastructure 🌠 present at my home 🏡","archived":false,"fork":false,"pushed_at":"2025-02-13T23:23:44.000Z","size":13178,"stargazers_count":10,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-13T01:36:40.096Z","etag":null,"topics":["gitops","homelab","kubernetes","kvm","libvirt","monorepo","qemu","talos","terraform"],"latest_commit_sha":null,"homepage":"","language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/achetronic.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2023-03-11T01:10:20.000Z","updated_at":"2025-02-13T23:23:48.000Z","dependencies_parsed_at":null,"dependency_job_id":"2b60759f-965c-46bf-befc-73992b4bf9d3","html_url":"https://github.com/achetronic/homelab-ops","commit_stats":null,"previous_names":["achetronic/homelab-ops"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/achetronic%2Fhomelab-ops","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/achetronic%2Fhomelab-ops/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/achetronic%2Fhomelab-ops/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/achetronic%2Fhomelab-ops/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/achetronic","download_url":"https://codeload.github.com/achetronic/homelab-ops/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249753088,"owners_count":21320664,"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":["gitops","homelab","kubernetes","kvm","libvirt","monorepo","qemu","talos","terraform"],"created_at":"2024-11-28T22:29:58.759Z","updated_at":"2025-04-19T17:51:59.455Z","avatar_url":"https://github.com/achetronic.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Homelab Ops\n\n\u003cimg src=\"https://raw.githubusercontent.com/achetronic/homelab-ops/main/docs/img/logo.png\" alt=\"Homelab Ops Logo (Main) logo.\" align=\"center\" width=\"144px\" height=\"144px\"/\u003e\n\n[//]: # (![GitHub]\u0026#40;https://img.shields.io/github/license/achetronic/homelab-ops\u0026#41;)\n\n![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UCeSb3yfsPNNVr13YsYNvCAw?label=achetronic\u0026link=http%3A%2F%2Fyoutube.com%2Fachetronic)\n![X (formerly Twitter) Follow](https://img.shields.io/twitter/follow/achetronic?style=flat\u0026logo=twitter\u0026link=https%3A%2F%2Ftwitter.com%2Fachetronic)\n\nMono repository to manage infrastructure present at my home\n\n\u003e Consider [contributing](#how-to-contribute)\n\n## 📖 Overview\n\nThis is how I manage my home lab. From infrastructure code managing base things such as: internal domains in the router\nor VMs on hypervisor; to how I manage Kubernetes clusters over that. Glue automations between all the technologies\nare covered too, as I'm too lazy to do the same twice.\n\n## 📐 Diagram\n\nTBD\n\n## 🧁 Hardware\n\n| Device      | Count | OS Disk Size | Data Disk Size | CPU Arch | CPU cores  | Ram  | Operating System              | Purpose             |\n|-------------|-------|--------------|----------------|----------|------------|------|-------------------------------|---------------------|\n| Generic     | 1     | 128G NVMe    | -              | AMD64    | 4c (4th)   | 8GB  | OPNsense                      | Router              |\n| Generic     | 1     | 128G NVMe    | -              | AMD64    | 8c (16th)  | 32GB | Ubuntu (KVM + Qemu + Libvirt) | Virtualization Host |\n| Generic     | 1     | 128G NVMe    | -              | AMD64    | 8c (16th)  | 32GB | Ubuntu (KVM + Qemu + Libvirt) | Virtualization Host |\n| Generic     | 1     | 256G NVMe    | 3x1TB HDD      | AMD64    | 8c (16th)  | 16GB | TrueNAS Scale                 | NAS                 |\n\n## 🛰️ Networking\n\n| Name                 | CIDR                                                                                          | IP range          |\n|----------------------|-----------------------------------------------------------------------------------------------|-------------------|\n| Compute Nodes        | `192.168.2.10/31`, `192.168.2.12/30`, `192.168.2.16/29`, `192.168.2.24/30`, `192.168.2.28/31` | 192.168.2.10 - 29 |\n| Storage Nodes        | `192.168.2.30/31`, `192.168.2.32/29`, `192.168.2.40/32`                                       | 192.168.2.30 - 40 |\n| Kubernetes LBs (BGP) | `192.168.2.60/30`, `192.168.2.64/28`, `192.168.2.80/32`                                       | 192.168.2.60 - 80 |\n| -                    | -                                                                                             | -                 |\n| Kubernetes pods      | `10.90.0.0/16`                                                                                |                   |\n| Kubernetes services  | `10.96.0.0/16`                                                                                |                   |\n\n## ☁️ Cloud resources\n\nWhile most of my infrastructure and workloads are self-hosted, I do rely upon the cloud for certain key parts of my setup.\nThis saves me from having to worry about several things:\n\n* Dealing with chicken/egg scenarios\n* Services I critically need to monitor my cluster\n\nThe alternative solution to these problems would be to host a Kubernetes cluster in the cloud and deploy applications\nlike [Hashicorp Vault], [Ntfy], and [Gatus].\n\nHowever, maintaining another cluster and monitoring another group of workloads is a lot more time and effort,\nwhich is not worth for a homelab.\n\n| Service      | Use                                           | Cost         |\n|--------------|-----------------------------------------------|--------------|\n| [Gitlab]     | Storing Terraform states. Storing secrets (*) | Free         |\n| [Cloudflare] | Domain, DNS and proxy management              | Free         |\n| [GitHub]     | Hosting this repository and CI/CD             | Free         |\n|              |                                               | Total: $0/mo |\n\n* *: This repo uses **Gitlab project's CI/CD variables** as a vault for infrastructure secrets, as Gitlab allows\n   storing and retrieving them by calling the API.\n\n## 🏗️ Infrastructure\n\nI use [Terraform] to provision resources in several systems.\n\nSome of them, need credentials. To know how credentials are retrieved, see [Cloud Resources](#-cloud-resources)\n\n\u003e Due to recent changes in the Terraform license, this repository will use [OpenTofu]\n\u003e in the near future as a replacement.\n\n### Terragrunt\n\n[Terragrunt] is a Terraform wrapper that provides extra tools for keeping Terraform configurations dry.\n\nThis allowed me to improve the UX related to how Terraform use environment variables or state backends\nand do less dirty tricks on Terraform code.\n\n### Router\n\nCode is used to manage router's stuff related to my rack. The key is treating the router as a networking cloud provider.\n\n* Internal domains assigned to specific machines:\n  * ARM64 SBCs, hypervisor, VMs: `compute-xx.internal.place`\n  * NAS: `storage-xx.internal.place`\n\n* Internal domains assigned to Kubernetes\n  * Ingress Controller `*.tools.internal.place`\n\n* Firewall rules: forward Wireguard traffic to Wireguard server\n\n* More things in the future. Some of them are already configured (ie: BGP to point k8s LBs to the right machines) but\n  provider currently in use is not supporting them yet.\n\nThis could change in the future as it depends on the evolution of this [OPNsense Terraform provider]:\n\nYou can inspect the code [here](infrastructure/terraform/opnsense)\n\n### Virtual Machines\n\nCode is also used to create VMs on the hypervisor. Hypervisor is using very simple and robust virtualization\ntechnologies like KVM, Qemu and Libvirt. The main advantage of managing it directly with code is using the most\navailable resources for the actual VMs.\n\nVMs were previously managed using [metal-cloud], an opensource Terraform module crafted on my own to declare\ngroups of VMs with ease on hosts that are using that stack. Those VMs are configured with cloud-init.\n\n\u003e Hey! I keep developing [metal-cloud], so if you find some bug, or whatever, please, open an issue there\n\nSome months ago I decided to migrate my Kubernetes clusters to [Talos] (immutable, configured through an API).\nSo currently I am using a different module due to Talos requires that machines are configured in a different way.\n\nYou can inspect the code [here](infrastructure/terraform/vms)\n\n## 🐳 Kubernetes\n\nMy cluster is currently using [Talos], and its configurations are applied through the official [Talos Terraform provider],\nas it allows creating and configuring clusters without intermediate manual intervention.\n\nThe cluster is called `kubernetes-01` and is running on AMD64 VMs machines hosted on a Linux hypervisor\n(KVM + QEMU + Libvirt) as compatibility is important for me. This is a semi hyper-converged cluster as workloads are\nsharing the same available resources while I have a separate server for data storage.\n\n\u003e The reason behind the numbers in the name is simply to keep the door open to create several clusters if needed.\n\n## 🤖 Automations\n\nIt's a super common practice to use a makefile and Bash scripts to automate everything.\nHowever, this is not the best way to manage automation for this repository, as there are modern ways to\ndo exactly the same. The requirements for a candidate are:\n\n* Able to use Bash scripts where needed\n* Replacing makefile with something easier to read\n* Using YAML manifests\n\nBingo! I decided to use [Taskfile]\n\nJust install the CLI from its [releases page](https://github.com/go-task/task/releases) and execute the following\ncommand from the root of the repository to list available tasks I have created for this repository:\n\n```console\ntask -l\n```\n\nTo see the scripts executed under the hoods, it's only needed to look into the right [place](Taskfile.yaml)\n(or [places](.taskfiles))\n\nThe way I organized the files implies being able to execute commands present on files into [.taskfiles](.taskfiles)\ndirectory in an independent way. At the same time, they can be combined to craft complex commands in the global scope.\nThis complex commands is what I call `glue` commands.\nThis way things are not mixed everywhere.\n\n## How to use it\n\nEvery good story starts with something small. This time is about bootstrapping everything that is needed:\n\n```console\ntask global:init\n```\n\nAfter that, it's needed to connect with Gitlab\n\n```console\ntask gitlab:login\n```\n\nWhat about getting some superpowers to provision infrastructure getting secrets from Gitlab?\n\n```console\ntask gitlab:generate-supertoken TOKEN_NAME=supertoken\n\ntask terragrunt:apply-opnsense GITLAB_ACCESS_TOKEN_NAME=supertoken\ntask terragrunt:apply-vms GITLAB_ACCESS_TOKEN_NAME=supertoken\n```\n\nThe story ending is about discovery the rest of really well documented tasks\n\n```console\ntask -l\n```\n\nOnce you have finished, don't forget about revoking your superpowers\n\n```console\ntask gitlab:revoke-token TOKEN_NAME=supertoken\ntask global:cleanup\n```\n\n## How to contribute\n\nThis repository is the final result of continuous failures so is intended to be used as a reference.\nBecause of that, code collaborations are not allowed at this point, but there are other ways to collaborate:\n\n* 🔖 Open issues to discuss what can be improved\n* 🧲 Fork the repository: use it or modify it for your own infrastructure with the half of the effort\n* 🌟 Give a star to make it more visible to others\n\n## License\n\nCopyright 2022.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\n## Special mention\n\nThis project was done using IDEs from JetBrains. They helped us to develop faster, so we recommend them a lot! 🤓\n\n\u003cimg src=\"https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.png\" alt=\"JetBrains Logo (Main) logo.\" width=\"150\"\u003e\n\n[//]: #\n\n[Taskfile]: \u003chttps://taskfile.dev/\u003e\n[Terragrunt]: \u003chttps://terragrunt.gruntwork.io/\u003e\n[metal-cloud]: \u003chttps://github.com/achetronic/metal-cloud\u003e\n[OPNsense Terraform provider]: \u003chttps://registry.terraform.io/providers/browningluke/opnsense/latest/docs\u003e\n[Talos Terraform provider]: \u003chttps://registry.terraform.io/providers/siderolabs/talos/latest/docs\u003e\n[Talos]: \u003chttps://www.talos.dev/\u003e\n[OpenTofu]: \u003chttps://github.com/opentofu/opentofu\u003e\n[Terraform]: \u003chttps://github.com/hashicorp/terraform\u003e\n[Hashicorp Vault]: \u003chttps://www.vaultproject.io/\u003e\n[Gitlab]: \u003chttps://gitlab.com\u003e\n[Cloudflare]: \u003chttps://www.cloudflare.com/\u003e\n[GitHub]: \u003chttps://github.com/\u003e\n[Ntfy]: \u003chttps://ntfy.sh/\u003e\n[Gatus]: \u003chttps://gatus.io/\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fachetronic%2Fhomelab-ops","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fachetronic%2Fhomelab-ops","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fachetronic%2Fhomelab-ops/lists"}