La création d’environnements de développement est en général un exercice chronophage et source de friction au sein d’une équipe. Les installations d’outils, leur configuration et authentification freinent la productivité et peuvent créer des blocages. En proposant une approche standard du problème, les environnements de développement en ligne sont des alternatives crédibles à l’environnement local. Les principaux Cloud publics en proposent désormais une version adaptée à leurs services.
En plus d’être une porte d’entrée efficace aux différents clouds, leurs configurations uniformes ainsi qu’une intégration avec leurs services respectifs sont gages de gains de temps importants pour un développeur.
Ils imposent néanmoins des contraintes qui ,dans certains cas, seront bloquantes pour un usage professionnel.

Des besoins communs pour interagir avec le Cloud

Que l’on travaille sur un cloud public ou privé le besoin d'interaction est quasiment impératif.
Les approches Gitops avec son Everything As Code, censées rendre minimal ce besoin, n'est pas réaliste dans toutes les situations.
Il faut tester les services, s’appuyer sur ces derniers lors de phases de développement, intervenir rapidement sur des incidents de productions, etc.


Plusieurs portes d’entrée existent. Les principales étant les APIs, la CLI via un cloud SDK et la cloud console. Dans un contexte programmatique l’API a du sens mais ne pourra répondre à un besoin interactif beaucoup mieux servi par un SDK et une cloud console (interface web).

Pourvue d’une interface graphique, la cloud console sera le premier choix de nombreux utilisateurs mais sera limitée vis-à-vis d’un cloud SDK plus réactif et avec la possibilité de fournir l’authentification à d’autres outils. Nous pensons en particulier à Docker, Kubectl, Terraform… Autrement dit, des outils généralement utilisés par des profils en interaction avec le Cloud. Se profile alors un environnement de développement commun avec des outils devops, de packaging et autres utilitaires simplifiant les tâches du quotidien.

Avoir une telle configuration prend du temps et doit se tenir à jour. Ce n’est pas la partie la plus productive du métier de développeur ou Ops.
Les Cloud Shells y remédient en apportant la notion de Development Environments As A Service.

La proposition des Cloud providers à travers l’exemple de Google Cloud Shell

Cette idée de Development Environments As A Service n’est pas neuve et est déjà portée par VSCode via son extension remote container. Une version headless de l’IDE démarrée dans un container local ou distant sera contactée à travers une interface graphique locale.
On décrit alors son environnement de développement as Dockerfile avec la possibilité de le partager/versionner via un gestionnaire de source. Nous en parlions ici. Au-delà de l’accès exclusif par le navigateur web, le Google Cloud Shell s’en démarque sur différents points.

Note: Nous accédons au Cloud Shell depuis la Google Cloud Console ou la documentation GCP. Il est nécessaire d’utiliser un compte Google pour s'authentifier.

Depuis la documentation Google Cloud
Depuis la Google Cloud Console

L’infrastructure

Techniquement Cloud Shell est hébergé sur une machine virtuelle Compute Engine. La documentation n’en dit pas grand-chose mais nous pouvons avoir certains détails en interrogeant le serveur de métadonnées compute engine depuis le shell lui-même:


curl "http://metadata.google.internal/computeMetadata/v1/instance/?recursive=true" -H "Metadata-Flavor: Google" | jq

