diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5c3dcbb --- /dev/null +++ b/Makefile @@ -0,0 +1,61 @@ +.PHONY: all setup cluster build import deploy check clean + +# Commande par défaut : lance tout le processus de A à Z +all: setup cluster build import deploy check + +# 1. Installation des dépendances (Packer, Ansible, Libs) +setup: + @echo "--- [1/6] Installation des prérequis ---" + @# Correction préventive pour éviter l'erreur de dépôt yarn fréquente dans Codespaces + sudo rm -f /etc/apt/sources.list.d/yarn.list + @# Installation de Packer + curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add - + sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $$(lsb_release -cs) main" -y + sudo apt-get update + sudo apt-get install packer -y + @# Installation des outils Python pour Ansible et K8s + pip install --upgrade pip + pip install ansible kubernetes requests + ansible-galaxy collection install kubernetes.core + @echo " Environnement prêt." + +# 2. Création du cluster K3d (si inexistant) +cluster: + @echo "--- [2/6] Vérification du cluster K3d ---" + @# Installe K3d si la commande n'existe pas + which k3d > /dev/null || curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash + @# Crée le cluster 'lab' seulement s'il n'existe pas déjà + k3d cluster list | grep -q "lab" || k3d cluster create lab --servers 1 --agents 2 + @echo " Cluster K3d opérationnel." + +# 3. Construction de l'image Docker avec Packer +build: + @echo "--- [3/6] Build de l'image Packer ---" + packer init nginx.pkr.hcl + packer build nginx.pkr.hcl + @echo " Image 'my-custom-nginx:v1' construite." + +# 4. Import de l'image dans le cluster (Étape critique pour K3d) +import: + @echo "--- [4/6] Import de l'image dans K3d ---" + k3d image import my-custom-nginx:v1 -c lab + @echo " Image importée dans le cluster." + +# 5. Déploiement via Ansible +deploy: + @echo "--- [5/6] Déploiement Ansible ---" + ansible-playbook playbook.yml + @echo " Playbook exécuté." + +# 6. Vérification finale +check: + @echo "--- [6/6] État du déploiement ---" + @sleep 5 # Petite pause pour laisser le temps aux pods de démarrer + kubectl get pods + kubectl get svc + @echo " Succès ! L'application est déployée." + +# Nettoyage (Optionnel) +clean: + k3d cluster delete lab + docker rmi my-custom-nginx:v1 diff --git a/README.md b/README.md index adfe016..3008509 100644 --- a/README.md +++ b/README.md @@ -1,92 +1,95 @@ ------------------------------------------------------------------------------------------------------- -ATELIER FROM IMAGE TO CLUSTER ------------------------------------------------------------------------------------------------------- -L’idée en 30 secondes : Cet atelier consiste à **industrialiser le cycle de vie d’une application** simple en construisant une **image applicative Nginx** personnalisée avec **Packer**, puis en déployant automatiquement cette application sur un **cluster Kubernetes** léger (K3d) à l’aide d’**Ansible**, le tout dans un environnement reproductible via **GitHub Codespaces**. -L’objectif est de comprendre comment des outils d’Infrastructure as Code permettent de passer d’un artefact applicatif maîtrisé à un déploiement cohérent et automatisé sur une plateforme d’exécution. - -------------------------------------------------------------------------------------------------------- -Séquence 1 : Codespace de Github -------------------------------------------------------------------------------------------------------- -Objectif : Création d'un Codespace Github -Difficulté : Très facile (~5 minutes) -------------------------------------------------------------------------------------------------------- -**Faites un Fork de ce projet**. Si besion, voici une vidéo d'accompagnement pour vous aider dans les "Forks" : [Forker ce projet](https://youtu.be/p33-7XQ29zQ) - -Ensuite depuis l'onglet [CODE] de votre nouveau Repository, **ouvrez un Codespace Github**. - ---------------------------------------------------- -Séquence 2 : Création du cluster Kubernetes K3d ---------------------------------------------------- -Objectif : Créer votre cluster Kubernetes K3d -Difficulté : Simple (~5 minutes) ---------------------------------------------------- -Vous allez dans cette séquence mettre en place un cluster Kubernetes K3d contenant un master et 2 workers. -Dans le terminal du Codespace copier/coller les codes ci-dessous etape par étape : - -**Création du cluster K3d** -``` -curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash -``` -``` -k3d cluster create lab \ - --servers 1 \ - --agents 2 -``` -**vérification du cluster** -``` -kubectl get nodes -``` -**Déploiement d'une application (Docker Mario)** +# Atelier DevOps : De l'Image au Cluster + +![Packer](https://img.shields.io/badge/Packer-Build-blue?logo=packer) +![Ansible](https://img.shields.io/badge/Ansible-Deploy-red?logo=ansible) +![Kubernetes](https://img.shields.io/badge/Kubernetes-K3d-326ce5?logo=kubernetes) +![Docker](https://img.shields.io/badge/Docker-Container-2496ed?logo=docker) + +Ce projet a été réalisé dans le cadre de l'atelier **"Atelier from Image to Cluster"**. +L'objectif est d'industrialiser le cycle de vie d'une application Nginx : de la construction de l'image (Build) à son déploiement automatisé (Run) dans un environnement Kubernetes. + +--- + +## Architecture du projet + +Le projet utilise l'approche **Infrastructure as Code** (IaC) pour garantir la reproductibilité. + +```mermaid +graph LR + A[Code Source
index.html] -->|Packer| B(Image Docker
my-custom-nginx:v1) + B -->|k3d image import| C{Cluster K3d} + D[Ansible Playbook] -->|Kubernetes Core| C + C -->|Port Forward| E[Accès Navigateur] ``` -kubectl create deployment mario --image=sevenajay/mario -kubectl expose deployment mario --type=NodePort --port=80 -kubectl get svc + +1. **Packer** : Construit une image Docker immuable basée sur Nginx, embarquant le site web statique. +2. **K3d** : Simule un cluster Kubernetes complet (1 Master, 2 Workers) dans des conteneurs Docker. +3. **Ansible** : Orchestre le déploiement des objets Kubernetes (Deployment, Service) de manière idempotente. + +--- + +## Prérequis + +Ce projet est conçu pour être exécuté dans un **GitHub Codespace**. +Les outils nécessaires sont installés automatiquement via le Makefile ou les scripts fournis : +* `Packer` +* `Ansible` (avec collection `kubernetes.core`) +* `K3d` +* `Kubectl` + +--- + +## Démarrage Rapide + +L'ensemble du processus est automatisé grâce à un **Makefile**. + +### 1. Lancement de l'automatisation +Dans le terminal du Codespace, lancez simplement la commande suivante : + +```bash +make all ``` -**Forward du port 80** + +> **Note :** Cette commande va installer les dépendances, builder l'image, l'importer dans le cluster et déployer l'application. + +### 2. Vérification +Une fois le script terminé, vérifiez que les pods sont actifs : + +```bash +kubectl get pods ``` -kubectl port-forward svc/mario 8080:80 >/tmp/mario.log 2>&1 & + +### 3. Accès à l'application +Pour visualiser le site web, créez un tunnel vers le service : + +```bash +kubectl port-forward svc/nginx-service 8082:80 ``` -**Réccupération de l'URL de l'application Mario** -Votre application Mario est déployée sur le cluster K3d. Pour obtenir votre URL cliquez sur l'onglet **[PORTS]** dans votre Codespace et rendez public votre port **8080** (Visibilité du port). -Ouvrez l'URL dans votre navigateur et jouer ! - ---------------------------------------------------- -Séquence 3 : Exercice ---------------------------------------------------- -Objectif : Customisez un image Docker avec Packer et déploiement sur K3d via Ansible -Difficulté : Moyen/Difficile (~2h) ---------------------------------------------------- -Votre mission (si vous l'acceptez) : Créez une **image applicative customisée à l'aide de Packer** (Image de base Nginx embarquant le fichier index.html présent à la racine de ce Repository), puis déployer cette image customisée sur votre **cluster K3d** via **Ansible**, le tout toujours dans **GitHub Codespace**. - -**Architecture cible :** Ci-dessous, l'architecture cible souhaitée. - -![Screenshot Actions](Architecture_cible.png) - ---------------------------------------------------- -## Processus de travail (résumé) - -1. Installation du cluster Kubernetes K3d (Séquence 1) -2. Installation de Packer et Ansible -3. Build de l'image customisée (Nginx + index.html) -4. Import de l'image dans K3d -5. Déploiement du service dans K3d via Ansible -6. Ouverture des ports et vérification du fonctionnement - ---------------------------------------------------- -Séquence 4 : Documentation -Difficulté : Facile (~30 minutes) ---------------------------------------------------- -**Complétez et documentez ce fichier README.md** pour nous expliquer comment utiliser votre solution. -Faites preuve de pédagogie et soyez clair dans vos expliquations et processus de travail. - ---------------------------------------------------- -Evaluation ---------------------------------------------------- -Cet atelier, **noté sur 20 points**, est évalué sur la base du barème suivant : -- Repository exécutable sans erreur majeure (4 points) -- Fonctionnement conforme au scénario annoncé (4 points) -- Degré d'automatisation du projet (utilisation de Makefile ? script ? ...) (4 points) -- Qualité du Readme (lisibilité, erreur, ...) (4 points) -- Processus travail (quantité de commits, cohérence globale, interventions externes, ...) (4 points) +Ouvrez ensuite votre navigateur (ou l'onglet "PORTS" de VS Code) à l'adresse : `http://localhost:8082`. + +--- + +## Structure des fichiers + +| Fichier | Description | +| :--- | :--- | +| `Makefile` | **Point d'entrée**. Orchestre les commandes (setup, build, deploy). | +| `nginx.pkr.hcl` | Configuration **Packer**. Définit comment l'image Docker est construite. | +| `playbook.yml` | Configuration **Ansible**. Décrit l'état souhaité dans Kubernetes. | +| `index.html` | Le site web statique déployé. | + +--- + +## Commandes détaillées (Makefile) + +Si vous souhaitez exécuter les étapes une par une plutôt que d'utiliser `make all` : + +* `make setup` : Installe les collections Ansible requises. +* `make build` : Lance Packer pour créer l'image `my-custom-nginx:v1`. +* `make import` : Importe l'image locale dans le registre interne de K3d . +* `make deploy` : Exécute le playbook Ansible pour créer les ressources Kubernetes. +* `make clean` : Nettoie l'environnement (suppression du cluster). + +--- diff --git a/index.html b/index.html index 972916a..ed1e039 100644 --- a/index.html +++ b/index.html @@ -1,62 +1,7 @@ + - - - - +Atelier DevOps - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +

