Comment déployer en continu un site Web statique avec style à l'aide de GitHub et AWS

Dans cet article, nous allons apprendre à utiliser AWS CodePipeline et CodeDeploy pour récupérer automatiquement le code source d'un site Web statique à partir de GitHub et le déployer sur S3.

Nous allons configurer le déploiement pour qu'il se produise lors de tout nouveau commit dans notre branche master.

Nous commençons par créer un pipeline de code avec une étape source liée à notre référentiel GitHub. Lorsqu'un nouveau commit est poussé vers notre branche maître, le pipeline extrait automatiquement le dernier code. Nous pouvons ensuite déclencher une étape de construction dans notre pipeline. Cette étape permet d'installer des dépendances, d'exécuter des tests et de conditionner notre site pour le déploiement. Notre dernière étape consiste à déployer notre site Web statique sur notre compartiment S3.

Maintenant que nous savons ce que nous allons construire, intervenons et apprenons encore plus en construisant cela.

Prérequis AWS CodePipeline

Pour configurer un AWS CodePipeline dans notre compte qui communique avec notre référentiel GitHub, vous devez prendre en compte certaines conditions préalables.

  1. Vous devriez déjà avoir un compte AWS configuré.
  2. Vous devez avoir un accès CLI configuré pour votre compte.
  3. Votre site Web statique doit déjà être hébergé sur AWS S3. Sinon, consultez ce lien.

Configuration de la communication GitHub et AWS

Pour qu'AWS puisse interroger les modifications apportées à notre branche principale dans GitHub, nous devons pouvoir générer un jeton d'accès pour notre référentiel GitHub. Nous pouvons générer un jeton d'accès personnel en effectuant les étapes suivantes à partir de GitHub.

  1. Une fois connecté à GitHub, cliquez sur la photo de votre profil en haut à droite, puis sur Paramètres.
  2. Sur la gauche, cliquez sur Paramètres du développeur.
  3. Sur la gauche, cliquez sur Jetons d'accès personnel.
  4. Cliquez sur Générer un nouveau jeton et entrez AWSCodePipeline comme nom.
  5. Pour les autorisations, sélectionnez repo.
  6. Cliquez sur Générer un jeton.
  7. Copiez le jeton quelque part afin que nous puissions l'utiliser plus tard.

Créer notre code à la main

La première chose à prévoir est CodePipeline. Notre pipeline se composera de deux étapes, une étape Source connectée à GitHub et une étape de construction qui déploie notre site Web statique.

Continuons et créons notre CodePipeline via la console AWS:

  1. Accédez à CodePipeline dans la console AWS.
  2. Cliquez sur Créer un pipeline.
  3. Entrez un nom pour votre pipeline.
  4. Sélectionnez GitHub en tant que fournisseur source.
  5. Cliquez sur Connect to GitHub. Cela ouvrira une fenêtre séparée où vous vous connecterez à votre compte GitHub. Une fois connecté, vous devez accorder un accès repo à AWS CodePipeline. C’est le lien de communication entre votre dépôt GitHub et CodePipeline.
  6. Sélectionnez le référentiel que vous souhaitez utiliser dans ce pipeline.
  7. Entrez master ou votre branche par défaut dans l’entrée Branch.
  8. Cliquez sur Suivant.
  9. Pour le fournisseur de construction, nous allons choisir AWS CodeBuild.
  10. Sélectionnez Créer un nouveau projet de construction.
  11. Entrez un nom pour votre projet de construction.
  12. Pour l'image d'environnement, nous utiliserons une image fournie par AWS CodeBuild.
  13. Sélectionnez Ubuntu comme système d'exploitation.
  14. Sélectionnez Node.js en tant que Runtime et nodejs: 6.3.1 en tant que version.
  15. Laissez la spécification de construction comme option buildspec.yml.
  16. Dans la section Rôle de service CodeBuild, nous voulons créer un nouveau rôle de service.
  17. Entrez un nom pour le rôle de service que CodeBuild utilisera.
  18. Laissez le reste des valeurs à leurs paramètres par défaut.
  19. Cliquez sur Enregistrer le projet de construction, puis sur Suivant.
  20. Pour le fournisseur de déploiement, nous voulons pas de déploiement.
  21. Cliquez sur Suivant.

