Thomas Derflinger Blog

Utilisation d'Ansible pour installer NodeJS

Cow like in Ansible book

Dans la première partie de la série DevOps, j’ai montré comment créer automatiquement une instance AWS EC2 Spot avec Terraform. Vous pouvez le relire ici: https://www.tderflinger.com/fr/ec2-spot-avec-terraform

Les compétences de DevOps deviennent de plus en plus importantes pour les développeurs de NodeJS. Avec Ansible, vous pouvez configurer automatiquement vos serveurs cloud. Maintenant je vous explique comment configurer automatiquement le serveur CentOS créé avec NodeJS et Nginx. Pour ce j’utilise l’outil open source Ansible. Ansible est un outil de configuration et de déploiement logiciel. Il a été écrit à l’origine par Michael DeHaan en 2012. L’entreprise à l’origine d’Ansible a été acquise en 2015 par Red Hat, aujourd’hui une division d’IBM.

Ansible vous permet d’automatiser l’installation des logiciels. Il s’agit donc d’un élément important dans le Infrastructure as Code (IaC). Avec Ansible, vous pouvez vous assurer que les bons paquets sont installés, que les bons fichiers de configuration sont à la bonne place et que les bons services fonctionnent. Vous pouvez également déployer votre logiciel écrit sur le serveur avec Ansible. De plus, Ansible permet de provisionner un nouveau serveur, mais j’ai utilisé Terraform pour cette tâche comme vous pouvez le lire dans l’article précédent.

Ansible est un bon outil pour les environnements de cloud computing de type IaaS (Infrastructure as a Service). Cela inclut les serveurs AWS EC2 ou les droplets de Digital Ocean. Sur ce type de serveurs de calcul vous devez configurer vous-même le logiciel nécessaire. Cela contraste avec les offres PaaS, où tout est géré, vous téléchargez uniquement le code source de votre application. Heroku est un exemple d’offre PaaS.

Lorsque vous utilisez Ansible, vous ferez la plupart de votre travail dans des fichiers de configuration appelés playbooks. Ce sont des fichiers yml qui sont DSL (Domain Specific Languages) et décrivent les fonctions à configurer.

L’avantage d’Ansible est que vous n’avez pas besoin d’installer plus sur le serveur cible. Tout fonctionne avec le port 22, via SSH. Seul Python 2 ou 3 doit être disponible sur la machine cible. Ceci distingue Ansible des outils comme Chef ou Puppet où vous devez installer un agent.

Serveur Mock

Pour cet exemple, je veux installer automatiquement un serveur mock NodeJS à des fins de test. Pour cela j’utilise le module NPM json-server et j’ajoute un peu de code maquette. Fondamentalement, le serveur mock est un serveur REST avec des données fantaisie.

json-server-http.js

var fs = require('fs'),
  jsonServer = require('json-server'),
  server = jsonServer.create(),
  router = jsonServer.router('db.json'),
  middlewares = jsonServer.defaults()
const cors = require('cors')
const bodyParser = require('body-parser')

server.use(cors())
server.use(bodyParser.json())

server.use(middlewares)
server.use(router)

server.listen(3002, function() {
  console.log('json-server started on port ' + 3002)
})

Il charge certaines données à partir d’un fichier JSON et renvoie les données via le terminal REST.

L’une des conditions requises pour ce serveur mock est qu’il soit disponible via HTTPS. Ainsi, j’utilise le serveur Nginx comme proxy avec une connexion TLS. Les fichiers de certificats et de clés nécessaires peuvent être générés hors ligne avec cet Ansible Playbook.

Générer un certificat TLS

Vous devez d’abord installer Ansible sur votre ordinateur.

Le playbook Ansible suivant génère sur votre ordinateur local le certificat auto-signé et les fichiers de clés privées. Ces fichiers sont plus tard téléchargé dans les répertoires Nginx.

generate_certificate.yml

--
- name: Generate Nginx TLS certificates and keys
  hosts: localhost

  tasks:
    - name: Generate OpenSSL private key
      openssl_privatekey: path=files/nginx.key

    - name: Generate OpenSSL Certificate Signing Request
      openssl_csr: path=files/csr.csr  privatekey_path=files/nginx.key common_name=www.someorg.org

    - name: Generate Self-signed certificate
      openssl_certificate: path=files/nginx.crt privatekey_path=files/nginx.key csr_path=files/csr.csr provider=selfsigned

Vous pouvez exécuter ce playbook avec la commande suivante:

ansible-playbook generate_certificate.yml

Installer NodeJS et Nginx

Le travail de configuration proprement dit s’effectue avec l’installation du logiciel requis. Premièrement, NodeJS est nécessaire dans la version 10.16. Une bonne façon d’installer NodeJS sur un serveur Linux est d’utiliser le Node Version Manager (NVM). Sur GitHub il y a un playbook Ansible prêt à l’emploi pour installer NVM. Nous l’utilisons ici et l’invoquons simplement dans notre script.

Ensuite, Nginx doit être installé. Le livre de jeu ressemble à ceci :

install_nodenginx.yml

