morgangraphics.ansible-role-nvm

Rôle Ansible : NVM

Installe NVM et Node.js sur les systèmes Debian/Ubuntu, RHEL/CentOS et d'autres systèmes *nix.

Les particularités d'Ansible avec SSH et les shells (non) interactifs rendent l'utilisation de NVM avec Ansible un peu problématique. Ce post sur Stack Overflow explique certaines des solutions trouvées par d'autres utilisateurs pour contourner ce problème spécifique.

Où d'autres rôles manquent

D'autres rôles Ansible qui installent NVM et/ou Node.js présentent certaines lacunes.

  1. Ils utilisent les gestionnaires de paquets apt-get ou yum pour installer Node.js. Cela signifie souvent que le paquet Node.js est plus ancien que ce qui est actuellement disponible via le dépôt Node.js. Dans certains cas, ces paquets peuvent ne pas être une version LTS et si vous avez besoin de plusieurs versions de Node.js sur le même hôte, cela peut poser problème.

  2. Ils installent souvent NVM et Node.js en tant qu'utilisateur root (sudo su ou become: true). Cela peut compliquer la gestion des permissions liées à la gestion des plugins NPM et comment Node fonctionne avec nvm, en plus de poser un risque de sécurité d'escalade de privilèges non nécessaire.

  3. Vous ne pouvez pas exécuter des commandes ad hoc nvm, npm, node, bash ou shell.

En quoi ce rôle est différent des autres rôles

  1. Vous pouvez installer NVM via wget, curl ou git.
  2. Vous pouvez utiliser NVM comme vous le feriez via votre ligne de commande dans vos propres tâches et playbooks Ansible.
  3. Vous pouvez installer la version ou les versions de Node.js que vous souhaitez.
  4. N'installe pas NVM ou Node.js en tant que root.
  5. Peut exécuter des commandes nvm, npm, node, bash ou shell arbitraires, éliminant potentiellement le besoin d'un rôle Ansible Node distinct.

Exigences

Version Ansible (ansible-core) 2.16.0+

:triangular_flag_on_post: Pour une version de ce rôle qui fonctionne sur des versions plus anciennes d'Ansible, consultez la branche légacy 1.5.X.

Voir Versions d'Ansible ci-dessous.

Installation

  1. Clonez ce dépôt dans votre dossier de rôles.
  2. Pointez la variable roles_path vers le dossier des rôles, par exemple roles_path = ../ansible-roles/ dans votre fichier ansible.cfg.
  3. Incluez le rôle dans votre playbook.

:warning: AVERTISSEMENT !

NE PAS EXÉCUTER CE RÔLE EN TANT QUE ROOT ! (par exemple become: true|yes|1).

Voici quelques raisons à cela :

  1. C'est un risque de sécurité d'escalade de privilèges non nécessaire. Il est peu probable que vous ayez besoin d'exécuter chaque tâche dans chaque rôle en tant qu'utilisateur root_user. Si, pour une raison quelconque, vous devez exécuter tout en tant qu'utilisateur root_user, réfléchissez à ce que fait le rôle et pourquoi il a besoin d'un accès root pour tout.

  2. Ce rôle installe nvm dans le même contexte/shell/session que vous exécuteriez NodeJS. Vous n'exécutez pas NodeJS en tant que root.

  3. Ansible changera le contexte du shell de connexion en root et nvm sera installé dans le répertoire personnel de l'utilisateur root, par exemple /root/.bashrc. Cela signifie que si votre utilisateur principal est vagrant, ec2-user, ubuntu, etc., le rôle NE FONCTIONNERA PAS COMME PRÉVU !

MAUVAIS :thumbsdown:

- hosts: all
  become: true           # CECI EXÉCUTE TOUTES LES TÂCHES, POUR TOUS LES HÔTES, EN TANT QUE ROOT_USER
  become_method: sudo    # CECI EXÉCUTE TOUTES LES TÂCHES, POUR TOUS LES HÔTES, EN TANT QUE ROOT_USER

  roles:
    - role: ansible-role-nvm
      nodejs_version: "8.16.0"
      nvm_commands:
       - "nvm exec default npm install"

    - role: some-other-role
      ...

MEILLEUR :thumbsup:

