← Retour au blog

Multi cloud et souveraineté

Lucian BLETAN

Le multi cloud apporte de la souplesse (choix technos, négociation, résilience), mais double la complexité opérationnelle. La souveraineté impose des contraintes de localisation, de contrôle d’accès et de chiffrement. La bonne approche: décider où vivent les données, rapprocher les calculs, standardiser les formats et fédérer l’identité, avec des runbooks de bascule testés.

objectifs et contraintes, en un coup d’oeil

multi cloud et souveraineté

objectifs

flexibilite

resilience

negociation

contraintes

localisation

controle_acces

chiffrement

arbitrages

couts

performance

portabilite

décisions

  • où sont les données et qui peut y accéder (règles de résidence et de partage).
  • quelles charges méritent la portabilité (éviter le “lift and shift” par défaut).
  • quels services sont critiques et doivent être réplicables (stockage, IAM, observabilité).

gabarit de politique de placement

placement_policy:
  data_classes:
    - name: "client_pii"
      residency: ["eu-central","eu-west"]
      cross_region_transfer: "denied_by_default"
      encryption: "byok"
      sharing: ["bi_aggregates_only"]
    - name: "logs_techniques"
      residency: ["any_eu"]
      cross_region_transfer: "allowed_with_controls"
      encryption: "cmk"
  compute_rules:
    prefer_compute_near_data: true
    allowed_runtimes: ["spark","trino","flink","postgres"]

architecture type lisible verticalement

sources de données

zones de stockage par region

table format iceberg parquet

compute proche des données

iam federation

observabilite hub unifie

catalogue et gouvernance

  • stockage structuré par région: classes de données et règles de résidence.
  • format de table ouvert (Iceberg, Parquet) pour la portabilité.
  • calcul au plus près des données pour limiter les egress.
  • fédération d’identité (OIDC/SAML) et RBAC homogène.
  • observabilité et facturation unifiées au-dessus des clouds.

standards

  • formats ouverts: Parquet pour les fichiers, Iceberg pour les tables versionnées.
  • IAM fédérable: identité unique, rôles mappés et secrets centralisés.
  • observabilité et facturation unifiées: métriques, logs, coûts, tags communs.

exemples minimaux

table Iceberg portable

-- table analytique portable (exemple generique)
CREATE TABLE analytics.orders_iceberg (
  order_id BIGINT,
  ts TIMESTAMP,
  country VARCHAR,
  amount_eur DOUBLE
)
WITH (
  format_version = '2',
  write_format = 'parquet'
);

trust OIDC inter-cloud

oidc_trust:
  issuer: "https://idp.data.pm"
  audiences: ["cloudA","cloudB"]
  claims_mapping:
    role: "groups"
    email: "email"
  rbac:
    - role: "data_engineer"
      allows: ["read:catalog","write:jobs","read:metrics"]
    - role: "bi_analyst"
      allows: ["read:catalog","read:data"]

observabilité unifiée (collecteur)

otel_collector:
  receivers:
    otlp: { protocols: { http: {}, grpc: {} } }
  processors:
    batch: {}
    attributes:
      actions:
        - key: cloud.provider
          action: upsert
          value: "${CLOUD}"
  exporters:
    prometheusremotewrite: { endpoint: "https://metrics.data.pm/api/v1/write" }
  service:
    pipelines:
      metrics:
        receivers: [otlp]
        processors: [attributes,batch]
        exporters: [prometheusremotewrite]

coûts et arbitrages

  • éviter la double écriture entre clouds: privilégier un maître et des réplications ciblées.
  • déplacer les calculs vers l’endroit où sont les données pour éviter l’egress.
  • chiffrer les scénarios de bascule et publier un coût total incluant la latence et l’opérationnel.

requêtes utiles pour agréger les coûts

-- normaliser et agreger couts mensuels multi cloud
WITH unified AS (
  SELECT 'cloudA' AS cloud, product, feature, CAST(cost_eur AS DOUBLE) AS cost_eur, month
  FROM billing_cloudA
  UNION ALL
  SELECT 'cloudB' AS cloud, product, feature, CAST(cost_eur AS DOUBLE), month
  FROM billing_cloudB
)
SELECT month, product, feature,
       ROUND(SUM(cost_eur), 2) AS cost_total_eur,
       COUNT(DISTINCT cloud) AS clouds_involved
