Maîtriser ses réseaux et son équipement grâce à la gestion des adresses IP (IPAM)
Ces derniers temps, je constate que de plus en plus de clients rencontrent des difficultés réseau, notamment au niveau du peering, à cause de collisions de plages d'adresses IP. Le signe évident qu'il est nécessaire de planifier et de gérer les adresses IP à l'échelle de l'organisation.
Vous pouvez bien sûr suivre vos IP dans une feuille de calcul partagée, mais il existe aussi des outils logiciels dédiés. Cet article montre comment exécuter un outil open source populaire de gestion des adresses IP (IPAM), Netbox, de manière cloud-native sur Google Cloud Platform (GCP).
Architecture traditionnelle
Historiquement, Netbox s'exécute sur une ou plusieurs machines virtuelles, derrière un serveur web. Il existe une image Docker maintenue par la communauté, mais les seules instructions disponibles consistent à l'exécuter via docker compose. Cette architecture ressemble à de nombreuses applications conçues ou exploitées en entreprise, ce qui en fait un excellent candidat pour illustrer une migration vers le cloud public.

Source : Netbox — installation Netbox standard
Conception cloud-native
J'ai décidé de comprendre le fonctionnement de l'image Docker, ses dépendances et ses paramètres de configuration, puis de la déployer sur GCP en n'utilisant que des services managés. Cet exemple peut illustrer la manière d'aborder une migration vers le cloud public, qu'il s'agisse de déplacer et améliorer ou de remplacer entièrement ses applications.

Installation Netbox revisitée sur GCP avec des services managés
Composants applicatifs
- Application Netbox (application Python utilisant le framework Django)
- Base de données PostgreSQL (Cloud SQL)
- Redis (Cloud Memorystore)
Choix de conception
- Base de données et cache managés (Cloud SQL, Cloud Memorystore)
- IP exclusivement privées pour les bases de données et le cache (Private Service Access)
- DNS privé pour les noms d'hôtes des bases de données (Cloud DNS)
- Secrets stockés dans le gestionnaire de secrets (Secret Manager)
- Runtime de conteneurs serverless (Cloud Run, Artifact Registry)
- Load balancer global avec TLS (HTTP(S) Load Balancing, Managed Certificate)
- Pare-feu WAF (Cloud Armor)
Une difficulté que je vois beaucoup d'organisations rencontrer : connecter des services managés et des applications serverless via des adresses IP privées. Cet exemple montre comment réserver des plages privées dans son réseau VPC, puis les attribuer aux services managés afin de créer un pont de connectivité.
Cloud DNS sert à établir des noms d'hôtes privés permettant aux applications de se connecter aux bases de données. Cela offre davantage de flexibilité par la suite, si vous changez de base de données ou si vous devez basculer en cas de panne : il suffit de mettre à jour vos enregistrements DNS pour que les applications continuent de pointer vers le même domaine. En théorie, j'aurais pu m'appuyer sur le forwarding DNS et tout connecter à mon domaine public, mais ce n'est pas nécessaire en interne ; j'ai donc utilisé example.com.
La VM bastion (ou jump host) n'était pas indispensable, mais j'en ai mis une en place pour tester les connexions pendant la phase de construction. En temps normal, un bastion se déploie dans un managed instance group (MIG) de taille 1, sans adresse IP externe.
Application web sécurisée et load-balancée

Application Netbox hébergée et servie par un Global Load Balancer en frontal du service Cloud Run
Pour mieux illustrer comment l'ensemble s'imbrique, j'ai utilisé un domaine personnel et enregistré un A record pointant vers l'adresse IP statique attribuée au Global Load Balancer ; un certificat managé a été automatiquement provisionné.

Pour renforcer la sécurité, j'ai appliqué une politique Cloud Armor (pare-feu WAF) au load balancer et restreint les plages d'IP (voir ci-dessous).
Code d'implémentation
Le code ci-dessous reprend, étape par étape, les commandes que j'ai utilisées pour tout mettre en place : réseau, variables d'environnement et secrets, bases de données, artifact registry et images Docker, Cloud Run, load balancing et pare-feu WAF.
Complexité et points complémentaires
Si j'ai choisi Netbox pour illustrer la modernisation et le déploiement d'applications de manière cloud-native, c'est précisément en raison de sa complexité technique. L'application embarque un système de fichiers, des sessions, des workers et même un traitement quotidien de nettoyage via cron.

Extrait Docker Compose pour l'application Netbox (notez netbox-worker et netbox-housekeeping)
L'extrait du fichier docker-compose.yaml ci-dessus illustre une fonctionnalité de YAML appelée ancres, qui n'est pas spécifique à docker-compose.

