Utiliser AWS pour déployer un projet d’une startup: Partie 1 - Frontend

Utiliser AWS pour déployer un projet d’une startup: Partie 1 - Frontend

Le défi

Il y a quelques années, j’ai rejoint une startup pour créer un produit qui voulait trouver sa place sur le marché.

D’abord, j’ai rejoint l’équipe en tant que développeur Frontend et, après avoir terminé la première version de l’application, je voulais m’impliquer davantage côté backend. Alors, j’ai échangé mon rôle avec le développeur Backend.

L’application était composée de trois services : une API Backend, un Frontend que nous voulions aussi déployer sur les appareils mobiles, et un panneau d’administration.

Avec le CTO, nous avons décidé que nous pouvions déployer nos services sur AWS, et que nous utiliserions des images Docker. Par conséquent, nous avons choisi AWS ECS comme notre plateforme de déploiement.

Nous n’avons pas choisi Kubernetes, car nous n’avions pas beaucoup d’utilisateurs au début.

Par ailleurs, nous avions des besoins spécifiques:

Frontend: Devrait être stocké dans le côté utilisateur (client-side), et l’utilisateur doit être capable de télécharger une photo.

API Backend: Devrait être publique, pour être consommée par l’application mobile et le Frontend.

Admin: Devrait être un outil d’utilisation interne. Du fait que nous étions une petite startup à ce temps-là, il était logique d’utiliser les connexions VPN.

Pour tous les cas précédents, nous avions besoin d’un environnement de test, que nous avons nommé l’environnement staging.

Pour les prochains exemples, je vais utiliser thestartup.domain (lastartup.domaine en français) comme un domaine d’exemple. Les exemples peuvent varier du diagramme et des cas réels, car c’est un concept général basé sur ma mémoire.

Pourquoi ne pas utiliser la console d’AWS, et pourquoi nous utilisons Terraform?

Du coup, nous avions expérimenté en créant les raccourcis manuellement dans la console, mais nous avons vu que dépendre de la mémoire pour commencer à faire les modifications peut être dangereux, et que nous pourrions endommager les ressources accidentellement.

Bien que nous ayons eu accès à CloudFormation, je ne me souviens pas des caractéristiques que nous avons mises à ce temps-là. Alors, nous avons choisi Terraform à la place de CloudFormation. Je me rappelle que la raison principale était la syntaxe plus claire et facile comparée à CloudFormation.

Frontend

L’architecture

Pour le frontend, nous avons fait des recherches pour utiliser S3 pour héberger notre application statique. Nous pourrions utiliser CloudFront connecté à AWS Certificate Manager pour déployer une application complète statique HTTPS pour servir HTML. Aussi, CloudFront héberge en cache le contenu dans ses Edges. Ça fait du sens, comme l’option la plus logique.

AWS Frontend

Deux zones de disponibilité différentes

Nous utilisions deux zones de disponibilité différentes, car utiliser us-east-1 est risqué, tous les nouveaux changements d’AWS seront déployés là, et ils peuvent causer des disruptions dans la plateforme.

Le seul service que nous ne pouvions pas déplacer était l’Administrateur des certificats. Pour valider notre domaine, il devait être dans us-east-1.

Nous utilisons deux domaines

La raison pour laquelle nous avions utilisé deux domaines pour déployer l’application, hors de thestartup.domain était parce que la page principale était une page landing, et nous voulions déployer l’application réelle dans un sous-domaine. Comme j’ai écrit, nous voulions avoir un environnement staging que chaque développeur peut utiliser.

Héberger les environnements de production et staging dans un seul bucket

Bien sûr, nous pouvons créer un bucket par projet. Mais avec Terraform, pour reproduire un environnement par développeur, nous avions utilisé un seul bucket avec des dossiers différents. Créer un bucket par dossier ressemblait à du sur-engineering pour l’architecture.

Utiliser CloudFront pour montrer le contenu du bucket

Pour profiter du cache et éviter de l’exposer, nous avons créé deux distributions CloudFront sur la couche de prix la moins chère : PriceClass_100. Avec ça, nous serons certains que notre contenu restera seulement dans le cache pour le public d’Amérique (nord et sud).

Certificat

Notre certificat était de type wildcard. C’est juste au cas où nous voudrions plus d’alternatives ou d’instances de test pour le frontend. Un certificat de type wildcard permet d’attribuer de multiples sous-domaines à un seul certificat.

Pour ce cas, nous avons utilisé *.frontend.thestartup.domain.

Un environnement par développeur

Pour deux semaines, nous avons essayé avec l’URL comme developpeurun.frontend.thestartup.domain. Mais, nous n’avions pas le temps de renforcer certaines politiques au moment de faire un merge dans nos branches de Git, il était dur de tenir le code comme ça. L’idée était d’avoir deux environnements alternatifs visant la même API de staging.

Même si nous avons recréé la même structure sur Terraform par Pull Request, ça peut prendre beaucoup de temps pour attendre le déploiement, nous avons laissé tomber l’idée.

Le flux pour déployer le projet (Pipeline)

Deployment

Le flux était pour construire le HTML et le déployer comme du contenu statique. Pour éviter de sortir de l’écosystème AWS, j’ai utilisé AWS CodeCommit combiné avec AWS CodeBuild pour la première version.