- hosts: all

  roles:
    - role: ansible-role-nvm
      nodejs_version: "8.16.0"
      nvm_commands:
       - "nvm exec default npm install"

    - role: some-other-role
      ...
      become: true            # CECI CIBLE TOUTES LES TÂCHES, UNIQUEMENT POUR LE SOME-OTHER-ROLE, EN TANT QUE ROOT_USER
      become_method: sudo     # CECI CIBLE TOUTES LES TÂCHES, UNIQUEMENT POUR LE SOME-OTHER-ROLE, EN TANT QUE ROOT_USER

MEILLEUR :metal:

- hosts: all

  roles:
    - role: ansible-role-nvm
      nodejs_version: "8.16.0"
      nvm_commands:
       - "nvm exec default npm install"
      become: true            # CECI CHANGERA LE CONTEXTE DE CONNEXION POUR UTILISER L'UTILISATEUR CI-DESSOUS
      become_user: ec2-user   # CECI INSTALLE NVM DANS LE CONTEXTE DE L'UTILISATEUR EC2/UTILISATEUR PAR DÉFAUT. CET UTILISATEUR DOIT EXISTE SUR LE SYSTÈME !

    - role: some-other-role
      ...
      become: true            # CECI CIBLE TOUTES LES TÂCHES, UNIQUEMENT POUR LE SOME-OTHER-ROLE, EN TANT QUE ROOT_USER
      become_method: sudo     # CECI CIBLE TOUTES LES TÂCHES, UNIQUEMENT POUR LE SOME-OTHER-ROLE, EN TANT QUE ROOT_USER

Voir Problèmes ci-dessous pour plus de détails.

Exemples de Playbooks

Super Simple

Incluez le rôle tel quel et il installera la dernière version LTS de Node.js.

- hosts: all

  roles:
    - role: ansible-role-nvm

Simple

Incluez le rôle et spécifiez la version spécifique de Node.js que vous souhaitez installer.

- hosts: all

  roles:
    - role: ansible-role-nvm
      nodejs_version: "8.15.0"

Plus Complexe

Cet exemple montre comment configurer plusieurs environnements (Dev/Prod) avec différentes options. La configuration Prod tire parti de l'option nvm_commands pour installer, construire et exécuter l'application. Le rôle prend en charge et utilise la syntaxe de variable Ansible, par exemple {{ variable_name }}.

- hosts: dev

  vars_files:
    - vars/dev.yml

  roles:
    - role: ansible-role-nvm
      nodejs_version: "{{ config.dev.nodejs.version }}"


- hosts: prod
  vars_files:
    - vars/prod.yml

  roles:
    - role: ansible-role-nvm
      nvm_install: "curl"
      nvm_dir: "/usr/local/nvm"
      nvm_commands:
       - "nvm install {{ config.prod.client-1.nodejs.version }}"
       - "nvm alias default {{ config.prod.client-1.nodejs.version }}"
       - "nvm exec default npm install"
       - "nvm exec default npm run prod"

Installation/Exécution/Maintien ou Mise à Jour de plusieurs versions de Node.js sur le même hôte

Par défaut, la première version de Node.js instanciée dans votre Playbook sera automatiquement aliasée comme la version "par défaut", quelle que soit la version que vous installez par la suite ou combien de fois vous exécutez le rôle. Il est important de déclarer quelle version est censée être la version "par défaut" si vous installez plusieurs versions de Node.js sur une seule machine.

Il existe deux alias NVM préexistants default (version "active" actuelle de Node.js) et system (version de base de Node.js dans le système d'exploitation).

L'aliasage est une fonctionnalité très puissante de NVM, et c'est une meilleure pratique recommandée pour gérer votre environnement.

Installation Multiple

- hosts: host-1

  roles:
    # Services
    - role: ansible-role-nvm
      nodejs_version: "8.15.0"    # <= Cela sera la version "par défaut" de Node.js

    # Application
    - role: ansible-role-nvm
      nodejs_version: "10.15.0"

Installation Multiple avec défaut

- hosts: host-2

  roles:
    # Services
    - role: ansible-role-nvm
      nodejs_version: "8.15.0"    

    # Application
    - role: ansible-role-nvm
      default: true
      nodejs_version: "10.15.0" # <= Ceci est maintenant la version "par défaut" de Node.js

Remarques sur les commandes NVM

Les commandes NVM sont une fonctionnalité très puissante de ce rôle qui tirent parti des bases mises en place par NVM. L'utilisation de nvm_commands peut potentiellement éliminer le besoin d'un rôle Node spécifique pour gérer vos applications Node.

Il existe une différence entre les commandes nvm run et nvm exec. La commande nvm run est fonctionnellement équivalente à node server.js ou node server où vous invoquez un fichier JavaScript.

nvm exec s'exécute dans un contexte de sous-processus et est fonctionnellement équivalent à npm run serverserver est un nom clé dans la section scripts du fichier package.json.

{
  "name": "my_application",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "preserver": "npm run dbService &",
    "server": "nodemon ./bin/www",
    "build": "node build/build.js",
    "dbService": "nodemon ./data-service/server.js --ignore node_modules/"
  },
  "dependencies": {
    "..."
  }
}

