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.
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.
Ils installent souvent NVM et Node.js en tant qu'utilisateur
root
(sudo su
oubecome: 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.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
- Vous pouvez installer NVM via wget, curl ou git.
- Vous pouvez utiliser NVM comme vous le feriez via votre ligne de commande dans vos propres tâches et playbooks Ansible.
- Vous pouvez installer la version ou les versions de Node.js que vous souhaitez.
- N'installe pas NVM ou Node.js en tant que root.
- 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
- Clonez ce dépôt dans votre dossier de rôles.
- Pointez la variable
roles_path
vers le dossier des rôles, par exempleroles_path = ../ansible-roles/
dans votre fichieransible.cfg
. - 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 :
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'utilisateurroot_user
, réfléchissez à ce que fait le rôle et pourquoi il a besoin d'un accès root pour tout.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
.Ansible changera le contexte du shell de connexion en
root
et nvm sera installé dans le répertoire personnel de l'utilisateurroot
, 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 server
où server
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
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 listenvm_commands
, comme- "nvm alias default <YOUR_VERSION>"
.Si vous avez
default: true
explicitement déclaré comme variable de rôle ET- "nvm alias default <SOME_OTHER_VERSION>"
comme partie de vosnvm_commands
, la version avecdefault: 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.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 lesré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 debecome
,become_user
etnvm_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.
NVM installation for Linux
ansible-galaxy install morgangraphics.ansible-role-nvm