migration: incorporate repository secrets and apply clean application definitions

This commit is contained in:
jv 2026-05-19 08:06:40 -05:00
parent 7ae96b4654
commit 199a06aae8
30 changed files with 321 additions and 148 deletions

View File

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 60 KiB

View File

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 60 KiB

View File

@ -1,135 +0,0 @@
resource "kubernetes_namespace" "argocd" {
metadata {
name = "argocd"
}
}
data "http" "argocd_manifest" {
url = "https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml"
}
resource "kubernetes_manifest" "argocd_core" {
for_each = { for idx, doc in provider::kubernetes::manifest_decode_multi(data.http.argocd_manifest.response_body) : idx => doc }
manifest = merge(
each.value,
contains(["ClusterRole", "ClusterRoleBinding", "CustomResourceDefinition", "Namespace"], lookup(each.value, "kind", "")) ? {} : {
metadata = merge(
try(each.value.metadata, {}),
{
namespace = kubernetes_namespace.argocd.metadata[0].name
}
)
},
lookup(each.value, "kind", "") == "Service" && lookup(try(each.value.metadata, {}), "name", "") == "argocd-server" ? {
spec = merge(
try(each.value.spec, {}),
{
type = "NodePort"
ports = [
{
name = "http"
port = 80
protocol = "TCP"
targetPort = 8080
nodePort = 30501
},
{
name = "https"
port = 443
protocol = "TCP"
targetPort = 8080
}
]
}
)
} : {}
)
field_manager {
force_conflicts = true
}
depends_on = [kubernetes_namespace.argocd]
}
resource "kubernetes_secret_v1" "argocd_private_repo" {
metadata {
name = "my-homelab-repo-secret"
namespace = kubernetes_namespace.argocd.metadata[0].name
labels = {
"argocd.argoproj.io/secret-type" = "repository"
}
}
data = {
type = "git"
url = "http://192.168.100.68:30300/jv/my-homelab-configs"
username = "jv"
password = "Summer12#$"
}
depends_on = [kubernetes_manifest.argocd_core]
}
resource "kubernetes_manifest" "argocd_app_registry" {
manifest = {
apiVersion = "argoproj.io/v1alpha1"
kind = "Application"
metadata = {
name = "container-registry"
namespace = "argocd"
}
spec = {
project = "default"
source = {
repoURL = "http://192.168.100.68:30300/jv/my-homelab-configs"
targetRevision = "HEAD"
path = "container-registry" # Points to the folder containing your registry YAMLs
}
destination = {
server = "https://kubernetes.default.svc"
namespace = "container-registry" # Deploys into this namespace
}
syncPolicy = {
automated = {
prune = true
selfHeal = true
}
syncOptions = ["CreateNamespace=true"]
}
}
}
depends_on = [kubernetes_manifest.argocd_core]
}
resource "kubernetes_manifest" "argocd_app_web_app" {
manifest = {
apiVersion = "argoproj.io/v1alpha1"
kind = "Application"
metadata = {
name = "php-web-app"
namespace = "argocd"
}
spec = {
project = "default"
source = {
repoURL = "http://192.168.100.68:30300/jv/my-homelab-configs"
targetRevision = "HEAD"
path = "web-app" # ArgoCD ignores the PHP/Docker files and grabs web-app.yaml
}
destination = {
server = "https://kubernetes.default.svc"
namespace = "default"
}
syncPolicy = {
automated = {
prune = true
selfHeal = true
}
syncOptions = ["CreateNamespace=true"]
}
}
}
depends_on = [kubernetes_manifest.argocd_core]
}

View File

@ -1,13 +0,0 @@
terraform {
required_providers {
kubernetes = {
source = "hashicorp/kubernetes"
version = "~> 2.24"
}
}
}
provider "kubernetes" {
config_path = "~/.kube/config"
config_context = "kubernetes-admin@kubernetes"
}

74
bootstrap/apps/main.tf Normal file
View File