FROM unified
GROUP BY month, product, feature
ORDER BY month DESC, cost_total_eur DESC;

matrice valeur x kWh

feature: "recalcul temps reel inventaire"
valeur: "moyenne"
kwh_mensuel: 820
egress_gb: 480
decision: "agregations 5 min, compute proche données, pas de cross cloud"

souveraineté: localisation, clé et preuve

  • localisation: classifier les jeux et restreindre les régions autorisées.
  • chiffrement: BYOK/HYOK quand requis, rotation et attestation.
  • preuve: journaux d’accès, contrats de partage, rapports d’audit exportables.

enveloppe de chiffrement simple

# chiffrement cote client avec une cle enveloppe
from cryptography.fernet import Fernet

def wrap_key(data_key, master_key):
    # demo illustrative, remplacer par un KMS reel
    f = Fernet(master_key)
    return f.encrypt(data_key)

def encrypt_payload(payload, data_key):
    f = Fernet(data_key)
    return f.encrypt(payload)

portabilité des charges: où la viser vraiment

  • ETL analytiques batch: portables si formats ouverts et SQL standard.
  • requêtes BI: portables via moteurs compatibles (Trino, DuckDB, Postgres).
  • temps réel et ML en ligne: souvent moins portables, préférer des abstractions minces.

contrats de schéma et compatibilité

schema_contract:
  dataset: "events"
  format: "parquet"
  partitioning: ["day","country"]
  compatibility: "backward"
  forbidden_changes: ["drop_required_field","change_type_incompatible"]

bascule contrôlée: runbook minimal

ClientsDNSCloud_BCloud_AOpsClientsDNSCloud_BCloud_AOpsalt[panne critique][panne non critique]verifier sante service et replicatsactiver service standbysante okbasculer trafic progressifnouvelles routessurveiller latence et erreursdegradation controlee

pratiques recommandées

  • définir un “cloud principal” par domaine de données, répliquer seulement ce qui est nécessaire.
  • imposer des formats ouverts et un schéma d’évolution (compatibilité déclarée).
  • fédérer l’identité et centraliser l’observabilité et la facturation.
  • tester trimestriellement les runbooks de bascule et de restauration.
  • rendre visibles les coûts et l’egress aux équipes (tableaux de bord partagés).

exemples complets

vue fédérée pour lecture cross cloud sans double écriture

-- vue lisible cote bi, la resolution de source se fait par region
CREATE VIEW bi.v_orders AS
SELECT * FROM cloudA.analytics.orders_iceberg WHERE region = 'eu-west'
UNION ALL
SELECT * FROM cloudB.analytics.orders_iceberg WHERE region = 'eu-central';

politiques d’accès harmonisées

rbac_policies:
  roles:
    - name: "bi_analyst"
      grants: ["read:bi.v_orders","read:catalog"]
    - name: "data_engineer"
      grants: ["readwrite:analytics.*","manage:jobs"]
  mfa: "required"
  session_max_hours: 8

erreurs courantes et parades

  • bricoler la portabilité → downtime → runbooks testés, formats ouverts, schémas compatibles.
  • services propriétaires partout → verrou → abstraction réaliste, mesures d’impact avant choix.
  • double écriture massive → coûts et divergences → une source de vérité, réplications ciblées.
  • egress silencieux → facture surprise → déplacer le compute, seuils et alertes d’egress.
  • IAM éclaté → accès incohérents → fédérer OIDC/SAML, réduire les secrets locaux.

faq

  • Faut-il viser la portabilité de tous les workloads ? Non. Ciblez les charges à forte valeur ou forte exposition au risque de verrou, pas tout le parc.

  • Comment réduire l’egress entre clouds ? Exécuter les calculs au plus près des données, utiliser des formats ouverts et évitez les jointures cross cloud.

  • Quels standards privilégier pour rester portable ? Parquet, Iceberg, SQL standard, OIDC/SAML pour l’identité, OpenTelemetry pour l’observabilité.

  • Comment prouver la souveraineté des données ? Classifier, restreindre les régions, chiffrer avec BYOK/HYOK, et conserver des journaux et rapports d’audit exportables.

  • Un seul tableau de bord pour tous les coûts, c’est réaliste ? Oui si vous normalisez les tags et exportez toutes les factures dans un schéma unifié avec des vues partagées.