How do I install .rpm package on remote machine using Ansible?

The obvious solution is to use command module, but that is a bit silly. Also I would like to avoid setting up a yum repository just for one package.

Is there some more pragmatic approach to this problem?

  • That's what ssh is good for. I know there are cool utils to play with, but for actual, non-trivial tasks is it ssh. – Lorinczy Zsigmond Oct 12 '18 at 11:44

Ansible yum module already provides a solution for this problem. The path to the local rpm file on the server can be passed to the name parameter.

From the Ansible yum module documentation:

You can also pass a url or a local path to a rpm file. To operate on several packages this can accept a comma separated list of packages or (as of 2.0) a list of packages.

The proper steps to do this would be something like this:

- name: Copy rpm file to server
     src: package.rpm
     dest: /tmp/package.rpm

- name: Install package.
     name: /tmp/package.rpm
     state: present
  • Sorry, I overlooked it. Thank you for your help! :) – NefariousOctopus Nov 15 '15 at 17:44
  • Any way to accomplish this without having to copy the file over first? – technocrat Sep 15 '17 at 18:17
  • 1
    If you make the package available via http you can pass the url to the name parameter. – Henrik Pingel Sep 15 '17 at 20:41
  • @technocrat, a little late, but answered – Flippym Nov 21 '17 at 16:21

The yum module can install RPM from an URL:

- name: Install NUX Repository
  yum: name=http://example.com/some_package.rpm

Or you can use command instead, since the rpm command has a built-in method for remote install:

- name: Install RPM from URL
  command: rpm -i http://example.com/some_package.rpm
  • Interesting... So that's an rpm feature... it'd be nice to not have to use command, just yum, but that could make it work. – technocrat Nov 21 '17 at 19:34
  • 3
    That command is by itself not idempotent – Henrik Pingel Nov 22 '17 at 7:16

Here's what I do to install multiple RPMs from the source machine:

- name: mkdir /tmp/RPMS
  file: path=/tmp/RPMS state=directory

- name: copy RPMs to /tmp/RPMS
    src: "{{ item }}"
    dest: /tmp/RPMS
    - "../files/*.rpm"
  register: rpms_copied

- name: local RPMs not found
    msg: "RPMs not found in ../files/"
  when: rpms_copied.results|length == 0 and rpms_copied.skipped and rpms_copied.skipped_reason.find('No items') != -1

- set_fact:
    rpm_list: "{{ rpms_copied.results | map(attribute='dest') | list}}"

- name: install RPMs
    name: "{{rpm_list}}"

I had to use mandatory the rpm command because I do not have yum (it is an AIX OS).

I have solved the idempotency with this:

- command: rpm -U "{{rpm}}"
    warn: false
  register: rpm_install
  failed_when: rpm_install.rc != 0 and "is already installed" not in rpm_install.stderr
  changed_when: rpm_install.rc == 0
  • This task only looks idempotent to Ansible. In reality, the RPM will get re-downloaded and reinstalled every time you run it. – Mike Dec 28 '18 at 22:06

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.