@ -0,0 +1,74 @@
terraform {
required_version = ">= 1.0"
required_providers {
kubernetes = {
source = "hashicorp/kubernetes"
version = "~> 2.26"
}
}
}
provider "kubernetes" {
config_path = "/home/jv/.kube/config"
}
resource "kubernetes_manifest" "container_registry" {
manifest = {
apiVersion = "argoproj.io/v1alpha1"
kind = "Application"
metadata = {
name = "container-registry"
namespace = "argocd"
}
spec = {
project = "default"
source = {
repoURL = "https://github.com/juvdiaz/my-homelab-configs.git"
targetRevision = "HEAD"
path = "apps/container-registry"
}
destination = {
server = "https://kubernetes.default.svc"
namespace = "container-registry"
}
syncPolicy = {
automated = {
prune = true
selfHeal = true
}
syncOptions = ["CreateNamespace=true"]
}
}
}
}
resource "kubernetes_manifest" "production_website" {
depends_on = [kubernetes_manifest.container_registry]
manifest = {
apiVersion = "argoproj.io/v1alpha1"
kind = "Application"
metadata = {
name = "production-website"
namespace = "argocd"
}
spec = {
project = "default"
source = {
repoURL = "https://github.com/juvdiaz/my-homelab-configs.git"
targetRevision = "HEAD"
path = "apps/website"
}
destination = {
server = "https://kubernetes.default.svc"
namespace = "website-production"
}
syncPolicy = {
automated = {
prune = true
selfHeal = true
}
syncOptions = ["CreateNamespace=true"]
}
}
}
}

75
bootstrap/cluster/main.tf Normal file
View File

@ -0,0 +1,75 @@
terraform {
required_version = ">= 1.0"
required_providers {
null = {
source = "hashicorp/null"
version = "~> 3.2"
}
external = {
source = "hashicorp/external"
version = "~> 2.3"
}
}
}
resource "null_resource" "kubeadm_control_plane" {
provisioner "local-exec" {
command = <<EOT
sudo apt-get update && sudo apt-get install -y open-iscsi nfs-common
sudo systemctl enable --now iscsid
sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --node-name=debian
mkdir -p /home/jv/.kube
sudo cp -i /etc/kubernetes/admin.conf /home/jv/.kube/config
sudo chown jv:jv /home/jv/.kube/config
kubectl taint nodes debian node-role.kubernetes.io/control-plane-
EOT
}
provisioner "local-exec" {
when = destroy
command = <<EOT
sudo kubeadm reset --force
sudo iptables -F && sudo iptables -t nat -F && sudo iptables -t mangle -F && sudo iptables -X
sudo ip link delete cilium_host || true
sudo ip link delete cilium_net || true
sudo ip link delete cilium_vxlan || true
rm -rf /home/jv/.kube
sudo rm -rf /etc/kubernetes/ /var/lib/etcd/ /var/lib/kubelet/ /var/lib/cni/ /etc/cni/net.d
EOT
}
}
data "external" "kubeadm_join_command" {
depends_on = [null_resource.kubeadm_control_plane]
program = ["sh", "-c", "echo \"{\\\"cmd\\\":\\\"$(sudo kubeadm token create --print-join-command)\\\"}\""]
}
resource "null_resource" "kubeadm_worker_raspberry" {
depends_on = [null_resource.kubeadm_control_plane]
connection {
type = "ssh"
user = "jv"
private_key = file("/home/jv/.ssh/id_ed25519")
host = "192.168.100.89"
}
provisioner "remote-exec" {
inline = [
"sudo apt-get update && sudo apt-get install -y open-iscsi nfs-common",
"sudo systemctl enable --now iscsid",
"echo '${data.external.kubeadm_join_command.result.cmd} --node-name=raspberry' > /tmp/join.sh",
"sudo sh /tmp/join.sh",
"rm -f /tmp/join.sh"
]
}
provisioner "remote-exec" {
when = destroy
inline = [
"sudo kubeadm reset --force",
"sudo iptables -F && sudo iptables -t nat -F && sudo iptables -t mangle -F && sudo iptables -X",
"sudo rm -rf /var/lib/kubelet/ /var/lib/cni/ /etc/cni/net.d"
]
}
}

108
bootstrap/platform/main.tf Normal file
View File

