# iac-homelab ## Description Ce repository contient l'Infrastructure as Code (IaC) pour un environnement de homelab moderne. Il utilise Terraform pour provisionner des machines virtuelles sur Proxmox VE avec une configuration automatique via Cloud-Init, une intégration Tailscale, et un déploiement Kubernetes avec AWX pour l'orchestration Ansible. ## Fonctionnalités - 🚀 **Déploiement automatisé** : Création de VMs via Terraform - 🔧 **Configuration automatique** : Initialisation via Cloud-Init - 🌐 **Réseau sécurisé** : Connexion automatique à Tailscale - ☸️ **Orchestration Kubernetes** : Cluster K8s avec services exposés via Tailscale - 🎯 **AWX/Ansible** : Interface web pour l'exécution de playbooks - 📦 **Templates multiples** : Support Ubuntu, Debian, Alpine, Rocky, CentOS - 🏷️ **Organisation** : Système de tags pour classifier les VMs - 🔒 **Exposition sécurisée** : Services HTTPS automatiques via Tailscale Operator ## Architecture ``` ┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐ │ Proxmox VE │ │ Tailscale │ │ Applications │ │ │ │ Network │ │ │ │ ┌─────────────┐ │ │ │ │ ┌─────────────┐ │ │ │ VM K8s │─┼────┤ ├────┤ │ AWX │ │ │ │ Master │ │ │ │ │ │ (HTTPS) │ │ │ └─────────────┘ │ │ │ │ └─────────────┘ │ │ ┌─────────────┐ │ │ │ │ ┌─────────────┐ │ │ │ VM Apps │─┼────┤ ├────┤ │ Autres │ │ │ │ │ │ │ │ │ │ Services │ │ │ └─────────────┘ │ │ │ │ └─────────────┘ │ └─────────────────┘ └──────────────────┘ └─────────────────┘ ``` ## Structure du projet ``` iac-homelab/ ├── README.md ├── terraform/ │ └── prod/ │ ├── 01-virtual-machines.tf # Configuration des VMs │ ├── 02-cloud-init.tf # Configuration Cloud-Init │ ├── providers.tf # Providers Terraform │ ├── variables.tf # Variables │ ├── terraform.tfvars # Configuration personnalisée │ └── terraform.tfvars.example # Exemple de configuration ├── cloud-init/ │ └── user-data.yml.tftpl # Template Cloud-Init └── k8s/ └── awx/ ├── awx-cr.yml # AWX Custom Resource ├── awx-pvc.yml # Stockage persistant AWX └── tailscale-ingress.yml # Exposition HTTPS via Tailscale ``` ## Prérequis ### Infrastructure de base - **Terraform** : Version récente installée - **Proxmox VE** : Serveur opérationnel avec API activée - **Templates VM** : Templates configurés avec les tags appropriés - **Tailscale** : Compte avec clé d'authentification - **SSH** : Clés SSH configurées ### Kubernetes et services - **kubectl** : CLI Kubernetes installé - **Helm** : Gestionnaire de packages Kubernetes - **AWX Operator** : Pour le déploiement d'AWX - **Tailscale Operator** : Pour l'exposition sécurisée des services ## Configuration initiale ### 1. Proxmox VE Créer un utilisateur dédié avec les permissions nécessaires : ```bash # Créer le rôle pveum role add TerraformProv -privs "Datastore.Allocate Datastore.AllocateSpace Datastore.Audit Pool.Allocate Sys.Audit Sys.Console Sys.Modify VM.Allocate VM.Audit VM.Clone VM.Config.CDROM VM.Config.Cloudinit VM.Config.CPU VM.Config.Disk VM.Config.HWType VM.Config.Memory VM.Config.Network VM.Config.Options VM.Console VM.Migrate VM.Monitor VM.PowerMgmt SDN.Use" # Créer l'utilisateur pveum user add terraform@pve --password pveum acl modify / -user terraform@pve -role TerraformProv # Générer le token API pveum user token add terraform@pve terraform -expire 0 -privsep 0 ``` ### 2. Templates VM Créer des templates sur Proxmox avec les tags suivants : | OS | Tags requis | | ------ | ------------------------ | | Ubuntu | `["ubuntu", "template"]` | | Debian | `["debian", "template"]` | | Alpine | `["alpine", "template"]` | | Rocky | `["rocky", "template"]` | | CentOS | `["centos", "template"]` | ### 3. Configuration Tailscale Dans votre console d'administration Tailscale, ajouter les tags requis dans le fichier ACL : ```json "tagOwners": { "tag:k8s-operator": [], "tag:k8s": ["tag:k8s-operator"], } ``` Créer un client OAuth avec les permissions : - **Devices** : Read/Write - **Keys/authkeys** : Read/Write - **Tags** : `k8s-operator` ## Déploiement ### 1. Infrastructure Terraform ```bash # Cloner le repository git clone cd iac-homelab/terraform/prod # Copier le fichier d'exemple cp terraform.tfvars.example terraform.tfvars # Éditer avec vos valeurs vim terraform.tfvars ``` Configuration des VMs dans `terraform.tfvars` : ```hcl # Proxmox proxmox_url = "https://pve01.taila5ad8.ts.net:8006" proxmox_api_token = "terraform@pve!terraform=" # Tailscale tailscale_auth_key = "tskey-auth-" # SSH admin_ssh_public_key_path = "~/.ssh/id_rsa.pub" # VMs virtual_machines = { "k8s-master" = { os = "debian" cores = 4 memory = 8192 disk_gb = 50 ip = "192.168.1.160" gateway = "192.168.1.254" tags = ["kubernetes", "master"] }, "apps" = { os = "debian" cores = 2 memory = 4096 disk_gb = 30 ip = "192.168.1.161" gateway = "192.168.1.254" tags = ["applications"] } } ``` Déployer l'infrastructure : ```bash # Initialisation terraform init # Vérification terraform plan # Déploiement terraform apply ``` ### 2. Installation Kubernetes Sur la VM master Kubernetes : ```bash # Installation de K3s (exemple) curl -sfL https://get.k3s.io | sh - # Récupérer le kubeconfig sudo cat /etc/rancher/k3s/k3s.yaml ``` ### 3. Installation Tailscale Operator ```bash # Créer le namespace avec labels privilégiés kubectl create namespace tailscale kubectl label namespace tailscale pod-security.kubernetes.io/enforce=privileged # Ajouter le repository Helm helm repo add tailscale https://pkgs.tailscale.com/helmcharts helm repo update # Installer l'opérateur helm upgrade \ --install \ tailscale-operator \ tailscale/tailscale-operator \ --namespace=tailscale \ --create-namespace \ --set-string oauth.clientId="" \ --set-string oauth.clientSecret="" \ --wait ``` ### 4. Installation AWX ```bash # Créer le namespace AWX kubectl create namespace awx # Installer l'opérateur AWX kubectl apply -f https://raw.githubusercontent.com/ansible/awx-operator/devel/deploy/awx-operator.yaml # Déployer AWX avec la configuration personnalisée kubectl apply -f k8s/awx/awx-pvc.yml kubectl apply -f k8s/awx/awx-cr.yml # Exposer AWX via Tailscale avec HTTPS automatique kubectl apply -f k8s/awx/tailscale-ingress.yml ``` ## Configuration des services ### AWX avec Tailscale Le fichier `k8s/awx/tailscale-ingress.yml` configure l'exposition sécurisée d'AWX : ```yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: awx-tailscale-ingress namespace: awx annotations: tailscale.com/expose: "true" tailscale.com/hostname: "awx" spec: ingressClassName: tailscale defaultBackend: service: name: awx-service port: number: 80 tls: - hosts: - awx.taila5ad8.ts.net ``` ### Fonctionnalités automatiques 1. **Certificats HTTPS automatiques** : Tailscale génère et renouvelle les certificats 2. **Terminaison TLS** : L'ingress gère HTTPS → HTTP 3. **Routage intelligent** : Traffic dirigé vers les bons services 4. **Sécurité réseau** : Exposition uniquement via Tailscale ### Flow de traffic ``` https://awx.taila5ad8.ts.net (HTTPS:443) ↓ Tailscale Ingress Controller ↓ (Terminaison TLS) awx-service (HTTP:80) ↓ AWX Pod (HTTP:8052) ``` ## Avantages de l'architecture ### Sécurité - ✅ **Pas d'exposition publique** : Services accessibles uniquement via Tailscale - ✅ **HTTPS automatique** : Certificats gérés par Tailscale - ✅ **Authentification** : Contrôle d'accès via Tailscale ACL - ✅ **Isolation réseau** : Pods non privilégiés ### Simplicité - ✅ **Configuration déclarative** : Infrastructure et services en code - ✅ **Déploiement automatisé** : Une commande pour tout déployer - ✅ **Gestion centralisée** : Tout via Kubernetes et Terraform - ✅ **URLs propres** : `https://service.tailnet.ts.net` ### Évolutivité - ✅ **Ajout facile de services** : Nouveau ingress = nouveau service exposé - ✅ **Load balancing** : Kubernetes gère la répartition de charge - ✅ **Haute disponibilité** : Pods redémarrés automatiquement - ✅ **Monitoring** : Métriques Kubernetes natives ## Utilisation d'AWX ### Accès - URL: `https://awx.taila5ad8.ts.net` - Identifiants: Configurés dans le secret Kubernetes ### Execution Environments (EE) Pour les playbooks nécessitant Tailscale, deux approches possibles : #### Approche recommandée : Tailscale Operator ```yaml # Les EE utilisent le réseau via l'opérateur task_privileged: false # Plus sécurisé ``` #### Approche alternative : Tailscale dans EE ```yaml # EE avec Tailscale installé directement task_privileged: true # Nécessaire pour networking ``` ## Maintenance ### Ajouter un service Kubernetes 1. Déployer le service : ```bash kubectl apply -f new-service.yml ``` 2. Créer l'ingress Tailscale : ```yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: new-service-ingress annotations: tailscale.com/expose: "true" tailscale.com/hostname: "new-service" spec: ingressClassName: tailscale defaultBackend: service: name: new-service port: number: 80 tls: - hosts: - new-service.taila5ad8.ts.net ``` ### Monitoring ```bash # Vérifier les services Tailscale kubectl get ingress -n kubectl describe ingress -n # Vérifier l'opérateur Tailscale kubectl logs -n tailscale -l app=tailscale-operator # Vérifier AWX kubectl get pods -n awx kubectl logs -n awx -l app.kubernetes.io/name=awx ``` ### Dépannage courant | Problème | Solution | | --------------------------- | ------------------------------------------------------------ | | Certificat HTTPS non généré | Vérifier les annotations Tailscale et les permissions OAuth | | Service non accessible | Vérifier l'ingress et le service backend | | AWX non fonctionnel | Vérifier les PVC et les secrets de configuration | | EE sans accès réseau | Configurer ProxyClass ou privilèges selon l'approche choisie | ## Configuration avancée ### Execution Environments avec Tailscale Operator ```yaml apiVersion: tailscale.com/v1alpha1 kind: ProxyClass metadata: name: awx-ee-proxy namespace: awx spec: hostname: "awx-ee" --- # Configuration AWX pour utiliser le proxy spec: task_extra_env: | - name: HTTPS_PROXY value: "http://tailscale-proxy:8080" ``` ### Autres services recommandés | Service | Description | URL | | ---------- | ------------------------ | ------------------------------------- | | Grafana | Monitoring et dashboards | `https://grafana.taila5ad8.ts.net` | | Prometheus | Métriques | `https://prometheus.taila5ad8.ts.net` | | ArgoCD | GitOps | `https://argocd.taila5ad8.ts.net` | | Longhorn | Stockage | `https://longhorn.taila5ad8.ts.net` | ## Ressources recommandées | Type de service | CPU | RAM | Disque | | --------------- | --- | ---- | ------ | | K8s Master | 4+ | 8GB+ | 50GB+ | | AWX | 2 | 4GB | 20GB | | Monitoring | 2 | 4GB | 30GB | | Applications | 2+ | 2GB+ | 20GB+ | ## Support et références - 📚 [Documentation Terraform Proxmox Provider](https://registry.terraform.io/providers/bpg/proxmox/latest/docs) - 🔧 [Proxmox VE Documentation](https://pve.proxmox.com/wiki/Main_Page) - 🌐 [Tailscale Documentation](https://tailscale.com/kb/) - ☸️ [Kubernetes Documentation](https://kubernetes.io/docs/) - 🎯 [AWX Operator Documentation](https://github.com/ansible/awx-operator) - 🔒 [Tailscale Kubernetes Operator](https://tailscale.com/kb/1236/kubernetes-operator) ## Inspirations Ce projet s'inspire des meilleures pratiques DevOps et des articles de la communauté, notamment : - [Securely Exposing Applications on Kubernetes With Tailscale](https://joshrnoll.com/securely-exposing-applications-on-kubernetes-with-tailscale/) par Josh Noll