OU

nvm exec peut exécuter un fichier script arbitraire. Par exemple, nvm exec hello-world.py.

Exemple de hello-world.py :

#!/usr/bin/env python
print('hello-world')

:warning: Vous devez inclure un en-tête de script pour que cela fonctionne correctement.

OU

exécuter une commande bash arbitraire :

ls -al >> output.txt

Les nvm_commands facilitent la mise en place d'une application Node et d'une couche d'API Node fonctionnant sur différentes versions de Node.js sur le même hôte.

- hosts: host-1
  roles:
    # Services
    # QUE SE PASSE-T-IL ?
    # 1. Exécute le fichier JavaScript des services avec la version de Node 8.15.0
    # AVERTISSEMENT : Ceci est aliasé comme la version par défaut de Node.js à ce moment-là !
    # Par conséquent, nous devons spécifier explicitement la version que nous utilisons, car
    # la version par défaut de Node.js change dans la section Application ci-dessous.
    - role: ansible-role-nvm
      nodejs_version: "8.15.0"
      nvm_commands:
        - "nvm exec 8.15.0 npm run services"

    # Application
    # QUE SE PASSE-T-IL ?
    # 1. Définit la version par défaut de Node.js à la version 10.15.0.
    # 2. Installe les dépendances de paquet avec npm.
    # 3. Définit l'environnement sur Production, exécute le fichier JavaScript de construction.
    # 4. Puis exécute le script de déploiement à la production.
    - role: ansible-role-nvm
      nodejs_version: "10.15.0"
      nvm_commands:
       - "nvm alias webapp {{ nodejs_version }}" # <= Change la version par défaut de NVM (supporte la syntaxe des variables Ansible)
       - "nvm exec webapp npm install" # installe les dépendances de l'application
       - "NODE_ENV=production nvm run webapp build" # invoque Node.js directement pour exécuter le script de construction de production
       - "nvm exec webapp npm run prod" # invoque npm pour exécuter le script de production dans votre fichier package.json

Un autre exemple :

- hosts: host-2
  roles:
    # Services
    # QUE SE PASSE-T-IL ?
    # 1. Crée un alias pour la version 8.15.0 intitulée service-default (supporte la syntaxe des variables Ansible)
    # 2. Exécute le script des services.
    #
    # ** Il est recommandé d'aliaser vos versions de Node.js et de les référencer en conséquence **
    - role: ansible-role-nvm
      nodejs_version: "8.15.0"
      nvm_commands:
        - "nvm alias service-default {{ nodejs_version }}" # <= (supporte la syntaxe des variables Ansible)
        - "nvm exec service-default npm run services" # exécute le script des services dans votre fichier package.json

    # Application - Pas besoin d'un rôle Ansible Node séparé
    # QUE SE PASSE-T-IL ?
    # 1. Installe la version 10.15.0 de Node.js.
    # 1. Définit la version par défaut de Node.js à la version 10.15.0.
    # 2. Exécute le fichier test.js en invoquant Node.js directement.
    # 3. Puis exécute le script de déploiement à la production.
    - role: ansible-role-nvm
      nodejs_version: "10.15.0"
      nvm_commands:
       - "nvm alias default 10.15.0" # <= Change la version par défaut de NVM
       - "nvm exec default node test.js" # invoque Node.js directement pour exécuter le script de test
       - "nvm exec ./deploy.sh" # exécute un script bash arbitraire

Quels que soient les arguments de ligne de commande que vous utilisez pour démarrer votre application ou les scripts de commande que vous avez déclarés dans votre fichier package.json, vous pouvez les placer dans la section nvm_commands: [] de ce rôle.