Plusieurs points sont à noter:

  • machineType
    L’entrée machine type nous renseigne sur le type de machine mais aussi le projet qui l’héberge. Plus intéressant que le type de machine, il est intéressant de constater que ce projet GCP n’est pas accessible.
  • networkInterfaces
    Assez logiquement le VPC qui héberge la machine est sur ce même projet dont Google est propriétaire. Pas de possibilité donc de créer une connexion VPN vers ce réseau par exemple.
  • Image
    Cela signifie qu’au démarrage de la VM GCE, docker lance un conteneur basé sur l’image pointée qui dans notre cas est optimisé pour l'expérience.
  • Disks
    Deux disques sont associés, un est dédié au contenu de notre HOME tandis que l’autre est dédié à l’OS. On remarquera que le HOME qui est persisté entre différentes sessions n’est pas sur un disque SSD contrairement à la partie éphémère i.e l’OS.
    On peut supposer que la motivation principale derrière ce choix est économique.
  • Region
    La région est choisie en cohérence avec notre IP de connexion pour être la plus proche possible de cette dernière et garantir un temps de latence minimal.
  • ServiceAccount
    Notre VM bénéficie d’une identité portée par un service account avec des droits en écriture sur stackDriver d’un projet différent de celui qui héberge la VM. Attention, il ne s’agit pas de l’identité avec laquelle nous nous authentifions sur Cloud Shell, qui elle, servira pour interagir avec les services clouds GCP de nos projets.
  • attributes.startup-script
    Une mine d’information sur l’initialisation de la VM. On laissera le soin au lecteur de le lire pour reverse-engineer la logique derrière l'environnement du Cloud Shell (en  particulier les ports accessibles pour la connexion et le démarrage des services via systemd).

L’OS

Cloud Shell utilise un Container-Optimized OS qui se base sur Debian.
Il existe quelques degrés de liberté pour en adapter le contenu à son besoin comme l’installation d’outils spécifiques:

  1. Modification du $HOME
    Toute modification en dehors du $HOME de l’environnement sera éphémère. Ce qui se trouvera dans le HOME sera sauvegardé entre vos différentes sessions à hauteur de 5Go et pour une inactivité ne dépassant pas 120 jours. Les installations d’outils et créations de configurations se feront donc dans cet espace.
    Un mode éphémère permet de renoncer à cet espace pour gagner en temps de démarrage.
  2. Script dédié
    Le contenu de “$HOME/.customize_environment” est rejoué à chaque début de session Cloud Shell. Vous y lancerez par exemple des installations via le gestionnaire de package apt.

Il est possible de créer un environnement basé sur l’image Cloud Shell. Cependant, il ne s’agit pas de faire pointer le service Cloud Shell vers une nouvelle image mais de reproduire une "expérience" Cloud Shell dans vos propres environnements.  

Enfin, nous sommes limités à 50h par semaine afin que ce service gratuit ne devienne pas un gouffre financier pour le provider (il s’agit de “vraies” heures et non pas d’heures VCpu).
Vous devrez attendre le renouvellement d’un quota épuisé.

L’offre utilisateur

Cloud Shell a pour finalité d’offrir une expérience “intégrée” à la GCP afin d’être productif dès l’ouverture de la session. Notons quelques points.

Accéder un shell interactif avec un navigateur Web pose assez rapidement le problème de collision sur les raccourcis clavier.
CTRL+W est un raccourci très utilisé tant sur un navigateur Web que sur un Shell… mais avec des conséquences différentes (la fermeture d’un onglet navigateur, ou la suppression d’un élément sous le curseur).
Chromium et ses dérivés proposent une solution en installant la Progressive Web Application qu’est le Cloud Shell. Cela ajoute un lien Desktop lié au Cloud Shell que vous accédez désormais en dehors du navigateur.

Note: Actuellement, seul Chromium et ses dérivés semble proposer cette feature.

L'environnement est provisionné avec un certain nombre d’outils et de langages.
La liste exhaustive se trouve ici et nous souhaitons en noter quelques-uns:

  • Cloud Shell
  • tmux
  • gcloud
  • Un IDE qui va permettre de créer des espaces de travail à partir du contenu accessible et pensé pour interagir avec la GCP via l’extension Cloud Code

