Intro
Dans l’épisode précédent, nous avons codé l’intégralité de notre CDN. Nous l’avons ensuite lancé en local avec un object storage Minio pour s’assurer de son bon fonctionnement.
Aujourd’hui c’est le grand jour, nous allons quitter le monde du local et envoyer notre application dans les nuages ☁️.
Notre application est développée en Rust et je souhaite la déployer sur du cloud français.
Le choix de l’hébergeur est dans le titre de l’article, nous allons utiliser Clever Cloud !
Clever Cloud fourni du Platform as a Service (PaaS) basé en Europe.
Leur solution est simple : vous fournissez le code et ils se chargent de le faire tourner sur leurs infras tout en garantissant la scalabilité, la disponibilité et la sécurité de façon transparente et automatisée pour les clients.
Reprenons notre application Rust, cela veut dire pour faire simple que nous avons seulement à fournir le code source et qu’ils se chargent de la compilation et du déploiement. Plus d’infra à gérer, je push juste mon code.
Mais tout d’abord, commençons par préparer la CI de notre projet.
Mise en place de la CI à l’aide de Gitlab CI
L’intégration continue (CI) est une pratique de développement logiciel consistant à automatiser l’intégration des modifications de code, permettant ainsi une détection rapide des erreurs et une livraison plus fiable des applications.
Dans notre cas, le projet est hébergé sur Gitlab, nous allons donc implémenter la CI à l’aide de Gitlab CI.
Gitlab détecte automatique le fichier .gitlab-ci.yml
dans le projet. Si celui-ci est présent, la CI sera automatiquement exécutée.
Pour cet article, notre pipeline de CI contiendra les actions suivantes :
- Exécution du linter pour vérifier la qualité du code
- Exécution des tests pour s’assurer que les commits n’introduisent pas de régressions (dans un monde idéal, dans la réalité, cela dépend de la qualité des tests et de la couverture du projet.)
Voici à quoi ressemble le fichier .gitlab-ci.yml
de notre projet :
image: rust:1.76-buster
stages:
- test
test:
stage: test
rules:
- if: $CI_COMMIT_TAG == null
script:
- cargo test
lint:
stage: test
rules:
- if: $CI_COMMIT_TAG == null
before_script:
- rustup component add clippy
script:
- cargo clippy
Avec cette configuration, le linting et les tests seront exécutés à chaque commit push sur le projet.
Création de l’application sur Clever Cloud
Installation de la CLI
Pour créer notre application sur Clever Cloud, nous allons utiliser la CLI fournie. Pour cela, nous allons suivre la documentation disponible ici : https://developers.clever-cloud.com/doc/cli/getting_started/.
❯ npm install -g clever-tools
Authentification et récupération des secrets
La CLI nécessite d’être authentifiée pour exécuter des actions. Pour cela, nous utilisons la commande clever login
.
❯ clever login
Opening https://console.clever-cloud.com/cli-oauth?cli_version=3.4.0&cli_token=xxxxx in your browser to log you in…
Login successful as User <yourmail@provider.xyz>
Cette commande va ouvrir votre navigateur par défaut avec la mire de connexion.
Et une fois connecté, nous pouvons récupérer des secrets, mettez-les de côté, nous allons en avoir besoin d’ici peu !
Création de l’application
Tout est prêt maintenant pour créer notre application via la CLI.
Nous allons utiliser la commande clever create
:
clever create --type rust gimme-demo --region par
💡 le paramètre
--region
est optionnel, il prendrapar
comme valeur par défaut
Si tout se passe bien, vous devez obtenir le résultat suivant :
Application created successfully!
ID: <your app id>
Name: gimme-demo
Vous devez également voir l’application créée depuis la console Clever https://console.clever-cloud.com :
Avant de push le code du projet, nous allons créer l’addon Cellar étant donné que nous avons besoin d’un object storage.
Cette fois c’est la commande clever addon create
que nous allons utiliser :
clever addon create cellar-addon --plan S gimme-store --link gimme-demo
💡 le paramètre
--link
permet de lier l’addon à notre application
Si tout se passe bien, vous devez obtenir le résultat suivant :
Add-on created and linked to application gimme-demo successfully!
ID: addon_<id>
Real ID: cellar_<id>
Name: gimme-store
Encore une fois, l’addon doit également être visible depuis la console.
Création des variables d’environnements
Dernière étape avant de procéder au déploiement, nous allons devoir créer quelques variables d’environnements sur notre application gimme-demo
.
Les variables d’environnements s’ajoutent via la commande clever env set
.
Et voici la création de nos variables :
➜ ~ clever env set BUCKET gimme
Your environment variable has been successfully saved
➜ ~ clever env set REGION us-west-1
Your environment variable has been successfully saved
➜ ~ clever env set ENDPOINT cellar-c2.services.clever-cloud.com
Your environment variable has been successfully saved
➜ ~ clever env set ACCESS_KEY <access_key>
Your environment variable has been successfully saved
➜ ~ clever env set SECRET_KEY <secret_key>
Your environment variable has been successfully saved
Nous pouvons vérifier la présence des variables à l’aide la commande clever env
:
➜ ~ clever env
# Manually set env variables
ACCESS_KEY="<access_key>"
BUCKET="gimme"
CC_CACHE_DEPENDENCIES="true"
ENDPOINT="cellar-c2.services.clever-cloud.com"
REGION="us-west-1"
SECRET_KEY="secret_key"
# Addon gimme-store
CELLAR_ADDON_HOST="cellar-c2.services.clever-cloud.com"
CELLAR_ADDON_KEY_ID="<access_key>"
CELLAR_ADDON_KEY_SECRET="secret_key"
💡 La valeur de la clé REGION importe peu car l’addon Cellar ne l’utilise pas.
Tout est prêt pour le déploiement.
Déploiement
Sûrement l’étape la plus simple de notre aventure, car elle se résume à une simple commande :
clever deploy
Tout ayant été paramétré durant les étapes précédentes, on donne notre code source Rust et on laisse Clever bosser !
➜ gimme-article git:(master) clever deploy
Remote application is app_id=app_<app_id>, alias=gimme-demo, name=gimme-demo
Remote application belongs to user_<user_id>
App is brand new, no commits on remote yet
New local commit to push is 9a6a98f57e02d153591ab6f643ef8540ac278c3b (from refs/heads/master)
Pushing source code to Clever Cloud…
Your source code has been pushed to Clever Cloud.
Waiting for deployment to start…
Deployment started (deployment_xxxxx)
Waiting for application logs…
Comme mentionné pendant l’intro, l’application est bien déployée en partant des sources. Une première étape consiste à compiler le code Rust pour produire le binaire. Binaire déployé sur notre application une fois prêt.
💡 Clever possède un système de cache sur la compilation qui permet de gagner du temps sur les compilations suivantes. Mes compilations suivantes de l’application ont été bien plus rapides.
Si tout a bien fonctionné, vous devez voir votre application en ligne depuis la console.
2024-03-06T21:52:28.743Z: Done uploading dependencies cache archive
2024-03-06T21:52:28.745Z: Creating build cache archive
2024-03-06T21:52:37.442Z: build cache archive successfully created
2024-03-06T21:52:40.641Z: Begin
2024-03-06T21:52:40.643Z: Starting the application…
2024-03-06T21:52:42.861Z: Application start successful
2024-03-06T21:52:42.861Z: No cron to setup
2024-03-06T21:52:43.407Z: Successfully deployed in 8 minutes and 49 seconds
La CI c’est bien, la CD c’est encore mieux !
Étant donné que Clever fourni une image docker de sa CLI, la partie déploiement continu va être très simple.
Tout d’abord nous allons configurer quelques variables accessibles par nos pipelines depuis l’interface du projet Gitlab.
Pour cela, nous allons nous rendre dans la partie Settings > CI/CD > Variables du projet.
Les variables à créer sont les suivantes :
- APP_ID : l’identifiant de l’application Clever
- CLEVER_TOKEN : token fourni au moment du login via la CLI
- CLEVER_SECRET : secret fourni au moment du login via la CLI
L’identifiant de l’application se trouve en haut à droite sur la vue d’ensemble de l’application :
Et voici les variables créées dans Gitlab :
Une fois ces variables configurées, nous pouvons mettre à jour le fichier .gitlab-ci.yml
avec un nouveau job.
Ce job aura la charge de déployer l’application sur Clever lorsqu’un commit arrive sur la branche principale du projet.
Voici le fichier à jour :
image: rust:1.76-buster
stages:
- test
- deploy
test:
stage: test
rules:
- if: $CI_COMMIT_TAG == null
script:
- cargo test
lint:
stage: test
rules:
- if: $CI_COMMIT_TAG == null
before_script:
- rustup component add clippy
script:
- cargo clippy
deploy:
stage: deploy
image:
name: clevercloud/clever-tools:latest
entrypoint: ["/bin/sh", "-c"]
rules:
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
script:
- clever link $APP_ID
- clever deploy
Notre déploiement est maintenant automatisé 🎉.
Une petite démonstration pour finir ?
💡 Partons du principe que nous avons déjà upload un package comme montré dans l’article précédent.
Comme la dernière fois, nous allons utiliser la librairie de web-components développée par mes collègues de MGDIS (lien vers le storybook du projet).
Créons une page qui utilise les mg-components via notre CDN comme ceci :
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>CDN Demo</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel="stylesheet"
href="https://myapp.cleverapps.io/gimme/mg-components@5.24.0/mg-components/mg-components.css" />
<script type="module"
src="https://myapp.cleverapps.io/gimme/mg-components@5.24.0/mg-components/mg-components.esm.js"></script>
<link rel="stylesheet" href="/assets/app.css">
<script src="/assets/app.js" defer></script>
</head>
<body>
<mg-form identifier="demo-form">
<mg-input-checkbox identifier="mgic-demo" label="Checkbox"></mg-input-checkbox>
<mg-input-date required=" true" identifier="mgid-demo" label="Date"></mg-input-date>
<mg-input-numeric identifier="mgin-demo" label="Numeric"></mg-input-numeric>
<mg-input-password identifier="mgip-demo" label="Password"></mg-input-password>
<mg-input-text identifier="mg-input-text" label="Text"></mg-input-text>
<mg-input-textarea identifier="mg-input-textarea" label="Text area"></mg-input-textarea>
<div slot="actions" class="mg-group-elements mg-group-elements--align-right">
<mg-button id="can-submit">Submit</mg-button>
<mg-button id="errors" variant="secondary" type="button">Display errors</mg-button>
</div>
</mg-form>
</body>
</html>
Dans cet exemple, nous chargeons deux fichiers depuis notre CDN déployé :
- https://myapp.cleverapps.io/gimme/mg-components@5.24.0/mg-components/mg-components.css
- https://myapp.cleverapps.io/gimme/mg-components@5.24.0/mg-components/mg-components.esm.js
Et voici le rendu de notre page de démonstration :
Conclusion
Notre voyage au cœur du CDN est désormais terminé.
Au fil de cette série d’articles, nous avons pu aborder différents sujets qui jalonnent le cycle de vie de la création d’une application.
Un CDN fait maison et déployé sur du cloud français, est-ce qu’on ne tiendrait pas un concept de CDN souverain ? 😁
Ce format épisodique était une nouveauté pour moi et j’espère que vous avez pu y découvrir des choses.
Sur ce, je vous dis à la prochaine avec un nouveau sujet !