- hosts: host1

  pre_tasks:
    # l'utilisateur test doit être un véritable utilisateur sur le système avant que nous puissions installer nvm dans son profil.
    - name: ajouter un nouvel utilisateur
      user:
        name: "test-user"
      become: true

  roles:
    - role: ansible-role-nvm
      nodejs_version: "8.16.0"
      nvm_profile: "/home/test-user/.bashrc"
      nvm_commands:
        - "whoami"
        - "node --version"
        - "nvm --version"
        - "npm --version"
        - "python3 -m hello"
      become_user: test-user
      become: true

Caveats

  1. Par défaut, la première version répertoriée dans votre Playbook, lors de la première exécution, sera automatiquement aliasée comme la version "par défaut" de Node.js, quelle que soit la version que vous installez par la suite ou le nombre de fois que vous exécutez le rôle. Le premier qui arrive/est installé est toujours le par défaut. Par conséquent, si vous prévoyez qu'une version de Node.js déclarée plus tard dans le playbook soit définie par défaut, utilisez default: true ou définissez-la explicitement dans la liste nvm_commands, comme - "nvm alias default <YOUR_VERSION>".

  2. Si vous avez default: true explicitement déclaré comme variable de rôle ET - "nvm alias default <SOME_OTHER_VERSION>" comme partie de vos nvm_commands, la version avec default: true sera TOUJOURS exécutée en premier. Cela est dû à la nécessité de rendre Node.js disponible avant de faire quoi que ce soit d'autre.

  3. NVM est sans état, c'est-à-dire que si vous avez plusieurs versions de Node.js installées sur une machine, vous devrez peut-être exécuter nvm use <VERSION> dans le cadre de votre script pour exécuter la version de Node.js que vous voulez ou attendez. Cependant, il est très recommandé d'aliaser vos versions en conséquence et de les référencer de cette manière. Voir les exemples ci-dessus.

Problèmes

"nvm: commande introuvable" erreur

C'est souvent le résultat d'une exécution du rôle dans un autre contexte utilisateur que celui dans lequel nvm et node s'exécuteront à l'intérieur de la machine. Si vous ajoutez become: true à tous les rôles de votre playbook pour contourner les erreurs que ces rôles génèrent à cause de problèmes de permissions, alors ce rôle installera nvm sous l'utilisateur ROOT_USER (généralement /root/.bashrc). Il est fort probable que vous souhaitiez exécuter nvm et node en tant qu'utilisateur par défaut, par exemple vagrant, ec2-user, ubuntu, etc. Si, pour une raison quelconque, vous ne pouvez pas retirer become: true pour tout, vous pouvez contourner le problème de become: true en spécifiant become: true ET become_user: ec2-user uniquement pour ce rôle. Voir bash: commande nvm introuvable pour une explication détaillée du problème.

"impossible de trouver /usr/bin/python" erreur

C'est dû aux systèmes d'exploitation qui exécutent Python 3 par défaut (par exemple, Fedora). Vous devrez spécifier la variable interpréteur Python d'Ansible dans le fichier d'inventaire ou via la ligne de commande.

[fedora1]
192.168.0.1 ansible_python_interpreter=/usr/bin/python3

[fedora2]
192.168.0.2

[fedora2:vars]
ansible_python_interpreter=/usr/bin/python3

ou

ansible-playbook my-playbook.yml -e "ansible_python_interpreter=/usr/bin/python3"

glibc_2.28' introuvable (nécessaire à node)

Vous tentez d'exécuter une version de Node.js sur un système d'exploitation qui n'est pas pris en charge par la version de Node.js que vous installez. Ce n'est pas un problème de NVM ni de rôle. Vous devez soit mettre à jour le système d'exploitation, soit rétrograder la version de Node.js que vous tentez d'installer.


Support des Versions Ansible

ansible-core 2.16 +

Il y a eu un changement fondamental sur la façon dont Ansible gère les inclusions/importations. Ansible a supprimé ansible.builtin.include d'ansible-core et l'a remplacé par ansible.builtin.include_tasks. Malheureusement, Ansible ne peut pas limiter ansible.builtin.include pour ignorer les versions plus anciennes, etc., donc j'ai mis à niveau ce rôle pour prendre complètement en charge ansible-core 2.16+

Si vous avez besoin du support pour ansible-core 2.15 et inférieur, veuillez utiliser la branche ansible-role-nvm-legacy.

ansible-core 2.15 et inférieur

Veuillez utiliser la branche légacy 1.5.X.

Variables du Rôle

Les variables disponibles sont listées ci-dessous, ainsi que les valeurs par défaut : voir defaults/main.yml.

