427 lines
13 KiB
Markdown
427 lines
13 KiB
Markdown
# 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 <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 :
|
|
|
|
```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 <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` :
|
|
|
|
```hcl
|
|
# 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 :
|
|
|
|
```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="<OAuth-client-ID>" \
|
|
--set-string oauth.clientSecret="<OAuth-client-secret>" \
|
|
--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 <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
|
|
|
|
```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 |