concourse
parent
b775797383
commit
fddb497635
@ -0,0 +1 @@
|
|||||||
|
.venv
|
||||||
@ -0,0 +1,402 @@
|
|||||||
|
# 🎯 Exercice : Améliorer le serveur Nginx avec Ansible
|
||||||
|
|
||||||
|
## 📋 Objectif de l'exercice
|
||||||
|
|
||||||
|
Tu vas améliorer ton projet Ansible actuel en ajoutant 3 fonctionnalités importantes :
|
||||||
|
1. ✅ **HTTPS** (sécuriser le site avec un certificat SSL)
|
||||||
|
2. ✅ **Authentification** (protéger l'accès avec login/password)
|
||||||
|
3. ✅ **Déployer des pages web** (mettre ton propre site HTML)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Partie 1 : Configurer HTTPS avec Let's Encrypt
|
||||||
|
|
||||||
|
### 🤔 C'est quoi HTTPS ?
|
||||||
|
- HTTP = ton site est accessible mais **pas sécurisé** (pas de cadenas 🔓)
|
||||||
|
- HTTPS = ton site est **sécurisé** avec un certificat SSL (cadenas vert 🔒)
|
||||||
|
- Les données sont **chiffrées** entre le navigateur et le serveur
|
||||||
|
|
||||||
|
### 📝 Ce que tu dois faire :
|
||||||
|
|
||||||
|
#### Étape 1.1 : Installer Certbot
|
||||||
|
Certbot = outil gratuit pour obtenir un certificat SSL
|
||||||
|
|
||||||
|
**Ajoute cette tâche dans `playbook.yml`** (après l'installation de Nginx) :
|
||||||
|
```yaml
|
||||||
|
- name: Installer Certbot pour Let's Encrypt
|
||||||
|
apt:
|
||||||
|
name:
|
||||||
|
- certbot
|
||||||
|
- python3-certbot-nginx
|
||||||
|
state: present
|
||||||
|
```
|
||||||
|
|
||||||
|
**💡 Explication** :
|
||||||
|
- `certbot` = l'outil principal
|
||||||
|
- `python3-certbot-nginx` = plugin pour configurer automatiquement Nginx
|
||||||
|
|
||||||
|
#### Étape 1.2 : Générer le certificat SSL
|
||||||
|
**Ajoute cette tâche** :
|
||||||
|
```yaml
|
||||||
|
- name: Obtenir un certificat SSL avec Certbot
|
||||||
|
command: certbot --nginx -d defder.fr --non-interactive --agree-tos --email ton-email@exemple.com
|
||||||
|
args:
|
||||||
|
creates: /etc/letsencrypt/live/defder.fr/fullchain.pem
|
||||||
|
```
|
||||||
|
|
||||||
|
**💡 Explication** :
|
||||||
|
- `--nginx` = configure automatiquement Nginx
|
||||||
|
- `-d defder.fr` = ton nom de domaine
|
||||||
|
- `--non-interactive` = pas de questions (automatique)
|
||||||
|
- `--agree-tos` = accepte les conditions
|
||||||
|
- `--email` = **REMPLACE par ton vrai email !**
|
||||||
|
- `creates: ...` = ne refait pas si le certificat existe déjà
|
||||||
|
|
||||||
|
#### Étape 1.3 : Renouvellement automatique
|
||||||
|
Les certificats expirent tous les 90 jours. Il faut les renouveler automatiquement.
|
||||||
|
|
||||||
|
**Ajoute cette tâche** :
|
||||||
|
```yaml
|
||||||
|
- name: Configurer le renouvellement automatique du certificat
|
||||||
|
cron:
|
||||||
|
name: "Renouveler certificat SSL"
|
||||||
|
minute: "0"
|
||||||
|
hour: "3"
|
||||||
|
job: "certbot renew --quiet"
|
||||||
|
```
|
||||||
|
|
||||||
|
**💡 Explication** :
|
||||||
|
- Vérifie chaque jour à 3h du matin si le certificat doit être renouvelé
|
||||||
|
- `--quiet` = ne fait pas de bruit dans les logs
|
||||||
|
|
||||||
|
#### ✅ Vérification Partie 1
|
||||||
|
Lance ton playbook : `./run.sh`
|
||||||
|
|
||||||
|
Ensuite, teste dans ton navigateur : `https://defder.fr`
|
||||||
|
- Tu dois voir le **cadenas vert 🔒**
|
||||||
|
- Le site est maintenant sécurisé !
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔐 Partie 2 : Ajouter une authentification
|
||||||
|
|
||||||
|
### 🤔 C'est quoi l'authentification ?
|
||||||
|
Une popup qui demande **login + password** avant d'accéder au site.
|
||||||
|
Utile pour protéger un site privé, un backoffice, etc.
|
||||||
|
|
||||||
|
### 📝 Ce que tu dois faire :
|
||||||
|
|
||||||
|
#### Étape 2.1 : Installer les outils nécessaires
|
||||||
|
**Ajoute cette tâche** :
|
||||||
|
```yaml
|
||||||
|
- name: Installer apache2-utils pour htpasswd
|
||||||
|
apt:
|
||||||
|
name: apache2-utils
|
||||||
|
state: present
|
||||||
|
```
|
||||||
|
|
||||||
|
**💡 Explication** :
|
||||||
|
- `htpasswd` = outil pour créer des fichiers de mots de passe
|
||||||
|
|
||||||
|
#### Étape 2.2 : Créer un utilisateur avec mot de passe
|
||||||
|
**Ajoute cette tâche** :
|
||||||
|
```yaml
|
||||||
|
- name: Créer un fichier de mots de passe
|
||||||
|
htpasswd:
|
||||||
|
path: /etc/nginx/.htpasswd
|
||||||
|
name: admin
|
||||||
|
password: "MonMotDePasse123"
|
||||||
|
owner: root
|
||||||
|
group: www-data
|
||||||
|
mode: '0640'
|
||||||
|
```
|
||||||
|
|
||||||
|
**💡 Explication** :
|
||||||
|
- Crée un fichier `/etc/nginx/.htpasswd`
|
||||||
|
- Utilisateur : `admin`
|
||||||
|
- Mot de passe : `MonMotDePasse123` (**CHANGE-LE !**)
|
||||||
|
- `mode: '0640'` = permissions sécurisées
|
||||||
|
|
||||||
|
#### Étape 2.3 : Créer un fichier de configuration Nginx
|
||||||
|
Tu vas créer un fichier de config personnalisé pour Nginx.
|
||||||
|
|
||||||
|
**D'abord, crée un dossier `templates/` dans ton projet** :
|
||||||
|
```
|
||||||
|
iaac/
|
||||||
|
├── templates/
|
||||||
|
│ └── nginx-auth.conf.j2
|
||||||
|
├── playbook.yml
|
||||||
|
├── inventory.yml
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
**Crée le fichier `templates/nginx-auth.conf.j2`** avec ce contenu :
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name defder.fr;
|
||||||
|
|
||||||
|
# Redirection HTTP vers HTTPS
|
||||||
|
return 301 https://$server_name$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name defder.fr;
|
||||||
|
|
||||||
|
# Certificats SSL (générés par Certbot)
|
||||||
|
ssl_certificate /etc/letsencrypt/live/defder.fr/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/defder.fr/privkey.pem;
|
||||||
|
|
||||||
|
# Dossier racine du site
|
||||||
|
root /var/www/html;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
# AUTHENTIFICATION
|
||||||
|
auth_basic "Zone protégée - Connexion requise";
|
||||||
|
auth_basic_user_file /etc/nginx/.htpasswd;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ =404;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**💡 Explication** :
|
||||||
|
- Redirige automatiquement HTTP → HTTPS
|
||||||
|
- Active l'authentification avec `auth_basic`
|
||||||
|
- Pointe vers le fichier de mots de passe
|
||||||
|
|
||||||
|
#### Étape 2.4 : Déployer la configuration
|
||||||
|
**Ajoute cette tâche dans `playbook.yml`** :
|
||||||
|
```yaml
|
||||||
|
- name: Déployer la configuration Nginx avec authentification
|
||||||
|
template:
|
||||||
|
src: templates/nginx-auth.conf.j2
|
||||||
|
dest: /etc/nginx/sites-available/defder
|
||||||
|
notify: Recharger Nginx
|
||||||
|
|
||||||
|
- name: Activer le site
|
||||||
|
file:
|
||||||
|
src: /etc/nginx/sites-available/defder
|
||||||
|
dest: /etc/nginx/sites-enabled/defder
|
||||||
|
state: link
|
||||||
|
|
||||||
|
- name: Désactiver le site par défaut
|
||||||
|
file:
|
||||||
|
path: /etc/nginx/sites-enabled/default
|
||||||
|
state: absent
|
||||||
|
notify: Recharger Nginx
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Étape 2.5 : Ajouter un handler pour recharger Nginx
|
||||||
|
**À la fin de `playbook.yml`**, ajoute :
|
||||||
|
```yaml
|
||||||
|
handlers:
|
||||||
|
- name: Recharger Nginx
|
||||||
|
systemd:
|
||||||
|
name: nginx
|
||||||
|
state: reloaded
|
||||||
|
```
|
||||||
|
|
||||||
|
**💡 Explication** :
|
||||||
|
- Un handler = une action qui se déclenche quand un fichier change
|
||||||
|
- Recharge Nginx quand la config est modifiée
|
||||||
|
|
||||||
|
#### ✅ Vérification Partie 2
|
||||||
|
Lance ton playbook : `./run.sh`
|
||||||
|
|
||||||
|
Visite `https://defder.fr` → Une popup apparaît !
|
||||||
|
- Login : `admin`
|
||||||
|
- Password : `MonMotDePasse123` (ou celui que tu as choisi)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎨 Partie 3 : Déployer des pages web personnalisées
|
||||||
|
|
||||||
|
### 🤔 C'est quoi déployer des pages ?
|
||||||
|
Remplacer la page par défaut de Nginx par **ton propre site HTML**.
|
||||||
|
|
||||||
|
### 📝 Ce que tu dois faire :
|
||||||
|
|
||||||
|
#### Étape 3.1 : Créer un dossier pour ton site
|
||||||
|
**Dans ton projet, crée un dossier `files/`** :
|
||||||
|
```
|
||||||
|
iaac/
|
||||||
|
├── files/
|
||||||
|
│ ├── index.html
|
||||||
|
│ └── style.css
|
||||||
|
├── templates/
|
||||||
|
├── playbook.yml
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Étape 3.2 : Créer une page HTML
|
||||||
|
**Crée `files/index.html`** :
|
||||||
|
```html
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Mon site déployé avec Ansible</title>
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1>🚀 Bienvenue sur mon serveur !</h1>
|
||||||
|
<p>Ce site a été déployé automatiquement avec Ansible.</p>
|
||||||
|
<ul>
|
||||||
|
<li>✅ Serveur : Nginx</li>
|
||||||
|
<li>✅ Sécurité : HTTPS activé</li>
|
||||||
|
<li>✅ Protection : Authentification activée</li>
|
||||||
|
<li>✅ Automatisation : 100% IaaC</li>
|
||||||
|
</ul>
|
||||||
|
<p class="footer">Déployé le {{ ansible_date_time.date }} 🎉</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Étape 3.3 : Créer un fichier CSS
|
||||||
|
**Crée `files/style.css`** :
|
||||||
|
```css
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
background: white;
|
||||||
|
padding: 3rem;
|
||||||
|
border-radius: 15px;
|
||||||
|
box-shadow: 0 10px 40px rgba(0,0,0,0.3);
|
||||||
|
max-width: 600px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
color: #667eea;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
font-size: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
margin: 2rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul li {
|
||||||
|
background: #f0f0f0;
|
||||||
|
padding: 0.8rem;
|
||||||
|
margin: 0.5rem 0;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
margin-top: 2rem;
|
||||||
|
font-style: italic;
|
||||||
|
color: #667eea;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Étape 3.4 : Déployer les fichiers sur le serveur
|
||||||
|
**Ajoute ces tâches dans `playbook.yml`** (avant le handler) :
|
||||||
|
```yaml
|
||||||
|
- name: Créer le dossier du site web
|
||||||
|
file:
|
||||||
|
path: /var/www/html
|
||||||
|
state: directory
|
||||||
|
owner: www-data
|
||||||
|
group: www-data
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: Déployer la page HTML
|
||||||
|
template:
|
||||||
|
src: files/index.html
|
||||||
|
dest: /var/www/html/index.html
|
||||||
|
owner: www-data
|
||||||
|
group: www-data
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Déployer le fichier CSS
|
||||||
|
copy:
|
||||||
|
src: files/style.css
|
||||||
|
dest: /var/www/html/style.css
|
||||||
|
owner: www-data
|
||||||
|
group: www-data
|
||||||
|
mode: '0644'
|
||||||
|
```
|
||||||
|
|
||||||
|
**💡 Explication** :
|
||||||
|
- `template:` pour index.html = permet d'utiliser des variables Ansible (comme la date)
|
||||||
|
- `copy:` pour style.css = copie simple du fichier
|
||||||
|
- `owner: www-data` = donne les bons droits à Nginx
|
||||||
|
|
||||||
|
#### ✅ Vérification Partie 3
|
||||||
|
Lance ton playbook : `./run.sh`
|
||||||
|
|
||||||
|
Visite `https://defder.fr` :
|
||||||
|
- Entre login/password
|
||||||
|
- Tu vois **ton site personnalisé** ! 🎉
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎓 Résumé de ce que tu as appris
|
||||||
|
|
||||||
|
| Fonctionnalité | Module Ansible | Utilité |
|
||||||
|
|---------------|----------------|---------|
|
||||||
|
| **HTTPS** | `command` (certbot) | Sécuriser le site |
|
||||||
|
| **Authentification** | `htpasswd` | Protéger l'accès |
|
||||||
|
| **Configuration Nginx** | `template` | Personnaliser le serveur |
|
||||||
|
| **Déploiement de fichiers** | `copy` / `template` | Mettre en ligne ton site |
|
||||||
|
| **Handlers** | `handlers` | Recharger Nginx automatiquement |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Pour aller plus loin (Bonus)
|
||||||
|
|
||||||
|
### Idées d'améliorations :
|
||||||
|
1. **Plusieurs utilisateurs** : Ajoute plusieurs logins dans htpasswd
|
||||||
|
2. **Variables** : Mets le nom de domaine, email, etc. dans un fichier `vars.yml`
|
||||||
|
3. **Rôles Ansible** : Organise ton code en rôles (nginx, ssl, web)
|
||||||
|
4. **CI/CD** : Automatise le déploiement avec GitHub Actions
|
||||||
|
5. **Monitoring** : Ajoute un outil pour surveiller le serveur
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📚 Ressources utiles
|
||||||
|
|
||||||
|
- **Documentation Ansible** : https://docs.ansible.com
|
||||||
|
- **Certbot** : https://certbot.eff.org
|
||||||
|
- **Nginx** : https://nginx.org/en/docs/
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Checklist finale
|
||||||
|
|
||||||
|
- [ ] HTTPS fonctionne (cadenas vert)
|
||||||
|
- [ ] Authentification demande login/password
|
||||||
|
- [ ] Page personnalisée affichée
|
||||||
|
- [ ] Certificat SSL se renouvelle automatiquement
|
||||||
|
- [ ] Code versionné sur Git
|
||||||
|
- [ ] Playbook s'exécute sans erreur
|
||||||
|
|
||||||
|
**Bravo ! Tu as créé une infrastructure complète et sécurisée avec Ansible ! 🎉**
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
# Projet Ansible - Installation Nginx sur VPS
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
1. **Modifier l'inventory** : Éditez `inventory.yml` et remplacez `YOUR_VPS_IP_ADDRESS` par l'adresse IP de votre VPS
|
||||||
|
|
||||||
|
2. **Configurer l'accès SSH** :
|
||||||
|
- Assurez-vous d'avoir accès SSH à votre VPS
|
||||||
|
- Si vous utilisez une clé SSH, décommentez et configurez `ansible_ssh_private_key_file`
|
||||||
|
|
||||||
|
## Utilisation
|
||||||
|
|
||||||
|
### Tester la connexion
|
||||||
|
```bash
|
||||||
|
ansible all -m ping
|
||||||
|
```
|
||||||
|
|
||||||
|
### Exécuter le playbook
|
||||||
|
```bash
|
||||||
|
ansible-playbook playbook.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
### Exécuter en mode vérification (dry-run)
|
||||||
|
```bash
|
||||||
|
ansible-playbook playbook.yml --check
|
||||||
|
```
|
||||||
|
|
||||||
|
### Exécuter avec verbosité
|
||||||
|
```bash
|
||||||
|
ansible-playbook playbook.yml -v
|
||||||
|
```
|
||||||
|
|
||||||
|
## Structure du projet
|
||||||
|
|
||||||
|
- `ansible.cfg` : Configuration Ansible
|
||||||
|
- `inventory.yml` : Inventaire des serveurs au format YAML
|
||||||
|
- `playbook.yml` : Playbook d'installation de Nginx
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
[defaults]
|
||||||
|
inventory = inventory.yml
|
||||||
|
host_key_checking = False
|
||||||
|
remote_user = root
|
||||||
|
retry_files_enabled = False
|
||||||
|
|
||||||
|
[privilege_escalation]
|
||||||
|
become = True
|
||||||
|
become_method = sudo
|
||||||
|
become_user = root
|
||||||
|
become_ask_pass = False
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Mon site déployé avec Ansible</title>
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1>🚀 Bienvenue sur mon serveur !</h1>
|
||||||
|
<p>Ce site a été déployé automatiquement avec Ansible.</p>
|
||||||
|
<ul>
|
||||||
|
<li>✅ Serveur : Nginx</li>
|
||||||
|
<li>✅ Sécurité : HTTPS activé</li>
|
||||||
|
<li>✅ Protection : Authentification activée</li>
|
||||||
|
<li>✅ Automatisation : 100% IaaC</li>
|
||||||
|
</ul>
|
||||||
|
<p class="footer">Déployé le {{ ansible_date_time.date }} 🎉</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
background: white;
|
||||||
|
padding: 3rem;
|
||||||
|
border-radius: 15px;
|
||||||
|
box-shadow: 0 10px 40px rgba(0,0,0,0.3);
|
||||||
|
max-width: 600px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
color: #667eea;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
font-size: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
margin: 2rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul li {
|
||||||
|
background: #f0f0f0;
|
||||||
|
padding: 0.8rem;
|
||||||
|
margin: 0.5rem 0;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
margin-top: 2rem;
|
||||||
|
font-style: italic;
|
||||||
|
color: #667eea;
|
||||||
|
}
|
||||||
@ -0,0 +1,51 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Script d'installation du projet Ansible
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "================================================"
|
||||||
|
echo "Installation du projet Ansible - Nginx sur VPS"
|
||||||
|
echo "================================================"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Vérifier si Python3 est installé
|
||||||
|
if ! command -v python3 &> /dev/null; then
|
||||||
|
echo "❌ Python3 n'est pas installé. Veuillez l'installer d'abord."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✅ Python3 est installé"
|
||||||
|
|
||||||
|
# Créer un environnement virtuel s'il n'existe pas
|
||||||
|
if [ ! -d ".venv" ]; then
|
||||||
|
echo "📦 Création de l'environnement virtuel..."
|
||||||
|
python3 -m venv .venv
|
||||||
|
echo "✅ Environnement virtuel créé"
|
||||||
|
else
|
||||||
|
echo "✅ Environnement virtuel existe déjà"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Activer l'environnement virtuel
|
||||||
|
echo "🔧 Activation de l'environnement virtuel..."
|
||||||
|
source .venv/bin/activate
|
||||||
|
|
||||||
|
# Mettre à jour pip
|
||||||
|
echo "⬆️ Mise à jour de pip..."
|
||||||
|
pip install --upgrade pip > /dev/null 2>&1
|
||||||
|
|
||||||
|
# Installer les dépendances
|
||||||
|
echo "📥 Installation d'Ansible et des dépendances..."
|
||||||
|
pip install -r requirements.txt
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "✅ Installation terminée avec succès!"
|
||||||
|
echo ""
|
||||||
|
echo "================================================"
|
||||||
|
echo "Prochaines étapes:"
|
||||||
|
echo "================================================"
|
||||||
|
echo "1. Éditez 'inventory.yml' et configurez l'IP de votre VPS"
|
||||||
|
echo "2. Activez l'environnement virtuel : source .venv/bin/activate"
|
||||||
|
echo "3. Testez la connexion : ansible all -m ping"
|
||||||
|
echo "4. Lancez le script : ./run.sh"
|
||||||
|
echo ""
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
all:
|
||||||
|
children:
|
||||||
|
webservers:
|
||||||
|
hosts:
|
||||||
|
vps1:
|
||||||
|
ansible_host: defder.fr
|
||||||
|
ansible_user: root
|
||||||
|
ansible_port: 22
|
||||||
|
ansible_ssh_private_key_file: ./defderkey
|
||||||
|
|
||||||
@ -0,0 +1,79 @@
|
|||||||
|
# ==============================================
|
||||||
|
# Pipeline Concourse - Déploiement Automatique
|
||||||
|
# ==============================================
|
||||||
|
# Surveille le repo Git et déploie automatiquement
|
||||||
|
|
||||||
|
resource_types: []
|
||||||
|
|
||||||
|
resources:
|
||||||
|
# Repo Git local (polling toutes les 30 secondes)
|
||||||
|
- name: repo
|
||||||
|
type: git
|
||||||
|
icon: gitlab
|
||||||
|
check_every: 30s
|
||||||
|
source:
|
||||||
|
uri: https://forge.gwenaelremond.fr/romain/ansiblenginx.git
|
||||||
|
branch: main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# Job principal : Déploiement automatique
|
||||||
|
- name: deploy-bricoloc
|
||||||
|
plan:
|
||||||
|
# 1. Récupère le code depuis Git
|
||||||
|
- get: repo
|
||||||
|
trigger: true # Déclenche automatiquement sur changement
|
||||||
|
|
||||||
|
# 2. Déploie sur le VPS
|
||||||
|
- task: deploy-to-vps
|
||||||
|
config:
|
||||||
|
platform: linux
|
||||||
|
|
||||||
|
image_resource:
|
||||||
|
type: registry-image
|
||||||
|
source:
|
||||||
|
repository: python
|
||||||
|
tag: "3.11-slim"
|
||||||
|
|
||||||
|
inputs:
|
||||||
|
- name: repo
|
||||||
|
|
||||||
|
params:
|
||||||
|
ssh_private_key: ((ssh_private_key))
|
||||||
|
vps_host: ((vps_host))
|
||||||
|
vps_user: ((vps_user))
|
||||||
|
|
||||||
|
run:
|
||||||
|
path: /bin/bash
|
||||||
|
args:
|
||||||
|
- -exc
|
||||||
|
- |
|
||||||
|
# Installer les dépendances
|
||||||
|
apt-get update && apt-get install -y openssh-client rsync sshpass
|
||||||
|
pip install ansible
|
||||||
|
|
||||||
|
# Configurer SSH
|
||||||
|
mkdir -p ~/.ssh
|
||||||
|
echo "$ssh_private_key" > ~/.ssh/id_rsa
|
||||||
|
chmod 600 ~/.ssh/id_rsa
|
||||||
|
ssh-keyscan -H $vps_host >> ~/.ssh/known_hosts 2>/dev/null
|
||||||
|
|
||||||
|
cd repo
|
||||||
|
|
||||||
|
# Créer l'inventaire dynamique
|
||||||
|
cat > inventory.yml << EOF
|
||||||
|
all:
|
||||||
|
hosts:
|
||||||
|
vps1:
|
||||||
|
ansible_host: $vps_host
|
||||||
|
ansible_user: $vps_user
|
||||||
|
ansible_ssh_private_key_file: ~/.ssh/id_rsa
|
||||||
|
children:
|
||||||
|
webservers:
|
||||||
|
hosts:
|
||||||
|
vps1:
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Lancer le playbook Ansible
|
||||||
|
ansible-playbook -i inventory.yml playbook.yml
|
||||||
|
|
||||||
|
echo "✅ Déploiement terminé sur $vps_host"
|
||||||
@ -0,0 +1,239 @@
|
|||||||
|
---
|
||||||
|
- name: Installer et configurer Nginx sur VPS Ubuntu
|
||||||
|
hosts: webservers
|
||||||
|
become: yes
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Mettre à jour le cache apt
|
||||||
|
apt:
|
||||||
|
update_cache: yes
|
||||||
|
cache_valid_time: 3600
|
||||||
|
|
||||||
|
- name: Installer Nginx
|
||||||
|
apt:
|
||||||
|
name: nginx
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Installer Node.js et npm
|
||||||
|
apt:
|
||||||
|
name:
|
||||||
|
- nodejs
|
||||||
|
- npm
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Installer pnpm globalement
|
||||||
|
command: npm install -g pnpm
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Installer apache2-utils pour htpasswd
|
||||||
|
apt:
|
||||||
|
name: apache2-utils
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Installer la librairie Python passlib
|
||||||
|
apt:
|
||||||
|
name: python3-passlib
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Créer un fichier de mots de passe
|
||||||
|
htpasswd:
|
||||||
|
path: /etc/nginx/.htpasswd
|
||||||
|
name: admin
|
||||||
|
password: "mdp123"
|
||||||
|
owner: root
|
||||||
|
group: www-data
|
||||||
|
mode: '0640'
|
||||||
|
|
||||||
|
- name: Installer Certbot pour Let's Encrypt
|
||||||
|
apt:
|
||||||
|
name:
|
||||||
|
- certbot
|
||||||
|
- python3-certbot-nginx
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Obtenir un certificat SSL avec Certbot
|
||||||
|
command: certbot --nginx -d defder.fr --non-interactive --agree-tos --email bottero.romain1811@gmail.com --redirect
|
||||||
|
notify: Restart Nginx
|
||||||
|
args:
|
||||||
|
creates: /etc/letsencrypt/live/defder.fr/fullchain.pem
|
||||||
|
|
||||||
|
- name: Configurer le renouvellement automatique du certificat
|
||||||
|
cron:
|
||||||
|
name: "Renouveler le certificat SSL"
|
||||||
|
minute: "0"
|
||||||
|
hour: "3"
|
||||||
|
job: "certbot renew --quiet"
|
||||||
|
|
||||||
|
|
||||||
|
- name: S'assurer qu'UFW est installé
|
||||||
|
apt:
|
||||||
|
name: ufw
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Autoriser le trafic SSH dans le firewall (UFW)
|
||||||
|
ufw:
|
||||||
|
rule: allow
|
||||||
|
port: '22'
|
||||||
|
proto: tcp
|
||||||
|
|
||||||
|
- name: Autoriser le trafic HTTP dans le firewall (UFW)
|
||||||
|
ufw:
|
||||||
|
rule: allow
|
||||||
|
port: '80'
|
||||||
|
proto: tcp
|
||||||
|
|
||||||
|
- name: Autoriser le trafic HTTPS dans le firewall (UFW)
|
||||||
|
ufw:
|
||||||
|
rule: allow
|
||||||
|
port: '443'
|
||||||
|
proto: tcp
|
||||||
|
|
||||||
|
- name: Activer UFW(uncomplicated firewall)
|
||||||
|
ufw:
|
||||||
|
state: enabled
|
||||||
|
|
||||||
|
- name: Démarrer et activer Nginx
|
||||||
|
systemd:
|
||||||
|
name: nginx
|
||||||
|
state: started
|
||||||
|
enabled: yes
|
||||||
|
# Config Nginx supprimée - on utilise uniquement nginx-app-legacy.conf.j2
|
||||||
|
# qui fait le reverse proxy vers l'app Node.js
|
||||||
|
|
||||||
|
- name: Supprimer toute ancienne config Nginx obsolète
|
||||||
|
file:
|
||||||
|
path: /etc/nginx/sites-available/defder
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Déployer la configuration Nginx pour l'app legacy
|
||||||
|
template:
|
||||||
|
src: templates/nginx-app-legacy.conf.j2
|
||||||
|
dest: /etc/nginx/sites-available/defder
|
||||||
|
notify: Recharger Nginx
|
||||||
|
|
||||||
|
- name: Déployer le service systemd pour l'app legacy
|
||||||
|
template:
|
||||||
|
src: templates/bricoloc-legacy.service.j2
|
||||||
|
dest: /etc/systemd/system/bricoloc-legacy.service
|
||||||
|
notify: Redémarrer l'app legacy
|
||||||
|
|
||||||
|
- name: Activer et démarrer le service legacy
|
||||||
|
systemd:
|
||||||
|
name: bricoloc-legacy
|
||||||
|
state: started
|
||||||
|
enabled: yes
|
||||||
|
daemon_reload: yes
|
||||||
|
|
||||||
|
- name: Activer le site
|
||||||
|
file:
|
||||||
|
src: /etc/nginx/sites-available/defder
|
||||||
|
dest: /etc/nginx/sites-enabled/defder
|
||||||
|
state: link
|
||||||
|
notify: Recharger Nginx
|
||||||
|
|
||||||
|
- name: Désactiver le site par défaut
|
||||||
|
file:
|
||||||
|
path: /etc/nginx/sites-enabled/default
|
||||||
|
state: absent
|
||||||
|
notify: Recharger Nginx
|
||||||
|
|
||||||
|
- name: Vérifier que Nginx est en cours d'exécution
|
||||||
|
service:
|
||||||
|
name: nginx
|
||||||
|
state: started
|
||||||
|
register: nginx_status
|
||||||
|
|
||||||
|
- name: Afficher le statut de Nginx
|
||||||
|
debug:
|
||||||
|
msg: "Nginx est installé et en cours d'exécution"
|
||||||
|
|
||||||
|
|
||||||
|
- name: Récupérer l'IP du serveur
|
||||||
|
command: hostname -I
|
||||||
|
register: server_ip
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Créer le dossier du site web
|
||||||
|
file:
|
||||||
|
path: /var/www/apps
|
||||||
|
state: directory
|
||||||
|
owner: www-data
|
||||||
|
group: www-data
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: Créer le dossier .local pour pnpm
|
||||||
|
file:
|
||||||
|
path: /var/www/.local/share/pnpm
|
||||||
|
state: directory
|
||||||
|
owner: www-data
|
||||||
|
group: www-data
|
||||||
|
mode: '0755'
|
||||||
|
recurse: yes
|
||||||
|
|
||||||
|
- name: Déployer l'app depuis le repo local
|
||||||
|
synchronize:
|
||||||
|
src: app/bricolociaac/
|
||||||
|
dest: /var/www/apps/bricolociaac/
|
||||||
|
delete: yes
|
||||||
|
rsync_opts:
|
||||||
|
- "--exclude=node_modules"
|
||||||
|
- "--exclude=.git"
|
||||||
|
|
||||||
|
- name: Définir les permissions sur les fichiers déployés
|
||||||
|
file:
|
||||||
|
path: /var/www/apps/bricolociaac
|
||||||
|
owner: www-data
|
||||||
|
group: www-data
|
||||||
|
recurse: yes
|
||||||
|
|
||||||
|
- name: Installer les dépendances du projet
|
||||||
|
shell: |
|
||||||
|
cd /var/www/apps/bricolociaac
|
||||||
|
pnpm install --frozen-lockfile || pnpm install
|
||||||
|
environment:
|
||||||
|
NODE_ENV: production
|
||||||
|
PNPM_HOME: /var/www/.local/share/pnpm
|
||||||
|
timeout: 600
|
||||||
|
|
||||||
|
- name: Installer les dépendances de l'app legacy spécifiquement
|
||||||
|
shell: |
|
||||||
|
cd /var/www/apps/bricolociaac
|
||||||
|
pnpm install --filter legacy --frozen-lockfile || pnpm install --filter legacy
|
||||||
|
environment:
|
||||||
|
NODE_ENV: production
|
||||||
|
PNPM_HOME: /var/www/.local/share/pnpm
|
||||||
|
timeout: 600
|
||||||
|
|
||||||
|
- name: Builder l'app legacy
|
||||||
|
command: pnpm build:legacy
|
||||||
|
args:
|
||||||
|
chdir: /var/www/apps/bricolociaac
|
||||||
|
environment:
|
||||||
|
NODE_ENV: production
|
||||||
|
PNPM_HOME: /var/www/.local/share/pnpm
|
||||||
|
|
||||||
|
- name: Redémarrer le service bricoloc-legacy après déploiement
|
||||||
|
systemd:
|
||||||
|
name: bricoloc-legacy
|
||||||
|
state: restarted
|
||||||
|
daemon_reload: yes
|
||||||
|
|
||||||
|
- name: Afficher l'URL d'accès
|
||||||
|
debug:
|
||||||
|
msg: "Nginx est accessible à l'adresse : https://defder.fr (ou http://{{ server_ip.stdout.split()[0] }} qui redirige vers HTTPS)"
|
||||||
|
|
||||||
|
handlers:
|
||||||
|
- name: Restart Nginx
|
||||||
|
service:
|
||||||
|
name: nginx
|
||||||
|
state: restarted
|
||||||
|
|
||||||
|
- name: Recharger Nginx
|
||||||
|
systemd:
|
||||||
|
name: nginx
|
||||||
|
state: reloaded
|
||||||
|
|
||||||
|
- name: Redémarrer l'app legacy
|
||||||
|
systemd:
|
||||||
|
name: bricoloc-legacy
|
||||||
|
state: restarted
|
||||||
@ -0,0 +1 @@
|
|||||||
|
ansible>=2.9
|
||||||
@ -0,0 +1 @@
|
|||||||
|
ansible-playbook -i inventory.yml --private-key defderkey playbook.yml
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Bricoloc Legacy App
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=www-data
|
||||||
|
WorkingDirectory=/var/www/apps/bricolociaac/apps/legacy-app
|
||||||
|
Environment="NODE_ENV=production"
|
||||||
|
ExecStart=/usr/bin/node src/server.js
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=10
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name defder.fr;
|
||||||
|
|
||||||
|
# Redirection HTTP vers HTTPS
|
||||||
|
return 301 https://$server_name$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name defder.fr;
|
||||||
|
|
||||||
|
# Certificats SSL (générés par Certbot)
|
||||||
|
ssl_certificate /etc/letsencrypt/live/defder.fr/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/defder.fr/privkey.pem;
|
||||||
|
|
||||||
|
# AUTHENTIFICATION
|
||||||
|
auth_basic "Zone protégée - Connexion requise";
|
||||||
|
auth_basic_user_file /etc/nginx/.htpasswd;
|
||||||
|
|
||||||
|
# Reverse proxy vers l'app legacy (port 3000)
|
||||||
|
location / {
|
||||||
|
proxy_pass http://localhost:3000;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection 'upgrade';
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_cache_bypass $http_upgrade;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue