Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Recréer les Review Apps CI/CD de Heroku sur Google Cloud Platform

By Mike SparrAug 26, 20207 min read

Cette page est également disponible en English, Deutsch, Español, Italiano, 日本語 et Português.

Parmi les fonctionnalités phares de Heroku figure sa solution Review Apps. Elle génère un environnement jetable et une instance de l'application le temps d'une pull request (PR), puis détruit cet environnement temporaire dès la fusion de la PR.

Inspiré par ce concept et par un récent échange client chez DoiT International, j'ai entrepris de reproduire ce comportement sur Google Cloud Platform (GCP) avec une approche cloud-native et des outils open source largement adoptés.

Expérience développeur (démo de 20 minutes)

En suivant les principes du GitOps, votre équipe de développement n'a plus qu'à se concentrer sur l'écriture du code : dès qu'une PR est créée, une version prête à relire de leur dernier code devient accessible en ligne en quelques secondes ou quelques minutes.

Les commits suivants mettent à jour la review app jusqu'à ce que les relecteurs ou testeurs soient satisfaits et approuvent ou fusionnent la PR. Une fois l'application promue vers un environnement supérieur, la review app est détruite — et le cycle reprend pour chaque nouvelle fonctionnalité.

Démo du pipeline CI/CD GitOps avec review apps façon Heroku (20 minutes)

Regarder la vidéo de démo sur YouTube

Composants utilisés

  • Github — gestion du code source
  • Kustomize — gestion de configuration native Kubernetes
  • Argo CD — CD GitOps déclaratif pour Kubernetes
  • Kong Ingress Controller — passerelle API
  • Google Kubernetes Engine (GKE) — Kubernetes managé
  • Google Cloud Build — serveur CI
  • Google Container Registry (GCR) — registre privé d'images de conteneurs
  • Google Secret Manager — gestion centralisée des secrets
  • Google Cloud DNS — service DNS pilotable par API ( optionnel)

Architecture

La fonction principale des review apps est la suivante : lorsqu'un développeur crée une pull request (PR) dans le gestionnaire de code source, le pipeline de déploiement construit une copie de l'application et l'héberge dans un environnement isolé, accessible via une URL unique pour relecture.

La PR du développeur déclenche la création de la Review App

Les fonctionnalités complémentaires incluent la promotion de l'application en production après la fusion de la PR, ainsi que la suppression de la review app.

La fusion par le relecteur ou l'admin déclenche la promotion et supprime la Review App

TL;DR

Pour que tout fonctionne comme illustré, voici les étapes à suivre :

  1. Créer deux dépôts Github distincts pour l'App et la Config
  2. Activer les API Google et provisionner le cluster GKE et Argo CD
  3. Installer Kong API Gateway (ingress controller) via le dépôt Config
  4. Créer un enregistrement DNS A pointant vers l'IP externe du kong-proxy
  5. Connecter Cloud Build à votre dépôt Github
  6. Créer une clé privée et la stocker dans Google Secret Manager
  7. Ajouter la clé publique au dépôt Github Config
  8. Créer 3 triggers Cloud Build ( push, PR, merge)
  9. Autoriser le service account Cloud Build à accéder aux Secrets
  10. Ajouter les fichiers de configuration Cloud Build au dépôt App
  11. Ajouter les manifestes Kubernetes et les overlays Kustomize au dépôt Config

Créer les dépôts source Github

Les dépôts ci-dessous sont des exemples fonctionnels ; je détaillerai les étapes de leur construction dans les sections qui suivent.

  • Demo App — Dockerfile et scripts CI Cloud Build
  • Demo App Config — scripts de configuration et manifestes Kubernetes pour Argo CD

Activer les API, provisionner GKE et Argo CD

Dans le script ci-dessous, j'active les API des services Google Cloud et je provisionne un cluster Kubernetes.

