À retenir
- Crossplane transforme votre cluster Kubernetes en control plane qui provisionne l’infrastructure cloud via des custom resources — plus de
terraform apply, juste du YAML qu’un contrôleur réconcilie en continu.- provider-ovh est un provider Crossplane open source développé par Edixos, généré avec Upjet à partir du provider Terraform officiel d’OVHcloud. Il expose plus de 135 ressources OVHcloud en CRD et est publié sur l’Upbound Marketplace.
- Ce guide est de bout en bout : un cluster
kind, Crossplane, le provider, la configuration des identifiants et un vrai cluster Kubernetes managé provisionné sur OVHcloud.
Introduction
La plupart des équipes provisionnent encore OVHcloud à l’ancienne : un run Terraform par-ci, un clic dans la console par-là, un script auquel personne ne veut toucher. Ça marche, jusqu’au jour où il faut du self-service, de la correction de dérive et du RBAC — précisément ce qu’une équipe plateforme doit livrer.
Crossplane inverse le modèle. Votre cluster Kubernetes devient le control plane, et l’infrastructure devient un ensemble de custom resources qu’un contrôleur maintient réconciliées. Chez Edixos, nous avons créé provider-ovh pour apporter ce modèle à OVHcloud, et cet article le parcourt de la machine vierge jusqu’à un cluster Kubernetes managé qui tourne sur OVH.
Si vous avez déjà utilisé Crossplane avec AWS ou GCP, vous serez en terrain connu. Sinon, vous aurez un control plane fonctionnel en une quinzaine de minutes.
Qu’est-ce que Crossplane ?
Crossplane est un control plane open source de la CNCF qui étend Kubernetes afin qu’il puisse provisionner et gérer de l’infrastructure externe. Vous installez un provider, qui enregistre des Custom Resource Definitions (CRD) pour les ressources d’un cloud, et à partir de là vous déclarez cette infrastructure comme des objets Kubernetes. Un contrôleur réconcilie chaque objet avec l’API du provider, corrige la dérive et nettoie à la suppression.
Le bénéfice : l’infrastructure hérite de tout ce que Kubernetes offre déjà — YAML déclaratif, RBAC, GitOps, admission control et une surface d’API unique pour tous les clouds. Au lieu d’ouvrir des tickets, les équipes appliquent un manifeste — et la plateforme applique les garde-fous.
Qu’est-ce que provider-ovh ?
provider-ovh est le provider Crossplane pour OVHcloud, développé et maintenu par Edixos. Il expose les services OVHcloud — projets public cloud, Kubernetes managé, bases de données, réseaux privés, IAM, stockage objet et bien plus — sous forme de managed resources Kubernetes. Il est disponible sur l’Upbound Marketplace et le code source vit sur GitHub.
L’histoire derrière ce projet vaut la peine d’être racontée, car elle explique pourquoi il existe. Au départ, il n’existait aucun provider Crossplane, officiel ou communautaire, pour OVHcloud. Nous avons créé le premier et proposé d’en faire don — la réponse de l’époque a été qu’un provider communautaire ne pouvait être considéré comme officiel, et qu’il ne serait pas maintenu en interne. Pris par d’autres engagements, le projet est resté dormant près d’un an.
Puis trois ingénieurs — Nicolas, Kevin et Ferréol, de Theseus — nous ont contactés. Ils utilisaient déjà le provider en production, pour propulser une offre Database-as-a-Service destinée au secteur public français. Peu après, Fabien a ouvert une pull request faisant passer le provider à Crossplane 2.0. Ce fut le déclencheur. Le provider a connu une renaissance sous la version v2.9.0, avec Endre Karlson et Alegrowin rejoignant l’équipe de mainteneurs. C’est aujourd’hui un projet communautaire activement maintenu, couvrant plus de 135 ressources OVH et plus de 90 % de la surface du provider Terraform, sur Crossplane 1.x comme 2.x.
La leçon que nous ne cessons de répéter : ce sont les vrais utilisateurs en production qui maintiennent en vie les projets d’infrastructure.
Comment provider-ovh est-il construit ?
provider-ovh est généré, pas écrit à la main. Il s’appuie sur Upjet, la boîte à outils de génération de code de Crossplane, à partir du provider Terraform officiel d’OVHcloud — figé dans cette version à la 2.13.1. Upjet lit le schéma du provider Terraform et génère des managed resources conformes au XRM : types d’API Go, fonctions deepcopy, contrôleurs et manifestes de CRD.
C’est cette approche qui explique une couverture aussi large. Plutôt que d’implémenter chaque endpoint OVH à la main, nous régénérons le provider à chaque nouvelle version Terraform d’OVHcloud, et les nouvelles ressources arrivent gratuitement. La version actuelle embarque 281 manifestes de CRD — les 135+ ressources apparaissent en deux déclinaisons, cluster-scoped et namespaced, grâce à Crossplane v2 (voir plus bas). Monter la version du provider Terraform sous-jacent est une routine documentée en quatre commandes : mettre à jour le Makefile et le go.mod, lancer make generate, puis committer le schéma, les types et les CRD régénérés.
Prérequis
Avant de commencer, installez les outils suivants en local. Tout tourne sur votre machine, sauf les appels à l’API OVHcloud, qui nécessitent un vrai compte.
- Docker (ou un autre runtime de conteneurs supporté par
kind) - kind — pour exécuter un cluster Kubernetes jetable
- kubectl — pour dialoguer avec le cluster
- Helm — pour installer Crossplane
- Un compte OVHcloud avec des identifiants API (nous les générons à l’étape 5)
Étape 1 : créer un cluster kind local
Crossplane est un control plane léger, donc un cluster kind mono-nœud suffit largement pour ce parcours. Créez-en un :
kind create cluster --name crossplane-ovh
Vérifiez que le cluster est bien lancé et que kubectl pointe dessus :
kubectl cluster-info --context kind-crossplane-ovh
Ce cluster n’exécute jamais vos workloads OVH — il héberge seulement le control plane Crossplane qui les provisionne.
Étape 2 : installer Crossplane
Installez Crossplane avec son chart Helm officiel, dans un namespace dédié crossplane-system. Cela déploie les contrôleurs cœur de Crossplane et le gestionnaire de packages qui installe les providers.
helm repo add crossplane-stable https://charts.crossplane.io/stable
helm repo update
helm install crossplane \
crossplane-stable/crossplane \
--namespace crossplane-system \
--create-namespace
Attendez que les pods soient prêts, puis vérifiez l’installation :
kubectl get pods -n crossplane-system
Vous devriez voir les pods crossplane et crossplane-rbac-manager en cours d’exécution. Crossplane a aussi enregistré ses propres CRD cœur — providers, configurations, providerconfigs — sur lesquelles s’appuie l’étape suivante.
Étape 3 : installer provider-ovh
Installer un provider est lui-même une ressource Kubernetes : vous appliquez un objet Provider pointant vers l’image du package, et le gestionnaire de packages de Crossplane le télécharge et enregistre ses CRD. Appliquez provider-ovh depuis le registre Upbound :
cat <<EOF | kubectl apply -f -
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
name: provider-ovh
spec:
package: xpkg.upbound.io/edixos/provider-ovh:v2.10.1
EOF
En production, figez un tag de version explicite — consultez le Marketplace pour la dernière release plutôt que d’utiliser :latest. Observez le provider devenir sain :
kubectl get providers
Une fois les colonnes INSTALLED et HEALTHY toutes deux à True, les contrôleurs du provider tournent et chaque CRD OVH est enregistrée dans votre cluster.
Étape 4 : découvrir les managed resources
Comme le provider enregistre ses ressources en tant que CRD standard, vous les explorez avec un simple kubectl — sans outillage particulier. C’est l’un des avantages discrets du modèle Crossplane : votre catalogue d’infrastructure est interrogeable depuis la même API que tout le reste.
Listez les types de ressources OVH ajoutés par le provider :
kubectl get crds | grep ovh.edixos.io
Vous verrez des ressources groupées par service — kube.ovh.edixos.io, network.ovh.edixos.io, cloud.ovh.edixos.io, databases.ovh.edixos.io, iam.ovh.edixos.io, et d’autres. Pour inspecter les champs d’une ressource, utilisez kubectl explain :
kubectl explain cluster.kube.ovh.edixos.io --recursive
Cela affiche le spec complet d’un cluster Kubernetes OVHcloud managé — chaque champ forProvider que vous pouvez renseigner — directement depuis le schéma OpenAPI de la CRD. La référence d’API complète est aussi publiée sur doc.crds.dev.
Étape 5 : configurer les identifiants OVHcloud
Le provider a besoin d’identifiants API OVHcloud pour réconcilier quoi que ce soit de réel. Vous les fournissez via un Secret Kubernetes, puis vous pointez un ProviderConfig dessus. D’abord, générez une application key, une application secret et une consumer key depuis la console API d’OVH, en accordant les droits d’API dont vos ressources ont besoin.
Créez le Secret dans le namespace crossplane-system :
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: provider-ovh
namespace: crossplane-system
type: Opaque
stringData:
credentials: |
{
"endpoint": "ovh-eu",
"application_key": "YOUR_APP_KEY",
"application_secret": "YOUR_APP_SECRET",
"consumer_key": "YOUR_CONSUMER_KEY"
}
EOF
Créez maintenant un ProviderConfig nommé default qui indique au provider où lire ces identifiants :
cat <<EOF | kubectl apply -f -
apiVersion: ovh.edixos.io/v1beta1
kind: ProviderConfig
metadata:
name: default
spec:
credentials:
source: Secret
secretRef:
name: provider-ovh
namespace: crossplane-system
key: credentials
EOF
Ne committez jamais de vrais identifiants dans Git. En production, sourcez le Secret depuis un coffre externe — provider-ovh supporte l’intégration external-secret-store de Crossplane précisément pour cela.
Étape 6 : provisionner vos premières ressources OVHcloud
Une fois les identifiants en place, le provisioning se résume à un kubectl apply. Construisons une vraie stack : un réseau privé, un subnet à l’intérieur, et un cluster Kubernetes managé rattaché aux deux. C’est le même parcours que je déroule dans la présentation Platform Engineering with Crossplane & OVHcloud. Chaque manifeste référence le ProviderConfig default de l’étape précédente.
Commencez par un réseau privé. Remplacez serviceName par l’identifiant de votre projet public cloud OVH :
apiVersion: network.ovh.edixos.io/v1alpha1
kind: PrivateNetwork
metadata:
name: sample-1
labels:
managed-by: crossplane
spec:
providerConfigRef:
name: default
forProvider:
name: sample-1
serviceName: 980cbcf06e6a4e6e8a91a7d125b26bba
regions:
- DE1
Ajoutez un subnet dans ce réseau — c’est là que les nœuds de votre cluster obtiennent leurs adresses IP. Il référence le réseau privé par son nom avec networkIdRef, donc Crossplane attend le réseau et y injecte l’identifiant pour vous :
apiVersion: network.ovh.edixos.io/v1alpha1
kind: Subnet
metadata:
name: subnet-1
labels:
managed-by: crossplane
spec:
providerConfigRef:
name: default
forProvider:
serviceName: 980cbcf06e6a4e6e8a91a7d125b26bba
networkIdRef:
name: sample-1
region: DE1
start: 192.168.168.100
end: 192.168.168.200
network: 192.168.168.0/24
dhcp: true
noGateway: false
Puis un cluster Kubernetes managé qui référence à la fois le réseau et le subnet par leur nom — Crossplane résout chaque référence et injecte automatiquement les identifiants obtenus :
apiVersion: kube.ovh.edixos.io/v1alpha1
kind: Cluster
metadata:
name: hello-edixos
spec:
providerConfigRef:
name: default
forProvider:
name: "hello-edixos"
region: DE1
serviceName: 980cbcf06e6a4e6e8a91a7d125b26bba
privateNetworkIdRef:
name: sample-1
nodesSubnetIdRef:
name: subnet-1
Appliquez-les et regardez Crossplane réconcilier avec l’API OVHcloud :
kubectl apply -f privatenetwork.yaml -f subnet.yaml -f cluster.yaml
kubectl get managed
La commande kubectl get managed liste chaque ressource externe suivie par Crossplane, avec les colonnes READY et SYNCED. Quand les deux affichent True, votre cluster existe sur OVHcloud — provisionné entièrement via l’API Kubernetes. Ajoutez un NodePool de la même façon, en référençant le cluster avec kubeIdRef, et vous obtenez un environnement Kubernetes managé complet décrit en YAML.
Ressources cluster-scoped vs namespaced
provider-ovh livre chaque ressource en deux déclinaisons, parce qu’il cible Crossplane 2.x. Les ressources cluster-scoped utilisent le groupe classique network.ovh.edixos.io ; les ressources namespaced utilisent les groupes *.m.ovh.edixos.io (le m marque l’API moderne, namespaced). Les ressources namespaced permettent de cantonner l’infrastructure OVH à un namespace Kubernetes, ce qui est la fondation d’un multi-tenant sûr — chaque équipe a son namespace, son RBAC et sa part d’infrastructure. Ce doublement explique pourquoi la release contient 281 manifestes de CRD pour environ 135 ressources logiques.
Au-delà des ressources brutes : les Compositions
Appliquer des managed resources individuelles est puissant, mais ce n’est pas encore une plateforme. Le vrai levier vient des Compositions : vous définissez une Composite Resource Definition (une XRD) qui présente une API simple et opinionnée — disons EdixosCluster — et une Composition qui la déploie en réseau privé, subnet, cluster et node pool sous-jacents. Les développeurs demandent une seule ressource de haut niveau ; la plateforme assemble les détails avec vos standards intégrés.
Le dépôt provider-ovh livre un exemple de Composition complet qui fait exactement cela. C’est là que Crossplane cesse d’être un remplaçant de Terraform pour devenir une plateforme self-service — le motif que nous construisons chaque semaine pour nos clients chez Edixos.
Dépannage
Quand une ressource refuse de devenir prête, la boucle de réconciliation vous dit pourquoi. Décrivez la managed resource et lisez ses conditions et événements :
kubectl describe cluster.kube.ovh.edixos.io hello-edixos
La plupart des échecs tombent dans trois catégories : erreurs d’identifiants (le JSON du Secret est mal formé, ou le jeton OVH manque des droits d’API requis), erreurs de référence (un *Ref pointe vers une ressource inexistante ou pas encore prête), et erreurs de quota ou de région renvoyées directement par l’API OVHcloud. Pour les problèmes au niveau du contrôleur, installez le provider avec le flag --debug via un DeploymentRuntimeConfig et consultez les logs du pod du provider dans crossplane-system.
Conclusion
Vous disposez maintenant de la boucle complète : un cluster kind faisant tourner Crossplane, provider-ovh installé et sain, des identifiants câblés via un ProviderConfig, et de la vraie infrastructure OVHcloud provisionnée en ressources Kubernetes. Les mêmes manifestes se glissent directement dans un dépôt Git et un pipeline GitOps — et c’est tout l’intérêt.
provider-ovh a démarré comme un projet qu’OVHcloud a refusé d’adopter et a survécu parce que des ingénieurs l’ont fait tourner en production et l’ont poussé plus loin. Il est open source, maintenu par la communauté, et pensé pour les équipes qui veulent qu’OVHcloud se comporte comme n’importe quel autre cloud dans un control plane Crossplane. Mettez-lui une étoile sur GitHub, essayez-le sur votre propre projet, et ouvrez une issue si quelque chose manque — ce retour est exactement ce qui le fait avancer.
Crossplane et provider-ovh ne sont qu’une pièce d’une pratique de platform engineering plus large. Pour le contexte complet, lisez pourquoi Kubernetes dépasse Terraform pour le platform engineering et notre blueprint éprouvé pour construire un Kubernetes as a Service — tous deux nourris par la décennie de Kubernetes en production derrière ce provider.
Parlons de votre plateforme Crossplane
Vous voulez exposer OVHcloud — ou n’importe quel cloud — en infrastructure self-service que vos équipes consomment via l’API Kubernetes ? Discutons de vos objectifs de plateforme et voyons comment un control plane Crossplane sur mesure peut vous apporter vitesse, gouvernance et passage à l’échelle.
Réponses directes
Questions fréquentes
Qu'est-ce que provider-ovh ?
provider-ovh est un provider Crossplane développé par Edixos qui expose les ressources OVHcloud sous forme de custom resources Kubernetes. Il est généré avec Upjet à partir du provider Terraform officiel d'OVHcloud, couvre plus de 135 ressources et est publié sur l'Upbound Marketplace sous edixos/provider-ovh, pour Crossplane 1.x et 2.x.
Ai-je besoin d'identifiants API OVHcloud pour utiliser provider-ovh ?
Oui. Le provider s'authentifie auprès de l'API OVHcloud avec une application key, une application secret et une consumer key. Vous générez ces jetons depuis la console API d'OVH, les stockez dans un Secret Kubernetes, puis les référencez depuis un ProviderConfig pour que Crossplane réconcilie vos ressources.
Puis-je exécuter Crossplane et provider-ovh sur un cluster kind local ?
Oui. Crossplane est un control plane léger et fonctionne parfaitement sur un cluster kind local pour l'apprentissage et le développement. Il ne provisionne de la vraie infrastructure OVHcloud qu'une fois que vous fournissez des identifiants API valides via un ProviderConfig ; le control plane lui-même n'a aucune contrainte d'hébergement particulière.
En quoi provider-ovh diffère-t-il du provider Terraform d'OVHcloud ?
provider-ovh réutilise en interne le schéma du provider Terraform d'OVHcloud mais l'expose en CRD Kubernetes réconciliées en continu par Crossplane. Au lieu de lancer un terraform apply, vous déclarez vos ressources en YAML et un contrôleur maintient l'infrastructure réelle conforme à l'état déclaré, avec RBAC et GitOps intégrés.