Mais les Github Actions ont commencé à gagner en popularité à ce temps-là, donc, nous avons décidé de faire la migration vers Github Actions, car nous pouvions créer des rapports par Pull Request.

Alors, dans le bucket nous avions deux répertoires : l’un appelé /production et l’autre /staging. Après la construction de chaque projet, nous avons changé les variables d’environnement pour viser l’API de staging aussi.

Flux en Github

Ceci est un script similaire à celui que nous avons utilisé pour déployer le code.

DOMAIN_NAME (nom de domaine) a été changé parmi les environnements. Nous avions l’habitude de détecter la distribution de CloudFront à viser pour invalider le cache quand nous avions fini avec le déploiement dans le bucket.

name: Déployer en production
on: workflow_dispatch
jobs:
deploy:
runs-on: ubuntu-latest
env:
NODE_OPTIONS: --max-old-space-size=8192
ENVIRONMENT: production
steps:
- name: Récupérer le code source
uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: ".nvmrc"
cache: npm
- name: Installer la dernière version de NPM
run: npm install -g npm@10
- name: Installer JQ
run: sudo apt-get install jq
- name: Configurer les identifiants AWS
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_FRONTEND_PIPELINE_ID }}
aws-secret-access-key: ${{ secrets.AWS_FRONTEND_PIPELINE_KEY }}
aws-region: us-east-2
- name: Récupérer et afficher l'URL CloudFront du Frontend
id: domain-data
run: |
DOMAIN_CNAME=$(dig -t cname app.thestartup.domain +short)
DOMAIN_CLOUDFRONT=${DOMAIN_CNAME%?}
echo "::set-output name=domain_name::$DOMAIN_CLOUDFRONT"
- name: Installer les dépendances
run: npm ci
- name: Copier le fichier d'environnement pour la production
run: npm run prod:config
- name: Générer la version de production du frontend
run: npm run prod:build
- name: Synchroniser les fichiers avec S3 et invalider le cache CloudFront
env:
CLOUDFRONT_DISTRIBUTION: ${{ steps.domain-data.outputs.domain_name }}
run: |
CLOUDFRONT_ID_RAW=$(aws cloudfront list-distributions|jq '.DistributionList.Items[] | select(.DomainName=="'$CLOUDFRONT_DISTRIBUTION'") | .Id')
CLOUDFRONT_ID="${CLOUDFRONT_ID_RAW//\"}"
aws s3 sync ./www s3://cloudfront-frontend-default-bucket/$ENVIRONMENT --delete
aws cloudfront create-invalidation --distribution-id $CLOUDFRONT_ID --paths '/*'

Qu’est-ce que je peux améliorer actuellement?

Le code que tu as révisé ces dernières années te fait te sentir embarrassé ? C’est complètement normal ! Nous, comme développeurs, quand nous avons plus de connaissances, nous verrons les échecs du passé et nous réfléchirons aux manières dont nous pouvons les éviter. C’est pourquoi j’ai créé une liste d’améliorations si je dois créer le même environnement actuellement.

Ajouter WAF

Car la sécurité est très importante maintenant, ajouter WAF serait obligatoire pour moi. AWS WAF ajoute une protection contre les injections SQL et le cross-site scripting (XSS). Aussi, il ajoute une couche de protection contre les bots. Dans le monde actuel, les bots continueront l’utilisation de ton site de manière répétée, en cherchant quelque vulnérabilité, ou ils peuvent « lire » ton site, en consommant des ressources et de la mémoire.

AWS Frontend Improved

Utiliser un bucket différent par projet

Pour des objectifs de sécurité, j’ai essayé de mettre tous les contenus de déploiement dans le même bucket. Donc, une fois que je dois donner des accès à chaque développeur, ça va être simple, parce qu’il faut gérer une seule ressource.

Mon but sera de créer des buckets séparés pour chaque environnement, nous permettant de gérer chaque permission de développeur individuellement par ressource et de restreindre l’accès au bucket de production au personnel autorisé dans la compagnie.

AWS Frontend Deployment Improved

Si nous avons besoin d’un environnement différent par développeur

Si nous avons besoin d’avoir plus d’environnements hors de staging ou production, je vais préférer déployer ces environnements temporels dans un conteneur NGINX qui servira le contenu comme un serveur web, car attendre pour la création d’une distribution CloudFront peut être cher en termes d’argent et de temps.

Sur la prochaine partie

La partie 2 couvrira le backend, dont la complexité la plus grande reste. Parce que nous avions à déployer les conteneurs, AWS ECS nous a aidé à réduire la maintenance de nos conteneurs.

Je vais faire une mise à jour au post dans la section des recommandés quand l’autre post sera prêt.

Mes articles ne sont pas generés par l'IA, cependant ils pourrait y être corrigés. Le premier brouillon est ma création originale

Tags

Auteur

Écrit par Helmer Davila

Dans d'autres langues

Cómo desplegamos el frontend de un proyecto de una startup usando AWS

Usando AWS para desplegar un proyecto de una startup: Parte 1 - Frontend

How we deployed the frontend of a startup project using AWS

Using AWS to deploy a Startup project: Part 1 - Frontend