My homelab, managed with GitOps using Terraform, Ansible, and ArgoCD on my k3s cluster.
Dependency updates are handled via Renovate with it's respective configuration.
The following tools are required to be installed locally for all sections to function properly.
kubectl
helm
ansible
terraform
(Optional)jq
yq
All cloud resources are configured via Terraform with their respective states stored in Terraform Cloud. Changes to the terraform/
directory will be detected and deployed automatically via the Terraform workflow.
System configurations are managed via Ansible and is used for any "bare metal" operations (including setting up the k3s cluster itself). There is no form of automatic deployment for files in the ansible/
directory; any updates will need to be deployed manually.
cd ansible/
ansible-playbook --vault-password-file ansible_vault.key -i inventory all.yaml
Secrets are managed via 1Password using the 1Password Connect Kubernetes Operator. Since other applications make use of this, we must install it manually the first time.
Create the Namespace for 1Password Connect Operator.
kubectl create namespace op-connect
Create the Secrets containing your 1password-credentials.json
and token (we Base64 encode the file because it's passed to 1Password through environment variables and gets decoded by the Operator)
kubectl create -n op-connect secret generic onepassword-token --from-literal=token=<your token here>
kubectl create -n op-connect secret generic op-credentials --from-literal=1password-credentials.json=$(base64 -w0 1password-credentials.json)
Install the 1Password Connect Operator.
helm repo add 1password https://1password.github.io/connect-helm-charts
helm repo update
OP_VERSION=$(cat k8s/deploy/op-connect/Chart.yaml | yq -r '.dependencies[0].version')
helm upgrade --install op-connect 1password/connect \
--version "$OP_VERSION" \
--set operator.create=true \
--namespace op-connect \
--create-namespace \
--atomic
Everything is deployed through ArgoCD, including ArgoCD itself. However, we must manually deploy it the first time before it can start to track it's own changes.
Because of how the ArgoCD Helm Chart is setup, it is not possible to inject the admin
password during setup.
helm repo add argo https://argoproj.github.io/argo-helm
helm repo update
ARGO_VERSION=$(cat k8s/deploy/argocd/Chart.yaml | yq -r '.dependencies[0].version')
helm upgrade --install argocd argo/argo-cd \
--version "$ARGO_VERSION" \
--namespace argocd \
--create-namespace \
--atomic
Get the default random admin
password:
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
There are a few secrets and data that needs to be configured before deploying any applications. These secrets are included via OnePasswordItem
CR's in the k8s/prep
folder.
for dir in k8s/prep/*; do
kubectl apply -f "$dir"
done
Each application is listed in the k8s/apps
folder, including "system" apps. Applications are deployed through ArgoCD and will track changes through it once initially configured. The deployments themselves are all stored in the k8s/deploy
folder and future changes are automatically picked up via ArgoCD.
kubectl apply -f k8s/apps/<app>.yaml
When initially setting up the Cluster, the order of how each component is deployed will matter since some componentes depend on one another.
# Core components
kubectl apply -f k8s/apps/op-connect.yaml
kubectl apply -f k8s/apps/metallb.yaml
kubectl apply -f k8s/apps/cert-manager.yaml
kubectl apply -f k8s/apps/external-dns.yaml
kubectl apply -f k8s/apps/ingress-nginx.yaml
kubectl apply -f k8s/apps/linkerd.yaml
# Storage
kubectl apply -f k8s/apps/snapshot-controller.yaml
kubectl apply -f k8s/apps/synology-csi.yaml
kubectl apply -f k8s/apps/longhorn.yaml
kubectl apply -f k8s/apps/nfs-subdir-external-provisioner.yaml
# System applications
kubectl apply -f k8s/apps/grafana.yaml
kubectl apply -f k8s/apps/loki.yaml
kubectl apply -f k8s/apps/promtail.yaml
kubectl apply -f k8s/apps/policy-controller.yaml
kubectl apply -f k8s/apps/node-problem-detector.yaml
kubectl apply -f k8s/apps/metrics-server.yaml
kubectl apply -f k8s/apps/descheduler.yaml
kubectl apply -f k8s/apps/argocd.yaml
# User applications
kubectl apply -f k8s/apps/bitwarden.yaml
kubectl apply -f k8s/apps/heimdall.yaml
kubectl apply -f k8s/apps/home-assistant.yaml
kubectl apply -f k8s/apps/mqtt.yaml
kubectl apply -f k8s/apps/starr-system.yaml
kubectl apply -f k8s/apps/thelounge.yaml
kubectl apply -f k8s/apps/unifi.yaml
kubectl apply -f k8s/apps/uptime-kuma.yaml
Feel free to contribute and make things better by opening an Issue or Pull Request.
See LICENSE.