Deployer une application Javascript sur Aws Ec2 à l'aide de gitlab runner CI/CD

Voici un petit tutoriel pour expliquer comment déployer rapidement une application sur une instance Linux dans un processus d'intégration continue grâce à Gitlab Runner.

Deployer une application Javascript sur Aws Ec2 à l'aide de gitlab runner CI/CD

1. Création de l’application

Pour notre exemple, nous allons créer utiliser une application Node.js simple renvoyant un texte.

Créer un serveur node

Notre application écoutera le port 3000 et renverra un \“Welcome to my EC2\“.

Créer un fichier server.js

const http = require('http')
const hostname = '0.0.0.0'
const port = 3000
const server = http.createServer((req, res) => {
  res.statusCode = 200
  res.setHeader('Content-Type', 'text/plain')
  res.end('Welcome to my EC2')
})
server.listen(port, hostname, () => {
  console.log('Server running at http://%s:%s/', hostname, port)
})
process.on('SIGINT', function () {
  console.log('Caught interrupt signal and will exit')
  process.exit()
})

2. Configuration d’une instance EC2

Lancement de l’instance sur AWS

Considérons pour la suite que vous avez déjà un compte AWS afin de configurer notre instance EC2 (à noter qu’AWS offre 1 an gratuit sur un grand nombre de service, notamment EC2 qui nous intéresse ici).Une fois arrivé sur le dashboard de votre espace Aws, sélectionnez le service EC2, puis cliquez sur Lancer une instance.

Il vous faudra ensuite choisir le type d’instance que vous souhaitez, pour notre exemple nous choisirons une instance Unbuntu, car c’est la distribution Linux la plus répandue et la plus simple à prendre en main.Vous pouvez désormais lancer votre application en cliquant sur Lancer.

Si vous n’avez pas encore créé de clés de sécurité, créez-en une dès maintenant, nous en aurons besoin pour la suite.Afin de faciliter la configuration, copiez votre clé publique dans le répertoire de votre application et ajoutez le nom de votre clé dans votre fichier .gitingnore afin de ne pas l’ajouter au commit.Avant d’aller plus loin, nous allons configurer les groupes de sécurité dont nous aurons besoin pour accéder à notre application web.

Notre application utilisera le port 3000, nous allons donc ouvrir le port 3000 à l’ensemble du traffic.Pour cela, allez dans l’onglet Groupe de sécurité du menu de gauche, puis cliquez sur Modifier les règles entrantes et ajoutez le port 3000 comme suit :

Groupe

Nous allons pouvoir nous connecter à notre instance à l’aide notre terminal.Pour cela, depuis la liste de vos instances EC2, sélectionnez votre instance, puis cliquez sur Se connecter pour récupérer le script de connexion SSH, en l’adaptant si nécessaire et rentrez la commande dans votre terminal.

ec2

Si tout se passe bien, vous devriez être connecté à votre instance distante et avoir dans votre terminal un message semblable à celui ci-dessous, Magique non ? :)

terminal

Configuration de l’instance

Comme si vous souhaitiez lancer une application depuis votre machine personnelle, vous allez d’abord devoir configurer votre instance afin de pouvoir exécuter des scripts.

Installer Node.js à l’aide de NVM

  curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
  . ~/.nvm/nvm.sh
  nvm install node
  node -v

Installer Docker

Ajouter la clé GPG de Docker
  curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
Ajouter la clé GPG de Docker
  sudo add-apt-repository \   \"deb [arch=amd64] https://download.docker.com/linux/ubuntu \   $(lsb_release -cs) \   stable\"
Puis installer Docker Engine
  sudo apt-get install docker-ce docker-ce-cli containerd.io

Notre instance Linux est dorénavant prête pour installer et packager notre application puis la lancer via une image Docker.

3. Configuration de Gitlab-Runner


Nous allons utiliser Gitlab-Runner afin que le pipeline de déploiement se lance sur notre instance Linux plutôt que sur les serveurs de Gitlab, ainsi nous serons en mesure de lancer notre image Docker et de l’exposer sur le port 3000.

Installation de Gitlab-Runner sur notre instance

Dans votre terminal
  curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash
  sudo apt-get install gitlab-runner

Puis nous allons maintenant enregistrer notre serveur comme runner spécifique.Pour cela, allez sur votre projet gitlab (créez le si ce n’est pas fait), puis dans: settings > CI/CD > expand Runners section > Set up a specific Runner manually

Register

Connectez votre server à Gitlab
  sudo gitlab-runner register

Renseigner l’Url du coordinateur, ainsi que le token de votre Runner.Saisissez le(s) tag(s) de votre choix que nous utiliserons dans l’étape suivante pour déclencher notre pipeline sur notre serveur, je vais utiliser le tag production pour ma part.Puis sélectionner shell comme executor

Donnez ensuite les droits à gitlab-runner d’exécuter les scripts sur la machine
  sudo nano /etc/sudoers
Ajoutez la ligne suivante en bas de fichier
gitlab-runner ALL=(ALL) NOPASSWD: ALL

4. Configuration du pipeline

Les pipelines dans Gitlab se configurent à l’aide du fichier .gitlab-ci.yml, à chaque push, Gitlab détectera le contenu de ce fichier et déclenchera les pipelines associés.

Créez un fichier .gitlab-ci.yml
default:
  image: node:6.9.2
  only:
    - production
  tags:
    - production
  script:
    - sudo docker stop $(sudo docker ps -a -q)
    - sudo docker build -t node-app:v1 .
    - sudo docker run -d -p 3000:3000 node-app:v1

Ce fichier sert à exécuter des scripts dans les pipelines de Gitlab, vous remarquerez que pour ce stage la valeur ‘production’ a été renseignée comme tags, il vous faudra la remplacer par celle que vous avez choisie en configurant votre Runner. Ainsi Gitlab lancera ce script sur votre Runner à chaque fois que ce tag sera renseigné.

La deuxième partie importante concerne les scripts qui pour résumer stop les instances en route puis build l’application pour la lancer via une image Docker.

5. Configuration de Docker

Afin de faciliter la mise en route et la scalabilité de notre application, nous allons la conteneuriser à l’aide de Docker.

Dockerfile
  FROM node:6.9.2
  EXPOSE 3000
  COPY server.js .
  CMD node server.js

6. Déploiement

Il nous reste plus qu’a pusher cela sur notre branche production et s’assurer que tout fonctionne

Pipeline

Maintenant voyons si c’est bien déployé, pour cela rendez-vous sur l’adresse IPv4 ou sur le DNC public de votre instance, en oubliant pas de pointer sur le port 3000 :

Final

Ça marche aussi ! Notre application est déployée !

Vous avez bien compris la méthode, vous pouvez maintenant imaginer avoir plusieurs environnements (stagging, uat, develop …) et jouer avec les tags pour assurer la qualité de vos releases.

À vous de jouer !