diff --git a/.gitignore b/.gitignore
index e001399d1..f191ab31e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,7 +7,7 @@ roles/*
!roles/fans/*
!roles/fans
*.retry
-ansible/kubeconfig
+metal/kubeconfig
master.key
.kube
bin/
diff --git a/LICENSE b/LICENSE
index 23b4ea9eb..c67222b6e 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2020 Paweł Krupa (@paulfantom)
+Copyright (c) 2020-2022 Paweł Krupa (@paulfantom)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index 93631ed74..75fd901fa 100644
--- a/README.md
+++ b/README.md
@@ -1,31 +1,165 @@
# Ankhmorpork
-## What is it?
+
+[![license](https://img.shields.io/github/license/thaum-xyz/ankhmorpork?style=flat-square&logo=mit&logoColor=white)](https://github.com/thaum-xyz/ankhmorpork/blob/master/LICENSE)
-This is a part of [@paulfantom](https://github.com/paulfantom) personal homelab. It is on purpose made public to be used as:
-- a configuration example
-- a proof that cluster configuration can live in the open and be secure
+This project utilizes [Infrastructure as Code](https://en.wikipedia.org/wiki/Infrastructure_as_code) to automate provisioning, operating, and updating self-hosted services in [@paulfantom](https://github.com/paulfantom) homelab.
-## How dos it work?
+## Overview
-Configuration is divided into three directories and is managed in two ways - either by ansible or by flux.
+This section provides a high level overview of the project.
+For further information, please see the [documentation](https://homelab.khuedoan.com).
-#### Ansible
+### Hardware
-Ansible is used to manage services which were easier to operate out of kubernetes cluster or putting them into a cluster
-would cause a circular dependency issue. Most of ansible code is related to hardening base operating system, setting up
-storage and bootstraping a k3s cluster.
+
-#### Base
+- 2 × Raspberry Pi 4B:
+ - CPU: `Broadcom BCM2711 64-bit 1.5GHz quad core`
+ - RAM: `4GB`
+ - Disk: `50GB SSD`
+- 2 x Raspberry Pi 3B+:
+ - CPU: `Broadcom BCM2837 64-bit 1.4GHz quad core`
+ - RAM: `1GB`
+ - Disk: `32GB SD card`
+- 1 x Custom-built Server
+ - CPU: `AMD Ryzen 5 3600`
+ - RAM: `64GB`
+ - Disk: `120GB NVMe + 1x 500GB SSD`
+ - GPU: `Palit GeForce GTX 1050Ti KalmX`
+- QNAP TS-431DeU
+ - Main storage: `4x HDD in RAID 5`
+ - Storage cache: `2x SSD in RAID 1`
+- Unifi US-16-PoE switch:
+ - Ports: `16` GbE + `2` SFP
+ - Speed: `1000Mbps`
+- Unifi Dream Machine Pro
+ - Ports: `8` GbE + `2` SFP+
-Directory contains all base application of k3s cluster. Initial bootstrap should be done manually with kubectl and after
-that updates are performed by flux.
+### Features
-Additionally it is a place where flux apps and projects are stored.
+Project status: **Alpha**
-#### Apps
+- [x] Common applications: Gitea, Seafile, Jellyfin, Paperless...
+- [x] Automated Kubernetes installation and management
+- [x] Monitoring and alerting
+- [x] Modular architecture, easy to add or remove features/components
+- [x] Automated certificate management
+- [x] Installing and managing applications using GitOps
+- [x] CI/CD platform
+- [ ] Automatically update DNS records for exposed services 🚧
+- [ ] Distributed storage 🚧
+- [ ] Automated bare metal provisioning with PXE boot 🚧
+- [ ] Support multiple environments (dev, stag, prod) 🚧
+- [ ] Automated offsite backups 🚧
+- [ ] Single sign-on 🚧
-Every other service that is installed into a cluster goes into `apps/` directory which should be governed by flux.
+Screenshots of some user-facing applications are shown here, I will update them before each release.
+They can't capture all of the project's features, but they are sufficient to get a concept of it.
+
+### Tech stack
+
+
+
+ Logo |
+ Name |
+ Description |
+
+
+ |
+ Ansible |
+ Automate bare metal provisioning and configuration |
+
+
+ |
+ Flux |
+ GitOps tool built to deploy applications to Kubernetes |
+
+
+ |
+ cert-manager |
+ Cloud native certificate management |
+
+
+ |
+ Cloudflare |
+ DNS |
+
+
+ |
+ Grafana |
+ Operational dashboards |
+
+
+ |
+ Prometheus |
+ Infrastructure monitoring |
+
+
+ |
+ Parca |
+ Continuous profiling |
+
+
+ |
+ Jsonnet |
+ Data templating language |
+
+
+ |
+ K3s |
+ Lightweight distribution of Kubernetes |
+
+
+ |
+ Kubernetes |
+ Container-orchestration system, the backbone of this project |
+
+
+ |
+ Loki |
+ Log aggregation system |
+
+
+ |
+ MetalLB |
+ Bare metal load-balancer for Kubernetes |
+
+
+ |
+ NGINX |
+ Kubernetes Ingress Controller |
+
+
+ |
+ Prometheus |
+ Systems monitoring and alerting toolkit |
+
+
+ |
+ Ubuntu |
+ Base OS for Kubernetes nodes |
+
+
+ |
+ GitHub Actions |
+ CI system |
+
+
+ |
+ SealedSecrets |
+ Secrets and encryption management system |
+
+
+ |
+ kured |
+ Kubernetes Reboot Daemon |
+
+
+
+## Contributing
+
+Any contributions you make, either big or small, are greatly appreciated.
## Security
@@ -34,3 +168,17 @@ If you find any security issue please ping me using one of following contact med
- kubernetes slack (@paulfantom)
- freenode IRC (@paulfantom)
- email (paulfantom+security@gmail.com)
+
+## License
+
+Distributed under the MIT License. See [`LICENSE`](LICENSE) for more information.
+
+## Acknowledgements
+
+- [Repository structure from similar project by @kuedoan](https://github.com/khuedoan/homelab)
+- [README template](https://github.com/othneildrew/Best-README-Template)
+
\ No newline at end of file
diff --git a/ansible/roles/k3s-master/templates/k3s.service.j2 b/ansible/roles/k3s-master/templates/k3s.service.j2
deleted file mode 100644
index 7280a6fae..000000000
--- a/ansible/roles/k3s-master/templates/k3s.service.j2
+++ /dev/null
@@ -1,22 +0,0 @@
-[Unit]
-Description=Lightweight Kubernetes
-Documentation=https://k3s.io
-After=network-online.target
-
-[Service]
-Type=notify
-ExecStartPre=-/sbin/modprobe br_netfilter
-ExecStartPre=-/sbin/modprobe overlay
-ExecStart=/usr/local/bin/k3s server {{ k3s_extra_server_args }}
-KillMode=process
-Delegate=yes
-LimitNOFILE=infinity
-LimitNPROC=infinity
-LimitCORE=infinity
-TasksMax=infinity
-TimeoutStartSec=infinity
-Restart=always
-RestartSec=5s
-
-[Install]
-WantedBy=multi-user.target
diff --git a/ansible/roles/k3s-node/templates/k3s.service.j2 b/ansible/roles/k3s-node/templates/k3s.service.j2
deleted file mode 100644
index 6b8af7a31..000000000
--- a/ansible/roles/k3s-node/templates/k3s.service.j2
+++ /dev/null
@@ -1,22 +0,0 @@
-[Unit]
-Description=Lightweight Kubernetes
-Documentation=https://k3s.io
-After=network-online.target
-
-[Service]
-Type=notify
-ExecStartPre=-/sbin/modprobe br_netfilter
-ExecStartPre=-/sbin/modprobe overlay
-ExecStart=/usr/local/bin/k3s agent --server https://{{ k3s_master_ip }}:6443 --token {{ k3s_token }} {{ k3s_extra_agent_args }}
-KillMode=process
-Delegate=yes
-LimitNOFILE=infinity
-LimitNPROC=infinity
-LimitCORE=infinity
-TasksMax=infinity
-TimeoutStartSec=infinity
-Restart=always
-RestartSec=5s
-
-[Install]
-WantedBy=multi-user.target
diff --git a/ansible/roles/system/templates/earlyoom.j2 b/ansible/roles/system/templates/earlyoom.j2
deleted file mode 100644
index 87bf4f231..000000000
--- a/ansible/roles/system/templates/earlyoom.j2
+++ /dev/null
@@ -1,3 +0,0 @@
-# {{ ansible_managed }}
-# See more options at `earlyoom -h'
-EARLYOOM_ARGS="{{ system_earlyoom_params }}"
diff --git a/ansible/roles/system/templates/systemd-mount.j2 b/ansible/roles/system/templates/systemd-mount.j2
deleted file mode 100644
index 5e7f0bbe0..000000000
--- a/ansible/roles/system/templates/systemd-mount.j2
+++ /dev/null
@@ -1,19 +0,0 @@
-{{ ansible_managed | comment }}
-[Unit]
-Description = {{ item.description }}
-{% if item.requires is defined %}
-Requires = {{ item.requires }}
-{% endif %}
-{% if item.after is defined %}
-After = {{ item.after }}
-{% endif %}
-{% if item.before is defined %}
-Before = {{ item.before }}
-{% endif %}
-[Mount]
-What = {{ item.device }}
-Where = {{ item.mountpoint }}
-Type = {{ item.type }}
-Options = {{ item.options | default("defaults") }}
-[Install]
-WantedBy = multi-user.target
diff --git a/base/README.md b/base/README.md
new file mode 100644
index 000000000..0653155f5
--- /dev/null
+++ b/base/README.md
@@ -0,0 +1,3 @@
+# Base
+
+Directory contains base system applications running on a cluster. This can be considered a "core" of a platform and needs to be provisioned first (before applications from `apps` directory)
\ No newline at end of file
diff --git a/hack/checkimages.sh b/hack/checkimages.sh
index 0783f003f..00b43c921 100755
--- a/hack/checkimages.sh
+++ b/hack/checkimages.sh
@@ -22,6 +22,7 @@ foomo/pagespeed_exporter
ghcr.io/parca-dev/parca-agent
ghcr.io/parca-dev/parca
quay.io/paulfantom/parca
+lloesche/valheim-server
EOM
)
diff --git a/ansible/00_site.yml b/metal/00_site.yml
similarity index 100%
rename from ansible/00_site.yml
rename to metal/00_site.yml
diff --git a/ansible/01_system.yml b/metal/01_system.yml
similarity index 100%
rename from ansible/01_system.yml
rename to metal/01_system.yml
diff --git a/ansible/10_storage.yml b/metal/10_storage.yml
similarity index 100%
rename from ansible/10_storage.yml
rename to metal/10_storage.yml
diff --git a/ansible/20_nvidia.yml b/metal/20_nvidia.yml
similarity index 100%
rename from ansible/20_nvidia.yml
rename to metal/20_nvidia.yml
diff --git a/ansible/70_k3s.yml b/metal/70_k3s.yml
similarity index 100%
rename from ansible/70_k3s.yml
rename to metal/70_k3s.yml
diff --git a/metal/README.md b/metal/README.md
new file mode 100644
index 000000000..847a11fdf
--- /dev/null
+++ b/metal/README.md
@@ -0,0 +1,5 @@
+# Bare metal
+
+- Ansible is used to harden each operating system, configure system-level settings, install few monitoring components, and configure GPUs
+- Ansible bootstraps and manages k3s cluster
+- Fan controller for raspberry pi enclosure is also deployed with ansible
diff --git a/ansible/ansible.cfg b/metal/ansible.cfg
similarity index 100%
rename from ansible/ansible.cfg
rename to metal/ansible.cfg
diff --git a/ansible/group_vars/all.yml b/metal/group_vars/all.yml
similarity index 100%
rename from ansible/group_vars/all.yml
rename to metal/group_vars/all.yml
diff --git a/ansible/group_vars/k3s.yml b/metal/group_vars/k3s.yml
similarity index 100%
rename from ansible/group_vars/k3s.yml
rename to metal/group_vars/k3s.yml
diff --git a/ansible/group_vars/raspberry.yml b/metal/group_vars/raspberry.yml
similarity index 100%
rename from ansible/group_vars/raspberry.yml
rename to metal/group_vars/raspberry.yml
diff --git a/ansible/host_vars/master01.yml b/metal/host_vars/master01.yml
similarity index 100%
rename from ansible/host_vars/master01.yml
rename to metal/host_vars/master01.yml
diff --git a/ansible/host_vars/metal01.yml b/metal/host_vars/metal01.yml
similarity index 100%
rename from ansible/host_vars/metal01.yml
rename to metal/host_vars/metal01.yml
diff --git a/ansible/inventory b/metal/inventory
similarity index 100%
rename from ansible/inventory
rename to metal/inventory
diff --git a/ansible/roles/fans/files/fan.py b/metal/roles/fans/files/fan.py
similarity index 100%
rename from ansible/roles/fans/files/fan.py
rename to metal/roles/fans/files/fan.py
diff --git a/ansible/roles/fans/files/fan.service b/metal/roles/fans/files/fan.service
similarity index 100%
rename from ansible/roles/fans/files/fan.service
rename to metal/roles/fans/files/fan.service
diff --git a/ansible/roles/fans/handlers/main.yml b/metal/roles/fans/handlers/main.yml
similarity index 100%
rename from ansible/roles/fans/handlers/main.yml
rename to metal/roles/fans/handlers/main.yml
diff --git a/ansible/roles/fans/tasks/main.yml b/metal/roles/fans/tasks/main.yml
similarity index 100%
rename from ansible/roles/fans/tasks/main.yml
rename to metal/roles/fans/tasks/main.yml
diff --git a/ansible/roles/k3s-download/defaults/main.yml b/metal/roles/k3s-download/defaults/main.yml
similarity index 100%
rename from ansible/roles/k3s-download/defaults/main.yml
rename to metal/roles/k3s-download/defaults/main.yml
diff --git a/ansible/roles/k3s-download/tasks/main.yml b/metal/roles/k3s-download/tasks/main.yml
similarity index 100%
rename from ansible/roles/k3s-download/tasks/main.yml
rename to metal/roles/k3s-download/tasks/main.yml
diff --git a/ansible/roles/k3s-download/vars/main.yml b/metal/roles/k3s-download/vars/main.yml
similarity index 100%
rename from ansible/roles/k3s-download/vars/main.yml
rename to metal/roles/k3s-download/vars/main.yml
diff --git a/ansible/roles/k3s-master/defaults/main.yml b/metal/roles/k3s-master/defaults/main.yml
similarity index 100%
rename from ansible/roles/k3s-master/defaults/main.yml
rename to metal/roles/k3s-master/defaults/main.yml
diff --git a/ansible/roles/k3s-master/handlers/main.yml b/metal/roles/k3s-master/handlers/main.yml
similarity index 100%
rename from ansible/roles/k3s-master/handlers/main.yml
rename to metal/roles/k3s-master/handlers/main.yml
diff --git a/ansible/roles/k3s-master/tasks/main.yml b/metal/roles/k3s-master/tasks/main.yml
similarity index 100%
rename from ansible/roles/k3s-master/tasks/main.yml
rename to metal/roles/k3s-master/tasks/main.yml
diff --git a/ansible/roles/k3s-node/defaults/main.yml b/metal/roles/k3s-node/defaults/main.yml
similarity index 100%
rename from ansible/roles/k3s-node/defaults/main.yml
rename to metal/roles/k3s-node/defaults/main.yml
diff --git a/ansible/roles/k3s-node/tasks/main.yml b/metal/roles/k3s-node/tasks/main.yml
similarity index 100%
rename from ansible/roles/k3s-node/tasks/main.yml
rename to metal/roles/k3s-node/tasks/main.yml
diff --git a/ansible/roles/k3s-prereq/tasks/main.yml b/metal/roles/k3s-prereq/tasks/main.yml
similarity index 100%
rename from ansible/roles/k3s-prereq/tasks/main.yml
rename to metal/roles/k3s-prereq/tasks/main.yml
diff --git a/ansible/roles/requirements.yml b/metal/roles/requirements.yml
similarity index 100%
rename from ansible/roles/requirements.yml
rename to metal/roles/requirements.yml
diff --git a/ansible/roles/system/defaults/main.yml b/metal/roles/system/defaults/main.yml
similarity index 100%
rename from ansible/roles/system/defaults/main.yml
rename to metal/roles/system/defaults/main.yml
diff --git a/ansible/roles/system/handlers/main.yml b/metal/roles/system/handlers/main.yml
similarity index 100%
rename from ansible/roles/system/handlers/main.yml
rename to metal/roles/system/handlers/main.yml
diff --git a/ansible/roles/system/tasks/earlyoom.yml b/metal/roles/system/tasks/earlyoom.yml
similarity index 100%
rename from ansible/roles/system/tasks/earlyoom.yml
rename to metal/roles/system/tasks/earlyoom.yml
diff --git a/ansible/roles/system/tasks/hostname.yml b/metal/roles/system/tasks/hostname.yml
similarity index 100%
rename from ansible/roles/system/tasks/hostname.yml
rename to metal/roles/system/tasks/hostname.yml
diff --git a/ansible/roles/system/tasks/main.yml b/metal/roles/system/tasks/main.yml
similarity index 100%
rename from ansible/roles/system/tasks/main.yml
rename to metal/roles/system/tasks/main.yml
diff --git a/ansible/roles/system/tasks/storage.yml b/metal/roles/system/tasks/storage.yml
similarity index 100%
rename from ansible/roles/system/tasks/storage.yml
rename to metal/roles/system/tasks/storage.yml
diff --git a/ansible/roles/system/vars/debian.yml b/metal/roles/system/vars/debian.yml
similarity index 100%
rename from ansible/roles/system/vars/debian.yml
rename to metal/roles/system/vars/debian.yml
diff --git a/ansible/roles/system/vars/redhat.yml b/metal/roles/system/vars/redhat.yml
similarity index 100%
rename from ansible/roles/system/vars/redhat.yml
rename to metal/roles/system/vars/redhat.yml