Qui aime cliquer sur les boutons? Pas moi.

C'était beaucoup de bouton en cliquant à droite? Pourriez-vous le refaire sans regarder toutes les 21 étapes? Je sais que je ne pourrais pas.

Bonnes nouvelles! Il existe un moyen bien plus efficace de créer et de gérer vos pipelines de code, ou toute infrastructure AWS. Vous avez peut-être entendu parler du terme infrastructure en tant que code, et c'est à peu près exactement ce que cela semble. Représentez votre infrastructure sous forme de code afin que vous puissiez la créer, la maintenir et la détruire sans même ouvrir une interface graphique.

Il n’ya rien de mal à démarrer avec l’interface graphique si vous êtes nouveau sur AWS, ou n’importe quel nouveau fournisseur de cloud. Mais nous voulons viser l'automatisation à mesure que nous évoluons.

Il existe de nombreux outils qui rendent cela très facile à faire. AWS fournit CloudFormation, qui vous permet de définir vos ressources au sein de modèles JSON ou YAML.

CloudFormation est génial, mais il existe également d'autres outils. Terraform est l'un de ceux que j'utilise le plus récemment. Il est agnostique vis-à-vis des fournisseurs de cloud et prend en charge une variété de fournisseurs via des modules développés par la communauté.

Pour cet article de blog, j'ai créé un modèle Terraform rapide qui fournit notre infrastructure AWS.

Voyons rapidement ce que fait ce modèle.

En haut, nous définissons les variables à transmettre au modèle. Pour provisionner les ressources, nous devons passer ce qui suit:

  • nom de notre pipeline
  • notre nom d'utilisateur GitHub
  • notre jeton GitHub de plus tôt
  • le référentiel GitHub que nous voulons lier à notre pipeline

Ensuite, nous spécifions que nous voulons utiliser AWS en tant que fournisseur avec la région transmise en tant que variable. Comme nous le verrons dans une minute, cela charge un fournisseur de Terraform qui prend en charge la plupart des ressources AWS. Vous pouvez consulter les ressources AWS prises en charge par Terraform ici.

Le prochain ensemble de ressources que nous créons concerne notre AWS CodePipeline.

  • Nous créons un compartiment S3 qui contiendra les artefacts / les sorties de chaque étape de notre pipeline.
  • Nous devons créer une stratégie IAM permettant à CodePipeline d'assumer le rôle que nous avons créé ici dans notre modèle, codepipeline_role. Ce rôle est associé à une stratégie, attach_codepipeline_policy. La stratégie accorde l'accès aux services AWS que nous devons appeler lors d'une invocation de notre pipeline.
  • Nous configurons les ressources nécessaires pour que CodeBuild fonctionne comme prévu. Nous définissons une stratégie de rôle assume qui permet à CodeBuild d'assumer un rôle et d'accéder à des services via codebuild_policy.
  • Nous créons notre projet CodeBuild, build_project, qui exécute l'étape de construction de notre CodePipeline. Remarquez ici que nous spécifions la source comme codepipeline et notre buildspec comme étant buildspec.yml.

Pour provisionner notre CodePipeline, nous affectons le magasin d'artefacts au compartiment S3 que nous avons configuré précédemment. Le rôle est le rôle de codepipeline que nous avons défini précédemment. L'étape Source utilise le fournisseur GitHub et le jeton que nous avons généré sur GitHub. Nous voulons envoyer la sortie de cette étape à une étiquette appelée code via la propriété output_artifacts.

La dernière étape de notre ressource CodePipeline est l'étape de génération. Ici, le fournisseur est CodeBuild et nous avons défini notre input_artifacts comme étant le code output_artifacts de notre étape Source. Ensuite, nous spécifions le nom du projet pour le projet CodeBuild qui sera responsable de l'exécution de l'étape de construction.