Dans un article précédent, j'ai présenté le concept de l'app of apps pattern, utilisé notamment par l'équipe Argo chez Intuit. Dans cette solution, la création et la suppression dynamiques d'une Application conviennent parfaitement à notre cas d'usage : créer et détruire les review apps.

Installer Kong API Gateway (ingress controller)

Pour Kong, ajoutez simplement un fichier kong.yaml dans le dossier /apps du dépôt Config. Argo CD détectera et surveillera tout dépôt ou dossier que vous lui indiquerez. J'ai choisi Kong parce que chaque Ingress que je crée configure un host, ce qui en fait un choix idéal pour générer dynamiquement les URL des nouvelles review apps.

Ajoutez les fichiers de configuration Kong dans le dossier cible : Kong sera installé sur votre cluster Kubernetes (à répéter pour chaque application souhaitée).

Notez le source.path (kong) : c'est le dossier du dépôt qui contient les manifestes YAML qu'Argo CD installera. J'ai créé un fichier nommé 01-install.yaml à partir du manifeste unique fourni par Kong, dans le dossier /kong du dépôt Config. ( https://bit.ly/k4k8s pointe vers la dernière configuration Kong )

curl https://raw.githubusercontent.com/Kong/kubernetes-ingress-controller/master/deploy/single/all-in-one-dbless.yaml --output kong/01-install.yaml

Créer un enregistrement DNS A pour Kong Proxy

Une fois Kong installé sur votre cluster, il crée un load balancer TCP externe (Service) doté d'une IP externe.

Service de load balancer Kong Proxy sur le cluster Kubernetes

Vous devez faire pointer votre domaine vers cette IP, ce que vous pouvez faire manuellement chez votre fournisseur. Pour ma première démo, j'ai simplement configuré l'enregistrement A et quelques alias CNAME comme ci-dessous.

Entrées DNS configurées manuellement

