I am new to Ansible and tried to formulate the following task:
- get a setup script via curl
- run it with sudo
- afterwards, install node.js with apt
- name: Install Node
become: true
command: "curl -fsSL https://deb.nodesource.com/setup_19.x | sudo -E bash - && sudo apt-get install -y nodejs"
tags: install_node
While the command can be run from the command line, it fails with the following error when I run it with Ansible - why is that?
TASK [Install Node] ***********************************************
fatal: [ai-training]: FAILED! => {"changed": true, "cmd": ["curl", "-fsSL", "https://deb.nodesource.com/setup_19.x", "|", "sudo", "-E", "bash", "-", "&&", "sudo", "apt-get", "install", "-y", "nodejs"], "delta": "0:00:00.012434", "end": "2022-11-01 08:24:51.941143", "msg": "non-zero return code", "rc": 2, "start": "2022-11-01 08:24:51.928709", "stderr": "curl: option -: is unknown\ncurl: try 'curl --help' or 'curl --manual' for more information", "stderr_lines": ["curl: option -: is unknown", "curl: try 'curl --help' or 'curl --manual' for more information"], "stdout": "", "stdout_lines": []}
Trying the alternative command with wget
gives a similar error:
wget -qO- https://deb.nodesource.com/setup_12.x \
| sudo -E bash - && sudo apt-get install -y nodejs
fatal: [ai-training]: FAILED! => {"changed": true, "cmd": ["wget", "-qO-", "https://deb.nodesource.com/setup_12.x", "|", "sudo", "-E", "bash", "-", "&&", "sudo", "apt-get", "install", "-y", "nodejs"], "delta": "0:00:00.007153", "end": "2022-11-01 13:06:08.298278", "msg": "non-zero return code", "rc": 2, "start": "2022-11-01 13:06:08.291125", "stderr": "wget: invalid option -- 'y'\nUsage: wget [OPTION]... [URL]...\n\nTry `wget --help' for more options.", "stderr_lines": ["wget: invalid option -- 'y'", "Usage: wget [OPTION]... [URL]...", "", "Try `wget --help' for more options."], "stdout": "", "stdout_lines": []}
CodePudding user response:
Your trial is just not the proper way to handle this kind of task in Ansible.
The script you are trying to launch is actually trying to solve some problems that Ansible is already solving for you, so you end up doing twice the same tasks and taking no advantage of what Ansible can bring you in terms of idempotency.
I am going to stress this again, although I thing everyone in the ansible tag is going it already: do not let the fact that you know how to do something in the command line get in the way when you want to do something in Ansible, as this is going to bring you to nightmarish situations that you will have to refactor either way.
Here are two proper ways to do this:
Homemade: you will need four tasks to achieve it,
- install prerequisites
- add the GPG key to apt
- add the two node repositories
- install node
Here, they are wrapped in a
block
to conveniently apply thebecome
and thetags
parameters to all of them at once.
Mind that you have to gather facts, or at least the OS ones for the variableansible_distribution_release
to be populated.- block: - apt: name: - apt-transport-https - gnupg2 - apt_key: url: https://deb.nodesource.com/gpgkey/nodesource.gpg.key - apt_repository: repo: "{{ item }}" update_cache: yes loop: - >- deb https://deb.nodesource.com/node_19.x {{ ansible_distribution_release }} main - >- deb-src https://deb.nodesource.com/node_19.x {{ ansible_distribution_release }} main - apt: name: nodejs become: true tags: install_node
Using an existing role: I would recommend the one of Jeff Geerling, as he is an active user of the Ansible community.
So, on you controller, install the role, from your terminal:ansible-galaxy install geerlingguy.nodejs
Then, just use it in a playbook:
- hosts: node roles: - role: geerlingguy.nodejs nodejs_version: 19.x nodejs_install_npm_user: "{{ ansible_user_id }}"
CodePudding user response:
Try to use wget instead:
wget -qO- https://deb.nodesource.com/setup_12.x \
| sudo -E bash - && sudo apt-get install -y nodejs
Refer this: curl option -: is unknown