From bc0c9dd4500738590542f70202cf56b1ede92e34 Mon Sep 17 00:00:00 2001 From: darnodo Date: Fri, 29 Aug 2025 15:05:17 +0200 Subject: [PATCH] Add k8s configs and update documentation with AWX setup --- .gitmodules | 1 + README.md | 374 ++++++++++++++++++++++++---------- k8s/awx/awx-cr.yml | 25 +++ k8s/awx/awx-pvc.yml | 12 ++ k8s/awx/tailscale-ingress.yml | 18 ++ 5 files changed, 325 insertions(+), 105 deletions(-) create mode 100644 k8s/awx/awx-cr.yml create mode 100644 k8s/awx/awx-pvc.yml create mode 100644 k8s/awx/tailscale-ingress.yml diff --git a/.gitmodules b/.gitmodules index 1ff96a7..53be097 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,4 @@ [submodule "k8s/aws/awx-operator"] path = k8s/aws/awx-operator url = https://github.com/ansible/awx-operator.git + ignore = all diff --git a/README.md b/README.md index da54011..59ff749 100644 --- a/README.md +++ b/README.md @@ -2,15 +2,35 @@ ## Description -Ce repository contient l'Infrastructure as Code (IaC) pour un environnement de homelab. Il utilise Terraform pour provisionner des machines virtuelles sur Proxmox VE avec une configuration automatique via Cloud-Init et une intégration Tailscale. +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 @@ -25,18 +45,30 @@ iac-homelab/ │ ├── variables.tf # Variables │ ├── terraform.tfvars # Configuration personnalisée │ └── terraform.tfvars.example # Exemple de configuration -└── cloud-init/ - └── user-data.yml.tftpl # Template Cloud-Init +├── 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 @@ -67,9 +99,25 @@ Créer des templates sur Proxmox avec les tags suivants : | 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. Configuration +### 1. Infrastructure Terraform ```bash # Cloner le repository @@ -83,9 +131,7 @@ cp terraform.tfvars.example terraform.tfvars vim terraform.tfvars ``` -### 2. Variables importantes - -Dans `terraform.tfvars`, configurer : +Configuration des VMs dans `terraform.tfvars` : ```hcl # Proxmox @@ -100,19 +146,28 @@ admin_ssh_public_key_path = "~/.ssh/id_rsa.pub" # VMs virtual_machines = { - "monitoring" = { + "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 = ["monitoring"] + tags = ["applications"] } } ``` -### 3. Déploiement +Déployer l'infrastructure : ```bash # Initialisation @@ -125,139 +180,248 @@ terraform plan terraform apply ``` -## Configuration des VMs +### 2. Installation Kubernetes -### Options de base +Sur la VM master Kubernetes : -```hcl -"nom-vm" = { - os = "debian" # Template à utiliser - cores = 2 # Nombre de cœurs CPU - memory = 4096 # RAM en MB - disk_gb = 30 # Taille du disque en GB - ip = "192.168.1.100" # Adresse IP statique - gateway = "192.168.1.254" # Passerelle réseau - tags = ["web"] # Tags pour l'organisation -} +```bash +# Installation de K3s (exemple) +curl -sfL https://get.k3s.io | sh - + +# Récupérer le kubeconfig +sudo cat /etc/rancher/k3s/k3s.yaml ``` -### Options avancées +### 3. Installation Tailscale Operator -```hcl -"nom-vm-avancee" = { - # Configuration de base - os = "ubuntu" - cores = 4 - memory = 8192 - disk_gb = 50 - ip = "192.168.1.101" - gateway = "192.168.1.254" - - # Options avancées - cpu_type = "host" - datastore = "local-lvm" - network_bridge = "vmbr0" - username = "admin" - - # Disques supplémentaires - additional_disks = [ - { - interface = "scsi1" - datastore = "local-lvm" - size = 100 - } - ] -} +```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 ``` -## Fonctionnalités automatiques +### 4. Installation AWX -### Cloud-Init +```bash +# Créer le namespace AWX +kubectl create namespace awx -Chaque VM est automatiquement configurée avec : -- Installation des packages de base -- Configuration de l'utilisateur et des clés SSH -- Installation du QEMU Guest Agent -- Configuration du hostname +# Installer l'opérateur AWX +kubectl apply -f https://raw.githubusercontent.com/ansible/awx-operator/devel/deploy/awx-operator.yaml -### Tailscale +# Déployer AWX avec la configuration personnalisée +kubectl apply -f k8s/awx/awx-pvc.yml +kubectl apply -f k8s/awx/awx-cr.yml -Installation et connexion automatique : -- Téléchargement et installation de Tailscale -- Connexion au réseau avec la clé d'authentification -- Configuration du hostname sur le réseau +# 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 une VM +### Ajouter un service Kubernetes +1. Déployer le service : ```bash -# 1. Ajouter la configuration dans terraform.tfvars -# 2. Appliquer les changements -terraform apply +kubectl apply -f new-service.yml ``` -### Supprimer une VM - -```bash -# 1. Retirer la configuration de terraform.tfvars -# 2. Appliquer les changements -terraform apply +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 ``` -### Modifier une VM +### Monitoring ```bash -# 1. Modifier la configuration dans terraform.tfvars -# 2. Vérifier les changements -terraform plan -# 3. Appliquer -terraform apply +# 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 ``` -## Sécurité - -- ✅ Authentification par tokens API -- ✅ Connexion SSH par clés uniquement -- ✅ Réseau sécurisé via Tailscale -- ✅ Isolation des VMs -- ✅ Permissions minimales sur Proxmox - -## Dépannage - -### Problèmes courants +### Dépannage courant | Problème | Solution | |---|---| -| Template non trouvé | Vérifier les tags sur Proxmox | -| IP déjà utilisée | Vérifier les conflits d'adresses | -| Erreur SSH | Vérifier le chemin de la clé publique | -| Tailscale | Vérifier la validité de la clé d'authentification | +| 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 | -### Logs détaillés +## Configuration avancée -```bash -# Logs Terraform détaillés -TF_LOG=DEBUG terraform apply +### Execution Environments avec Tailscale Operator -# État des ressources -terraform show - -# Liste des ressources -terraform state list +```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 | -| Web server | 2 | 2GB | 20GB | -| Database | 4+ | 8GB+ | 50GB+ | -| Kubernetes | 4+ | 4GB+ | 40GB+ | +| Applications | 2+ | 2GB+ | 20GB+ | -## Support +## 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/) \ No newline at end of file +- 🌐 [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 \ No newline at end of file diff --git a/k8s/awx/awx-cr.yml b/k8s/awx/awx-cr.yml new file mode 100644 index 0000000..a84032f --- /dev/null +++ b/k8s/awx/awx-cr.yml @@ -0,0 +1,25 @@ +apiVersion: awx.ansible.com/v1beta1 +kind: AWX +metadata: + name: awx + namespace: awx +spec: + # Ajuste ces valeurs selon ta version & ressources + postgres_configuration_secret: awx-postgres-configuration + postgres_storage_class: local-path + postgres_storage_requirements: + requests: + storage: 8Gi + projects_persistence: true + projects_existing_claim: awx-projects-claim + + # important: pas d'exposition publique + service_type: ClusterIP + ingress_type: none + + # Job pods puissent être privilégiés + # (Necessaire avec tailscale dans les EE) + task_privileged: true + + image: quay.io/ansible/awx + image_version: "latest" diff --git a/k8s/awx/awx-pvc.yml b/k8s/awx/awx-pvc.yml new file mode 100644 index 0000000..76c3b8e --- /dev/null +++ b/k8s/awx/awx-pvc.yml @@ -0,0 +1,12 @@ +# awx-pvc.yml +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: awx-projects-claim + namespace: awx +spec: + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 12Gi + storageClassName: local-path diff --git a/k8s/awx/tailscale-ingress.yml b/k8s/awx/tailscale-ingress.yml new file mode 100644 index 0000000..c5986a8 --- /dev/null +++ b/k8s/awx/tailscale-ingress.yml @@ -0,0 +1,18 @@ +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