@ -0,0 +1,108 @@
terraform {
required_version = ">= 1.0"
required_providers {
helm = {
source = "hashicorp/helm"
version = "~> 2.12"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = "~> 2.26"
}
}
}
provider "kubernetes" {
config_path = "/home/jv/.kube/config"
}
provider "helm" {
kubernetes {
config_path = "/home/jv/.kube/config"
}
}
resource "helm_release" "cilium" {
name = "cilium"
repository = "https://helm.cilium.io/"
chart = "cilium"
namespace = "kube-system"
set {
name = "operator.replicas"
value = "1"
}
}
resource "helm_release" "longhorn" {
depends_on = [helm_release.cilium]
name = "longhorn"
repository = "https://charts.longhorn.io"
chart = "longhorn"
namespace = "longhorn-system"
create_namespace = true
timeout = 600
# Scale configurations down for our small 2-node footprint
set {
name = "csi.attacherReplicaCount"
value = "1"
}
set {
name = "csi.provisionerReplicaCount"
value = "1"
}
set {
name = "csi.resizerReplicaCount"
value = "1"
}
set {
name = "csi.snapshotterReplicaCount"
value = "1"
}
set {
name = "defaultSettings.defaultReplicaCount"
value = "1"
}
# Global Tolerations to allow Longhorn structural pods to map onto control planes
set {
name = "global.tolerations[0].key"
value = "node-role.kubernetes.io/control-plane"
}
set {
name = "global.tolerations[0].operator"
value = "Exists"
}
set {
name = "global.tolerations[0].effect"
value = "NoSchedule"
}
}
resource "helm_release" "argocd" {
depends_on = [helm_release.longhorn]
name = "argocd"
repository = "https://argoproj.github.io/argo-helm"
chart = "argo-cd"
namespace = "argocd"
create_namespace = true
}
resource "kubernetes_secret_v1" "argocd_private_repo" {
depends_on = [helm_release.argocd]
metadata {
name = "my-homelab-repo-secret"
namespace = "argocd"
labels = {
"argocd.argoproj.io/secret-type" = "repository"
}
}
data = {
type = "git"
url = "http://192.168.100.68:30300/jv/my-homelab-configs"
username = "jv"
password = "Summer12#$"
}
}

64
lab.sh Executable file
View File

@ -0,0 +1,64 @@
up() {
echo "Deploying the homelab infrastructure..."
cd bootstrap/cluster
tofu init
tofu apply -auto-approve
cd ../platform
tofu init
tofu apply -auto-approve
cd ../apps
tofu init
tofu apply -auto-approve
cd ../..
echo "Deployment successfully completed!"
}
nuke() {
echo "Brutally nuking the homelab infrastructure..."
echo "--> Terminating local OpenTofu tasks..."
killall tofu terraform 2>/dev/null || true
echo "--> Eviscerating local Kubernetes components (Laptop)..."
sudo kubeadm reset --force || true
sudo systemctl stop containerd 2>/dev/null || true
sudo killall containerd-shim-runc-v2 2>/dev/null || true
sudo umount /var/lib/containerd/srun/* 2>/dev/null || true
sudo rm -rf /var/lib/containerd/* /run/containerd/*
sudo rm -rf /etc/kubernetes/ /var/lib/etcd/ /var/lib/kubelet/ /var/lib/cni/ /etc/cni/net.d /home/jv/.kube/
sudo iptables -F && sudo iptables -t nat -F && sudo iptables -t mangle -F && sudo iptables -X
sudo ip link delete cilium_host 2>/dev/null || true
sudo ip link delete cilium_net 2>/dev/null || true
sudo ip link delete cilium_vxlan 2>/dev/null || true
sudo systemctl start containerd
echo "--> Eviscerating remote Kubernetes components (Raspberry Pi)..."
ssh -o ConnectTimeout=5 jv@192.168.100.89 << 'EOF' 2>/dev/null || true
sudo kubeadm reset --force
sudo killall containerd-shim-runc-v2 2>/dev/null || true
sudo rm -rf /var/lib/kubelet/ /var/lib/cni/ /etc/cni/net.d /var/lib/containerd/*
sudo iptables -F && sudo iptables -t nat -F && sudo iptables -t mangle -F && sudo iptables -X
EOF
echo "--> Deleting OpenTofu tracking state files..."
rm -rf bootstrap/cluster/terraform.tfstate*
rm -rf bootstrap/cluster/.terraform/
rm -rf bootstrap/cluster/.terraform.lock.hcl
rm -rf bootstrap/platform/terraform.tfstate*
rm -rf bootstrap/platform/.terraform/
rm -rf bootstrap/platform/.terraform.lock.hcl
rm -rf bootstrap/apps/terraform.tfstate*
rm -rf bootstrap/apps/.terraform/
rm -rf bootstrap/apps/.terraform.lock.hcl
echo "Destruction complete! Your hardware is completely sanitized."
}