Victoire ! Mon image Nginx personnalisée est déployée sur K3d via Ansible.

diff --git a/nginx.pkr.hcl b/nginx.pkr.hcl new file mode 100644 index 0000000..28c5f57 --- /dev/null +++ b/nginx.pkr.hcl @@ -0,0 +1,32 @@ +packer { + required_plugins { + docker = { + version = ">= 0.0.7" + source = "github.com/hashicorp/docker" + } + } +} + +source "docker" "nginx" { + image = "nginx:latest" + commit = true + changes = [ + "EXPOSE 80", + "CMD [\"nginx\", \"-g\", \"daemon off;\"]" + ] +} + +build { + name = "atelier-packer" + sources = ["source.docker.nginx"] + + provisioner "file" { + source = "index.html" + destination = "/usr/share/nginx/html/index.html" + } + + post-processor "docker-tag" { + repository = "my-custom-nginx" + tag = ["v1"] + } +} diff --git a/playbook.yml b/playbook.yml new file mode 100644 index 0000000..545701e --- /dev/null +++ b/playbook.yml @@ -0,0 +1,49 @@ +- name: Déployer Nginx Custom sur K3d + hosts: localhost + connection: local + gather_facts: false + + tasks: + - name: Créer le Déploiement + kubernetes.core.k8s: + kubeconfig: "~/.kube/config" + definition: + apiVersion: apps/v1 + kind: Deployment + metadata: + name: nginx-custom + namespace: default + spec: + replicas: 1 + selector: + matchLabels: + app: nginx-custom + template: + metadata: + labels: + app: nginx-custom + spec: + containers: + - name: nginx + image: my-custom-nginx:v1 + imagePullPolicy: Never + ports: + - containerPort: 80 + + - name: Créer le Service + kubernetes.core.k8s: + kubeconfig: "~/.kube/config" + definition: + apiVersion: v1 + kind: Service + metadata: + name: nginx-service + namespace: default + spec: + selector: + app: nginx-custom + ports: + - protocol: TCP + port: 80 + targetPort: 80 + type: ClusterIP