---
- name: Install curl and wget
  gather_facts: 'no'
  hosts: mock
  become: yes
  remote_user: root

  tasks:
    - name: Install curl
      yum:
        name: curl
        state: present

    - name: Install wget
      yum:
        name: wget
        state: present

- name: Create nvm
  gather_facts: 'no'
  hosts: mock
  become: yes
  remote_user: root

  roles:
    - role: ansible-role-nvm
      nodejs_version: '10.16.0'

## Credits to John Lieske - https://www.ansible.com/blog/getting-started-writing-your-first-playbook
- name: Install Nginx
  hosts: mock
  become: yes
  remote_user: root

  tasks:
    - name: Add epel-release repo
      yum:
        name: epel-release
        state: present

    - name: Install Nginx
      yum:
        name: nginx
        state: present

    - name: Start NGiNX
      service:
        name: nginx
        state: started

Avant d’exécuter ce playbook, vous devez également spécifier votre fichier hosts.

Il peut ressembler à ceci, mais vous devez mettre à jour l’adresse IP avec l’adresse IP du serveur sur lequel vous souhaitez installer.

hosts

[default]
mock ansible_host=100.24.146.164

Lancez ensuite le script du playbook avec :

ansible-playbook install_node_nginx.yml -i hosts

Les playbooks sont idempotents. Cela signifie que peu importe la fréquence à laquelle vous courez, le résultat est toujours le même. Vous spécifiez le résultat, comme si un fichier devait être absent. Ansible trouve alors le moyen d’y parvenir.

Installer l’application mock

Les étapes suivantes consistent à copier les fichiers JavaScript mock et les fichiers de certificats pour Nginx. Pour exécuter l’application mock NodeJS, nous utilisons le gestionnaire de processus PM2.

run_mock.yml

---
- name: Start mock and some other stuff
  hosts: mock
  become: true
  remote_user: root

  vars:
    key_file: /etc/nginx/ssl/nginx.key
    cert_file: /etc/nginx/ssl/nginx.crt
    conf_file: /etc/nginx/nginx.conf

  tasks:
    - name: Copy files
      copy: src=../../db.json dest=/home/centos

    - name: Copy package.json
      copy: src=../../package.json dest=/home/centos

    - name: Copy json-server-https
      copy: src=../../json-server-http.js dest=/home/centos

    - name: NPM installation
      shell: npm i
      args:
        chdir: /home/centos

    - name: Install PM2
      npm:
        name: pm2
        global: yes

    - name: Create directories for certificates
      file: path=/etc/nginx/ssl state=directory

    - name: Copy TLS key
      copy: src=files/nginx.key dest={{ key_file }} owner=root mode=0600

    - name: Copy TLS certificate
      copy: src=files/nginx.crt dest={{ cert_file }} owner=root mode=0600

    - name: Copy Nginx config file
      template: src=templates/nginx.conf.j2 dest={{ conf_file }}

    - name: Remove nginx.default
      file:
        path: /etc/nginx/nginx.conf.default
        state: absent

    - name: Restart Nginx
      service:
        name: nginx
        state: restarted

    - name: Start Mock
      shell: pm2 start json-server-http.js
      args:
        chdir: /home/centos

Dans ce playbook vous pouvez voir la définition des variables. Elles sont appliquées avec l’interpolation de deux accolades bouclées {{ var }}. De plus, un modèle est utilisé pour la génération du fichier de configuration Nginx. Les modèles d’Ansible sont compatibles avec Jinja2, un Python moteur de modèle.

Quand tout est démarré et que vous pouvez aller dans votre navigateur vers l’IP de votre serveur à l’aide de https. Le navigateur affichera un avertissement d’apparence dangereuse parce que le certificat est auto-signé. Vous devez accepter le certificat et ensuite vous verrez l`application Mock.

Une chose à noter est que ces scripts Ansible ne fonctionnent que sur les machines Linux CentOS. Ansible n’abstrait pas entre les distributions Linux. Ainsi, si vous souhaitez configurer et déployer sur Ubuntu, vous devrez adapter les scripts.

Conclusion

Si vous avez de l’expérience avec l’administration système Linux, comprendre un playbook Ansible ne devrait pas être trop difficile. Avec Infrastructure as Code, il est devenu obligatoire d’automatiser ces tâches d’administration système. De plus, lorsque vous avez besoin de configurer plusieurs serveurs, des outils comme Ansible sont une nécessité évidente. Ainsi, les compétences d’Ansible sont précieuses pour les développeurs de NodeJS dans le contexte de DevOps.

Sources et lectures complémentaires

  • Infrastructure as Code: Managing Servers in the Cloud, 2016, Kief Morris, O’Reilly Media
  • Ansible: Up and Running, 2nd edition, 2017, Rene Moser and Lorin Hochstein, O’Reilly Media
  • Code source de cet article: https://github.com/tderflinger/ansible-node-mock
Publié le 17 juillet 2019

Thomas Derflinger

Thomas Derflinger

Je suis entrepreneur indépendant et développeur de logiciels.

DevOps est un sujet que j'aime beaucoup. Prenons contact!