Tout ce que nous devons prévoir pour notre pipeline de déploiement continu se trouve dans ce modèle. Si vous souhaitez simplement utiliser AWS, il peut être plus rapide de le configurer manuellement que d'écrire votre premier modèle Terraform. Mais à long terme, définir votre infrastructure en tant que code présente des avantages considérables:

  • Votre définition d'infrastructure réside dans le contrôle de source. Il peut être itéré comme le serait le code.
  • Votre infrastructure est maintenant reproductible. Si vous devez le déplacer vers une autre région AWS, vous pouvez exécuter le modèle dans cette région.
  • Vous pouvez rapidement apporter des modifications en modifiant le modèle et en appliquant des mises à jour.

Maintenant que nous savons ce que fait ce modèle et que Terraform est installé, nous pouvons exécuter ce modèle à partir de la ligne de commande.

Tout d'abord, nous exécutons terraform init à partir du répertoire où réside notre modèle. Cela introduit les dépendances dont Terraform a besoin pour exécuter le modèle.

Une fois que notre modèle Terraform a été initialisé, nous pouvons utiliser la commande «plan» afin de voir exactement ce qui va être créé.

Remarquez tout en vert? Ce sont les ressources qui seront créées. S'il y avait des ressources en jaune, ce seraient des ressources qui allaient être mises à jour. Ensuite, s'il y avait des ressources en rouge, elles seraient supprimées.

Vous pouvez ensuite exécuter la commande apply pour tout créer dans le modèle. Il y a une invite de confirmation, tapez simplement oui.

Une fois le modèle terminé, nous devrions voir que toutes nos ressources AWS ont été créées pour prendre en charge notre pipeline de déploiement continu.

Attend, qu'est-ce qu'on vient de faire?

Cela fait beaucoup d'étapes et d'infrastructure que nous avons mise en place dans AWS. Voyons donc à un niveau élevé ce que nous venons de créer.

Au sommet de notre pipeline, nous avons la source, dans notre cas, il s'agit de notre référentiel GitHub. Nous avons configuré notre pipeline pour interroger périodiquement la branche principale de notre référentiel. S'il y a de nouveaux commits dans la branche principale, le pipeline s'active pour lancer un nouveau processus de construction. C'est ce que l'on appelle souvent un déclencheur pour notre pipeline de construction.

Quand une nouvelle génération commence, notre pipeline extrait les derniers commits de la branche principale. Une fois les modifications extraites, elles sont transmises à l'étape suivante de notre pipeline, l'étape de génération. Pour cette étape, nous utilisons un autre service AWS, CodeBuild. Nous avons configuré notre projet CodeBuild pour utiliser une image Node.js fournie par Amazon. Cette image est livrée avec Node.js déjà installé pour que la machine de construction qui construit notre référentiel y ait accès.

Mais comment AWS CodeBuild sait-il comment construire notre référentiel? C'est là que buildspec.yml entre en jeu. Il s'agit d'un fichier spécial que nous allons placer à la racine de notre référentiel. Nous y configurons différentes phases du processus de construction, telles que pré_install, construction et post_build. Pour notre cas d'utilisation, nous allons juste configurer le processus de construction dans le fichier buildspec. Cela consistera à copier le contenu de notre source vers le compartiment de notre site Web S3, en déployant efficacement notre site Web statique.

Passons au référentiel statique de notre site Web et configurons notre fichier buildspec.

Configurer notre fichier buildspec

Nous allons commencer par ajouter un fichier buildspec.yml à la racine de notre site Web statique.

Ce fichier sera le modèle utilisé par AWS CodeBuild pour créer et, dans notre cas, déployer notre site Web statique. Il comprend les étapes de pré-installation, d'installation, de construction et de post-construction. Pour notre cas d'utilisation, nous allons tirer parti de l'étape de construction.

Ce que nous faisons dans la spécification de construction ci-dessus est assez simple, il ne s'agit en fait que d'une ligne. Nous prenons le contenu de notre site Web statique et le copions dans le compartiment S3 qui héberge notre site via l'interface de ligne de commande AWS. Pour les autres étapes, nous indiquons quelle étape a été effectuée dans notre processus de construction.