Il est possible de “casser” cet environnement avec sudo rm -rf /*
Forcer le redémarrage de la machine ne réglera rien, car il sera aussi bloqué (potentiellement Google interagit avec la VM avant de la redémarrer ce qui n’est plus possible au vu de la casse). Une astuce consiste à passer en mode éphémère avant de repasser en default mode.  

Vers un environnement de développement Cloud Native

En quoi ce type d’environnement serait-il Cloud Native, c'est-à-dire lui-même porteur de patterns adaptés au cloud et pour le cloud ?

Techniquement, le débat semble assez tranché. Une machine éphémère complètement managée et instanciée au plus proche de vous va dans ce sens.
La réponse est moins tranchée en matière d’usage.
Nous consommons une machine qui ne va pas drastiquement changer nos habitudes de travail par rapport à notre environnement local. Elle va les simplifier mais pas nécessairement les modifier.
Cloud Shell ne serait de ce point de vue qu’une version dématérialisée d’une machine physique.
Il est possible d'appréhender Cloud Shell d’une autre manière. Paradoxalement cette idée vient des limitations imposées par le type de machine provisionnée dont le stockage, mémoire et puissance de calcul sont limités.
On peut clairement penser le Cloud Shell comme un control plane de notre cloud dont chacun des services va prendre la place de notre processeur, disque dur, RAM, système de fichiers, etc.

Prenons l’exemple du stockage. 5Go est assez peu dans l'absolu. Cela convient pour de l’installation d’outils et autres fichiers de configurations mais moins quand on commence à travailler avec des conteneurs voire des projets d’envergure avec de nombreuses dépendances.
Dans ces cas, il est nécessaire de penser “out of the box” et ne pas hésiter à utiliser l’intégration offerte avec la GCP.

Prenons l'exemple du file système intégré que l'on peut étendre:

  • Via Google Cloud Storage
    Il est possible de monter un bucket GCS sur le file system de Cloud Storage en utilisant ce projet. Il faut être conscient des limitations quant à la concurrence d’écriture, ou de politique de cache mais nous donnons déjà un aperçu de stockage infini as a service.
    On aurait aimé aller plus loin en utilisant un disque SSD voire le service managé FileStore mais le non contrôle du VPC hôte de notre Cloud Shell nous empêche de créer le VPN nécessaire à la communication entre ces services.

  • Via Google Cloud repository
    La version managée Google de dépôt Git est une option. Au vu de la bande passante que l’on a depuis Cloud Shell il n’est pas nécessaire de se contraindre à garder en local le code applicatif avec lequel on interagit. Une intégration avec le Cloud Shell en simplifie la mise en place.

  • Via Google Cloud Artifact
    Au même titre que le code applicatif, les artefacts ou conteneurs ne peuvent jamais avoir à être produit localement mais plutôt via un service de CI/CD comme Google Cloud Build. L’intégration sera portée par la commande “gcloud builds submit” qui déporte le build et le stockage des artifact sur votre projet GCP cible. Les entités produites seraient alors directement consommées depuis un cluster GKE avec lequel l’interaction depuis Cloud Shell est prise en charge par l’extension Cloud Code installée par défaut.

On pourra améliorer sa RAM et son compute de la même manière.
Nul besoin de lancer des builds ou applications en local à partir du moment où nous avons des feedbacks rapides depuis les services Cloud Build et Stackdriver dont un mode tail est accessible avec gcloud.

Ce sont des exemples parmi d’autres. L’idée à retenir est que la notion d’environnement de développement englobe désormais la plateforme cloud plutôt que de se fermer à un environnement local.
Au même titre que le Cloud a transformé le réseau, le stockage, le compute en services à louer, nous appliquons le même principe aux éléments de notre environnement de développement.

En raisonnant architecture applicative, l'environnement local serait au monolithe ce que notre environnement Cloud Native serait à l’approche micro service.

L’environnement local VS environment As A Service‌‌

Il est possible de penser ainsi sur un environnement local mais c’est moins adapté et opportun. D’abord parce que l'environnement local sera à configurer pour trouver le même niveau d’intégration avec le Cloud Provider et surtout à mettre à jour régulièrement. Tout cela est déjà pris en charge dans le Cloud Shell, avec l’avantage supplémentaire de pouvoir casser sa configuration sans trop de conséquences.

On notera aussi que la qualité de la connexion internet est importante dans un tel paradigme. Avec Cloud Shell nous décorrélons la connexion domestique de celle dont nous bénéficions depuis Cloud Shell pour interagir avec les services GCP. On aura alors une expérience similaire que si nous travaillions depuis une bibliothèque municipale (qui par ailleurs pourra bloquer certains protocoles comme SSH) ou un réseau d’entreprise.

Les limitations et contraintes

Point de vue expérience utilisateur

Le besoin constant d’une connexion est un élément à avoir en tête.

La réactivité du shell dépendra de la qualité de la connexion et on voit que ce type d’environnement ne pourra jamais complètement remplacer un environnement local qui s’en abstrait plus.

L’approche qui consiste à se baser sur les services managés du cloud provider n’est pas naturelle.
Il faut la mettre en place et c’est un changement d’habitude de travail qui est nécessaire.
Un consensus devra être trouvé au sein d’une équipe et/ou entreprise.
Le seul exemple de se baser sur Cloud Build pour s’abstraire des limitations de compute suppose l’hypothèse forte qu’une intégration est possible entre la plateforme d’hébergement de code et Cloud Build. Pire, que nous acceptions qu’un membre de l’équipe crée son propre remote Cloud Repository pour exposer le code à Cloud Build…

Point de vue entreprise

Plusieurs points appellent à ne pas utiliser ce type de service dans un cadre professionnel.

Cloud Shell est un service gratuit ne bénéficiant d’aucun SLA. On apprécierait une version professionnelle qui irait plus loin en donnant la possibilité de choisir son type d’instance, sa configuration ainsi qu’une capacité d’hébergement sur ses VPCs.

D’un point de vue sécurité, Cloud Shell pose les mêmes problématiques qu’une machine personnelle dans un réseau d’entreprise avec l’inconvénient supplémentaire de ne pas pouvoir accéder à la configuration de la machine. Tout le monde n’est pas forcément prêt à des approches Zero-Trust network et ouvrir un réseau à ce type de machine n’est tout simplement pas envisageable. Il est d’ailleurs possible de désactiver le service Cloud Shell au niveau d’une organisation Google.
On gardera en tête que l’usage du Cloud Shell s’impose comme une solution efficace pour tester ou faire des démos de produits GCP.
En ce qui concerne un usage d’entreprise, il reste encore du chemin à parcourir.

Note: Et la concurrence ?
Nous allons retrouver le même type de service chez Azure et AWS. Moins généreux en termes de quota d'usage, il n'en reste pas moins similaire sur le fond malgré l’absence d’un IDE intégré.

Conclusion

Nous avons défini une expérience de développement que l’on pourrait qualifier de Cloud Native à travers l’exemple de Google Cloud Shell.
Simple d’usage, économique, intégré sont autant de qualificatifs qui le rendent attrayant et plaident pour un usage quotidien.
Un changement d’état d’esprit dans la relation que nous avons avec notre environnement de développement est toutefois nécessaire pour dépasser les contraintes de ressources imposées.
Malgré ces avantages apparents, ces environnements s’adaptent difficilement à un cadre de travail en équipe et encore plus à un cadre professionnel.
Reste alors pour le développeur un usage minimaliste pour les tests et démos, domaine sur lequel vous ne devriez pas vous priver d’utiliser cet outil gratuit et performant.

Il existe toutefois d’autres approches de Development Environment As A Service. Elles offrent une vision différente et surtout des solutions aux problèmes pointés.
Une nouvelle façon de travailler en entreprise qui se profile ? C’est ce que nous étudierons dans un prochain article.

Pour aller plus loin:

  1. Les documentations officielles des Cloud Shells des principaux cloud providers
  2. GCP
  3. AWS
  4. Azure
  5. L’extension Cloud Code intégré à l’IDE Google Cloud Shell