npm module not working with nvm in ansible

Viewed 1259

I am using Ansible with ubuntu 18.

Issue: Unable to execute npm command with nvm installation

When I executing following code, i get error message in install npm package globally. What should I do to resolve this issue? Note that i am able to run both nvm and npm install when i ssh inside but not using ansible

failed: [X.X>X.X] (item=apn) => {"ansible_loop_var": "item", "changed": false, "item": "apn", "msg": "Failed to find required executable npm in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin"}

Ansible playbook:

 roles:
        - role: ansible-role-nvm
            nodejs_version: "12.21.0"
            nvm_profile: "home/{{ ansible_user }}/.bashrc"
    
    tasks:
        - name: install npm package globally
          npm:
            name: "{{ item }}"
            global: yes
            loop: "{{ npm_packages }}"

Even after I set the executable path for npm to /home/ubuntu/.nvm/versions/node/v12.21.0/bin/npm, it still shows error:

failed: [X.X.X.X] (item=apn) => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"}, "ansible_loop_var": "item", "changed": false, "cmd": "/home/ubuntu/.nvm/versions/node/v12.21.0/bin/npm install --global apn", "item": "apn", "msg": "/usr/bin/env: ‘node’: No such file or directory", "rc": 127, "stderr": "/usr/bin/env: ‘node’: No such file or directory\n", "stderr_lines": ["/usr/bin/env: ‘node’: No such file or directory"], "stdout": "", "stdout_lines": []}

After the installation, the script will put following code in user .bashrc. It works fine when in interactive shell (when ssh in the seerver)

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
1 Answers

As you found out, the npm module does not work properly when node is not on the path. I came across the same issue when using asdf. You can solve this by installing npm packages using the command module in combination with nvm.

vars:
  nodejs_version: "12.21.0"
  npm_packages: ...

tasks:
  - name: Discover npm binaries directory
    ansible.builtin.command:
      cmd: >
        bash -c "source $HOME/.nvm/nvm.sh &&
        nvm exec --silent {{ nodejs_version }} npm bin -g"
    register: npm_bin_result
    changed_when: false

  - name: Set npm binaries directory
    ansible.builtin.set_fact:
      npm_binaries_dir: "{{ npm_bin_result.stdout }}"

  - name: Install global npm packages
    ansible.builtin.command:
      cmd: >
        bash -c "source $HOME/.nvm/nvm.sh &&
        nvm exec {{ nodejs_version }} npm install -g {{ item }}"
      creates: "{{ npm_binaries_dir }}/{{ item }}"
    loop: "{{ npm_packages }}"
Related