Retour aux projets
20 oct. 2026 • Projet

Migration GCP → OVH : extranet Symfony

Migration d'un extranet Symfony et de son site vitrine de GCP vers un projet OVH Public Cloud dédié. Infra en Terraform, applicatif sous Docker Compose derrière Traefik, déploiement par GitHub Actions, bascule de la prod en 40 minutes.

TerraformOVH Public CloudOpenStackDockerTraefikFrankenPHPMySQLRedisGitHub Actions
Contexte
Un extranet Symfony et son site vitrine hébergés sur GCP, à passer sur OVH dans une région française sans casser la prod.
Mon rôle
Infra écrite en Terraform, stack Docker Compose, déploiement GitHub Actions, puis bascule de la prod.
Résultat
La prod tourne sur OVH. Bascule complète en 40 minutes : export de la base, import, changement DNS.

Le projet

L’extranet (Symfony) et son site vitrine tournaient sur GCP. Il fallait les passer sur OVH, dans une région française, sans casser la prod.

Tout le Terraform est écrit à la main, sans module tout fait, pour savoir exactement ce que chaque ressource crée.

Architecture

Un projet OVH dédié

Au départ, l’infra devait aller dans le projet Public Cloud existant de PharmaGDD. Elle a finalement été isolée dans son propre projet OVH : identifiants OpenStack et API séparés, facturation séparée, et une erreur sur ce projet ne peut pas toucher l’infra principale.

Ce choix a demandé un peu plus de travail au début : nouveaux identifiants, accès au registry et au S3 à refaire.

Réseau privé + bastion

La VM applicative est dans un réseau privé dédié (vRack/VLAN), séparé de celui de PharmaGDD. L’accès SSH passe uniquement par un bastion. Dans le security group, seuls le 80 et le 443 sont ouverts au public, et le 22 n’est ouvert que depuis le bastion.

Internet ──► Traefik (80/443) ──► FrankenPHP (extranet Symfony)
                               └─► conteneur SPA (site vitrine)
Admin ──► Bastion ──SSH──► VM app (réseau privé)

Terraform

Le Terraform est dans un repo à part. Le provider ovh gère le projet, le réseau et le DNS, OpenStack gère les instances et les security groups. Il faut respecter l’ordre réseau → sous-réseau → instance, et bien savoir ce qui dépend de l’API OVH et ce qui dépend d’OpenStack.

La VM est ensuite préparée (Docker, Compose, utilisateur, arborescence /opt/...) par un script lancé en SSH via le bastion.

Stack applicative

Tout tourne en Docker Compose sur la VM :

CI/CD

Le déploiement passe par GitHub Actions, avec un runner self-hosted partagé au niveau de l’organisation. Il n’y a aucun runner sur la VM de prod.

La bascule des données

La réplication, étudiée puis écartée

La prod GCP écrit dans MySQL jusqu’au dernier jour. Ma première proposition était de passer par de la réplication : copie initiale avec position GTID, la base OVH en réplique de la prod GCP, puis promotion de la réplique le jour J. La coupure se serait limitée au temps de rattrapage.

J’ai fait l’étude pour voir si c’était faisable. Les deux MySQL étaient sur deux réseaux différents : pour que la réplique OVH lise la prod GCP, il fallait ouvrir le port MySQL en public, mettre en place le TLS, filtrer les IP, le tout sur la base de prod. Trop de contraintes et trop d’exposition pour gagner quelques dizaines de minutes de coupure.

Ce qui a été fait

Une bascule plus simple, en une fois :

  1. Backup et export de la base de prod GCP.
  2. Import de l’export dans la MySQL OVH.
  3. Changement DNS vers OVH.

L’ensemble a pris 40 minutes.

Ce que je retiens

La solution la plus élégante n’était pas la bonne ici. Pour un extranet, 40 minutes de coupure prévues valaient mieux qu’une base de prod exposée sur Internet le temps de la migration. L’étude n’a pas été perdue pour autant : elle a permis de trancher avec des arguments concrets plutôt qu’à l’intuition.