Damien Arnodo 804b94a837
All checks were successful
Terraform Deploy / Validate (push) Successful in 4s
Terraform Deploy / Plan (push) Successful in 4s
Terraform Deploy / Apply (push) Has been skipped
feat(ci): create dedicated deploy workflow for Terraform
- Separate workflow for push events to dev only
- Apply job runs when plan detects changes
- Use has_changes output (true/false) instead of exitcode

Refs #3
2025-12-08 16:26:44 +00:00

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

  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

# 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

  1. Déployer le service :
kubectl apply -f new-service.yml
  1. 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

Inspirations

Ce projet s'inspire des meilleures pratiques DevOps et des articles de la communauté, notamment :

Description
This repository contains Infrastructure as Code (IaC) configurations for a home lab environment.
Readme 209 KiB
Languages
HCL 100%