Exemple de fonctionnalité YAML (ancres) et de clés de fusion
Vous pouvez dupliquer des configurations de manière concise, puis surcharger les commandes pour exécuter différents scripts au runtime.
Recréer les workers sur Cloud Run
Pour reproduire ce type de fonctionnalité sur Cloud Run, il existe deux flags : --cmd et --args. Il suffit de dupliquer les commandes utilisées pour déployer l'application principale, de changer son nom, puis de surcharger CMD pour exécuter un autre script d'entrée, comme ci-dessous :
gcloud run deploy $WORKER_NAME \
--platform managed \
--allow-unauthenticated \
--vpc-connector $CONNECTOR_NAME \
--ingress=internal-and-cloud-load-balancing \
--region $GCP_REGION \
--image $IMAGE_PATH \
--set-env-vars "ALLOWED_HOSTS=$ALLOWED_HOSTS" \
...
--cmd "/opt/netbox/venv/bin/python" \
--args "/opt/netbox/netbox/manage.py" \
--args "rqworker"
Tâche de housekeeping quotidienne avec Cloud Run et Cloud Scheduler
La tâche de housekeeping quotidienne peut être exécutée en créant un service dupliqué sur Cloud Run, puis en planifiant son invocation chaque jour via Cloud Scheduler.
gcloud run deploy $HOUSEKEEPING_NAME \
--platform managed \
--allow-unauthenticated \
--vpc-connector $CONNECTOR_NAME \
--ingress=internal-and-cloud-load-balancing \
--region $GCP_REGION \
--image $IMAGE_PATH \
--set-env-vars "ALLOWED_HOSTS=$ALLOWED_HOSTS" \
...
--cmd "/opt/netbox/housekeeping.sh"
Une fois le service de housekeeping déployé, on active l'API Cloud Scheduler :
gcloud services enable cloudscheduler.googleapis.com
On crée ensuite un compte de service, on lui accorde les permissions d'invocation, puis on crée la tâche planifiée :
# récupérer l'URL du service
export SVC_URL=$(gcloud run services describe $HOUSEKEEPING_NAME \
--platform managed --region $GCP_REGION --format="value(status.url)")
#########################################################
# créer la tâche cloud scheduler
#########################################################
export SA_NAME="cloud-scheduler-runner"
export SA_EMAIL="${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com"
# créer le compte de service
gcloud iam service-accounts create $SA_NAME \
--display-name "${SA_NAME}"
# ajouter le binding sa à l'application cloud run
gcloud run services add-iam-policy-binding $HOUSEKEEPING_NAME \
--platform managed \
--region $GCP_REGION \
--member=serviceAccount:$SA_EMAIL \
--role=roles/run.invoker
# créer la tâche pour invoquer le service tous les jours à 2h30
gcloud scheduler jobs create http housekeeping-job --schedule "30 2 * * *" \
--http-method=GET \
--uri=$SVC_URL \
--oidc-service-account-email=$SA_EMAIL \
--oidc-token-audience=$SVC_URL
Systèmes de fichiers
Mon objectif était de démontrer qu'il est possible de découper une application complexe comme Netbox et de la déployer dans le cloud avec Cloud Run et d'autres services managés. Ce n'est sans doute pas la meilleure solution pour cette application précise, mais c'est faisable.
Si vous avez besoin du système de fichiers, les plateformes serverless restent aujourd'hui limitées, et vous aurez sans doute intérêt à vous tourner plutôt vers Kubernetes Engine, voire simplement une VM Compute Engine. Vous pouvez exécuter une VM en tant que conteneur, ce qui est très élégant, puis y attacher des disques ou des volumes selon vos besoins.
Une astuce pour disposer malgré tout d'un système de fichiers simple dans Cloud Run consiste à exploiter Secret Manager, comme je l'ai fait dans le code d'exemple et l'extrait ci-dessous.
# créer un secret pour toutes les variables
gcloud secrets create $SECRET_ID --replication-policy="automatic"
gcloud secrets versions add $SECRET_ID --data-file=${PWD}/$SECRET_FILE
# monter le chemin de fichier dans cloud run
gcloud run deploy $SERVICE --image $IMAGE_URL \
--update-secrets="/env/netbox.env"=$SECRET_ID:$SECRET_VERSION
Bonne pratique : des comptes de service distincts
Bien que les exemples partagés s'appuient sur un compte de service distinct pour le module complémentaire Cloud Scheduler, la bonne pratique consiste à créer des comptes de service dédiés pour chaque service ainsi que pour le bastion (VM), et à n'attribuer à chacun que les rôles IAM strictement nécessaires. C'est le principe du moindre privilège.
Pour le service Cloud Run, il convient de créer un compte de service dédié netbox-runner, puis de ne lui accorder que les rôles requis, par exemple :
J'espère que cet exemple vous aura montré comment moderniser des applications existantes et tirer parti des services managés du cloud public. Si vous cherchez simplement à mettre Netbox en route, les extraits de code ci-dessus devraient suffire, mais vous pouvez aussi envisager de l'exécuter sur une VM ou sur K8s.
Vous pourriez également convertir cet exemple fonctionnel en Terraform à l'aide de solutions tierces comme Terraformer, ou même les outils d'export en masse de GCP, capables de rétro-concevoir votre infrastructure existante et de générer le code Terraform correspondant.
Si votre organisation rencontre des difficultés similaires liées aux collisions d'IP au moment de configurer ses réseaux, le moment est sans doute venu de vous mettre à l'IPAM, que ce soit avec une feuille de calcul partagée ou avec un outil reconnu comme Netbox.