Bien sûr, nous pourrions faire encore plus ici si nous en avions besoin. Par exemple, si nous avions besoin d'exécuter un processus de construction dans notre package.json, les étapes de construction et post_build ressemblent à ceci:

Nous exécutons maintenant npm build à l’intérieur de notre étape de construction et enregistrons la commande s3 sync pour notre étape de post-construction. Notre buildspec nous donne la possibilité de script non seulement les déploiements de notre site, mais également la façon dont ils sont construits et testés. Nous pourrions également utiliser les autres étapes, telles que l’installation, pour ajouter toutes les dépendances dont notre processus de construction a besoin.

Pour l’instant, restons fidèles à notre fichier buildspec original, qui copie notre site statique sur S3. Assurez-vous qu'il se trouve à la racine de votre référentiel, car c'est ici que CodeBuild le recherchera. Vérifiez-le dans votre référentiel afin que nous puissions déclencher notre CodePipeline.

Déclencher notre CodePipeline

Auparavant, nous avions lié l'étape Source de notre CodePipeline au référentiel GitHub de notre site Web statique. Il est configuré pour surveiller les changements dans notre branche principale. Ainsi, toute nouvelle modification transmise à cette branche déclenche une nouvelle exécution de CodePipeline. Comme nous venons de vérifier notre fichier buildspec.yml, nous devrions maintenant voir un appel de notre CodePipeline en cours d'exécution.

Nous voyons ici que notre étape Source a été invoquée en raison des nouvelles modifications apportées à la branche principale de notre référentiel. Cette terminé et envoyé ses artefacts à l'étape de construction. L'étape de génération a pris ces artefacts et a exécuté le fichier buildspec.yml pour les déployer dans notre compartiment S3.

Si nous devions cliquer sur le lien de détails de notre étape DeployToS3, nous pouvons voir les journaux que notre processus de génération est en train de générer.

Une fois que notre étape DeployToS3 a réussi, nous devrions pouvoir recharger notre site Web statique dans le navigateur et voir nos modifications.

Bam! Nous avons un déploiement continu

En canalisant mon Emeril intérieur ici, nous avons maintenant un déploiement continu pour notre site Web statique. À chaque nouvel engagement dans notre branche principale, une nouvelle exécution de CodePipeline est déclenchée. Ceci vérifie le dernier code de GitHub et le passe à CodeBuild. Notre projet de construction exécute ensuite ce qui est dans notre fichier buildspec.

Actuellement, notre fichier buildspec ne fait que copier le contenu de notre site Web statique dans notre compartiment S3. Mais nous pourrions étendre cela à faire plus de choses. Nous pourrions exécuter des tâches npm pour construire notre site ou exécuter des tests. Si nous utilisons également CloudFront devant notre site Web statique, nous pouvons émettre une demande d'invalidation lorsque nous déployons notre nouveau site.

Il y a tellement de choses que vous pouvez apprendre en plongeant et en utilisant réellement AWS. Un site Web statique peut sembler un cas d'utilisation simple, mais il est génial pour apprendre une grande variété de choses.

Envie d'en savoir plus sur Amazon Web Services?

J'utilise AWS depuis plus de six ans et j'apprends toujours de nouveaux services et de nouvelles manières d'utiliser les services existants. C'est une plate-forme massive avec beaucoup de documentation. Mais il arrive parfois que cette documentation donne l’impression d’une immense masse d’informations. Au point où vous vous y perdez.

Inspiré par ce problème, j'ai récemment publié un ebook et un cours vidéo qui traversent une foule d'informations. Il se concentre sur l'hébergement, la sécurisation et le déploiement de sites Web statiques sur AWS. L'objectif est d'apprendre les services liés à ce problème au fur et à mesure que vous les utilisez. Si vous vouliez apprendre à utiliser AWS mais que vous ne savez pas par où commencer, consultez mon cours.

Si cela vous a plu, n’oubliez pas d’offrir des applaudissements pour montrer votre soutien!