Reviewed-on: #15
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 :
# 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 <mot_de_passe_securise>
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 :
"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
# Cloner le repository
git clone <repository-url>
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 :
# Proxmox
proxmox_url = "https://pve01.taila5ad8.ts.net:8006"
proxmox_api_token = "terraform@pve!terraform=<token>"
# Tailscale
tailscale_auth_key = "tskey-auth-<votre-cle>"
# 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 :
# Initialisation
terraform init
# Vérification
terraform plan
# Déploiement
terraform apply
2. Installation Kubernetes
Sur la VM master Kubernetes :
# 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
# 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="<OAuth-client-ID>" \
--set-string oauth.clientSecret="<OAuth-client-secret>" \
--wait
4. Installation AWX
# 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 :
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
- Certificats HTTPS automatiques : Tailscale génère et renouvelle les certificats
- Terminaison TLS : L'ingress gère HTTPS → HTTP
- Routage intelligent : Traffic dirigé vers les bons services
- 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
# Les EE utilisent le réseau via l'opérateur
task_privileged: false # Plus sécurisé
Approche alternative : Tailscale dans EE
# EE avec Tailscale installé directement
task_privileged: true # Nécessaire pour networking
Maintenance
Ajouter un service Kubernetes
- Déployer le service :
kubectl apply -f new-service.yml
- Créer l'ingress Tailscale :
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
# Vérifier les services Tailscale
kubectl get ingress -n <namespace>
kubectl describe ingress <ingress-name> -n <namespace>
# 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
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
- 🔧 Proxmox VE Documentation
- 🌐 Tailscale Documentation
- ☸️ Kubernetes Documentation
- 🎯 AWX Operator Documentation
- 🔒 Tailscale Kubernetes Operator
Inspirations
Ce projet s'inspire des meilleures pratiques DevOps et des articles de la communauté, notamment :