La version de Node.js à installer. La dernière version "lts" est la valeur par défaut et fonctionne sur la plupart des systèmes d'exploitation pris en charge.

nodejs_version: "lts"

Méthode pratique pour installer l'autocomplétion bash de NVM (nvm <TAB>) lorsqu'un utilisateur doit maintenir un serveur ou un poste de travail manuellement.

autocomplete: false

Installe NVM à partir de zéro en supprimant TOUTES et CHAQUE référence existante ou précédente à .nvm (répertoires) et TOUTES et CHAQUE référence existante ou précédente dans les entrées de profil, par exemple .bashrc dans le système.

clean_install: false

clean_install: true recherche toutes les références dans /home, /root, /etc, et dans les répertoires d'installation personnalisés, ainsi que la recherche de tout dossier .nvm dans le système. Cela équivaut à une configuration de machine neuve, UTILISEZ AVEC PRÉCAUTION.

default: false

Définissez la version par défaut de Node lors de la maintenance/de l'installation de plusieurs versions de Node.

NVM aliasera automatiquement la première version installée lors de la première exécution comme "par défaut", ce qui est probablement la raison pour laquelle de nombreuses personnes utiliseront ce rôle, cependant, cela permettra d'installer/mettre à jour plusieurs versions sur une machine existante.

Liste des commandes NVM à exécuter. Par défaut, il s'agit d'une liste vide.

nvm_commands: []

Type d'installation de NVM. Les options sont wget, curl et git.

nvm_install: "wget"

Répertoire d'installation de NVM.

nvm_dir: ""

NVM installera par défaut le répertoire .nvm dans le répertoire personnel de l'utilisateur, par exemple /home/vagrant/.nvm. Vous pouvez remplacer ce répertoire d'installation en modifiant cette variable, par exemple /opt/nvm pour le mettre dans un espace global (non lié à un compte utilisateur spécifique) si vous le souhaitez. Cette variable respectera les variables de substitution Ansible, par exemple {{ansible_env.HOME}}.

Emplacement du profil NVM. Les options sont .bashrc, .cshrc, .tcshrc, .zshrc.

nvm_profile: ".bashrc"

L'emplacement du fichier de profil SHELL de connexion qui sourcera la commande nvm. Il y a deux contextes potentiels à considérer :

Globalement, c'est-à-dire que tout le monde qui se connecte aura accès à nvm (ce qui peut ou non être ce que vous voulez vraiment).

Par exemple : /etc/bash.bashrc, /etc/profile, etc.

OU

Sur une base par utilisateur liée à un compte utilisateur spécifique.

Par exemple : /home/vagrant/.bashrc.

Ce rôle créera le fichier de profil approprié s'il n'existe pas déjà.

Si vous spécifiez explicitement nvm_profile: "/home/node-user/.bashrc" et que l'utilisateur node-user n'est pas un véritable utilisateur sur la machine, alors nvm ne fonctionnera pas comme vous l'attendez. Les chemins de become, become_user et nvm_profile sont symbiotiques.

:warning: VEUILLEZ ÊTRE AWARE DES LIMITATIONS LORSQUE VOUS DÉCLAREZ EXPLICITEMENT DES FICHIERS .profile OU .bash_profile SUR DES SYSTÈMES UBUNTU.

https://askubuntu.com/a/969923 explique en détail.

https://kb.iu.edu/d/abdy montre les options pour chaque type de shell.

Les options d'emplacement de profil NVM sont :

BASH : .bashrc

CSH : /etc/csh.cshrc, .cshrc

TSCH : /etc/csh.cshrc, .tcshrc, .cshrc

ZSH : .zshrc.

Emplacement de la source NVM, c'est-à-dire que vous hébergez votre propre fork de NVM.

nvm_source: ""

Version de NVM à installer.

nvm_version: "0.39.7"

Désintallez NVM, supprimera le répertoire .nvm et nettoiera le fichier situé au chemin de la variable {{ nvm_profile }} (généralement $HOME/.bashrc), où que ce fichier soit situé.

uninstall: False

Dépendances

Aucune.

Journal des Changements


2.0.0 Voir les NOTES DE VERSION.

Licence

MIT / BSD.

Informations sur l'Auteur

dm00000 via MORGANGRAPHICS, INC.

Ce rôle s'inspire largement du rôle Node.js de Jeff Geerling, auteur de Ansible for DevOps.

Installer
ansible-galaxy install morgangraphics.ansible-role-nvm
Licence
mit
Téléchargements
476
Propriétaire