38

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?

1
  • 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. Oct 12, 2018 at 11:44

6 Answers 6

49

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
  copy:
     src: package.rpm
     dest: /tmp/package.rpm

- name: Install package.
  yum:
     name: /tmp/package.rpm
     state: present
5
  • Sorry, I overlooked it. Thank you for your help! :) Nov 15, 2015 at 17:44
  • Any way to accomplish this without having to copy the file over first?
    – technocrat
    Sep 15, 2017 at 18:17
  • 2
    If you make the package available via http you can pass the url to the name parameter. Sep 15, 2017 at 20:41
  • @technocrat, a little late, but answered Nov 21, 2017 at 16:21
  • If anyone got here running into this problem in a shell (not using Ansible) here are two options I found: 1) yum localinstall ./package.rpm or 2) if ! rpm -q "$(rpm -qp ./package.rpm)"; then rpm -Uhv ./package.rpm; fi Jan 8, 2021 at 1:58
23

Actually the yum module can install an RPM directly from a given URL:

- name: Remote RPM install with yum
  yum: name=http://example.com/some_package.rpm
2
  • out of curiosity (other than it's the wrong way) why doesn't this work ? It was failing for me shell: yum install redhat.com/repo/my.rpm
    – eramm
    Nov 12, 2019 at 17:48
  • I would say it's probably because it's missing the protocol Nov 13, 2019 at 0:14
7

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
  copy:
    src: "{{ item }}"
    dest: /tmp/RPMS
  with_fileglob:
    - "../files/*.rpm"
  register: rpms_copied

- name: local RPMs not found
  fail:
    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
  yum:
    name: "{{rpm_list}}"
1
  • Very useful code snippet! Thanks
    – akirekadu
    May 18, 2020 at 20:09
2

Because I trapped over the same problem, and the post of @Jim Hunziker pushed me into the right direction, I like to share my solution for installing a specific rpm version and only upload the rpm if neccessary.

---
- hosts: testhosts
  tasks:
          - name: check if package installed
            command: rpm -q --qf "%{VERSION}\n" package
            args:
                    warn: false
            register: package_installed
            failed_when: false
            changed_when: package_installed.rc != 0
          - name: check package version
            shell: "[[ `rpm -q --qf \"%{VERSION}\n\" package` == '{{ package_version }}' ]]"
            args:
                    warn: false
            register: package_installed_version
            failed_when: false
            changed_when: package_installed_version.rc != 0
          - name: uninstall old package
            yum:
                    name: package
                    state: removed
            when: package_installed_version.rc != 0 and package_installed.rc == 0
          - name: copy package-rpm to /tmp
            copy:
                    src: package-{{ package_version }}-1.el7.x86_64.rpm
                    dest: /tmp/
            notify:
                    - remove package-rpm from /tmp
            when: package_installed_version.rc != 0
          - name: install package
            yum:
                    name: /tmp/package-{{ package_version }}-1.el7.x86_64.rpm
                    state: present
            when: package_installed_version.rc != 0
  handlers:
          - name: remove package-rpm from /tmp
            file:
                    name: /tmp/package-{{ package_version }}-1.el7.x86_64.rpm
                    state: absent
1

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}}"
  args:
    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
1
  • This task only looks idempotent to Ansible. In reality, the RPM will get re-downloaded and reinstalled every time you run it. Dec 28, 2018 at 22:06
0

try this:

- name: Installed the rpm files
  shell: yum localinstall *.rpm -y
  args:
    chdir: /tmp/rpm_dir

ignore the waring.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .