Compare commits
6 Commits
b56749182e
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
83779cf5d7 | ||
|
|
7c0cb330d9 | ||
|
|
f45ac0cb6e | ||
|
|
66ac47b684 | ||
|
|
fb62291b3e | ||
|
|
8c2251faba |
24
.gitignore
vendored
Normal file
24
.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# Dependencies
|
||||||
|
node_modules/
|
||||||
|
*/node_modules/
|
||||||
|
|
||||||
|
# Build outputs
|
||||||
|
dist/
|
||||||
|
build/
|
||||||
|
*.pyc
|
||||||
|
__pycache__/
|
||||||
|
|
||||||
|
# Environment files
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
*.env
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
173
TODO.md
173
TODO.md
@@ -1,100 +1,121 @@
|
|||||||
# Smart City Digital Twin — TODO List
|
# Smart City Digital Twin — TODO List
|
||||||
|
|
||||||
> Dernière mise à jour : 2026-06-01 22:00 (session continue - smart app + ditto)
|
> Dernière mise à jour : 2026-06-04 02:00 (finalisation)
|
||||||
|
|
||||||
## ✅ Complété (session 2026-06-01)
|
## ✅ Complété (session 2026-06-03 / 06-04)
|
||||||
|
|
||||||
| ID | Tâche | Détail |
|
| ID | Tâche | Détail |
|
||||||
|----|-------|--------|
|
|----|-------|--------|
|
||||||
| jupyterhub-fix | JupyterHub DB path | `sqlite:////srv/jupyterhub/jupyterhub.sqlite` (absolute path, 4 slashes) |
|
| airflow-deploy | Apache Airflow déployé | `airflow.digitribe.fr` — Python 3.11, LocalExecutor |
|
||||||
| jupyterhub-rebuild | Rebuild Dockerfile | Supprimé double-nested `/srv/jupyterhub/srv/jupyterhub` |
|
| openfn-cleanup | OpenFN supprimé | Race condition Cachex/Ecto non résolue |
|
||||||
| jupyterhub-spawner | Spawner config | `SimpleLocalProcessSpawner`, timeout 300s |
|
| ditto-cleanup | Stack Ditto supprimée | API v2 non fonctionnelle (schema-versions) |
|
||||||
| jupyterhub-user | User eric | Créé id=2, admin, authorized |
|
| openremote-cleanup | Stack OpenRemote supprimée | Patches bundle appliqués |
|
||||||
| jupyterhub-sudo | sudo + eric user in container | Dockerfile modifié, spawn vérifié fonctionnel |
|
| gravitino-cleanup | Gravitino supprimé | Unhealthy |
|
||||||
| hermes-dashboard | Dashboard WebUI+TUI | systemd service, localhost:9119, auto-boot |
|
| fiware-gis-cleanup | FIWARE GIS Quickstart supprimé | |
|
||||||
| or-mbtiles-metadata | Bounds monde + center Martinique | `sqlite3` UPDATE sur metadata |
|
| contexus-cleanup | Contexus supprimé | Unhealthy |
|
||||||
| or-map-settings | mapsettings.json vérifié | center=[-61,14.5], bounds=Martinique, minZoom=0 |
|
| kafka-cleanup | Kafka supprimé | Unhealthy + sera redeployé via Helm |
|
||||||
| or-mbtiles-location | mbtiles actif = /storage/map/ | PAS /opt/map/ (écrasé par volume) |
|
| flink-cleanup | Flink supprimé | Dépendances kafka |
|
||||||
| trino-fix | node.properties créé | `node.environment=production`, `node.id=trino-lakehouse-01` |
|
| bi-cleanup | Superset + Metabase supprimés | Seront redeployés via Helm |
|
||||||
| trino-config | config.properties nettoyé | `plugin.bundles` retiré (incompatible Trino 435) |
|
| mindsdb-cleanup | MindsDB supprimé | Autoheal unhealthy |
|
||||||
| kafka-fix | Kafka KRaft env vars | `KAFKA_CFG_*` → `KAFKA_*`, `CLUSTER_ID` ajouté, volumes recréés |
|
| odk-cleanup | ODK Central supprimé | Sera redeployé via Helm |
|
||||||
| git-push | Commits | Pushé sur Gitea (smart-city-digital-twin-martinique + lakehouse) |
|
| jupyterhub-cleanup | JupyterHub supprimé | Sera redeployé via Helm |
|
||||||
| **smart-app-mvp** | **Smart App City MVP complet** | **Voir détail ci-dessous** |
|
| zeppelin-cleanup | Zeppelin supprimé | Sera redeployé via Helm |
|
||||||
| honcho-api | Honcho API déployée | `honcho-api-1` — Up sur `honcho.digitribe.fr`, workspace `hermes-agent` |
|
| gis-cleanup | MapStore + GeoServer + FROST supprimés | Seront redeployés via Helm |
|
||||||
| honcho-plugin | Plugin mémoire Hermes ↔ Honcho | `~/.hermes/honcho.json` configuré, baseUrl `http://127.0.0.1:8089` |
|
| iot-cleanup | Node-RED + phpIPAM + EMQX + Mosquitto + BunkerM + ChirpStack supprimés | Seront redeployés via Helm |
|
||||||
| honcho-mémoire | Mémoire Honcho fonctionnelle | Stockage messages OK. Dialectic chat → nécessite clé LLM valide |
|
| monitoring-cleanup | Grafana + Loki + Prometheus + InfluxDB + Telegraf supprimés | Seront redeployés via Helm |
|
||||||
| cicd-pipeline | Gitea Actions CI/CD | Workflow lint + build + deploy, runner docker-runner-01 |
|
| storage-cleanup | MinIO + PostgreSQL + PostGIS + Redis + Zookeeper supprimés | Seront redeployés via Helm |
|
||||||
| ci-cd-secrets | Secrets Gitea Actions | SERVER_HOST, SERVER_USER, SSH_PRIVATE_KEY configurés |
|
| misc-cleanup | AgentGateway + Esperotech + Redpanda Console + Docker exporter + Simulator supprimés | |
|
||||||
| smart-app-docker | Dockerfile web + Traefik | Multi-stage node + nginx, SPA routing, smartapp.digitribe.fr |
|
| backups | Sauvegardes config | Fichiers sauvegardés dans /home/eric/backups/2026-06-04/ |
|
||||||
| smart-app-deploy | Script de déploiement | `deploy.sh` — web/docker/api/all |
|
| helms-ansible | Fichiers Helm/Ansibles générés | 25+ rôles dans helms/ |
|
||||||
| localai-fix | LocalAI Bad Gateway | Container n'existe plus, config Traefik supprimée |
|
| helms-readme | README déploiement K8s | Architecture, installation, troubleshooting |
|
||||||
| ditto-mongodb-fix | MongoDB connection | `-Dditto.mongodb.uri` dans JAVA_TOOL_OPTIONS |
|
| helms-vault | Template vault.yml | Variables chiffrées pour le déploiement |
|
||||||
| ditto-secrets | Nouveaux secrets JWT/devops | Générés aléatoirement, sauvegardés `.env.ditto` |
|
| git-push | Push sur Gitea | 2 commits pushés (TODO + helms) |
|
||||||
| ditto-official-images | Gateway custom → latest | `eclipse/ditto-gateway:latest` officiel |
|
|
||||||
|
|
||||||
## 🔴 En cours
|
## 🔴 En cours
|
||||||
|
|
||||||
| ID | Tâche | Raison | Prochaine action |
|
| ID | Tâche | Raison | Prochaine action |
|
||||||
|----|-------|--------|------------------|
|
|----|-------|--------|------------------|
|
||||||
| or-map-bounds | MapService retourne bounds Pays-Bas | Bug MapResourceImpl.java: mbtiles metadata bounds prioritaire sur mapsettings.json | Générer vrai mbtiles MVT Martinique OU patcher code source OR |
|
| (aucune) | — | — | — |
|
||||||
|
|
||||||
## ⏳ En attente
|
## ⏳ En attente (déploiement Kubernetes via Ansible)
|
||||||
|
|
||||||
| ID | Tâche |
|
| ID | Tâche |
|
||||||
|----|-------|
|
|----|-------|
|
||||||
| or-mbtiles-martinique | Générer mbtiles MVT PBF pour Martinique (tippecanoe depuis GeoJSON filtré) |
|
| k8s-cluster | Créer le cluster Kubernetes (3 nœuds minimum) |
|
||||||
| p1-or-map | Vérifier carte Martinique après fix bounds |
|
| nfs-server | Configurer le serveur NFS pour le storage |
|
||||||
| p1-contexus-60 | Configurer les 60 devices Contexus |
|
| traefik-deploy | Déployer Traefik via Helm |
|
||||||
| p3-analyse | GeoMesa + KeplerGL |
|
| cert-manager-deploy | Déployer cert-manager pour TLS |
|
||||||
| p0-chirpstack | ChirpStack login API gRPC-REST |
|
| storage-deploy | Déployer NFS provisioner + StorageClass |
|
||||||
| p1-thingsboard | Relancer ThingsBoard (si CPU dispo) |
|
| monitoring-deploy | Déployer Prometheus + Grafana + Loki |
|
||||||
| smart-app Phase 1 | MVP React Native |
|
| databases-deploy | Déployer PostgreSQL HA + Redis + MinIO |
|
||||||
| p2-geoserver | GeoServer + PostGIS couches Martinique |
|
| kafka-deploy | Déployer Kafka (Strimzi) |
|
||||||
|
| flink-deploy | Déployer Apache Flink |
|
||||||
|
| airflow-deploy | Déployer Apache Airflow |
|
||||||
|
| iot-deploy | Déployer EMQX + Mosquitto + Node-RED + phpIPAM |
|
||||||
|
| gitea-deploy | Déployer Gitea |
|
||||||
|
| jupyterhub-deploy | Déployer JupyterHub |
|
||||||
|
| bi-deploy | Déployer Superset + Metabase |
|
||||||
|
| mindsdb-deploy | Déployer MindsDB |
|
||||||
|
| odk-deploy | Déployer ODK Central |
|
||||||
|
| gis-deploy | Déployer MapStore + GeoServer + FROST |
|
||||||
|
| clickhouse-deploy | Déployer ClickHouse (`clickhouse.digitribe.fr`) |
|
||||||
|
| starrocks-deploy | Déployer StarRocks (`starrocks.digitribe.fr`) |
|
||||||
|
| trino-deploy | Déployer Trino (`trino.digitribe.fr`) |
|
||||||
|
| deltalake-deploy | Déployer Delta Lake (`deltalake.digitribe.fr`) |
|
||||||
|
| streamlit-deploy | Déployer Streamlit (`streamlit.digitribe.fr`) |
|
||||||
|
| duckdb-deploy | Déployer DuckDB (`duckdb.digitribe.fr`) |
|
||||||
|
| smartapp-deploy | Déployer Smart App (`smartapp.digitribe.fr`) |
|
||||||
|
| backup-deploy | Déployer Velero pour les sauvegardes |
|
||||||
|
|
||||||
## 📝 Notes techniques 2026-06-01
|
## 📁 Fichiers Helm / Ansible générés
|
||||||
|
|
||||||
### OpenRemote mbtiles — Points critiques
|
Le répertoire `helms/` (dans le repo Gitea) contient les fichiers pour un déploiement modulaire sur Kubernetes via Ansible.
|
||||||
- Fichier actif : `/storage/map/mapdata.mbtiles` (volume Docker), PAS `/opt/map/`
|
|
||||||
- OR 1.24.0 ne sert que du **PBF vectoriel** — PNG raster = 404
|
|
||||||
- Bug : MapService.java donne priorité aux bounds du mbtiles metadata sur mapsettings.json
|
|
||||||
- Fix : bounds mbtiles metadata = monde (`-180,-85,180,85`), bounds mapsettings = zone désirée
|
|
||||||
- Pour mettre à jour : `docker cp file.mbtiles openremote-manager:/storage/map/mapdata.mbtiles`
|
|
||||||
|
|
||||||
### JupyterHub
|
### Structure
|
||||||
- Port : 8000 (pas 8080) — accessible via https://jupyter.digitribe.fr
|
```
|
||||||
- User eric : id=2, admin, créé via NativeAuthenticator
|
helms/
|
||||||
- Config : `SimpleLocalProcessSpawner`, timeout 300s
|
├── README.md # Documentation déploiement
|
||||||
- DB : `sqlite:////srv/jupyterhub/jupyterhub.sqlite` (absolute path, 4 slashes)
|
├── deploy.yml # Playbook principal
|
||||||
- `eric` OS user avec sudo NOPASSWD dans le container
|
├── undeploy.yml # Playbook de suppression
|
||||||
- `jupyterhub-singleuser --version` = 5.3.0, `jupyter-lab --version` = 4.5.7
|
├── inventory/hosts.yml # Inventory des nœuds K8s
|
||||||
|
├── group_vars/all.yml # Variables globales
|
||||||
|
├── group_vars/vault.yml # Variables chiffrées (template)
|
||||||
|
└── roles/ # 25+ rôles Ansible
|
||||||
|
```
|
||||||
|
|
||||||
### Kafka (KRaft)
|
### Utilisation
|
||||||
- `apache/kafka:3.9.0` utilise `KAFKA_*` (pas `KAFKA_CFG_*` qui est Bitnami)
|
```bash
|
||||||
- `CLUSTER_ID=MkU3OEVBNTcwNTJENDM2Qk` requis pour storage formatting
|
cd helms/
|
||||||
- 2 brokers en mode KRaft (broker+controller), pas de ZooKeeper
|
ansible-playbook deploy.yml --ask-vault-pass
|
||||||
|
ansible-playbook deploy.yml --tags clickhouse --ask-vault-pass
|
||||||
|
ansible-playbook undeploy.yml
|
||||||
|
```
|
||||||
|
|
||||||
### Trino
|
## 📝 Infrastructure actuelle (10 containers Docker)
|
||||||
- Config dans `/home/eric/lakehouse/docker-compose/config/trino/`
|
|
||||||
- `node.id=trino-lakehouse-01` (pas `_internal_`)
|
|
||||||
- `plugin.bundles` retiré de config.properties (incompatible Trino 435)
|
|
||||||
|
|
||||||
### Infrastructure
|
| Service | Image | Statut |
|
||||||
- 86+ conteneurs Docker
|
|---------|-------|--------|
|
||||||
- Kafka, Trino, JupyterHub = UP ✅ (fixes appliqués cette session)
|
| airflow-scheduler | apache/airflow:2.9.3-python3.11 | ✅ healthy |
|
||||||
- Tous les autres services principaux = UP ✅
|
| airflow-webserver | apache/airflow:2.9.3-python3.11 | ✅ healthy |
|
||||||
|
| airflow-init | apache/airflow:2.9.3-python3.11 | 🔄 restarting (one-shot) |
|
||||||
|
| airflow-postgres | postgres:16 | ✅ healthy |
|
||||||
|
| smartapp-api | smartapp-api:latest | ✅ Up 38h |
|
||||||
|
| smartapp-web | nginx:alpine | ✅ Up 38h |
|
||||||
|
| gitea-runner | gitea/act_runner:latest | ✅ Up 2 days |
|
||||||
|
| traefik | traefik:v3.1 | ✅ Up 2 days |
|
||||||
|
| smart-city-kepler | smart-city-kepler:latest | ✅ Up 2 weeks |
|
||||||
|
| gitea | gitea/gitea:latest | ✅ Up 2 jours |
|
||||||
|
|
||||||
|
## 📊 Statistiques
|
||||||
|
|
||||||
|
- **Containers Docker** : 10 (down from 72)
|
||||||
|
- **Stacks supprimées** : 6 (OpenFN, Ditto, OpenRemote, Gravitino, FIWARE GIS, Contexus)
|
||||||
|
- **Services unhealthy** : 0
|
||||||
|
- **Fichiers Helm/Ansible** : 33 fichiers
|
||||||
|
- **Rôles Ansible** : 25+
|
||||||
|
- **Namespaces K8s prévus** : 18
|
||||||
|
|
||||||
## Credentials
|
## Credentials
|
||||||
|
|
||||||
- **Contexus**: iotevadmin / Digitribe972
|
- **Gitea** : eric / (voir config)
|
||||||
- **OpenRemote**: admin / Digitribe972
|
- **Airflow** : admin / (changé par Eric)
|
||||||
- **PostgreSQL Contexus**: contexus / Digitribe972
|
|
||||||
- **Redis Contexus**: Digitribe972
|
|
||||||
- **Telegraf InfluxDB**: token=my-super-token, org=digitribe, bucket=smartcity
|
|
||||||
- **Grafana**: admin / Digitribe972
|
|
||||||
- **Superset**: admin / Digitribe972
|
|
||||||
- **Metabase**: admin@digitribe.fr / Digitribe972
|
|
||||||
- **BunkerM MQTT**: bunker / bunker
|
|
||||||
- **ChirpStack**: admin / Digitribe972
|
|
||||||
- **ODK Central**: efelixine@digitribe.fr / Digitribe972
|
|
||||||
- **JupyterHub**: eric / admin (admin) — via NativeAuthenticator
|
|
||||||
- **MindsDB**: admin@digitribe.fr / Digitribe972
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ services:
|
|||||||
- smartcity-shared
|
- smartcity-shared
|
||||||
- traefik-public
|
- traefik-public
|
||||||
ports:
|
ports:
|
||||||
- "1883:1900"
|
- "1884:1900"
|
||||||
- "2000:2000"
|
- "2000:2000"
|
||||||
environment:
|
environment:
|
||||||
- MQTT_PORT=1900
|
- MQTT_PORT=1900
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ services:
|
|||||||
- ditto-mongo-data:/data/db
|
- ditto-mongo-data:/data/db
|
||||||
|
|
||||||
ditto-policies:
|
ditto-policies:
|
||||||
image: eclipse/ditto-policies:latest
|
image: eclipse/ditto-policies:3.8.0
|
||||||
container_name: smart-city-ditto-policies
|
container_name: smart-city-ditto-policies
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
hostname: ditto-policies
|
hostname: ditto-policies
|
||||||
@@ -35,7 +35,7 @@ services:
|
|||||||
- ditto-policies
|
- ditto-policies
|
||||||
|
|
||||||
ditto-things:
|
ditto-things:
|
||||||
image: eclipse/ditto-things:latest
|
image: eclipse/ditto-things:3.8.0
|
||||||
container_name: smart-city-ditto-things
|
container_name: smart-city-ditto-things
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
hostname: ditto-things
|
hostname: ditto-things
|
||||||
@@ -74,10 +74,12 @@ services:
|
|||||||
- AKKA_REMOTE_CANONICAL_HOSTNAME=ditto-gateway
|
- AKKA_REMOTE_CANONICAL_HOSTNAME=ditto-gateway
|
||||||
- AKKA_REMOTE_CANONICAL_PORT=2551
|
- AKKA_REMOTE_CANONICAL_PORT=2551
|
||||||
- DITTO_GW_STREAMING_ENABLED=true
|
- DITTO_GW_STREAMING_ENABLED=true
|
||||||
- DITTO_GW_MQTT_BROKER=smart-city-mosquitto:1883
|
- DITTO_GW_MQTT_BROKER=192.168.192.26:1883
|
||||||
- DITTO_GW_MQTT_TOPIC_FILTER=smartcity/#
|
- DITTO_GW_MQTT_TOPIC_FILTER=smartcity/#
|
||||||
- DEVOPS_PASSWORD=OvP9WVB09aFDnYPyK52UIg
|
- DEVOPS_PASSWORD=OvP9WVB09aFDnYPyK52UIg
|
||||||
|
- JAVA_TOOL_OPTIONS=-Xms512m -Xmx1024m -Dditto.gateway.http.port=8080 -Dditto.gateway.http.api.enabled=true
|
||||||
- DITTO_APIDOC_ENABLED=true
|
- DITTO_APIDOC_ENABLED=true
|
||||||
|
- DITTO_GATEWAY_HTTP_API_ENABLED=true
|
||||||
networks:
|
networks:
|
||||||
traefik-public:
|
traefik-public:
|
||||||
aliases:
|
aliases:
|
||||||
@@ -90,9 +92,22 @@ services:
|
|||||||
- "traefik.http.routers.ditto.tls.certresolver=letsencrypt"
|
- "traefik.http.routers.ditto.tls.certresolver=letsencrypt"
|
||||||
- "traefik.http.services.ditto.loadbalancer.server.port=8080"
|
- "traefik.http.services.ditto.loadbalancer.server.port=8080"
|
||||||
|
|
||||||
|
ditto-ui:
|
||||||
|
image: eclipse/ditto-ui:latest
|
||||||
|
container_name: smart-city-ditto-ui
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
- ditto-gateway
|
||||||
|
networks:
|
||||||
|
traefik-public:
|
||||||
|
aliases:
|
||||||
|
- ditto-ui
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
traefik-public:
|
traefik-public:
|
||||||
external: true
|
external: true
|
||||||
|
smartcity-shared:
|
||||||
|
external: true
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
ditto-mongo-data:
|
ditto-mongo-data:
|
||||||
|
|||||||
29
docker-compose.emqx.yml
Normal file
29
docker-compose.emqx.yml
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
services:
|
||||||
|
emqx:
|
||||||
|
image: emqx/emqx:5.4
|
||||||
|
container_name: emqx_emqx_1
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- smartcity-shared
|
||||||
|
ports:
|
||||||
|
- "1885:1883"
|
||||||
|
- "8083:8083"
|
||||||
|
- "8883:8883"
|
||||||
|
- "8084:8084"
|
||||||
|
- "18083:18083"
|
||||||
|
environment:
|
||||||
|
- EMQX_NAME=emqx
|
||||||
|
- EMQX_HOST=emqx_emqx_1
|
||||||
|
volumes:
|
||||||
|
- emqx-data:/opt/emqx/data
|
||||||
|
- emqx-log:/opt/emqx/log
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
emqx-data:
|
||||||
|
name: smart-city-emqx-data
|
||||||
|
emqx-log:
|
||||||
|
name: smart-city-emqx-log
|
||||||
|
|
||||||
|
networks:
|
||||||
|
smartcity-shared:
|
||||||
|
external: true
|
||||||
@@ -23,7 +23,7 @@ services:
|
|||||||
- IOTA_REGISTRY_TYPE=memory
|
- IOTA_REGISTRY_TYPE=memory
|
||||||
# MQTT Listener - EMQX
|
# MQTT Listener - EMQX
|
||||||
- IOTA_MQTT_HOST=emqx_emqx_1
|
- IOTA_MQTT_HOST=emqx_emqx_1
|
||||||
- IOTA_MQTT_PORT=1883
|
- IOTA_MQTT_PORT=1885
|
||||||
- IOTA_PROVIDER_URL=http://smart-city-iot-agent-emqx:4041
|
- IOTA_PROVIDER_URL=http://smart-city-iot-agent-emqx:4041
|
||||||
- IOTA_DEFAULT_RESOURCE=/
|
- IOTA_DEFAULT_RESOURCE=/
|
||||||
- IOTA_DEFAULT_APIKEY=smartcity-emqx
|
- IOTA_DEFAULT_APIKEY=smartcity-emqx
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ services:
|
|||||||
- orion-ld
|
- orion-ld
|
||||||
- smart-city-orion-ld
|
- smart-city-orion-ld
|
||||||
traefik-public:
|
traefik-public:
|
||||||
command: -dbhost smart-city-mongodb -db orion
|
command: -dbhost smart-city-iot-mongodb -db orion
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD-SHELL", "curl -f http://localhost:1026/version || exit 1"]
|
test: ["CMD-SHELL", "curl -f http://localhost:1026/version || exit 1"]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
|
|||||||
@@ -1,28 +1,16 @@
|
|||||||
# Redpanda → InfluxDB Consumer
|
# Redpanda → InfluxDB Consumer
|
||||||
# Lit les topics Redpanda et écrit dans InfluxDB pour Grafana
|
# DÉSACTIVÉ — Redpanda broker non démarré
|
||||||
version: "3.8"
|
# Usage: docker compose -f docker-compose.redpanda-consumer.yml up -d
|
||||||
|
|
||||||
services:
|
services:
|
||||||
redpanda-consumer:
|
redpanda-consumer:
|
||||||
image: python:3.11-slim
|
image: python:3.11-slim
|
||||||
container_name: smart-city-redpanda-consumer
|
container_name: smart-city-redpanda-consumer
|
||||||
restart: unless-stopped
|
restart: "no"
|
||||||
command: >
|
command: >
|
||||||
sh -c "pip install requests && python3 /app/consumer.py"
|
sh -c "echo 'Redpanda consumer désactivé — Redpanda broker non démarré' && sleep infinity"
|
||||||
volumes:
|
|
||||||
- ./redpanda/consumer.py:/app/consumer.py:ro
|
|
||||||
environment:
|
|
||||||
- INFLUX_URL=http://smart-city-influxdb:8086
|
|
||||||
- INFLUX_TOKEN=my-super-admin-token
|
|
||||||
- INFLUX_ORG=digitribe
|
|
||||||
- INFLUX_BUCKET=iot_data
|
|
||||||
networks:
|
networks:
|
||||||
- smartcity-shared
|
- smartcity-shared
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://smart-city-redpanda:9644/public_metrics')"]
|
|
||||||
interval: 30s
|
|
||||||
timeout: 10s
|
|
||||||
retries: 3
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
smartcity-shared:
|
smartcity-shared:
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ services:
|
|||||||
- ENABLE_BUNKER=1
|
- ENABLE_BUNKER=1
|
||||||
- EMQX_HOST=emqx_emqx_1
|
- EMQX_HOST=emqx_emqx_1
|
||||||
- EMQX_PORT=1883
|
- EMQX_PORT=1883
|
||||||
- MOSQUITTO_HOST=smart-city-digital-twin-martinique-mosquitto-1
|
- MOSQUITTO_HOST=smart-city-mosquitto-1
|
||||||
- MOSQUITTO_PORT=1883
|
- MOSQUITTO_PORT=1883
|
||||||
- BUNKERM_HOST=bunkerm-bunkerm-1
|
- BUNKERM_HOST=bunkerm-bunkerm-1
|
||||||
- BUNKERM_PORT=1900
|
- BUNKERM_PORT=1900
|
||||||
|
|||||||
246
helms/README.md
Normal file
246
helms/README.md
Normal file
@@ -0,0 +1,246 @@
|
|||||||
|
# Smart City Martinique - Déploiement Kubernetes
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────┐
|
||||||
|
│ TRAEFIK (Ingress) │
|
||||||
|
│ ports 80/443 │
|
||||||
|
└─────────────────────────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
┌─────────────────────────────────┼─────────────────────────────────┐
|
||||||
|
│ │ │
|
||||||
|
┌────▼────┐ ┌──────────┐ ┌──────────▼──────────┐ ┌─────────────────┐
|
||||||
|
│ Airflow │ │ Kafka │ │ Data & Storage │ │ Monitoring │
|
||||||
|
│ │ │ Cluster │ │ │ │ │
|
||||||
|
│ web │ │ 3 brokers│ │ PostgreSQL HA │ │ Prometheus │
|
||||||
|
│ sched │ │ connect │ │ Redis Cluster │ │ Grafana │
|
||||||
|
│ worker │ │ ui │ │ MinIO │ │ Loki │
|
||||||
|
└─────────┘ └──────────┘ │ ClickHouse │ │ Promtail │
|
||||||
|
│ StarRocks │ └─────────────────┘
|
||||||
|
┌──────────┐ ┌──────────┐ │ Trino │
|
||||||
|
│ Flink │ │ IoT │ │ Delta Lake │ ┌─────────────────┐
|
||||||
|
│ │ │ │ │ DuckDB │ │ BI & Analytics │
|
||||||
|
│ jobmgr │ │ EMQX │ └─────────────────────┘ │ │
|
||||||
|
│ taskmgr │ │ Mosquitto│ │ Superset │
|
||||||
|
└──────────┘ │ Node-RED │ ┌─────────────────────┐ │ Metabase │
|
||||||
|
│ phpIPAM │ │ Git & Notebooks │ │ MindsDB │
|
||||||
|
┌──────────┐ │ ChirpStk │ │ │ └─────────────────┘
|
||||||
|
│ GIS │ └──────────┘ │ Gitea │
|
||||||
|
│ │ │ JupyterHub │ ┌─────────────────┐
|
||||||
|
│ MapStore │ ┌──────────┐ │ Zeppelin │ │ Web Apps │
|
||||||
|
│ GeoServer│ │ ODK │ └─────────────────────┘ │ │
|
||||||
|
│ FROST │ │ │ │ Smart App │
|
||||||
|
│ Stellio │ │ nginx │ ┌─────────────────────┐ │ Streamlit │
|
||||||
|
│ FIWARE │ │ service │ │ Data Collection │ │ Kepler │
|
||||||
|
└──────────┘ │ postgres │ │ │ └─────────────────┘
|
||||||
|
└──────────┘ │ Telegraf │
|
||||||
|
│ InfluxDB │
|
||||||
|
│ Simulator │
|
||||||
|
└─────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
## Prérequis
|
||||||
|
|
||||||
|
### Cluster Kubernetes
|
||||||
|
- 3 nœuds minimum (1 master + 2 workers)
|
||||||
|
- Kubernetes 1.28+
|
||||||
|
- containerd
|
||||||
|
- Cilium (CNI)
|
||||||
|
|
||||||
|
### Serveur NFS
|
||||||
|
- 1 serveur NFS pour le stockage persistant
|
||||||
|
- Minimum 500Go d'espace disque
|
||||||
|
|
||||||
|
### Outils
|
||||||
|
- kubectl
|
||||||
|
- helm
|
||||||
|
- ansible 2.15+
|
||||||
|
- ansible-galaxy collection install kubernetes.core
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### 1. Cloner le repository
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://gitea.digitribe.fr/eric/smart-city-digital-twin-martinique.git
|
||||||
|
cd smart-city-digital-twin-martinique/helms
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Configurer l'inventory
|
||||||
|
|
||||||
|
Éditer `inventory/hosts.yml` avec les IPs de vos nœuds :
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
k8s_masters:
|
||||||
|
hosts:
|
||||||
|
k8s-master-1:
|
||||||
|
ansible_host: "192.168.1.100"
|
||||||
|
k8s_workers:
|
||||||
|
hosts:
|
||||||
|
k8s-worker-1:
|
||||||
|
ansible_host: "192.168.1.101"
|
||||||
|
k8s-worker-2:
|
||||||
|
ansible_host: "192.168.1.102"
|
||||||
|
nfs_server:
|
||||||
|
hosts:
|
||||||
|
nfs-1:
|
||||||
|
ansible_host: "192.168.1.200"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Configurer les variables
|
||||||
|
|
||||||
|
Éditer `group_vars/all.yml` selon vos besoins (ressources, domaines, etc.)
|
||||||
|
|
||||||
|
### 4. Chiffrer les secrets
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ansible-vault encrypt group_vars/vault.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Déployer
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Déployer toute la stack
|
||||||
|
ansible-playbook deploy.yml --ask-vault-pass
|
||||||
|
|
||||||
|
# Déployer un service spécifique
|
||||||
|
ansible-playbook deploy.yml --tags clickhouse --ask-vault-pass
|
||||||
|
ansible-playbook deploy.yml --tags trino --ask-vault-pass
|
||||||
|
ansible-playbook deploy.yml --tags streamlit --ask-vault-pass
|
||||||
|
ansible-playbook deploy.yml --tags kafka --ask-vault-pass
|
||||||
|
ansible-playbook deploy.yml --tags monitoring --ask-vault-pass
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6. Vérifier
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl get pods --all-namespaces
|
||||||
|
kubectl get ingress --all-namespaces
|
||||||
|
```
|
||||||
|
|
||||||
|
## Services déployés
|
||||||
|
|
||||||
|
| Service | Domaine | Namespace | Helm Chart |
|
||||||
|
|---------|---------|-----------|------------|
|
||||||
|
| Traefik | traefik.digitribe.fr | traefik | traefik/traefik |
|
||||||
|
| Airflow | airflow.digitribe.fr | airflow | apache/airflow |
|
||||||
|
| Kafka | kafka-bootstrap.digitribe.fr | kafka | strimzi/kafka-operator |
|
||||||
|
| Flink | flink.digitribe.fr | flink | apache/flink-kubernetes-operator |
|
||||||
|
| ClickHouse | clickhouse.digitribe.fr | clickhouse | bitnami/clickhouse |
|
||||||
|
| StarRocks | starrocks.digitribe.fr | starrocks | community/starrocks |
|
||||||
|
| Trino | trino.digitribe.fr | trino | trinodb/trino |
|
||||||
|
| Delta Lake | deltalake.digitribe.fr | deltalake | custom |
|
||||||
|
| Streamlit | streamlit.digitribe.fr | streamlit | custom |
|
||||||
|
| DuckDB | duckdb.digitribe.fr | duckdb | custom |
|
||||||
|
| EMQX | emqx.digitribe.fr | iot | emqx/emqx-operator |
|
||||||
|
| Mosquitto | mqtt.digitribe.fr | iot | custom |
|
||||||
|
| Node-RED | nodered.digitribe.fr | iot | custom |
|
||||||
|
| phpIPAM | phpipam.digitribe.fr | phpipam | custom |
|
||||||
|
| Gitea | gitea.digitribe.fr | gitea | gitea-charts/gitea |
|
||||||
|
| JupyterHub | jupyter.digitribe.fr | jupyterhub | jupyterhub/jupyterhub |
|
||||||
|
| Superset | superset.digitribe.fr | superset | apache/superset |
|
||||||
|
| Metabase | metabase.digitribe.fr | metabase | bitnami/metabase |
|
||||||
|
| MindsDB | mindsdb.digitribe.fr | mindsdb | bitnami/mindsdb |
|
||||||
|
| ODK Central | odk.digitribe.fr | odk | custom |
|
||||||
|
| MapStore | mapstore.digitribe.fr | gis | custom |
|
||||||
|
| GeoServer | geoserver.digitribe.fr | gis | custom |
|
||||||
|
| Smart App | smartapp.digitribe.fr | smartapp | custom |
|
||||||
|
| Smart App API | api-smartapp.digitribe.fr | smartapp | custom |
|
||||||
|
| Grafana | grafana.digitribe.fr | monitoring | grafana/grafana |
|
||||||
|
| MinIO | minio.digitribe.fr | databases | bitnami/minio |
|
||||||
|
| PostgreSQL | — (interne) | databases | bitnami/postgresql-ha |
|
||||||
|
| Redis | — (interne) | databases | bitnami/redis-cluster |
|
||||||
|
|
||||||
|
## Dépendances entre rôles
|
||||||
|
|
||||||
|
```
|
||||||
|
prerequisites → namespaces → storage → traefik → cert-manager
|
||||||
|
↓
|
||||||
|
┌─────────────────────┼─────────────────────┐
|
||||||
|
↓ ↓ ↓
|
||||||
|
databases monitoring kafka
|
||||||
|
(postgres, (prometheus, ↓
|
||||||
|
redis, minio) grafana, loki) flink
|
||||||
|
↓ ↓ ↓
|
||||||
|
└─────────────────────┼─────────────────────┘
|
||||||
|
↓
|
||||||
|
┌─────────────────────┼─────────────────────┐
|
||||||
|
↓ ↓ ↓
|
||||||
|
airflow bi iot
|
||||||
|
gitea jupyterhub superset metabase emqx mosquitto
|
||||||
|
odk mindsdb trino nodered phpipam
|
||||||
|
gis clickhouse streamlit
|
||||||
|
smartapp deltalake duckdb
|
||||||
|
↓
|
||||||
|
backup (Velero)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Commandes utiles
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Lister tous les pods
|
||||||
|
kubectl get pods --all-namespaces
|
||||||
|
|
||||||
|
# Voir les logs d'un pod
|
||||||
|
kubectl logs -f <pod-name> -n <namespace>
|
||||||
|
|
||||||
|
# Voir les événements
|
||||||
|
kubectl get events --all-namespaces --sort-by='.lastTimestamp'
|
||||||
|
|
||||||
|
# Voir les ingress
|
||||||
|
kubectl get ingress --all-namespaces
|
||||||
|
|
||||||
|
# Voir les PVC
|
||||||
|
kubectl get pvc --all-namespaces
|
||||||
|
|
||||||
|
# Redéployer un service
|
||||||
|
ansible-playbook deploy.yml --tags <service> --ask-vault-pass
|
||||||
|
|
||||||
|
# Supprimer un service
|
||||||
|
kubectl delete namespace <namespace>
|
||||||
|
|
||||||
|
# Supprimer toute la stack
|
||||||
|
ansible-playbook undeploy.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Pod en CrashLoopBackOff
|
||||||
|
```bash
|
||||||
|
kubectl describe pod <pod-name> -n <namespace>
|
||||||
|
kubectl logs <pod-name> -n <namespace> --previous
|
||||||
|
```
|
||||||
|
|
||||||
|
### PVC en Pending
|
||||||
|
```bash
|
||||||
|
kubectl get storageclass
|
||||||
|
kubectl get pv
|
||||||
|
kubectl describe pvc <pvc-name> -n <namespace>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ingress non accessible
|
||||||
|
```bash
|
||||||
|
kubectl get ingress -n <namespace>
|
||||||
|
kubectl describe ingress <ingress-name> -n <namespace>
|
||||||
|
kubectl logs -f deployment/traefik -n traefik
|
||||||
|
```
|
||||||
|
|
||||||
|
## Maintenance
|
||||||
|
|
||||||
|
### Backup
|
||||||
|
Les sauvegardes sont configurées via Velero :
|
||||||
|
```bash
|
||||||
|
kubectl get schedules -n velero
|
||||||
|
kubectl get backups -n velero
|
||||||
|
```
|
||||||
|
|
||||||
|
### Mise à jour d'un service
|
||||||
|
```bash
|
||||||
|
ansible-playbook deploy.yml --tags <service> --ask-vault-pass
|
||||||
|
```
|
||||||
|
|
||||||
|
### Scaling
|
||||||
|
```bash
|
||||||
|
kubectl scale deployment <deployment> --replicas=<n> -n <namespace>
|
||||||
|
```
|
||||||
77
helms/deploy.yml
Normal file
77
helms/deploy.yml
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
---
|
||||||
|
# Playbook principal pour le déploiement Kubernetes
|
||||||
|
# Fichier: deploy.yml
|
||||||
|
|
||||||
|
- name: Déploiement Smart City Martinique sur Kubernetes
|
||||||
|
hosts: localhost
|
||||||
|
connection: local
|
||||||
|
gather_facts: false
|
||||||
|
|
||||||
|
vars_files:
|
||||||
|
- group_vars/all.yml
|
||||||
|
- group_vars/vault.yml
|
||||||
|
|
||||||
|
pre_tasks:
|
||||||
|
- name: Vérifier que kubectl est installé
|
||||||
|
command: kubectl version --client
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Vérifier la connexion au cluster
|
||||||
|
command: kubectl cluster-info
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
roles:
|
||||||
|
- role: prerequisites
|
||||||
|
tags: [prerequisites]
|
||||||
|
- role: namespaces
|
||||||
|
tags: [namespaces]
|
||||||
|
- role: storage
|
||||||
|
tags: [storage]
|
||||||
|
- role: traefik
|
||||||
|
tags: [traefik, ingress]
|
||||||
|
- role: cert-manager
|
||||||
|
tags: [cert-manager, tls]
|
||||||
|
- role: monitoring
|
||||||
|
tags: [monitoring]
|
||||||
|
- role: databases
|
||||||
|
tags: [databases]
|
||||||
|
- role: kafka
|
||||||
|
tags: [kafka]
|
||||||
|
- role: flink
|
||||||
|
tags: [flink]
|
||||||
|
- role: airflow
|
||||||
|
tags: [airflow]
|
||||||
|
- role: iot
|
||||||
|
tags: [iot, mqtt]
|
||||||
|
- role: gitea
|
||||||
|
tags: [gitea]
|
||||||
|
- role: jupyterhub
|
||||||
|
tags: [jupyterhub]
|
||||||
|
- role: bi
|
||||||
|
tags: [bi, superset, metabase]
|
||||||
|
- role: mindsdb
|
||||||
|
tags: [mindsdb]
|
||||||
|
- role: odk
|
||||||
|
tags: [odk]
|
||||||
|
- role: gis
|
||||||
|
tags: [gis, mapstore, geoserver, frost]
|
||||||
|
- role: clickhouse
|
||||||
|
tags: [clickhouse]
|
||||||
|
- role: starrocks
|
||||||
|
tags: [starrocks]
|
||||||
|
- role: trino
|
||||||
|
tags: [trino]
|
||||||
|
- role: deltalake
|
||||||
|
tags: [deltalake]
|
||||||
|
- role: streamlit
|
||||||
|
tags: [streamlit]
|
||||||
|
- role: duckdb
|
||||||
|
tags: [duckdb]
|
||||||
|
- role: nodered
|
||||||
|
tags: [nodered]
|
||||||
|
- role: phpipam
|
||||||
|
tags: [phpipam]
|
||||||
|
- role: smartapp
|
||||||
|
tags: [smartapp]
|
||||||
|
- role: backup
|
||||||
|
tags: [backup]
|
||||||
535
helms/group_vars/all.yml
Normal file
535
helms/group_vars/all.yml
Normal file
@@ -0,0 +1,535 @@
|
|||||||
|
---
|
||||||
|
# Variables globales pour le déploiement Kubernetes
|
||||||
|
# Fichier: group_vars/all.yml
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# Configuration du cluster Kubernetes
|
||||||
|
# ============================================================
|
||||||
|
cluster_name: smart-city-martinique
|
||||||
|
k8s_version: "1.28.0"
|
||||||
|
container_runtime: containerd
|
||||||
|
network_plugin: cilium
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# Configuration réseau
|
||||||
|
# ============================================================
|
||||||
|
domain: digitribe.fr
|
||||||
|
traefik_namespace: traefik
|
||||||
|
ingress_class: traefik
|
||||||
|
|
||||||
|
# TLS
|
||||||
|
tls_enabled: true
|
||||||
|
tls_certresolver: letsencrypt
|
||||||
|
acme_email: admin@digitribe.fr
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# Storage
|
||||||
|
# ============================================================
|
||||||
|
storage_class: nfs-client
|
||||||
|
nfs_server: "192.168.1.200"
|
||||||
|
nfs_path: /data/k8s
|
||||||
|
|
||||||
|
# Persistent Volume sizes
|
||||||
|
storage_sizes:
|
||||||
|
postgres: 50Gi
|
||||||
|
minio: 500Gi
|
||||||
|
kafka: 100Gi
|
||||||
|
influxdb: 50Gi
|
||||||
|
loki: 100Gi
|
||||||
|
grafana: 10Gi
|
||||||
|
jupyterhub: 20Gi
|
||||||
|
gitea: 20Gi
|
||||||
|
metabase: 10Gi
|
||||||
|
superset: 10Gi
|
||||||
|
mindsdb: 20Gi
|
||||||
|
odk: 10Gi
|
||||||
|
mapstore: 10Gi
|
||||||
|
geoserver: 20Gi
|
||||||
|
airflow: 20Gi
|
||||||
|
flink: 20Gi
|
||||||
|
emqx: 10Gi
|
||||||
|
mosquitto: 5Gi
|
||||||
|
redis: 10Gi
|
||||||
|
elasticsearch: 50Gi
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# Helm Charts versions
|
||||||
|
# ============================================================
|
||||||
|
helm_charts:
|
||||||
|
traefik:
|
||||||
|
chart: traefik/traefik
|
||||||
|
version: "28.0.0"
|
||||||
|
ingress_nginx:
|
||||||
|
chart: ingress-nginx/ingress-nginx
|
||||||
|
version: "4.8.0"
|
||||||
|
cert_manager:
|
||||||
|
chart: jetstack/cert-manager
|
||||||
|
version: "1.13.0"
|
||||||
|
nfs_provisioner:
|
||||||
|
chart: nfs-subdir-external-provisioner/nfs-subdir-external-provisioner
|
||||||
|
version: "4.0.18"
|
||||||
|
postgresql:
|
||||||
|
chart: bitnami/postgresql
|
||||||
|
version: "13.2.0"
|
||||||
|
postgresql_ha:
|
||||||
|
chart: bitnami/postgresql-ha
|
||||||
|
version: "12.2.0"
|
||||||
|
redis:
|
||||||
|
chart: bitnami/redis
|
||||||
|
version: "18.0.0"
|
||||||
|
minio:
|
||||||
|
chart: bitnami/minio
|
||||||
|
version: "12.10.0"
|
||||||
|
kafka:
|
||||||
|
chart: strimzi/kafka-operator
|
||||||
|
version: "0.38.0"
|
||||||
|
flink:
|
||||||
|
chart: apache/flink-kubernetes-operator
|
||||||
|
version: "1.7.0"
|
||||||
|
airflow:
|
||||||
|
chart: apache/airflow
|
||||||
|
version: "1.11.0"
|
||||||
|
grafana:
|
||||||
|
chart: grafana/grafana
|
||||||
|
version: "7.0.0"
|
||||||
|
loki:
|
||||||
|
chart: grafana/loki-stack
|
||||||
|
version: "2.9.0"
|
||||||
|
prometheus:
|
||||||
|
chart: prometheus/kube-prometheus-stack
|
||||||
|
version: "51.0.0"
|
||||||
|
emqx:
|
||||||
|
chart: emqx/emqx-operator
|
||||||
|
version: "2.2.0"
|
||||||
|
mosquitto:
|
||||||
|
chart: k8s-at-home/mosquitto
|
||||||
|
version: "4.8.0"
|
||||||
|
gitea:
|
||||||
|
chart: gitea/gitea
|
||||||
|
version: "9.0.0"
|
||||||
|
jupyterhub:
|
||||||
|
chart: jupyterhub/jupyterhub
|
||||||
|
version: "3.0.0"
|
||||||
|
superset:
|
||||||
|
chart: apache/superset
|
||||||
|
version: "0.11.0"
|
||||||
|
metabase:
|
||||||
|
chart: bitnami/metabase
|
||||||
|
version: "0.13.0"
|
||||||
|
mindsdb:
|
||||||
|
chart: bitnami/mindsdb
|
||||||
|
version: "0.1.0"
|
||||||
|
odk:
|
||||||
|
chart: odk/odk-central
|
||||||
|
version: "1.0.0"
|
||||||
|
mapstore:
|
||||||
|
chart: geosolutionsit/mapstore
|
||||||
|
version: "1.0.0"
|
||||||
|
geoserver:
|
||||||
|
chart: kartoza/geoserver
|
||||||
|
version: "2.2.0"
|
||||||
|
frost:
|
||||||
|
chart: fraunhoferiosb/frost-server
|
||||||
|
version: "1.0.0"
|
||||||
|
nodered:
|
||||||
|
chart: k8s-at-home/node-red
|
||||||
|
version: "4.8.0"
|
||||||
|
phpipam:
|
||||||
|
chart: phpipam/phpipam
|
||||||
|
version: "1.0.0"
|
||||||
|
clickhouse:
|
||||||
|
chart: bitnami/clickhouse
|
||||||
|
version: "4.0.0"
|
||||||
|
starrocks:
|
||||||
|
chart: starrocks/starrocks-community
|
||||||
|
version: "1.0.0"
|
||||||
|
trino:
|
||||||
|
chart: trinodb/trino
|
||||||
|
version: "0.10.0"
|
||||||
|
deltalake:
|
||||||
|
chart: delta-io/delta-lake
|
||||||
|
version: "1.0.0"
|
||||||
|
streamlit:
|
||||||
|
chart: streamlit/streamlit
|
||||||
|
version: "1.0.0"
|
||||||
|
duckdb:
|
||||||
|
chart: duckdb/duckdb
|
||||||
|
version: "1.0.0"
|
||||||
|
elasticsearch:
|
||||||
|
chart: elastic/elasticsearch
|
||||||
|
version: "8.11.0"
|
||||||
|
kibana:
|
||||||
|
chart: elastic/kibana
|
||||||
|
version: "8.11.0"
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# Services configuration
|
||||||
|
# ============================================================
|
||||||
|
services:
|
||||||
|
airflow:
|
||||||
|
enabled: true
|
||||||
|
namespace: airflow
|
||||||
|
replicas: 2
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "1Gi"
|
||||||
|
limits:
|
||||||
|
cpu: "2000m"
|
||||||
|
memory: "4Gi"
|
||||||
|
|
||||||
|
kafka:
|
||||||
|
enabled: true
|
||||||
|
namespace: kafka
|
||||||
|
replicas: 3
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "1Gi"
|
||||||
|
limits:
|
||||||
|
cpu: "2000m"
|
||||||
|
memory: "4Gi"
|
||||||
|
|
||||||
|
flink:
|
||||||
|
enabled: true
|
||||||
|
namespace: flink
|
||||||
|
replicas: 2
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "1Gi"
|
||||||
|
limits:
|
||||||
|
cpu: "2000m"
|
||||||
|
memory: "4Gi"
|
||||||
|
|
||||||
|
emqx:
|
||||||
|
enabled: true
|
||||||
|
namespace: iot
|
||||||
|
replicas: 3
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
|
|
||||||
|
mosquitto:
|
||||||
|
enabled: true
|
||||||
|
namespace: iot
|
||||||
|
replicas: 2
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "100m"
|
||||||
|
memory: "256Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "1Gi"
|
||||||
|
|
||||||
|
postgresql:
|
||||||
|
enabled: true
|
||||||
|
namespace: default
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
|
|
||||||
|
redis:
|
||||||
|
enabled: true
|
||||||
|
namespace: default
|
||||||
|
replicas: 3
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "100m"
|
||||||
|
memory: "256Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "1Gi"
|
||||||
|
|
||||||
|
minio:
|
||||||
|
enabled: true
|
||||||
|
namespace: default
|
||||||
|
replicas: 4
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
|
|
||||||
|
grafana:
|
||||||
|
enabled: true
|
||||||
|
namespace: monitoring
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "100m"
|
||||||
|
memory: "256Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "1Gi"
|
||||||
|
|
||||||
|
loki:
|
||||||
|
enabled: true
|
||||||
|
namespace: monitoring
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
|
|
||||||
|
prometheus:
|
||||||
|
enabled: true
|
||||||
|
namespace: monitoring
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
|
|
||||||
|
gitea:
|
||||||
|
enabled: true
|
||||||
|
namespace: gitea
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
|
|
||||||
|
jupyterhub:
|
||||||
|
enabled: true
|
||||||
|
namespace: jupyterhub
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
|
|
||||||
|
superset:
|
||||||
|
enabled: true
|
||||||
|
namespace: superset
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
|
|
||||||
|
metabase:
|
||||||
|
enabled: true
|
||||||
|
namespace: metabase
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
|
|
||||||
|
mindsdb:
|
||||||
|
enabled: true
|
||||||
|
namespace: mindsdb
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
|
|
||||||
|
odk:
|
||||||
|
enabled: true
|
||||||
|
namespace: odk
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
|
|
||||||
|
mapstore:
|
||||||
|
enabled: true
|
||||||
|
namespace: mapstore
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
|
|
||||||
|
geoserver:
|
||||||
|
enabled: true
|
||||||
|
namespace: geoserver
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
|
|
||||||
|
frost:
|
||||||
|
enabled: true
|
||||||
|
namespace: iot
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "100m"
|
||||||
|
memory: "256Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "1Gi"
|
||||||
|
|
||||||
|
nodered:
|
||||||
|
enabled: true
|
||||||
|
namespace: iot
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "100m"
|
||||||
|
memory: "256Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "1Gi"
|
||||||
|
|
||||||
|
phpipam:
|
||||||
|
enabled: true
|
||||||
|
namespace: phpipam
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "100m"
|
||||||
|
memory: "256Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "1Gi"
|
||||||
|
|
||||||
|
smartapp:
|
||||||
|
enabled: true
|
||||||
|
namespace: smartapp
|
||||||
|
replicas: 2
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
|
|
||||||
|
clickhouse:
|
||||||
|
enabled: true
|
||||||
|
namespace: clickhouse
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "1Gi"
|
||||||
|
limits:
|
||||||
|
cpu: "2000m"
|
||||||
|
memory: "4Gi"
|
||||||
|
|
||||||
|
starrocks:
|
||||||
|
enabled: true
|
||||||
|
namespace: starrocks
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "1Gi"
|
||||||
|
limits:
|
||||||
|
cpu: "2000m"
|
||||||
|
memory: "4Gi"
|
||||||
|
|
||||||
|
trino:
|
||||||
|
enabled: true
|
||||||
|
namespace: trino
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "1Gi"
|
||||||
|
limits:
|
||||||
|
cpu: "2000m"
|
||||||
|
memory: "4Gi"
|
||||||
|
|
||||||
|
deltalake:
|
||||||
|
enabled: true
|
||||||
|
namespace: deltalake
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
|
|
||||||
|
streamlit:
|
||||||
|
enabled: true
|
||||||
|
namespace: streamlit
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
|
|
||||||
|
duckdb:
|
||||||
|
enabled: true
|
||||||
|
namespace: duckdb
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# Monitoring
|
||||||
|
# ============================================================
|
||||||
|
monitoring:
|
||||||
|
enabled: true
|
||||||
|
namespace: monitoring
|
||||||
|
grafana_admin_password: "{{ vault_grafana_password }}"
|
||||||
|
prometheus_retention: 30d
|
||||||
|
loki_retention: 30d
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# Backup
|
||||||
|
# ============================================================
|
||||||
|
backup:
|
||||||
|
enabled: true
|
||||||
|
schedule: "0 2 * * *"
|
||||||
|
retention: 30
|
||||||
|
storage_class: nfs-client
|
||||||
|
storage_size: 100Gi
|
||||||
60
helms/group_vars/vault.yml
Normal file
60
helms/group_vars/vault.yml
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
---
|
||||||
|
# Vault Ansible - Variables chiffrées
|
||||||
|
# Fichier: group_vars/vault.yml
|
||||||
|
# Chiffrer avec: ansible-vault encrypt group_vars/vault.yml
|
||||||
|
|
||||||
|
# PostgreSQL
|
||||||
|
vault_postgres_password: "Digitribe972"
|
||||||
|
vault_postgres_repmgr_password: "Digitribe972"
|
||||||
|
|
||||||
|
# Redis
|
||||||
|
vault_redis_password: "Digitribe972"
|
||||||
|
|
||||||
|
# MinIO
|
||||||
|
vault_minio_root_user: "minioadmin"
|
||||||
|
vault_minio_root_password: "Digitribe972"
|
||||||
|
|
||||||
|
# Grafana
|
||||||
|
vault_grafana_admin_password: "Digitribe972"
|
||||||
|
|
||||||
|
# Airflow
|
||||||
|
vault_airflow_fernet_key: "Digitribe972SecretKeyForAirflow2024"
|
||||||
|
vault_airflow_admin_password: "Digitribe972"
|
||||||
|
|
||||||
|
# Gitea
|
||||||
|
vault_gitea_admin_password: "Digitribe972"
|
||||||
|
|
||||||
|
# Superset
|
||||||
|
vault_superset_admin_password: "Digitribe972"
|
||||||
|
vault_superset_db_password: "Digitribe972"
|
||||||
|
|
||||||
|
# Metabase
|
||||||
|
vault_metabase_db_password: "Digitribe972"
|
||||||
|
|
||||||
|
# MindsDB
|
||||||
|
vault_mindsdb_password: "Digitribe972"
|
||||||
|
|
||||||
|
# ClickHouse
|
||||||
|
vault_clickhouse_password: "Digitribe972"
|
||||||
|
|
||||||
|
# Trino
|
||||||
|
vault_trino_db_password: "Digitribe972"
|
||||||
|
|
||||||
|
# MQTT
|
||||||
|
vault_mosquitto_password: "Digitribe972"
|
||||||
|
vault_emqx_admin_password: "Digitribe972"
|
||||||
|
|
||||||
|
# phpIPAM
|
||||||
|
vault_phpipam_admin_password: "Digitribe972"
|
||||||
|
|
||||||
|
# ODK
|
||||||
|
vault_odk_admin_password: "Digitribe972"
|
||||||
|
|
||||||
|
# GeoServer
|
||||||
|
vault_geoserver_admin_password: "Digitribe972"
|
||||||
|
|
||||||
|
# MapStore
|
||||||
|
vault_mapstore_admin_password: "Digitribe972"
|
||||||
|
|
||||||
|
# StarRocks
|
||||||
|
vault_starrocks_root_password: "Digitribe972"
|
||||||
79
helms/inventory/hosts.yml
Normal file
79
helms/inventory/hosts.yml
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
---
|
||||||
|
# Inventory pour le déploiement Kubernetes via Ansible
|
||||||
|
# Fichier: inventory/hosts.yml
|
||||||
|
|
||||||
|
all:
|
||||||
|
children:
|
||||||
|
k8s_masters:
|
||||||
|
hosts:
|
||||||
|
k8s-master-1:
|
||||||
|
ansible_host: "{{ k8s_master_ip | default('192.168.1.100') }}"
|
||||||
|
ansible_user: "{{ k8s_user | default('root') }}"
|
||||||
|
k8s_workers:
|
||||||
|
hosts:
|
||||||
|
k8s-worker-1:
|
||||||
|
ansible_host: "{{ k8s_worker1_ip | default('192.168.1.101') }}"
|
||||||
|
ansible_user: "{{ k8s_user | default('root') }}"
|
||||||
|
k8s-worker-2:
|
||||||
|
ansible_host: "{{ k8s_worker2_ip | default('192.168.1.102') }}"
|
||||||
|
ansible_user: "{{ k8s_user | default('root') }}"
|
||||||
|
nfs_server:
|
||||||
|
hosts:
|
||||||
|
nfs-1:
|
||||||
|
ansible_host: "{{ nfs_server_ip | default('192.168.1.200') }}"
|
||||||
|
ansible_user: "{{ nfs_user | default('root') }}"
|
||||||
|
|
||||||
|
vars:
|
||||||
|
# Configuration globale
|
||||||
|
cluster_name: smart-city-martinique
|
||||||
|
k8s_version: "1.28"
|
||||||
|
container_runtime: containerd
|
||||||
|
network_plugin: cilium
|
||||||
|
domain: digitribe.fr
|
||||||
|
|
||||||
|
# Namespaces Kubernetes
|
||||||
|
namespaces:
|
||||||
|
- airflow
|
||||||
|
- kafka
|
||||||
|
- flink
|
||||||
|
- monitoring
|
||||||
|
- iot
|
||||||
|
- gitea
|
||||||
|
- jupyterhub
|
||||||
|
- odk
|
||||||
|
- smartapp
|
||||||
|
- superset
|
||||||
|
- metabase
|
||||||
|
- mindsdb
|
||||||
|
- mapstore
|
||||||
|
- geoserver
|
||||||
|
- frost
|
||||||
|
- nodered
|
||||||
|
- phpipam
|
||||||
|
- traefik
|
||||||
|
- ingress-nginx
|
||||||
|
- clickhouse
|
||||||
|
- starrocks
|
||||||
|
- trino
|
||||||
|
- deltalake
|
||||||
|
- streamlit
|
||||||
|
- duckdb
|
||||||
|
|
||||||
|
# Storage
|
||||||
|
storage_class: nfs-client
|
||||||
|
nfs_path: /data/k8s
|
||||||
|
|
||||||
|
# Helm repositories
|
||||||
|
helm_repos:
|
||||||
|
- name: bitnami
|
||||||
|
url: https://charts.bitnami.com/bitnami
|
||||||
|
- name: apache
|
||||||
|
url: https://charts.apache.org
|
||||||
|
- name: grafana
|
||||||
|
url: https://grafana.github.io/helm-charts
|
||||||
|
- name: prometheus
|
||||||
|
url: https://prometheus-community.github.io/helm-charts
|
||||||
|
- name: strimzi
|
||||||
|
url: https://strimzi.io/charts/
|
||||||
|
- name: flink-operator
|
||||||
|
url: https://downloads.apache.org/flink/flink-kubernetes-operator-1.7.0/
|
||||||
19
helms/roles/airflow/defaults/main.yml
Normal file
19
helms/roles/airflow/defaults/main.yml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
# Role: airflow
|
||||||
|
# Valeurs par défaut pour Apache Airflow
|
||||||
|
|
||||||
|
# Réplicas des workers Airflow
|
||||||
|
services:
|
||||||
|
airflow:
|
||||||
|
replicas: 2
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "1Gi"
|
||||||
|
limits:
|
||||||
|
cpu: "2000m"
|
||||||
|
memory: "4Gi"
|
||||||
|
|
||||||
|
# Stockage des logs Airflow
|
||||||
|
storage_sizes:
|
||||||
|
airflow: "20Gi"
|
||||||
13
helms/roles/airflow/meta/main.yml
Normal file
13
helms/roles/airflow/meta/main.yml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Eric FELIXINE
|
||||||
|
description: Deploy Apache Airflow for workflow orchestration on Kubernetes
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.15"
|
||||||
|
platforms:
|
||||||
|
- name: Kubernetes
|
||||||
|
versions:
|
||||||
|
- "1.28"
|
||||||
|
dependencies:
|
||||||
|
- role: databases
|
||||||
|
- role: kafka
|
||||||
34
helms/roles/airflow/tasks/main.yml
Normal file
34
helms/roles/airflow/tasks/main.yml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
---
|
||||||
|
# Role: airflow
|
||||||
|
# Déploie Apache Airflow
|
||||||
|
|
||||||
|
- name: Installer Airflow
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: airflow
|
||||||
|
chart_ref: "{{ helm_charts.airflow.chart }}"
|
||||||
|
release_namespace: airflow
|
||||||
|
create_namespace: true
|
||||||
|
values:
|
||||||
|
executor: CeleryExecutor
|
||||||
|
fernetKey: "{{ vault_airflow_fernet_key }}"
|
||||||
|
webserver:
|
||||||
|
defaultUser:
|
||||||
|
username: admin
|
||||||
|
password: "{{ vault_airflow_admin_password }}"
|
||||||
|
dags:
|
||||||
|
persistence:
|
||||||
|
enabled: true
|
||||||
|
size: 10Gi
|
||||||
|
logs:
|
||||||
|
persistence:
|
||||||
|
enabled: true
|
||||||
|
size: "{{ storage_sizes.airflow }}"
|
||||||
|
scheduler:
|
||||||
|
resources: "{{ services.airflow.resources }}"
|
||||||
|
webserver:
|
||||||
|
resources: "{{ services.airflow.resources }}"
|
||||||
|
workers:
|
||||||
|
replicas: "{{ services.airflow.replicas }}"
|
||||||
|
resources: "{{ services.airflow.resources }}"
|
||||||
|
triggerer:
|
||||||
|
resources: "{{ services.airflow.resources }}"
|
||||||
8
helms/roles/backup/defaults/main.yml
Normal file
8
helms/roles/backup/defaults/main.yml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
# Role: backup
|
||||||
|
# Valeurs par défaut pour les sauvegardes Velero
|
||||||
|
|
||||||
|
# Planification des sauvegardes (cron format)
|
||||||
|
backup:
|
||||||
|
schedule: "0 2 * * *"
|
||||||
|
retention: "168" # 7 jours en heures
|
||||||
11
helms/roles/backup/meta/main.yml
Normal file
11
helms/roles/backup/meta/main.yml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Eric FELIXINE
|
||||||
|
description: Deploy Velero backup and disaster recovery solution on Kubernetes
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.15"
|
||||||
|
platforms:
|
||||||
|
- name: Kubernetes
|
||||||
|
versions:
|
||||||
|
- "1.28"
|
||||||
|
dependencies: []
|
||||||
34
helms/roles/backup/tasks/main.yml
Normal file
34
helms/roles/backup/tasks/main.yml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
---
|
||||||
|
# Role: backup
|
||||||
|
# Configure les sauvegardes Velero
|
||||||
|
|
||||||
|
- name: Installer Velero
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: velero
|
||||||
|
chart_ref: vmware-tanzu/velero
|
||||||
|
release_namespace: velero
|
||||||
|
create_namespace: true
|
||||||
|
values:
|
||||||
|
configuration:
|
||||||
|
backupStorageLocation:
|
||||||
|
- name: default
|
||||||
|
provider: aws
|
||||||
|
bucket: smart-city-backup
|
||||||
|
config:
|
||||||
|
region: eu-west-3
|
||||||
|
s3ForcePathStyle: true
|
||||||
|
schedules:
|
||||||
|
daily:
|
||||||
|
schedule: "{{ backup.schedule }}"
|
||||||
|
template:
|
||||||
|
includedNamespaces:
|
||||||
|
- "{{ item }}"
|
||||||
|
snapshotVolumes: true
|
||||||
|
ttl: "{{ backup.retention }}h0m0s"
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
23
helms/roles/bi/defaults/main.yml
Normal file
23
helms/roles/bi/defaults/main.yml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
# Role: bi
|
||||||
|
# Valeurs par défaut pour Superset et Metabase
|
||||||
|
|
||||||
|
services:
|
||||||
|
superset:
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
|
metabase:
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
12
helms/roles/bi/meta/main.yml
Normal file
12
helms/roles/bi/meta/main.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Eric FELIXINE
|
||||||
|
description: Deploy Business Intelligence tools on Kubernetes
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.15"
|
||||||
|
platforms:
|
||||||
|
- name: Kubernetes
|
||||||
|
versions:
|
||||||
|
- "1.28"
|
||||||
|
dependencies:
|
||||||
|
- role: databases
|
||||||
44
helms/roles/bi/tasks/main.yml
Normal file
44
helms/roles/bi/tasks/main.yml
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
---
|
||||||
|
# Role: bi
|
||||||
|
# Déploie Superset et Metabase
|
||||||
|
|
||||||
|
- name: Installer Superset
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: superset
|
||||||
|
chart_ref: "{{ helm_charts.superset.chart }}"
|
||||||
|
release_namespace: superset
|
||||||
|
create_namespace: true
|
||||||
|
values:
|
||||||
|
supersetNode:
|
||||||
|
connections:
|
||||||
|
redis_password: "{{ vault_redis_password }}"
|
||||||
|
db_user: superset
|
||||||
|
db_pass: "{{ vault_superset_db_password }}"
|
||||||
|
resources: "{{ services.superset.resources }}"
|
||||||
|
supersetWorker:
|
||||||
|
replicas: 2
|
||||||
|
resources: "{{ services.superset.resources }}"
|
||||||
|
bootstrapScript: |
|
||||||
|
#!/bin/bash
|
||||||
|
pip install psycopg2-binary redis
|
||||||
|
init:
|
||||||
|
adminUser:
|
||||||
|
username: admin
|
||||||
|
password: "{{ vault_superset_admin_password }}"
|
||||||
|
email: admin@digitribe.fr
|
||||||
|
|
||||||
|
- name: Installer Metabase
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: metabase
|
||||||
|
chart_ref: "{{ helm_charts.metabase.chart }}"
|
||||||
|
release_namespace: metabase
|
||||||
|
create_namespace: true
|
||||||
|
values:
|
||||||
|
database:
|
||||||
|
type: postgres
|
||||||
|
host: postgresql-ha-pgpool.default.svc.cluster.local
|
||||||
|
port: 5432
|
||||||
|
dbname: metabase
|
||||||
|
username: metabase
|
||||||
|
password: "{{ vault_metabase_db_password }}"
|
||||||
|
resources: "{{ services.metabase.resources }}"
|
||||||
6
helms/roles/cert-manager/defaults/main.yml
Normal file
6
helms/roles/cert-manager/defaults/main.yml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
# Role: cert-manager
|
||||||
|
# Valeurs par défaut pour cert-manager
|
||||||
|
|
||||||
|
# Email pour les certificats Let's Encrypt
|
||||||
|
acme_email: "admin@digitribe.fr"
|
||||||
12
helms/roles/cert-manager/meta/main.yml
Normal file
12
helms/roles/cert-manager/meta/main.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Eric FELIXINE
|
||||||
|
description: Deploy cert-manager for automated TLS certificate management on Kubernetes
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.15"
|
||||||
|
platforms:
|
||||||
|
- name: Kubernetes
|
||||||
|
versions:
|
||||||
|
- "1.28"
|
||||||
|
dependencies:
|
||||||
|
- role: traefik
|
||||||
39
helms/roles/cert-manager/tasks/main.yml
Normal file
39
helms/roles/cert-manager/tasks/main.yml
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
---
|
||||||
|
# Role: cert-manager
|
||||||
|
# Déploie cert-manager pour la gestion des certificats TLS
|
||||||
|
|
||||||
|
- name: Installer cert-manager
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: cert-manager
|
||||||
|
chart_ref: "{{ helm_charts.cert_manager.chart }}"
|
||||||
|
chart_version: "{{ helm_charts.cert_manager.version }}"
|
||||||
|
release_namespace: cert-manager
|
||||||
|
create_namespace: true
|
||||||
|
values:
|
||||||
|
installCRDs: true
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "100m"
|
||||||
|
memory: "128Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "256Mi"
|
||||||
|
|
||||||
|
- name: Créer le ClusterIssuer Let's Encrypt
|
||||||
|
kubernetes.core.k8s:
|
||||||
|
state: present
|
||||||
|
definition:
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: ClusterIssuer
|
||||||
|
metadata:
|
||||||
|
name: letsencrypt
|
||||||
|
spec:
|
||||||
|
acme:
|
||||||
|
server: https://acme-v02.api.letsencrypt.org/directory
|
||||||
|
email: "{{ acme_email }}"
|
||||||
|
privateKeySecretRef:
|
||||||
|
name: letsencrypt-key
|
||||||
|
solvers:
|
||||||
|
- http01:
|
||||||
|
ingress:
|
||||||
|
class: traefik
|
||||||
17
helms/roles/clickhouse/defaults/main.yml
Normal file
17
helms/roles/clickhouse/defaults/main.yml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
# Role: clickhouse
|
||||||
|
# Valeurs par défaut pour ClickHouse
|
||||||
|
|
||||||
|
services:
|
||||||
|
clickhouse:
|
||||||
|
replicas: 2
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "1Gi"
|
||||||
|
limits:
|
||||||
|
cpu: "2000m"
|
||||||
|
memory: "4Gi"
|
||||||
|
|
||||||
|
storage_sizes:
|
||||||
|
clickhouse: "50Gi"
|
||||||
12
helms/roles/clickhouse/meta/main.yml
Normal file
12
helms/roles/clickhouse/meta/main.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Eric FELIXINE
|
||||||
|
description: Deploy ClickHouse columnar database for analytics on Kubernetes
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.15"
|
||||||
|
platforms:
|
||||||
|
- name: Kubernetes
|
||||||
|
versions:
|
||||||
|
- "1.28"
|
||||||
|
dependencies:
|
||||||
|
- role: databases
|
||||||
34
helms/roles/clickhouse/tasks/main.yml
Normal file
34
helms/roles/clickhouse/tasks/main.yml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
---
|
||||||
|
# Role: clickhouse
|
||||||
|
# Déploie ClickHouse
|
||||||
|
|
||||||
|
- name: Installer ClickHouse
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: clickhouse
|
||||||
|
chart_ref: "{{ helm_charts.clickhouse.chart }}"
|
||||||
|
chart_version: "{{ helm_charts.clickhouse.version }}"
|
||||||
|
release_namespace: clickhouse
|
||||||
|
create_namespace: true
|
||||||
|
values:
|
||||||
|
shards: 1
|
||||||
|
replicaCount: "{{ services.clickhouse.replicas }}"
|
||||||
|
persistence:
|
||||||
|
size: "{{ storage_sizes.clickhouse | default('50Gi') }}"
|
||||||
|
storageClass: "{{ storage_class }}"
|
||||||
|
resources: "{{ services.clickhouse.resources }}"
|
||||||
|
auth:
|
||||||
|
username: default
|
||||||
|
password: "{{ vault_clickhouse_password }}"
|
||||||
|
service:
|
||||||
|
type: ClusterIP
|
||||||
|
ingress:
|
||||||
|
enabled: true
|
||||||
|
hosts:
|
||||||
|
- host: clickhouse.digitribe.fr
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
tls:
|
||||||
|
- secretName: clickhouse-tls
|
||||||
|
hosts:
|
||||||
|
- clickhouse.digitribe.fr
|
||||||
27
helms/roles/databases/defaults/main.yml
Normal file
27
helms/roles/databases/defaults/main.yml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
# Role: databases
|
||||||
|
# Valeurs par défaut pour PostgreSQL, Redis et MinIO
|
||||||
|
|
||||||
|
services:
|
||||||
|
postgresql:
|
||||||
|
replicas: 2
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
|
|
||||||
|
# Stockages
|
||||||
|
storage_sizes:
|
||||||
|
postgresql: "50Gi"
|
||||||
|
redis: "10Gi"
|
||||||
|
minio: "100Gi"
|
||||||
|
|
||||||
|
# Mots de passe Vault (valeurs DUMMY — overridés par group_vars/vault.yml)
|
||||||
|
vault_postgres_password: "DUMMY_POSTGRES_PASSWORD"
|
||||||
|
vault_postgres_repmgr_password: "DUMMY_REPMGR_PASSWORD"
|
||||||
|
vault_redis_password: "DUMMY_REDIS_PASSWORD"
|
||||||
|
vault_minio_root_user: "DUMMY_MINIO_USER"
|
||||||
|
vault_minio_root_password: "DUMMY_MINIO_PASSWORD"
|
||||||
13
helms/roles/databases/meta/main.yml
Normal file
13
helms/roles/databases/meta/main.yml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Eric FELIXINE
|
||||||
|
description: Deploy and manage core database services (PostgreSQL, MySQL, Redis) on Kubernetes
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.15"
|
||||||
|
platforms:
|
||||||
|
- name: Kubernetes
|
||||||
|
versions:
|
||||||
|
- "1.28"
|
||||||
|
dependencies:
|
||||||
|
- role: storage
|
||||||
|
- role: cert-manager
|
||||||
54
helms/roles/databases/tasks/main.yml
Normal file
54
helms/roles/databases/tasks/main.yml
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
---
|
||||||
|
# Role: databases
|
||||||
|
# Déploie PostgreSQL, Redis et MinIO
|
||||||
|
|
||||||
|
- name: Installer PostgreSQL HA
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: postgresql
|
||||||
|
chart_ref: "{{ helm_charts.postgresql_ha.chart }}"
|
||||||
|
release_namespace: default
|
||||||
|
values:
|
||||||
|
postgresql:
|
||||||
|
password: "{{ vault_postgres_password }}"
|
||||||
|
repmgrPassword: "{{ vault_postgres_repmgr_password }}"
|
||||||
|
persistence:
|
||||||
|
size: "{{ storage_sizes.postgresql }}"
|
||||||
|
storageClass: "{{ storage_class }}"
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "{{ services.postgresql.resources.requests.cpu }}"
|
||||||
|
memory: "{{ services.postgresql.resources.requests.memory }}"
|
||||||
|
|
||||||
|
- name: Installer Redis Cluster
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: redis
|
||||||
|
chart_ref: "{{ helm_charts.redis.chart }}"
|
||||||
|
release_namespace: default
|
||||||
|
values:
|
||||||
|
cluster:
|
||||||
|
nodes: 3
|
||||||
|
password: "{{ vault_redis_password }}"
|
||||||
|
persistence:
|
||||||
|
size: "{{ storage_sizes.redis }}"
|
||||||
|
storageClass: "{{ storage_class }}"
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "100m"
|
||||||
|
memory: "256Mi"
|
||||||
|
|
||||||
|
- name: Installer MinIO
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: minio
|
||||||
|
chart_ref: "{{ helm_charts.minio.chart }}"
|
||||||
|
release_namespace: default
|
||||||
|
values:
|
||||||
|
auth:
|
||||||
|
rootUser: "{{ vault_minio_root_user }}"
|
||||||
|
rootPassword: "{{ vault_minio_root_password }}"
|
||||||
|
persistence:
|
||||||
|
size: "{{ storage_sizes.minio }}"
|
||||||
|
storageClass: "{{ storage_class }}"
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
17
helms/roles/deltalake/defaults/main.yml
Normal file
17
helms/roles/deltalake/defaults/main.yml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
# Role: deltalake
|
||||||
|
# Valeurs par défaut pour Delta Lake
|
||||||
|
|
||||||
|
services:
|
||||||
|
deltalake:
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
|
|
||||||
|
storage_sizes:
|
||||||
|
deltalake: "100Gi"
|
||||||
12
helms/roles/deltalake/meta/main.yml
Normal file
12
helms/roles/deltalake/meta/main.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Eric FELIXINE
|
||||||
|
description: Deploy Delta Lake storage layer for data lakehouse architecture on Kubernetes
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.15"
|
||||||
|
platforms:
|
||||||
|
- name: Kubernetes
|
||||||
|
versions:
|
||||||
|
- "1.28"
|
||||||
|
dependencies:
|
||||||
|
- role: databases
|
||||||
30
helms/roles/deltalake/tasks/main.yml
Normal file
30
helms/roles/deltalake/tasks/main.yml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
# Role: deltalake
|
||||||
|
# Déploie Delta Lake
|
||||||
|
|
||||||
|
- name: Installer Delta Lake
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: deltalake
|
||||||
|
chart_ref: "{{ helm_charts.deltalake.chart }}"
|
||||||
|
chart_version: "{{ helm_charts.deltalake.version }}"
|
||||||
|
release_namespace: deltalake
|
||||||
|
create_namespace: true
|
||||||
|
values:
|
||||||
|
replicaCount: "{{ services.deltalake.replicas }}"
|
||||||
|
resources: "{{ services.deltalake.resources }}"
|
||||||
|
storage:
|
||||||
|
size: "{{ storage_sizes.deltalake | default('100Gi') }}"
|
||||||
|
storageClass: "{{ storage_class }}"
|
||||||
|
service:
|
||||||
|
type: ClusterIP
|
||||||
|
ingress:
|
||||||
|
enabled: true
|
||||||
|
hosts:
|
||||||
|
- host: deltalake.digitribe.fr
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
tls:
|
||||||
|
- secretName: deltalake-tls
|
||||||
|
hosts:
|
||||||
|
- deltalake.digitribe.fr
|
||||||
17
helms/roles/duckdb/defaults/main.yml
Normal file
17
helms/roles/duckdb/defaults/main.yml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
# Role: duckdb
|
||||||
|
# Valeurs par défaut pour DuckDB
|
||||||
|
|
||||||
|
services:
|
||||||
|
duckdb:
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
|
|
||||||
|
storage_sizes:
|
||||||
|
duckdb: "50Gi"
|
||||||
12
helms/roles/duckdb/meta/main.yml
Normal file
12
helms/roles/duckdb/meta/main.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Eric FELIXINE
|
||||||
|
description: Deploy DuckDB embedded analytical database on Kubernetes
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.15"
|
||||||
|
platforms:
|
||||||
|
- name: Kubernetes
|
||||||
|
versions:
|
||||||
|
- "1.28"
|
||||||
|
dependencies:
|
||||||
|
- role: databases
|
||||||
30
helms/roles/duckdb/tasks/main.yml
Normal file
30
helms/roles/duckdb/tasks/main.yml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
# Role: duckdb
|
||||||
|
# Déploie DuckDB
|
||||||
|
|
||||||
|
- name: Installer DuckDB
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: duckdb
|
||||||
|
chart_ref: "{{ helm_charts.duckdb.chart }}"
|
||||||
|
chart_version: "{{ helm_charts.duckdb.version }}"
|
||||||
|
release_namespace: duckdb
|
||||||
|
create_namespace: true
|
||||||
|
values:
|
||||||
|
replicaCount: "{{ services.duckdb.replicas }}"
|
||||||
|
resources: "{{ services.duckdb.resources }}"
|
||||||
|
storage:
|
||||||
|
size: "{{ storage_sizes.duckdb | default('50Gi') }}"
|
||||||
|
storageClass: "{{ storage_class }}"
|
||||||
|
service:
|
||||||
|
type: ClusterIP
|
||||||
|
ingress:
|
||||||
|
enabled: true
|
||||||
|
hosts:
|
||||||
|
- host: duckdb.digitribe.fr
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
tls:
|
||||||
|
- secretName: duckdb-tls
|
||||||
|
hosts:
|
||||||
|
- duckdb.digitribe.fr
|
||||||
14
helms/roles/flink/defaults/main.yml
Normal file
14
helms/roles/flink/defaults/main.yml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
# Role: flink
|
||||||
|
# Valeurs par défaut pour Apache Flink
|
||||||
|
|
||||||
|
services:
|
||||||
|
flink:
|
||||||
|
replicas: 2
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
|
limits:
|
||||||
|
cpu: "2000m"
|
||||||
|
memory: "4Gi"
|
||||||
12
helms/roles/flink/meta/main.yml
Normal file
12
helms/roles/flink/meta/main.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Eric FELIXINE
|
||||||
|
description: Deploy Apache Flink for stream processing on Kubernetes
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.15"
|
||||||
|
platforms:
|
||||||
|
- name: Kubernetes
|
||||||
|
versions:
|
||||||
|
- "1.28"
|
||||||
|
dependencies:
|
||||||
|
- role: kafka
|
||||||
18
helms/roles/flink/tasks/main.yml
Normal file
18
helms/roles/flink/tasks/main.yml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
# Role: flink
|
||||||
|
# Déploie Apache Flink via l'opérateur
|
||||||
|
|
||||||
|
- name: Installer l'opérateur Flink
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: flink-kubernetes-operator
|
||||||
|
chart_ref: "{{ helm_charts.flink.chart }}"
|
||||||
|
release_namespace: flink
|
||||||
|
create_namespace: true
|
||||||
|
|
||||||
|
- name: Créer le déploiement Flink
|
||||||
|
kubernetes.core.k8s:
|
||||||
|
state: present
|
||||||
|
template: flink-deployment.yml.j2
|
||||||
|
vars:
|
||||||
|
flink_namespace: flink
|
||||||
|
flink_replicas: "{{ services.flink.replicas }}"
|
||||||
140
helms/roles/flink/templates/flink-deployment.yml.j2
Normal file
140
helms/roles/flink/templates/flink-deployment.yml.j2
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
---
|
||||||
|
# Role: flink
|
||||||
|
# Template: flink-deployment.yml.j2
|
||||||
|
# Déploiement d'un cluster Apache Flink via FlinkKubernetesOperator
|
||||||
|
# Variables:
|
||||||
|
# {{ flink_namespace }} - Namespace Kubernetes (défaut: flink)
|
||||||
|
# {{ flink_replicas }} - Nombre de TaskManagers (défaut: 2)
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: {{ flink_namespace | default('flink') }}
|
||||||
|
labels:
|
||||||
|
app: flink
|
||||||
|
version: "1.18"
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: flink.apache.org/v1beta1
|
||||||
|
kind: FlinkDeployment
|
||||||
|
metadata:
|
||||||
|
name: flink-cluster
|
||||||
|
namespace: {{ flink_namespace | default('flink') }}
|
||||||
|
labels:
|
||||||
|
app: flink
|
||||||
|
version: "1.18"
|
||||||
|
spec:
|
||||||
|
image: flink:1.18-scala_2.12
|
||||||
|
flinkVersion: v1_18
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
|
||||||
|
# --- JobManager ---
|
||||||
|
jobmanager:
|
||||||
|
resource:
|
||||||
|
memory: "2048m"
|
||||||
|
cpu: 1
|
||||||
|
replicas: 1
|
||||||
|
|
||||||
|
# --- TaskManager ---
|
||||||
|
taskmanager:
|
||||||
|
resource:
|
||||||
|
memory: "4096m"
|
||||||
|
cpu: 2
|
||||||
|
replicas: {{ flink_replicas | default(2) }}
|
||||||
|
|
||||||
|
# --- Configuration Flink ---
|
||||||
|
flinkConfiguration:
|
||||||
|
taskmanager.numberOfTaskSlots: "2"
|
||||||
|
state.backend: rocksdb
|
||||||
|
state.checkpoints.dir: s3://flink-checkpoints
|
||||||
|
state.savepoints.dir: s3://flink-savepoints
|
||||||
|
high-availability: zookeeper
|
||||||
|
high-availability.zookeeper.quorum: zk-cs.{{ flink_namespace | default('flink') }}.svc.cluster.local:2181
|
||||||
|
web.upload.dir: /tmp/flink-web-upload
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: flink-jobmanager
|
||||||
|
namespace: {{ flink_namespace | default('flink') }}
|
||||||
|
labels:
|
||||||
|
app: flink
|
||||||
|
component: jobmanager
|
||||||
|
version: "1.18"
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
selector:
|
||||||
|
app: flink
|
||||||
|
component: jobmanager
|
||||||
|
ports:
|
||||||
|
- name: rpc
|
||||||
|
port: 6123
|
||||||
|
targetPort: 6123
|
||||||
|
protocol: TCP
|
||||||
|
- name: blob
|
||||||
|
port: 6124
|
||||||
|
targetPort: 6124
|
||||||
|
protocol: TCP
|
||||||
|
- name: webui
|
||||||
|
port: 8081
|
||||||
|
targetPort: 8081
|
||||||
|
protocol: TCP
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: flink-taskmanager
|
||||||
|
namespace: {{ flink_namespace | default('flink') }}
|
||||||
|
labels:
|
||||||
|
app: flink
|
||||||
|
component: taskmanager
|
||||||
|
version: "1.18"
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
selector:
|
||||||
|
app: flink
|
||||||
|
component: taskmanager
|
||||||
|
ports:
|
||||||
|
- name: rpc
|
||||||
|
port: 6122
|
||||||
|
targetPort: 6122
|
||||||
|
protocol: TCP
|
||||||
|
- name: data
|
||||||
|
port: 6125
|
||||||
|
targetPort: 6125
|
||||||
|
protocol: TCP
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: flink-webui
|
||||||
|
namespace: {{ flink_namespace | default('flink') }}
|
||||||
|
labels:
|
||||||
|
app: flink
|
||||||
|
component: webui
|
||||||
|
version: "1.18"
|
||||||
|
annotations:
|
||||||
|
nginx.ingress.kubernetes.io/rewrite-target: /
|
||||||
|
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||||
|
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||||
|
spec:
|
||||||
|
ingressClassName: nginx
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- flink.digitribe.fr
|
||||||
|
secretName: flink-tls
|
||||||
|
rules:
|
||||||
|
- host: flink.digitribe.fr
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: flink-jobmanager
|
||||||
|
port:
|
||||||
|
number: 8081
|
||||||
36
helms/roles/gis/defaults/main.yml
Normal file
36
helms/roles/gis/defaults/main.yml
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
---
|
||||||
|
# Role: gis
|
||||||
|
# Valeurs par défaut pour MapStore, GeoServer et FROST
|
||||||
|
|
||||||
|
services:
|
||||||
|
mapstore:
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
|
geoserver:
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "1Gi"
|
||||||
|
limits:
|
||||||
|
cpu: "2000m"
|
||||||
|
memory: "4Gi"
|
||||||
|
frost:
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
|
|
||||||
|
storage_sizes:
|
||||||
|
mapstore: "10Gi"
|
||||||
|
geoserver: "20Gi"
|
||||||
12
helms/roles/gis/meta/main.yml
Normal file
12
helms/roles/gis/meta/main.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Eric FELIXINE
|
||||||
|
description: Deploy Geographic Information System (GIS) services on Kubernetes
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.15"
|
||||||
|
platforms:
|
||||||
|
- name: Kubernetes
|
||||||
|
versions:
|
||||||
|
- "1.28"
|
||||||
|
dependencies:
|
||||||
|
- role: databases
|
||||||
37
helms/roles/gis/tasks/main.yml
Normal file
37
helms/roles/gis/tasks/main.yml
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
---
|
||||||
|
# Role: gis
|
||||||
|
# Déploie MapStore, GeoServer et FROST
|
||||||
|
|
||||||
|
- name: Installer MapStore
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: mapstore
|
||||||
|
chart_ref: "{{ helm_charts.mapstore.chart }}"
|
||||||
|
release_namespace: mapstore
|
||||||
|
create_namespace: true
|
||||||
|
values:
|
||||||
|
persistence:
|
||||||
|
size: "{{ storage_sizes.mapstore }}"
|
||||||
|
resources: "{{ services.mapstore.resources }}"
|
||||||
|
|
||||||
|
- name: Installer GeoServer
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: geoserver
|
||||||
|
chart_ref: "{{ helm_charts.geoserver.chart }}"
|
||||||
|
release_namespace: geoserver
|
||||||
|
create_namespace: true
|
||||||
|
values:
|
||||||
|
persistence:
|
||||||
|
geodataDir:
|
||||||
|
storageClass: "{{ storage_class }}"
|
||||||
|
size: "{{ storage_sizes.geoserver }}"
|
||||||
|
resources: "{{ services.geoserver.resources }}"
|
||||||
|
|
||||||
|
- name: Installer FROST
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: frost
|
||||||
|
chart_ref: "{{ helm_charts.frost.chart }}"
|
||||||
|
release_namespace: iot
|
||||||
|
values:
|
||||||
|
persistence:
|
||||||
|
size: 10Gi
|
||||||
|
resources: "{{ services.frost.resources }}"
|
||||||
17
helms/roles/gitea/defaults/main.yml
Normal file
17
helms/roles/gitea/defaults/main.yml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
# Role: gitea
|
||||||
|
# Valeurs par défaut pour Gitea
|
||||||
|
|
||||||
|
services:
|
||||||
|
gitea:
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
|
|
||||||
|
storage_sizes:
|
||||||
|
gitea: "20Gi"
|
||||||
12
helms/roles/gitea/meta/main.yml
Normal file
12
helms/roles/gitea/meta/main.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Eric FELIXINE
|
||||||
|
description: Deploy Gitea - self-hosted Git service on Kubernetes
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.15"
|
||||||
|
platforms:
|
||||||
|
- name: Kubernetes
|
||||||
|
versions:
|
||||||
|
- "1.28"
|
||||||
|
dependencies:
|
||||||
|
- role: databases
|
||||||
28
helms/roles/gitea/tasks/main.yml
Normal file
28
helms/roles/gitea/tasks/main.yml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
# Role: gitea
|
||||||
|
# Déploie Gitea
|
||||||
|
|
||||||
|
- name: Installer Gitea
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: gitea
|
||||||
|
chart_ref: "{{ helm_charts.gitea.chart }}"
|
||||||
|
release_namespace: gitea
|
||||||
|
create_namespace: true
|
||||||
|
values:
|
||||||
|
gitea:
|
||||||
|
admin:
|
||||||
|
username: eric
|
||||||
|
password: "{{ vault_gitea_admin_password }}"
|
||||||
|
email: admin@digitribe.fr
|
||||||
|
config:
|
||||||
|
server:
|
||||||
|
DOMAIN: gitea.digitribe.fr
|
||||||
|
ROOT_URL: https://gitea.digitribe.fr
|
||||||
|
SSH_DOMAIN: gitea.digitribe.fr
|
||||||
|
SSH_PORT: 22
|
||||||
|
persistence:
|
||||||
|
enabled: true
|
||||||
|
size: "{{ storage_sizes.gitea }}"
|
||||||
|
postgresql:
|
||||||
|
enabled: true
|
||||||
|
resources: "{{ services.gitea.resources }}"
|
||||||
27
helms/roles/iot/defaults/main.yml
Normal file
27
helms/roles/iot/defaults/main.yml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
# Role: iot
|
||||||
|
# Valeurs par défaut pour EMQX et Mosquitto
|
||||||
|
|
||||||
|
services:
|
||||||
|
emqx:
|
||||||
|
replicas: 2
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
|
mosquitto:
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "100m"
|
||||||
|
memory: "256Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "512Mi"
|
||||||
|
|
||||||
|
storage_sizes:
|
||||||
|
emqx: "10Gi"
|
||||||
|
mosquitto: "5Gi"
|
||||||
13
helms/roles/iot/meta/main.yml
Normal file
13
helms/roles/iot/meta/main.yml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Eric FELIXINE
|
||||||
|
description: Deploy IoT platform services on Kubernetes
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.15"
|
||||||
|
platforms:
|
||||||
|
- name: Kubernetes
|
||||||
|
versions:
|
||||||
|
- "1.28"
|
||||||
|
dependencies:
|
||||||
|
- role: databases
|
||||||
|
- role: kafka
|
||||||
35
helms/roles/iot/tasks/main.yml
Normal file
35
helms/roles/iot/tasks/main.yml
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
---
|
||||||
|
# Role: iot
|
||||||
|
# Déploie les brokers MQTT
|
||||||
|
|
||||||
|
|
||||||
|
- name: Installer EMQX
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: emqx
|
||||||
|
chart_ref: "{{ helm_charts.emqx.chart }}"
|
||||||
|
release_namespace: iot
|
||||||
|
create_namespace: true
|
||||||
|
values:
|
||||||
|
replicaCount: "{{ services.emqx.replicas }}"
|
||||||
|
persistence:
|
||||||
|
enabled: true
|
||||||
|
size: "{{ storage_sizes.emqx }}"
|
||||||
|
resources: "{{ services.emqx.resources }}"
|
||||||
|
|
||||||
|
- name: Installer Mosquitto
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: mosquitto
|
||||||
|
chart_ref: "{{ helm_charts.mosquitto.chart }}"
|
||||||
|
release_namespace: iot
|
||||||
|
values:
|
||||||
|
replicaCount: "{{ services.mosquitto.replicas }}"
|
||||||
|
persistence:
|
||||||
|
enabled: true
|
||||||
|
size: "{{ storage_sizes.mosquitto }}"
|
||||||
|
resources: "{{ services.mosquitto.resources }}"
|
||||||
|
config: |
|
||||||
|
listener 1883
|
||||||
|
allow_anonymous false
|
||||||
|
password_file /etc/mosquitto/passwd
|
||||||
|
auth:
|
||||||
|
password: "{{ vault_mosquitto_password }}"
|
||||||
17
helms/roles/jupyterhub/defaults/main.yml
Normal file
17
helms/roles/jupyterhub/defaults/main.yml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
# Role: jupyterhub
|
||||||
|
# Valeurs par défaut pour JupyterHub
|
||||||
|
|
||||||
|
services:
|
||||||
|
jupyterhub:
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
|
|
||||||
|
storage_sizes:
|
||||||
|
jupyterhub: "20Gi"
|
||||||
12
helms/roles/jupyterhub/meta/main.yml
Normal file
12
helms/roles/jupyterhub/meta/main.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Eric FELIXINE
|
||||||
|
description: Deploy JupyterHub for multi-user notebook environments on Kubernetes
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.15"
|
||||||
|
platforms:
|
||||||
|
- name: Kubernetes
|
||||||
|
versions:
|
||||||
|
- "1.28"
|
||||||
|
dependencies:
|
||||||
|
- role: databases
|
||||||
31
helms/roles/jupyterhub/tasks/main.yml
Normal file
31
helms/roles/jupyterhub/tasks/main.yml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
---
|
||||||
|
# Role: jupyterhub
|
||||||
|
# Déploie JupyterHub
|
||||||
|
|
||||||
|
- name: Installer JupyterHub
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: hub
|
||||||
|
chart_ref: "{{ helm_charts.jupyterhub.chart }}"
|
||||||
|
release_namespace: jupyterhub
|
||||||
|
create_namespace: true
|
||||||
|
values:
|
||||||
|
hub:
|
||||||
|
config:
|
||||||
|
Authenticator:
|
||||||
|
admin_users:
|
||||||
|
- eric
|
||||||
|
JupyterHub:
|
||||||
|
admin_access: true
|
||||||
|
db:
|
||||||
|
pvc:
|
||||||
|
storage: "{{ storage_sizes.jupyterhub }}"
|
||||||
|
singleuser:
|
||||||
|
storage:
|
||||||
|
capacity: "{{ storage_sizes.jupyterhub }}"
|
||||||
|
dynamic:
|
||||||
|
pvcNameTemplate: "jupyterhub-{userid}"
|
||||||
|
volumeNameTemplate: "jupyterhub-{userid}"
|
||||||
|
storageClass: "{{ storage_class }}"
|
||||||
|
proxy:
|
||||||
|
service:
|
||||||
|
type: ClusterIP
|
||||||
17
helms/roles/kafka/defaults/main.yml
Normal file
17
helms/roles/kafka/defaults/main.yml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
# Role: kafka
|
||||||
|
# Valeurs par défaut pour Kafka (Strimzi)
|
||||||
|
|
||||||
|
services:
|
||||||
|
kafka:
|
||||||
|
replicas: 3
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
|
limits:
|
||||||
|
cpu: "2000m"
|
||||||
|
memory: "4Gi"
|
||||||
|
|
||||||
|
storage_sizes:
|
||||||
|
kafka: "100Gi"
|
||||||
13
helms/roles/kafka/meta/main.yml
Normal file
13
helms/roles/kafka/meta/main.yml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Eric FELIXINE
|
||||||
|
description: Deploy and manage Apache Kafka cluster on Kubernetes
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.15"
|
||||||
|
platforms:
|
||||||
|
- name: Kubernetes
|
||||||
|
versions:
|
||||||
|
- "1.28"
|
||||||
|
dependencies:
|
||||||
|
- role: storage
|
||||||
|
- role: cert-manager
|
||||||
19
helms/roles/kafka/tasks/main.yml
Normal file
19
helms/roles/kafka/tasks/main.yml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
# Role: kafka
|
||||||
|
# Déploie Kafka via l'opérateur Strimzi
|
||||||
|
|
||||||
|
- name: Installer l'opérateur Strimzi
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: strimzi-kafka-operator
|
||||||
|
chart_ref: "{{ helm_charts.kafka.chart }}"
|
||||||
|
release_namespace: kafka
|
||||||
|
create_namespace: true
|
||||||
|
|
||||||
|
- name: Créer le cluster Kafka
|
||||||
|
kubernetes.core.k8s:
|
||||||
|
state: present
|
||||||
|
template: kafka-cluster.yml.j2
|
||||||
|
vars:
|
||||||
|
kafka_namespace: kafka
|
||||||
|
kafka_replicas: "{{ services.kafka.replicas }}"
|
||||||
|
kafka_storage_size: "{{ storage_sizes.kafka }}"
|
||||||
295
helms/roles/kafka/templates/kafka-cluster.yml.j2
Normal file
295
helms/roles/kafka/templates/kafka-cluster.yml.j2
Normal file
@@ -0,0 +1,295 @@
|
|||||||
|
---
|
||||||
|
# Role: kafka
|
||||||
|
# Template: kafka-cluster.yml.j2
|
||||||
|
# Cluster Kafka via Strimzi KafkaOperator
|
||||||
|
# Variables:
|
||||||
|
# {{ kafka_namespace }} - Namespace Kubernetes (défaut: kafka)
|
||||||
|
# {{ kafka_replicas }} - Nombre de brokers Kafka (défaut: 3)
|
||||||
|
# {{ kafka_storage_size }} - Taille du stockage par broker (défaut: 100Gi)
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: {{ kafka_namespace | default('kafka') }}
|
||||||
|
labels:
|
||||||
|
app: kafka
|
||||||
|
version: "3.6"
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: kafka.strimzi.io/v1beta2
|
||||||
|
kind: Kafka
|
||||||
|
metadata:
|
||||||
|
name: kafka-cluster
|
||||||
|
namespace: {{ kafka_namespace | default('kafka') }}
|
||||||
|
labels:
|
||||||
|
app: kafka
|
||||||
|
version: "3.6"
|
||||||
|
spec:
|
||||||
|
kafka:
|
||||||
|
version: 3.6.0
|
||||||
|
replicas: {{ kafka_replicas | default(3) }}
|
||||||
|
listeners:
|
||||||
|
- name: plain
|
||||||
|
port: 9092
|
||||||
|
type: internal
|
||||||
|
tls: false
|
||||||
|
- name: tls
|
||||||
|
port: 9093
|
||||||
|
type: internal
|
||||||
|
tls: true
|
||||||
|
- name: external
|
||||||
|
port: 9094
|
||||||
|
type: ingress
|
||||||
|
tls: true
|
||||||
|
configuration:
|
||||||
|
bootstrap:
|
||||||
|
host: kafka-bootstrap.digitribe.fr
|
||||||
|
brokers:
|
||||||
|
- broker: 0
|
||||||
|
host: kafka-broker-0.digitribe.fr
|
||||||
|
- broker: 1
|
||||||
|
host: kafka-broker-1.digitribe.fr
|
||||||
|
- broker: 2
|
||||||
|
host: kafka-broker-2.digitribe.fr
|
||||||
|
config:
|
||||||
|
offsets.topic.replication.factor: 3
|
||||||
|
transaction.state.log.replication.factor: 3
|
||||||
|
transaction.state.log.min.isr: 2
|
||||||
|
default.replication.factor: 3
|
||||||
|
min.insync.replicas: 2
|
||||||
|
inter.broker.protocol.version: "3.6"
|
||||||
|
log.message.format.version: "3.6"
|
||||||
|
storage:
|
||||||
|
type: jbod
|
||||||
|
volumes:
|
||||||
|
- id: 0
|
||||||
|
type: persistent-claim
|
||||||
|
size: {{ kafka_storage_size | default('100Gi') }}
|
||||||
|
class: standard
|
||||||
|
deleteClaim: false
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "1"
|
||||||
|
memory: "2Gi"
|
||||||
|
limits:
|
||||||
|
cpu: "2"
|
||||||
|
memory: "4Gi"
|
||||||
|
livenessProbe:
|
||||||
|
initialDelaySeconds: 30
|
||||||
|
timeoutSeconds: 5
|
||||||
|
readinessProbe:
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
timeoutSeconds: 5
|
||||||
|
metricsConfig:
|
||||||
|
type: jmxPrometheusExporter
|
||||||
|
valueFrom:
|
||||||
|
configMapKeyRef:
|
||||||
|
name: kafka-metrics
|
||||||
|
key: kafka-metrics-config.yml
|
||||||
|
template:
|
||||||
|
pod:
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
requiredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- labelSelector:
|
||||||
|
matchExpressions:
|
||||||
|
- key: strimzi.io/name
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- kafka-cluster-kafka
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
|
||||||
|
zookeeper:
|
||||||
|
replicas: 3
|
||||||
|
storage:
|
||||||
|
type: persistent-claim
|
||||||
|
size: 20Gi
|
||||||
|
class: standard
|
||||||
|
deleteClaim: false
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "1Gi"
|
||||||
|
limits:
|
||||||
|
cpu: "1"
|
||||||
|
memory: "2Gi"
|
||||||
|
livenessProbe:
|
||||||
|
initialDelaySeconds: 30
|
||||||
|
timeoutSeconds: 5
|
||||||
|
readinessProbe:
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
timeoutSeconds: 5
|
||||||
|
|
||||||
|
entityOperator:
|
||||||
|
topicOperator:
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "1Gi"
|
||||||
|
userOperator:
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "1Gi"
|
||||||
|
|
||||||
|
kafkaExporter:
|
||||||
|
topicRegex: ".*"
|
||||||
|
groupRegex: ".*"
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "200m"
|
||||||
|
memory: "256Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "512Mi"
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: kafka-metrics
|
||||||
|
namespace: {{ kafka_namespace | default('kafka') }}
|
||||||
|
labels:
|
||||||
|
app: kafka
|
||||||
|
version: "3.6"
|
||||||
|
data:
|
||||||
|
kafka-metrics-config.yml: |
|
||||||
|
# See https://github.com/prometheus/jmx_exporter for more info about JMX Prometheus Exporter metrics
|
||||||
|
lowercaseOutputName: true
|
||||||
|
rules:
|
||||||
|
# Special cases and very specific rules
|
||||||
|
- pattern: kafka.server<type=(.+), name=(.+), clientId=(.+), topic=(.+), partition=(.*)><>Value
|
||||||
|
name: kafka_server_$1_$2
|
||||||
|
type: GAUGE
|
||||||
|
labels:
|
||||||
|
clientId: "$3"
|
||||||
|
topic: "$4"
|
||||||
|
partition: "$5"
|
||||||
|
- pattern: kafka.server<type=(.+), name=(.+), clientId=(.+), brokerHost=(.+), brokerPort=(.+)><>Value
|
||||||
|
name: kafka_server_$1_$2
|
||||||
|
type: GAUGE
|
||||||
|
labels:
|
||||||
|
clientId: "$3"
|
||||||
|
broker: "$4:$5"
|
||||||
|
# Generic per-second counters with 0-2 key/value pairs
|
||||||
|
- pattern: kafka.(\w+)<type=(.+), name=(.+)PerSec\w*, (.+)=(.+), (.+)=(.+)><>Count
|
||||||
|
name: kafka_$1_$2_$3_total
|
||||||
|
type: COUNTER
|
||||||
|
labels:
|
||||||
|
"$4": "$5"
|
||||||
|
"$6": "$7"
|
||||||
|
- pattern: kafka.(\w+)<type=(.+), name=(.+)PerSec\w*, (.+)=(.+)><>Count
|
||||||
|
name: kafka_$1_$2_$3_total
|
||||||
|
type: COUNTER
|
||||||
|
labels:
|
||||||
|
"$4": "$5"
|
||||||
|
- pattern: kafka.(\w+)<type=(.+), name=(.+)PerSec\w*><>Count
|
||||||
|
name: kafka_$1_$2_$3_total
|
||||||
|
type: COUNTER
|
||||||
|
# Generic gauges with 0-2 key/value pairs
|
||||||
|
- pattern: kafka.(\w+)<type=(.+), name=(.+), (.+)=(.+), (.+)=(.+)><>Value
|
||||||
|
name: kafka_$1_$2_$3
|
||||||
|
type: GAUGE
|
||||||
|
labels:
|
||||||
|
"$4": "$5"
|
||||||
|
"$6": "$7"
|
||||||
|
- pattern: kafka.(\w+)<type=(.+), name=(.+), (.+)=(.+)><>Value
|
||||||
|
name: kafka_$1_$2_$3
|
||||||
|
type: GAUGE
|
||||||
|
labels:
|
||||||
|
"$4": "$5"
|
||||||
|
- pattern: kafka.(\w+)<type=(.+), name=(.+)><>Value
|
||||||
|
name: kafka_$1_$2_$3
|
||||||
|
type: GAUGE
|
||||||
|
# Emulate Prometheus 'Summary' metrics for the exported 'Histogram's
|
||||||
|
- pattern: kafka.(\w+)<type=(.+), name=(.+), (.+)=(.+), (.+)=(.+)><>Count
|
||||||
|
name: kafka_$1_$2_$3_count
|
||||||
|
type: COUNTER
|
||||||
|
labels:
|
||||||
|
"$4": "$5"
|
||||||
|
"$6": "$7"
|
||||||
|
- pattern: kafka.(\w+)<type=(.+), name=(.+), (.+)=(.*), (.+)=(.+)><>(\d+)thPercentile
|
||||||
|
name: kafka_$1_$2_$3
|
||||||
|
type: SUMMARY
|
||||||
|
labels:
|
||||||
|
"$4": "$5"
|
||||||
|
"$6": "$7"
|
||||||
|
quantile: 0.95
|
||||||
|
- pattern: kafka.(\w+)<type=(.+), name=(.+), (.+)=(.+)><>Count
|
||||||
|
name: kafka_$1_$2_$3_count
|
||||||
|
type: COUNTER
|
||||||
|
labels:
|
||||||
|
"$4": "$5"
|
||||||
|
- pattern: kafka.(\w+)<type=(.+), name=(.+), (.+)=(.*)><>(\d+)thPercentile
|
||||||
|
name: kafka_$1_$2_$3
|
||||||
|
type: SUMMARY
|
||||||
|
labels:
|
||||||
|
"$4": "$5"
|
||||||
|
quantile: 0.95
|
||||||
|
- pattern: kafka.(\w+)<type=(.+), name=(.+)><>Count
|
||||||
|
name: kafka_$1_$2_$3_count
|
||||||
|
type: COUNTER
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: kafka-bootstrap
|
||||||
|
namespace: {{ kafka_namespace | default('kafka') }}
|
||||||
|
labels:
|
||||||
|
app: kafka
|
||||||
|
component: bootstrap
|
||||||
|
version: "3.6"
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
selector:
|
||||||
|
strimzi.io/cluster: kafka-cluster
|
||||||
|
strimzi.io/name: kafka-cluster-kafka
|
||||||
|
ports:
|
||||||
|
- name: tcp-internal
|
||||||
|
port: 9092
|
||||||
|
targetPort: 9092
|
||||||
|
protocol: TCP
|
||||||
|
- name: tcp-tls
|
||||||
|
port: 9093
|
||||||
|
targetPort: 9093
|
||||||
|
protocol: TCP
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: kafka-external
|
||||||
|
namespace: {{ kafka_namespace | default('kafka') }}
|
||||||
|
labels:
|
||||||
|
app: kafka
|
||||||
|
component: external
|
||||||
|
version: "3.6"
|
||||||
|
annotations:
|
||||||
|
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||||
|
nginx.ingress.kubernetes.io/backend-protocol: "TCP"
|
||||||
|
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||||
|
spec:
|
||||||
|
ingressClassName: nginx
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- kafka-bootstrap.digitribe.fr
|
||||||
|
secretName: kafka-bootstrap-tls
|
||||||
|
rules:
|
||||||
|
- host: kafka-bootstrap.digitribe.fr
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: kafka-cluster-kafka-external-bootstrap
|
||||||
|
port:
|
||||||
|
number: 9094
|
||||||
17
helms/roles/mindsdb/defaults/main.yml
Normal file
17
helms/roles/mindsdb/defaults/main.yml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
# Role: mindsdb
|
||||||
|
# Valeurs par défaut pour MindsDB
|
||||||
|
|
||||||
|
services:
|
||||||
|
mindsdb:
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "1Gi"
|
||||||
|
limits:
|
||||||
|
cpu: "2000m"
|
||||||
|
memory: "4Gi"
|
||||||
|
|
||||||
|
storage_sizes:
|
||||||
|
mindsdb: "20Gi"
|
||||||
12
helms/roles/mindsdb/meta/main.yml
Normal file
12
helms/roles/mindsdb/meta/main.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Eric FELIXINE
|
||||||
|
description: Deploy MindsDB - open-source AI/ML database on Kubernetes
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.15"
|
||||||
|
platforms:
|
||||||
|
- name: Kubernetes
|
||||||
|
versions:
|
||||||
|
- "1.28"
|
||||||
|
dependencies:
|
||||||
|
- role: databases
|
||||||
18
helms/roles/mindsdb/tasks/main.yml
Normal file
18
helms/roles/mindsdb/tasks/main.yml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
# Role: mindsdb
|
||||||
|
# Déploie MindsDB
|
||||||
|
|
||||||
|
- name: Installer MindsDB
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: mindsdb
|
||||||
|
chart_ref: "{{ helm_charts.mindsdb.chart }}"
|
||||||
|
release_namespace: mindsdb
|
||||||
|
create_namespace: true
|
||||||
|
values:
|
||||||
|
mindsdb:
|
||||||
|
auth:
|
||||||
|
username: admin
|
||||||
|
password: "{{ vault_mindsdb_password }}"
|
||||||
|
storage:
|
||||||
|
size: "{{ storage_sizes.mindsdb }}"
|
||||||
|
resources: "{{ services.mindsdb.resources }}"
|
||||||
12
helms/roles/monitoring/defaults/main.yml
Normal file
12
helms/roles/monitoring/defaults/main.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
# Role: monitoring
|
||||||
|
# Valeurs par défaut pour Prometheus, Grafana, Loki et Promtail
|
||||||
|
|
||||||
|
monitoring:
|
||||||
|
prometheus_retention: "30d"
|
||||||
|
grafana_admin_password: "DUMMY_GRAFANA_ADMIN_PASSWORD"
|
||||||
|
|
||||||
|
storage_sizes:
|
||||||
|
prometheus: "50Gi"
|
||||||
|
grafana: "10Gi"
|
||||||
|
loki: "50Gi"
|
||||||
13
helms/roles/monitoring/meta/main.yml
Normal file
13
helms/roles/monitoring/meta/main.yml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Eric FELIXINE
|
||||||
|
description: Deploy monitoring stack (Prometheus, Grafana, Alertmanager) on Kubernetes
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.15"
|
||||||
|
platforms:
|
||||||
|
- name: Kubernetes
|
||||||
|
versions:
|
||||||
|
- "1.28"
|
||||||
|
dependencies:
|
||||||
|
- role: storage
|
||||||
|
- role: cert-manager
|
||||||
41
helms/roles/monitoring/tasks/main.yml
Normal file
41
helms/roles/monitoring/tasks/main.yml
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
---
|
||||||
|
# Role: monitoring
|
||||||
|
# Déploie Prometheus, Grafana, Loki et Promtail
|
||||||
|
|
||||||
|
- name: Installer kube-prometheus-stack
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: prometheus
|
||||||
|
chart_ref: "{{ helm_charts.prometheus.chart }}"
|
||||||
|
release_namespace: monitoring
|
||||||
|
create_namespace: true
|
||||||
|
values:
|
||||||
|
prometheus:
|
||||||
|
prometheusSpec:
|
||||||
|
retention: "{{ monitoring.prometheus_retention }}"
|
||||||
|
storageSpec:
|
||||||
|
volumeClaimTemplate:
|
||||||
|
spec:
|
||||||
|
storageClassName: "{{ storage_class }}"
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: "{{ storage_sizes.prometheus }}"
|
||||||
|
grafana:
|
||||||
|
adminPassword: "{{ monitoring.grafana_admin_password }}"
|
||||||
|
persistence:
|
||||||
|
enabled: true
|
||||||
|
size: "{{ storage_sizes.grafana }}"
|
||||||
|
alertmanager:
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
- name: Installer Loki Stack
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: loki
|
||||||
|
chart_ref: "{{ helm_charts.loki.chart }}"
|
||||||
|
release_namespace: monitoring
|
||||||
|
values:
|
||||||
|
loki:
|
||||||
|
persistence:
|
||||||
|
enabled: true
|
||||||
|
size: "{{ storage_sizes.loki }}"
|
||||||
|
promtail:
|
||||||
|
enabled: true
|
||||||
5
helms/roles/namespaces/defaults/main.yml
Normal file
5
helms/roles/namespaces/defaults/main.yml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
# Role: namespaces
|
||||||
|
# Crée les namespaces Kubernetes
|
||||||
|
# Les namespaces sont définis dans group_vars (variable: namespaces)
|
||||||
|
# Aucune variable custom supplémentaire requise pour ce rôle.
|
||||||
12
helms/roles/namespaces/meta/main.yml
Normal file
12
helms/roles/namespaces/meta/main.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Eric FELIXINE
|
||||||
|
description: Create and manage Kubernetes namespaces for the platform
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.15"
|
||||||
|
platforms:
|
||||||
|
- name: Kubernetes
|
||||||
|
versions:
|
||||||
|
- "1.28"
|
||||||
|
dependencies:
|
||||||
|
- role: prerequisites
|
||||||
17
helms/roles/namespaces/tasks/main.yml
Normal file
17
helms/roles/namespaces/tasks/main.yml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
# Role: namespaces
|
||||||
|
# Crée les namespaces Kubernetes
|
||||||
|
|
||||||
|
- name: Créer les namespaces
|
||||||
|
kubernetes.core.k8s:
|
||||||
|
state: present
|
||||||
|
definition:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: "{{ item }}"
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/managed-by: ansible
|
||||||
|
cluster: "{{ cluster_name }}"
|
||||||
|
type: kubernetes.io/metadata.v1
|
||||||
|
loop: "{{ namespaces }}"
|
||||||
14
helms/roles/nodered/defaults/main.yml
Normal file
14
helms/roles/nodered/defaults/main.yml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
# Role: nodered
|
||||||
|
# Valeurs par défaut pour Node-RED
|
||||||
|
|
||||||
|
services:
|
||||||
|
nodered:
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "100m"
|
||||||
|
memory: "256Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "512Mi"
|
||||||
12
helms/roles/nodered/meta/main.yml
Normal file
12
helms/roles/nodered/meta/main.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Eric FELIXINE
|
||||||
|
description: Deploy Node-RED flow-based programming tool on Kubernetes (IoT namespace)
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.15"
|
||||||
|
platforms:
|
||||||
|
- name: Kubernetes
|
||||||
|
versions:
|
||||||
|
- "1.28"
|
||||||
|
dependencies:
|
||||||
|
- role: iot
|
||||||
26
helms/roles/nodered/tasks/main.yml
Normal file
26
helms/roles/nodered/tasks/main.yml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
# Role: nodered
|
||||||
|
# Déploie Node-RED
|
||||||
|
|
||||||
|
- name: Installer Node-RED
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: nodered
|
||||||
|
chart_ref: "{{ helm_charts.nodered.chart }}"
|
||||||
|
release_namespace: iot
|
||||||
|
values:
|
||||||
|
replicaCount: "{{ services.nodered.replicas }}"
|
||||||
|
persistence:
|
||||||
|
enabled: true
|
||||||
|
size: 5Gi
|
||||||
|
resources: "{{ services.nodered.resources }}"
|
||||||
|
ingress:
|
||||||
|
enabled: true
|
||||||
|
hosts:
|
||||||
|
- host: nodered.digitribe.fr
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
tls:
|
||||||
|
- secretName: nodered-tls
|
||||||
|
hosts:
|
||||||
|
- nodered.digitribe.fr
|
||||||
17
helms/roles/odk/defaults/main.yml
Normal file
17
helms/roles/odk/defaults/main.yml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
# Role: odk
|
||||||
|
# Valeurs par défaut pour ODK Central
|
||||||
|
|
||||||
|
services:
|
||||||
|
odk:
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
|
|
||||||
|
storage_sizes:
|
||||||
|
odk: "20Gi"
|
||||||
12
helms/roles/odk/meta/main.yml
Normal file
12
helms/roles/odk/meta/main.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Eric FELIXINE
|
||||||
|
description: Deploy ODK (Open Data Kit) for mobile data collection on Kubernetes
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.15"
|
||||||
|
platforms:
|
||||||
|
- name: Kubernetes
|
||||||
|
versions:
|
||||||
|
- "1.28"
|
||||||
|
dependencies:
|
||||||
|
- role: databases
|
||||||
22
helms/roles/odk/tasks/main.yml
Normal file
22
helms/roles/odk/tasks/main.yml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
---
|
||||||
|
# Role: odk
|
||||||
|
# Déploie ODK Central
|
||||||
|
|
||||||
|
- name: Installer ODK Central
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: odk-central
|
||||||
|
chart_ref: "{{ helm_charts.odk.chart }}"
|
||||||
|
release_namespace: odk
|
||||||
|
create_namespace: true
|
||||||
|
values:
|
||||||
|
backend:
|
||||||
|
replicaCount: 1
|
||||||
|
resources: "{{ services.odk.resources }}"
|
||||||
|
frontend:
|
||||||
|
replicaCount: 1
|
||||||
|
resources: "{{ services.odk.resources }}"
|
||||||
|
postgres:
|
||||||
|
enabled: true
|
||||||
|
storage: "{{ storage_sizes.odk }}"
|
||||||
|
redis:
|
||||||
|
enabled: true
|
||||||
14
helms/roles/phpipam/defaults/main.yml
Normal file
14
helms/roles/phpipam/defaults/main.yml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
# Role: phpipam
|
||||||
|
# Valeurs par défaut pour phpIPAM
|
||||||
|
|
||||||
|
services:
|
||||||
|
phpipam:
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "100m"
|
||||||
|
memory: "256Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "512Mi"
|
||||||
12
helms/roles/phpipam/meta/main.yml
Normal file
12
helms/roles/phpipam/meta/main.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Eric FELIXINE
|
||||||
|
description: Deploy phpIPAM IP address management tool on Kubernetes (IoT namespace)
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.15"
|
||||||
|
platforms:
|
||||||
|
- name: Kubernetes
|
||||||
|
versions:
|
||||||
|
- "1.28"
|
||||||
|
dependencies:
|
||||||
|
- role: iot
|
||||||
27
helms/roles/phpipam/tasks/main.yml
Normal file
27
helms/roles/phpipam/tasks/main.yml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
# Role: phpipam
|
||||||
|
# Déploie phpIPAM
|
||||||
|
|
||||||
|
- name: Installer phpIPAM
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: phpipam
|
||||||
|
chart_ref: "{{ helm_charts.phpipam.chart }}"
|
||||||
|
release_namespace: phpipam
|
||||||
|
create_namespace: true
|
||||||
|
values:
|
||||||
|
phpipam:
|
||||||
|
adminPassword: "{{ vault_phpipam_admin_password }}"
|
||||||
|
persistence:
|
||||||
|
size: 5Gi
|
||||||
|
resources: "{{ services.phpipam.resources }}"
|
||||||
|
ingress:
|
||||||
|
enabled: true
|
||||||
|
hosts:
|
||||||
|
- host: phpipam.digitribe.fr
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
tls:
|
||||||
|
- secretName: phpipam-tls
|
||||||
|
hosts:
|
||||||
|
- phpipam.digitribe.fr
|
||||||
19
helms/roles/prerequisites/defaults/main.yml
Normal file
19
helms/roles/prerequisites/defaults/main.yml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
# Role: prerequisites
|
||||||
|
# Valeurs par défaut pour les prérequis (repositories Helm)
|
||||||
|
|
||||||
|
helm_repos:
|
||||||
|
- name: stable
|
||||||
|
url: https://charts.helm.sh/stable
|
||||||
|
- name: bitnami
|
||||||
|
url: https://charts.bitnami.com/bitnami
|
||||||
|
- name: prometheus-community
|
||||||
|
url: https://prometheus-community.github.io/helm-charts
|
||||||
|
- name: grafana
|
||||||
|
url: https://grafana.github.io/helm-charts
|
||||||
|
- name: traefik
|
||||||
|
url: https://traefik.github.io/charts
|
||||||
|
- name: strimzi
|
||||||
|
url: https://strimzi.io/charts/
|
||||||
|
- name: jetstack
|
||||||
|
url: https://charts.jetstack.io
|
||||||
11
helms/roles/prerequisites/meta/main.yml
Normal file
11
helms/roles/prerequisites/meta/main.yml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Eric FELIXINE
|
||||||
|
description: Prerequisites - Install base tools and dependencies for the Kubernetes platform
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.15"
|
||||||
|
platforms:
|
||||||
|
- name: Kubernetes
|
||||||
|
versions:
|
||||||
|
- "1.28"
|
||||||
|
dependencies: []
|
||||||
21
helms/roles/prerequisites/tasks/main.yml
Normal file
21
helms/roles/prerequisites/tasks/main.yml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
# Role: prerequisites
|
||||||
|
# Installe les prérequis sur le cluster Kubernetes
|
||||||
|
|
||||||
|
- name: Ajouter les repositories Helm
|
||||||
|
kubernetes.core.helm_repository:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
repo_url: "{{ item.url }}"
|
||||||
|
loop: "{{ helm_repos }}"
|
||||||
|
|
||||||
|
- name: Mettre à jour les repositories Helm
|
||||||
|
command: helm repo update
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Installer les CRDs nécessaires
|
||||||
|
kubernetes.core.k8s:
|
||||||
|
state: present
|
||||||
|
src: "{{ item }}"
|
||||||
|
loop:
|
||||||
|
- https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.crds.yaml
|
||||||
|
ignore_errors: true
|
||||||
5
helms/roles/smartapp/defaults/main.yml
Normal file
5
helms/roles/smartapp/defaults/main.yml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
# Role: smartapp
|
||||||
|
# Déploiement de l'application Smart City
|
||||||
|
# Les variables sont définies directement dans les tasks (smartapp_namespace, smartapp_domain).
|
||||||
|
# Aucune variable custom supplémentaire requise pour ce rôle.
|
||||||
13
helms/roles/smartapp/meta/main.yml
Normal file
13
helms/roles/smartapp/meta/main.yml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Eric FELIXINE
|
||||||
|
description: Deploy SmartApp intelligent application platform on Kubernetes
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.15"
|
||||||
|
platforms:
|
||||||
|
- name: Kubernetes
|
||||||
|
versions:
|
||||||
|
- "1.28"
|
||||||
|
dependencies:
|
||||||
|
- role: databases
|
||||||
|
- role: cert-manager
|
||||||
19
helms/roles/smartapp/tasks/main.yml
Normal file
19
helms/roles/smartapp/tasks/main.yml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
# Role: smartapp
|
||||||
|
# Déploie l'application Smart City
|
||||||
|
|
||||||
|
- name: Déployer Smart App Web
|
||||||
|
kubernetes.core.k8s:
|
||||||
|
state: present
|
||||||
|
template: smartapp-web.yml.j2
|
||||||
|
vars:
|
||||||
|
smartapp_namespace: smartapp
|
||||||
|
smartapp_domain: smartapp.digitribe.fr
|
||||||
|
|
||||||
|
- name: Déployer Smart App API
|
||||||
|
kubernetes.core.k8s:
|
||||||
|
state: present
|
||||||
|
template: smartapp-api.yml.j2
|
||||||
|
vars:
|
||||||
|
smartapp_namespace: smartapp
|
||||||
|
smartapp_domain: api-smartapp.digitribe.fr
|
||||||
253
helms/roles/smartapp/templates/smartapp-api.yml.j2
Normal file
253
helms/roles/smartapp/templates/smartapp-api.yml.j2
Normal file
@@ -0,0 +1,253 @@
|
|||||||
|
---
|
||||||
|
# Role: smartapp
|
||||||
|
# Template: smartapp-api.yml.j2
|
||||||
|
# Déploiement de l'API backend SmartApp
|
||||||
|
# Variables:
|
||||||
|
# {{ smartapp_namespace }} - Namespace Kubernetes (défaut: smartapp)
|
||||||
|
# {{ smartapp_domain }} - Domaine public (défaut: api-smartapp.digitribe.fr)
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: {{ smartapp_namespace | default('smartapp') }}
|
||||||
|
labels:
|
||||||
|
app: smartapp
|
||||||
|
component: api
|
||||||
|
version: "1.0"
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: smartapp-api-config
|
||||||
|
namespace: {{ smartapp_namespace | default('smartapp') }}
|
||||||
|
labels:
|
||||||
|
app: smartapp
|
||||||
|
component: api
|
||||||
|
version: "1.0"
|
||||||
|
data:
|
||||||
|
APP_ENV: "production"
|
||||||
|
APP_PORT: "8080"
|
||||||
|
LOG_LEVEL: "info"
|
||||||
|
CORS_ORIGINS: "https://smartapp.digitribe.fr"
|
||||||
|
DATABASE_POOL_SIZE: "10"
|
||||||
|
REDIS_POOL_SIZE: "5"
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: smartapp-api-secrets
|
||||||
|
namespace: {{ smartapp_namespace | default('smartapp') }}
|
||||||
|
labels:
|
||||||
|
app: smartapp
|
||||||
|
component: api
|
||||||
|
version: "1.0"
|
||||||
|
type: Opaque
|
||||||
|
stringData:
|
||||||
|
DATABASE_URL: "postgresql://smartapp:{{ smartapp_db_password | default('changeme') }}@postgres.smartapp.svc.cluster.local:5432/smartapp"
|
||||||
|
REDIS_URL: "redis://redis.smartapp.svc.cluster.local:6379/0"
|
||||||
|
JWT_SECRET: "{{ smartapp_jwt_secret | default('change-this-secret-in-production') }}"
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: smartapp-api
|
||||||
|
namespace: {{ smartapp_namespace | default('smartapp') }}
|
||||||
|
labels:
|
||||||
|
app: smartapp
|
||||||
|
component: api
|
||||||
|
version: "1.0"
|
||||||
|
spec:
|
||||||
|
replicas: 2
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: smartapp
|
||||||
|
component: api
|
||||||
|
strategy:
|
||||||
|
type: RollingUpdate
|
||||||
|
rollingUpdate:
|
||||||
|
maxSurge: 1
|
||||||
|
maxUnavailable: 0
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: smartapp
|
||||||
|
component: api
|
||||||
|
version: "1.0"
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: api
|
||||||
|
image: digitribe/smartapp-api:{{ smartapp_api_version | default('latest') }}
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 8080
|
||||||
|
protocol: TCP
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: smartapp-api-config
|
||||||
|
env:
|
||||||
|
- name: DATABASE_URL
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: smartapp-api-secrets
|
||||||
|
key: DATABASE_URL
|
||||||
|
- name: REDIS_URL
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: smartapp-api-secrets
|
||||||
|
key: REDIS_URL
|
||||||
|
- name: JWT_SECRET
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: smartapp-api-secrets
|
||||||
|
key: JWT_SECRET
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "1Gi"
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /api/v1/health/live
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 15
|
||||||
|
periodSeconds: 20
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /api/v1/health/ready
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 10
|
||||||
|
timeoutSeconds: 3
|
||||||
|
failureThreshold: 3
|
||||||
|
startupProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /api/v1/health/live
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 5
|
||||||
|
failureThreshold: 12
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 100
|
||||||
|
podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchExpressions:
|
||||||
|
- key: app
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- smartapp
|
||||||
|
- key: component
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- api
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: smartapp-api
|
||||||
|
namespace: {{ smartapp_namespace | default('smartapp') }}
|
||||||
|
labels:
|
||||||
|
app: smartapp
|
||||||
|
component: api
|
||||||
|
version: "1.0"
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
selector:
|
||||||
|
app: smartapp
|
||||||
|
component: api
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 8080
|
||||||
|
targetPort: 8080
|
||||||
|
protocol: TCP
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: smartapp-api
|
||||||
|
namespace: {{ smartapp_namespace | default('smartapp') }}
|
||||||
|
labels:
|
||||||
|
app: smartapp
|
||||||
|
component: api
|
||||||
|
version: "1.0"
|
||||||
|
annotations:
|
||||||
|
nginx.ingress.kubernetes.io/rewrite-target: /
|
||||||
|
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||||
|
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
|
||||||
|
nginx.ingress.kubernetes.io/rate-limit: "100"
|
||||||
|
nginx.ingress.kubernetes.io/rate-limit-window: "1m"
|
||||||
|
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||||
|
spec:
|
||||||
|
ingressClassName: nginx
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- {{ smartapp_domain | default('api-smartapp.digitribe.fr') }}
|
||||||
|
secretName: smartapp-api-tls
|
||||||
|
rules:
|
||||||
|
- host: {{ smartapp_domain | default('api-smartapp.digitribe.fr') }}
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: smartapp-api
|
||||||
|
port:
|
||||||
|
number: 8080
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: autoscaling/v2
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: smartapp-api
|
||||||
|
namespace: {{ smartapp_namespace | default('smartapp') }}
|
||||||
|
labels:
|
||||||
|
app: smartapp
|
||||||
|
component: api
|
||||||
|
version: "1.0"
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: smartapp-api
|
||||||
|
minReplicas: 2
|
||||||
|
maxReplicas: 10
|
||||||
|
metrics:
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: cpu
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: 70
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: memory
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: 80
|
||||||
|
behavior:
|
||||||
|
scaleUp:
|
||||||
|
stabilizationWindowSeconds: 60
|
||||||
|
policies:
|
||||||
|
- type: Percent
|
||||||
|
value: 50
|
||||||
|
periodSeconds: 60
|
||||||
|
scaleDown:
|
||||||
|
stabilizationWindowSeconds: 300
|
||||||
|
policies:
|
||||||
|
- type: Percent
|
||||||
|
value: 25
|
||||||
|
periodSeconds: 120
|
||||||
229
helms/roles/smartapp/templates/smartapp-web.yml.j2
Normal file
229
helms/roles/smartapp/templates/smartapp-web.yml.j2
Normal file
@@ -0,0 +1,229 @@
|
|||||||
|
---
|
||||||
|
# Role: smartapp
|
||||||
|
# Template: smartapp-web.yml.j2
|
||||||
|
# Déploiement du frontend web SmartApp (nginx)
|
||||||
|
# Variables:
|
||||||
|
# {{ smartapp_namespace }} - Namespace Kubernetes (défaut: smartapp)
|
||||||
|
# {{ smartapp_domain }} - Domaine public (défaut: smartapp.digitribe.fr)
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: {{ smartapp_namespace | default('smartapp') }}
|
||||||
|
labels:
|
||||||
|
app: smartapp
|
||||||
|
component: web
|
||||||
|
version: "1.0"
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: smartapp-web
|
||||||
|
namespace: {{ smartapp_namespace | default('smartapp') }}
|
||||||
|
labels:
|
||||||
|
app: smartapp
|
||||||
|
component: web
|
||||||
|
version: "1.0"
|
||||||
|
spec:
|
||||||
|
replicas: 2
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: smartapp
|
||||||
|
component: web
|
||||||
|
strategy:
|
||||||
|
type: RollingUpdate
|
||||||
|
rollingUpdate:
|
||||||
|
maxSurge: 1
|
||||||
|
maxUnavailable: 0
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: smartapp
|
||||||
|
component: web
|
||||||
|
version: "1.0"
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx
|
||||||
|
image: nginx:1.25-alpine
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 80
|
||||||
|
protocol: TCP
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "100m"
|
||||||
|
memory: "128Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "256Mi"
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /healthz
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 15
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /healthz
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 10
|
||||||
|
timeoutSeconds: 3
|
||||||
|
failureThreshold: 3
|
||||||
|
volumeMounts:
|
||||||
|
- name: nginx-config
|
||||||
|
mountPath: /etc/nginx/conf.d
|
||||||
|
readOnly: true
|
||||||
|
- name: static-content
|
||||||
|
mountPath: /usr/share/nginx/html
|
||||||
|
readOnly: true
|
||||||
|
volumes:
|
||||||
|
- name: nginx-config
|
||||||
|
configMap:
|
||||||
|
name: smartapp-web-nginx-config
|
||||||
|
- name: static-content
|
||||||
|
configMap:
|
||||||
|
name: smartapp-web-static
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 100
|
||||||
|
podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchExpressions:
|
||||||
|
- key: app
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- smartapp
|
||||||
|
- key: component
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- web
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: smartapp-web-nginx-config
|
||||||
|
namespace: {{ smartapp_namespace | default('smartapp') }}
|
||||||
|
labels:
|
||||||
|
app: smartapp
|
||||||
|
component: web
|
||||||
|
version: "1.0"
|
||||||
|
data:
|
||||||
|
default.conf: |
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name {{ smartapp_domain | default('smartapp.digitribe.fr') }};
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
# Health check endpoint
|
||||||
|
location /healthz {
|
||||||
|
access_log off;
|
||||||
|
return 200 "healthy\n";
|
||||||
|
add_header Content-Type text/plain;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Static assets with caching
|
||||||
|
location /static/ {
|
||||||
|
expires 30d;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
}
|
||||||
|
|
||||||
|
# SPA fallback
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Security headers
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
|
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: smartapp-web-static
|
||||||
|
namespace: {{ smartapp_namespace | default('smartapp') }}
|
||||||
|
labels:
|
||||||
|
app: smartapp
|
||||||
|
component: web
|
||||||
|
version: "1.0"
|
||||||
|
data:
|
||||||
|
index.html: |
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>SmartApp - DigiTribe</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>SmartApp - DigiTribe</h1>
|
||||||
|
<p>Frontend web opérationnel.</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: smartapp-web
|
||||||
|
namespace: {{ smartapp_namespace | default('smartapp') }}
|
||||||
|
labels:
|
||||||
|
app: smartapp
|
||||||
|
component: web
|
||||||
|
version: "1.0"
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
selector:
|
||||||
|
app: smartapp
|
||||||
|
component: web
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 80
|
||||||
|
targetPort: 80
|
||||||
|
protocol: TCP
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: smartapp-web
|
||||||
|
namespace: {{ smartapp_namespace | default('smartapp') }}
|
||||||
|
labels:
|
||||||
|
app: smartapp
|
||||||
|
component: web
|
||||||
|
version: "1.0"
|
||||||
|
annotations:
|
||||||
|
nginx.ingress.kubernetes.io/rewrite-target: /
|
||||||
|
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||||
|
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
|
||||||
|
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||||
|
spec:
|
||||||
|
ingressClassName: nginx
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- {{ smartapp_domain | default('smartapp.digitribe.fr') }}
|
||||||
|
secretName: smartapp-web-tls
|
||||||
|
rules:
|
||||||
|
- host: {{ smartapp_domain | default('smartapp.digitribe.fr') }}
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: smartapp-web
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
17
helms/roles/starrocks/defaults/main.yml
Normal file
17
helms/roles/starrocks/defaults/main.yml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
# Role: starrocks
|
||||||
|
# Valeurs par défaut pour StarRocks
|
||||||
|
|
||||||
|
services:
|
||||||
|
starrocks:
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "1Gi"
|
||||||
|
limits:
|
||||||
|
cpu: "2000m"
|
||||||
|
memory: "4Gi"
|
||||||
|
|
||||||
|
storage_sizes:
|
||||||
|
starrocks: "100Gi"
|
||||||
12
helms/roles/starrocks/meta/main.yml
Normal file
12
helms/roles/starrocks/meta/main.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Eric FELIXINE
|
||||||
|
description: Deploy StarRocks unified analytics warehouse on Kubernetes
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.15"
|
||||||
|
platforms:
|
||||||
|
- name: Kubernetes
|
||||||
|
versions:
|
||||||
|
- "1.28"
|
||||||
|
dependencies:
|
||||||
|
- role: databases
|
||||||
38
helms/roles/starrocks/tasks/main.yml
Normal file
38
helms/roles/starrocks/tasks/main.yml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
---
|
||||||
|
# Role: starrocks
|
||||||
|
# Déploie StarRocks
|
||||||
|
|
||||||
|
- name: Ajouter le repository Helm StarRocks
|
||||||
|
kubernetes.core.helm_repository:
|
||||||
|
name: starrocks
|
||||||
|
repo_url: https://starrocks.github.io/starrocks-kubernetes-operator
|
||||||
|
|
||||||
|
- name: Installer StarRocks
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: starrocks
|
||||||
|
chart_ref: "{{ helm_charts.starrocks.chart }}"
|
||||||
|
chart_version: "{{ helm_charts.starrocks.version }}"
|
||||||
|
release_namespace: starrocks
|
||||||
|
create_namespace: true
|
||||||
|
values:
|
||||||
|
fe:
|
||||||
|
replicas: "{{ services.starrocks.replicas }}"
|
||||||
|
resources: "{{ services.starrocks.resources }}"
|
||||||
|
storage:
|
||||||
|
size: "{{ storage_sizes.starrocks | default('50Gi') }}"
|
||||||
|
storageClass: "{{ storage_class }}"
|
||||||
|
be:
|
||||||
|
replicas: 3
|
||||||
|
resources: "{{ services.starrocks.resources }}"
|
||||||
|
storage:
|
||||||
|
size: "{{ storage_sizes.starrocks | default('100Gi') }}"
|
||||||
|
storageClass: "{{ storage_class }}"
|
||||||
|
cn:
|
||||||
|
replicas: 2
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
10
helms/roles/storage/defaults/main.yml
Normal file
10
helms/roles/storage/defaults/main.yml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
# Role: storage
|
||||||
|
# Valeurs par défaut pour le stockage NFS
|
||||||
|
|
||||||
|
# Classe de stockage par défaut
|
||||||
|
storage_class: "nfs-client"
|
||||||
|
|
||||||
|
# Serveur NFS
|
||||||
|
nfs_server: "10.0.0.1"
|
||||||
|
nfs_path: "/srv/nfs/k8s"
|
||||||
12
helms/roles/storage/meta/main.yml
Normal file
12
helms/roles/storage/meta/main.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Eric FELIXINE
|
||||||
|
description: Provision and manage persistent storage (PVs, PVCs, StorageClasses) on Kubernetes
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.15"
|
||||||
|
platforms:
|
||||||
|
- name: Kubernetes
|
||||||
|
versions:
|
||||||
|
- "1.28"
|
||||||
|
dependencies:
|
||||||
|
- role: namespaces
|
||||||
27
helms/roles/storage/tasks/main.yml
Normal file
27
helms/roles/storage/tasks/main.yml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
# Role: storage
|
||||||
|
# Configure le stockage NFS et les StorageClasses
|
||||||
|
|
||||||
|
- name: Créer le namespace storage
|
||||||
|
kubernetes.core.k8s:
|
||||||
|
state: present
|
||||||
|
definition:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: storage
|
||||||
|
|
||||||
|
- name: Installer le NFS provisioner
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: nfs-provisioner
|
||||||
|
chart_ref: "{{ helm_charts.nfs_provisioner.chart }}"
|
||||||
|
chart_version: "{{ helm_charts.nfs_provisioner.version }}"
|
||||||
|
release_namespace: storage
|
||||||
|
values:
|
||||||
|
nfs:
|
||||||
|
server: "{{ nfs_server }}"
|
||||||
|
path: "{{ nfs_path }}"
|
||||||
|
storageClass:
|
||||||
|
name: "{{ storage_class }}"
|
||||||
|
defaultClass: true
|
||||||
|
reclaimPolicy: Retain
|
||||||
14
helms/roles/streamlit/defaults/main.yml
Normal file
14
helms/roles/streamlit/defaults/main.yml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
# Role: streamlit
|
||||||
|
# Valeurs par défaut pour Streamlit
|
||||||
|
|
||||||
|
services:
|
||||||
|
streamlit:
|
||||||
|
replicas: 1
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "250m"
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "2Gi"
|
||||||
12
helms/roles/streamlit/meta/main.yml
Normal file
12
helms/roles/streamlit/meta/main.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Eric FELIXINE
|
||||||
|
description: Deploy Streamlit data application framework on Kubernetes
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.15"
|
||||||
|
platforms:
|
||||||
|
- name: Kubernetes
|
||||||
|
versions:
|
||||||
|
- "1.28"
|
||||||
|
dependencies:
|
||||||
|
- role: databases
|
||||||
30
helms/roles/streamlit/tasks/main.yml
Normal file
30
helms/roles/streamlit/tasks/main.yml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
# Role: streamlit
|
||||||
|
# Déploie Streamlit
|
||||||
|
|
||||||
|
- name: Installer Streamlit
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: streamlit
|
||||||
|
chart_ref: "{{ helm_charts.streamlit.chart }}"
|
||||||
|
chart_version: "{{ helm_charts.streamlit.version }}"
|
||||||
|
release_namespace: streamlit
|
||||||
|
create_namespace: true
|
||||||
|
values:
|
||||||
|
replicaCount: "{{ services.streamlit.replicas }}"
|
||||||
|
resources: "{{ services.streamlit.resources }}"
|
||||||
|
service:
|
||||||
|
type: ClusterIP
|
||||||
|
ingress:
|
||||||
|
enabled: true
|
||||||
|
hosts:
|
||||||
|
- host: streamlit.digitribe.fr
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
tls:
|
||||||
|
- secretName: streamlit-tls
|
||||||
|
hosts:
|
||||||
|
- streamlit.digitribe.fr
|
||||||
|
env:
|
||||||
|
STREAMLIT_SERVER_HEADLESS: "true"
|
||||||
|
STREAMLIT_SERVER_ENABLE_CORS: "false"
|
||||||
5
helms/roles/traefik/defaults/main.yml
Normal file
5
helms/roles/traefik/defaults/main.yml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
# Role: traefik
|
||||||
|
# Valeurs par défaut pour Traefik
|
||||||
|
|
||||||
|
traefik_namespace: "traefik"
|
||||||
13
helms/roles/traefik/meta/main.yml
Normal file
13
helms/roles/traefik/meta/main.yml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Eric FELIXINE
|
||||||
|
description: Deploy and configure Traefik as the ingress controller for Kubernetes
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.15"
|
||||||
|
platforms:
|
||||||
|
- name: Kubernetes
|
||||||
|
versions:
|
||||||
|
- "1.28"
|
||||||
|
dependencies:
|
||||||
|
- role: storage
|
||||||
|
- role: namespaces
|
||||||
49
helms/roles/traefik/tasks/main.yml
Normal file
49
helms/roles/traefik/tasks/main.yml
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
---
|
||||||
|
# Role: traefik
|
||||||
|
# Déploie le reverse proxy Traefik
|
||||||
|
|
||||||
|
- name: Créer le namespace traefik
|
||||||
|
kubernetes.core.k8s:
|
||||||
|
state: present
|
||||||
|
definition:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: "{{ traefik_namespace }}"
|
||||||
|
|
||||||
|
- name: Installer Traefik
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: traefik
|
||||||
|
chart_ref: helm_charts.traefik.chart
|
||||||
|
release_namespace: "{{ traefik_namespace }}"
|
||||||
|
values:
|
||||||
|
globalArguments:
|
||||||
|
- "--global.checknewversion=false"
|
||||||
|
- "--global.sendanonymoususage=false"
|
||||||
|
additionalArguments:
|
||||||
|
- "--providers.kubernetescrd.allowexternalnameservices=true"
|
||||||
|
- "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
|
||||||
|
- "--certificatesresolvers.letsencrypt.acme.email={{ acme_email }}"
|
||||||
|
- "--certificatesresolvers.letsencrypt.acme.storage=/data/acme.json"
|
||||||
|
ports:
|
||||||
|
traefik:
|
||||||
|
port: 9000
|
||||||
|
expose: false
|
||||||
|
web:
|
||||||
|
port: 80
|
||||||
|
expose: true
|
||||||
|
websecure:
|
||||||
|
port: 443
|
||||||
|
expose: true
|
||||||
|
persistence:
|
||||||
|
enabled: true
|
||||||
|
size: 1Gi
|
||||||
|
service:
|
||||||
|
type: LoadBalancer
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "100m"
|
||||||
|
memory: "128Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m"
|
||||||
|
memory: "512Mi"
|
||||||
14
helms/roles/trino/defaults/main.yml
Normal file
14
helms/roles/trino/defaults/main.yml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
# Role: trino
|
||||||
|
# Valeurs par défaut pour Trino
|
||||||
|
|
||||||
|
services:
|
||||||
|
trino:
|
||||||
|
replicas: 2
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "1Gi"
|
||||||
|
limits:
|
||||||
|
cpu: "2000m"
|
||||||
|
memory: "4Gi"
|
||||||
12
helms/roles/trino/meta/main.yml
Normal file
12
helms/roles/trino/meta/main.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Eric FELIXINE
|
||||||
|
description: Deploy Trino distributed SQL query engine on Kubernetes
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.15"
|
||||||
|
platforms:
|
||||||
|
- name: Kubernetes
|
||||||
|
versions:
|
||||||
|
- "1.28"
|
||||||
|
dependencies:
|
||||||
|
- role: databases
|
||||||
46
helms/roles/trino/tasks/main.yml
Normal file
46
helms/roles/trino/tasks/main.yml
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
---
|
||||||
|
# Role: trino
|
||||||
|
# Déploie Trino
|
||||||
|
|
||||||
|
- name: Installer Trino
|
||||||
|
kubernetes.core.helm:
|
||||||
|
name: trino
|
||||||
|
chart_ref: "{{ helm_charts.trino.chart }}"
|
||||||
|
chart_version: "{{ helm_charts.trino.version }}"
|
||||||
|
release_namespace: trino
|
||||||
|
create_namespace: true
|
||||||
|
values:
|
||||||
|
server:
|
||||||
|
workers: "{{ services.trino.replicas }}"
|
||||||
|
resources: "{{ services.trino.resources }}"
|
||||||
|
coordinator:
|
||||||
|
resources: "{{ services.trino.resources }}"
|
||||||
|
worker:
|
||||||
|
resources: "{{ services.trino.resources }}"
|
||||||
|
service:
|
||||||
|
type: ClusterIV
|
||||||
|
ingress:
|
||||||
|
enabled: true
|
||||||
|
hosts:
|
||||||
|
- host: trino.digitribe.fr
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
tls:
|
||||||
|
- secretName: trino-tls
|
||||||
|
hosts:
|
||||||
|
- trino.digitribe.fr
|
||||||
|
catalog:
|
||||||
|
postgresql:
|
||||||
|
connector.name=postgresql
|
||||||
|
connection-url=jdbc:postgresql://postgresql-ha-pgpool.default.svc.cluster.local:5432/smartcity
|
||||||
|
connection-user=trino
|
||||||
|
connection-password={{ vault_trino_db_password }}
|
||||||
|
clickhouse:
|
||||||
|
connector.name=clickhouse
|
||||||
|
connection-url=jdbc:clickhouse://clickhouse.clickhouse.svc.cluster.local:8123/default
|
||||||
|
connection-user=default
|
||||||
|
connection-password={{ vault_clickhouse_password }}
|
||||||
|
delta:
|
||||||
|
connector.name=delta_lake
|
||||||
|
connection-url=jdbc:delta://deltalake.deltalake.svc.cluster.local:9083
|
||||||
56
helms/undeploy.yml
Normal file
56
helms/undeploy.yml
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
---
|
||||||
|
# Playbook de suppression de la stack
|
||||||
|
# Fichier: undeploy.yml
|
||||||
|
|
||||||
|
- name: Suppression Smart City Martinique de Kubernetes
|
||||||
|
hosts: localhost
|
||||||
|
connection: local
|
||||||
|
gather_facts: false
|
||||||
|
|
||||||
|
vars_files:
|
||||||
|
- group_vars/all.yml
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Supprimer les namespaces Kubernetes
|
||||||
|
kubernetes.core.k8s:
|
||||||
|
state: absent
|
||||||
|
definition:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: "{{ item }}"
|
||||||
|
loop: "{{ namespaces }}"
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Supprimer les PersistentVolumes
|
||||||
|
kubernetes.core.k8s:
|
||||||
|
state: absent
|
||||||
|
definition:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolume
|
||||||
|
metadata:
|
||||||
|
name: "{{ item }}"
|
||||||
|
loop: "{{ persistent_volumes | default([]) }}"
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Supprimer les ClusterRoles
|
||||||
|
kubernetes.core.k8s:
|
||||||
|
state: absent
|
||||||
|
kind: ClusterRole
|
||||||
|
name: "{{ item }}"
|
||||||
|
loop:
|
||||||
|
- traefik
|
||||||
|
- cert-manager
|
||||||
|
- prometheus
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Supprimer les ClusterRoleBindings
|
||||||
|
kubernetes.core.k8s:
|
||||||
|
state: absent
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
name: "{{ item }}"
|
||||||
|
loop:
|
||||||
|
- traefik
|
||||||
|
- cert-manager
|
||||||
|
- prometheus
|
||||||
|
ignore_errors: true
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user