feat: add helm/ansible deployment files for Kubernetes
Some checks failed
Build & Deploy Smart App Web / lint (push) Failing after 1s
Build & Deploy Smart App Web / build-web (push) Has been skipped
Build & Deploy Smart App Web / docker-build (push) Has been skipped
Build & Deploy Smart App Web / deploy (push) Has been skipped

This commit is contained in:
Eric FELIXINE
2026-06-04 02:09:17 -04:00
parent 8c2251faba
commit fb62291b3e
33 changed files with 1876 additions and 0 deletions

View 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 }}"

View 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"

View 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 }}"

View 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

View 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

View 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"

View 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

View 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

View 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 }}"

View 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 }}"

View 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 }}"

View 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 }}"

View 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

View 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 }}"

View 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 }}"

View 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

View 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 }}"

View 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

View 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

View 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

View 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

View 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

View 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"

View 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

View 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"

View 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"

View 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