Une approche alternative consiste à confier la gestion du domaine à Google Cloud DNS. Il faudrait alors pointer vers les serveurs de noms de Google, ce qui permettrait ensuite de générer dynamiquement les URL des review apps à partir du numéro de PR (l'idéal). Une fois GKE et Kong initialisés, vous pouvez utiliser les commandes suivantes pour le configurer.

Connecter Cloud Build à Github

D'ordinaire, je déteste les articles qui renvoient à d'autres articles, mais par souci de concision, veuillez suivre ces deux étapes pour connecter Cloud Build à Github et ajouter une clé SSH dans Secret Manager : elles sont très bien décrites dans les deux articles suivants de Google :

  1. Connecter Cloud Build à Github
  2. Ajouter une clé et un secret pour accéder aux dépôts privés — pensez à cocher la case commit sur le dépôt Config, afin que le pipeline de build de l'App puisse committer les changements de version du tag de l'image Docker.

Créer 3 triggers Cloud Build

Pour reproduire le comportement souhaité, il suffirait techniquement de créer les triggers de PR et de merge ainsi que leurs fichiers de configuration. Mais en pratique, vous voudrez aussi des builds et des déploiements pour les développeurs : j'ai donc ajouté un troisième trigger sur les push vers la branche develop.

Triggers Cloud Build

Notez que dans les configurations ci-dessous, j'ajoute des variables d'environnement définies par l'utilisateur (en bas de chaque page). Elles permettent aux fichiers de configuration de référencer le nom de l'application et, en option, d'ajouter des étapes conditionnelles selon l'environnement.

Par souci de simplicité, j'ai créé 3 triggers et 3 fichiers de configuration distincts (section suivante), mais vous pourriez les regrouper en exploitant ces fonctionnalités.

Build et déploiement de l'image Docker à chaque push sur la branche develop

Pull request d'une autre branche vers master (prod)

Fusion de la PR dans la branche master (prod)

Ajouter les fichiers de configuration Cloud Build au dépôt App

La première partie des fichiers de configuration de build est assez basique : elle se contente de construire une image Docker et de la pousser vers Google Container Registry (GCR). Les étapes suivantes utilisent le secret de Secret Manager pour cloner le dépôt de configuration, modifier des fichiers et pousser un commit. Cela déclenche Argo CD, qui synchronise les derniers changements et met à jour les applications sur votre cluster GKE.

Notez dans ce fichier que la commande sed -i ... est l'endroit où le tag de l'image est mis à jour vers le dernier build poussé sur GCR.

À noter qu'à l'étape PR, nous utilisons v$_PR_NUMBER pour taguer les images, afin qu'elles puissent être mises à jour lors des commits suivants pendant la revue de PR (je modifierai peut-être ce comportement plus tard). Autre particularité : nous copions /templates/demo-app-review.yaml vers le dossier /apps pour qu'Argo CD commence à surveiller le chemin cible.

L'élément vraiment original ici, c'est l'étape Removing review app… où nous exécutons rm apps/demo-app-review.yaml. Comme nous avons activé autoSync et prune dans la configuration de notre Application, ArgoCD le détecte et supprime la review app du cluster GKE.

Ajouter les manifestes Kubernetes et les overlays Kustomize

Nous pourrions (et devrions) consacrer un article entier à Kustomize et à la façon dont il permet une gestion de configuration native Kubernetes. Traditionnellement, on package ses applications avec des charts Helm ou des outils sonnet basés sur du code, mais ma préférence va à la simplicité et à l'extensibilité offertes par Kustomize.

Le dépôt Config est organisé de telle sorte que chaque application — dans notre cas /demo-app/base — contient ses manifestes et un fichier kustomization.yaml.

  • namespace.yaml — namespace personnalisé
  • ingress.yaml — configuration Ingress que Kong détecte pour ajouter la route
  • service.yamlwrapper réseau pour les pods backend
  • deployment.yaml — votre application proprement dite (pointant vers l'image)
  • kustomization.yaml — configuration Kustomize

Nous ajoutons ensuite des overlays pour représenter nos environnements : ces configurations remplacent ou patchent les fichiers YAML avec des valeurs spécifiques à chaque environnement, comme le suffixe du nom d'application, le namespace ou le host de l'Ingress (pour permettre des URL de review apps dynamiques).

  • /overlays/develop — configurations de l'environnement develop
  • /overlays/review — configurations de l'environnement review app
  • /overlays/production — configurations de l'environnement production

Vous pouvez consulter ces fichiers dans l'exemple de dépôt Github de configuration. Voici ci-dessous un exemple de configuration d'overlay et de fichier de patch pour créer des URL spécifiques à chaque environnement dans l'Ingress.

Notez que la propriété patchesStrategicMerge pointe vers un fichier. Kustomize fusionne le contenu de ce fichier (ou de ces fichiers) pour remplacer des valeurs personnalisées, comme le host de l'Ingress ci-dessous, afin de définir une URL personnalisée par environnement.

URL dynamiques par PR (optionnel)

Pour ma première démo, j'ai utilisé la même URL, mais si vous utilisez Cloud DNS, ajoutez une étape supplémentaire à votre fichier cloudbuild-pr.yaml comme ci-dessous pour rendre les URL dynamiques. Au moment où j'écris ces lignes, je ne l'ai pas encore testé, mais je compte mettre à jour mes serveurs de noms et le tester aussi.

Vous ajouteriez également une autre commande sed -i ... dans le script de configuration pour remplacer dynamiquement le fichier de patch ingress-host.yaml à chaque déploiement de PR.

Rejoignez mon équipe

Rejoignez DoiT International et faites vos propres découvertes passionnantes comme celle-ci en consultant notre page carrières

Même si cet article est dense, le processus global n'a rien d'insurmontable. En vous appuyant sur les dépôts d'exemple que j'ai partagés, vous pourrez vous aussi permettre à vos Engineers de se concentrer moins sur l'infrastructure et davantage sur ce qu'ils font de mieux.

Pipeline de build CI/CD réussi avec GitOps et Review Apps façon Heroku pendant une PR