To my surprise I didn't find the simplest solution in all the answers, so here it is. Referring to the question title Installing multiple packages in Ansible this is (using the yum module):

- name: Install MongoDB
  yum:
    name:
      - mongodb-org-server
      - mongodb-org-mongos
      - mongodb-org-shell
      - mongodb-org-tools 
    state: latest
    update_cache: true

Or with the apt module:

- name: Install MongoDB
  apt:
    pkg:
      - mongodb-org-server
      - mongodb-org-mongos
      - mongodb-org-shell
      - mongodb-org-tools 
    state: latest
    update_cache: true

Both modules support inline lists!

The second part of your question is how to integrate specific version numbers into the package lists. No problem - simply remove the state: latest (since using specific version numbers together with state: latest would raise errors) and add the version numbers to the package names using a preceding = like this:

- name: Install MongoDB
  yum:
    name:
      - mongodb-org-server=1:3.6.3-0centos1.1
      - mongodb-org-mongos=1:3.6.3-0centos1.1
      - mongodb-org-shell=1:3.6.3-0centos1.1
      - mongodb-org-tools=1:3.6.3-0centos1.1 
    update_cache: true

You could also optimize further and template the version numbers. In this case don't forget to add quotation marks :)

Answer from jonashackt on Stack Overflow
Top answer
1 of 6
59

To my surprise I didn't find the simplest solution in all the answers, so here it is. Referring to the question title Installing multiple packages in Ansible this is (using the yum module):

- name: Install MongoDB
  yum:
    name:
      - mongodb-org-server
      - mongodb-org-mongos
      - mongodb-org-shell
      - mongodb-org-tools 
    state: latest
    update_cache: true

Or with the apt module:

- name: Install MongoDB
  apt:
    pkg:
      - mongodb-org-server
      - mongodb-org-mongos
      - mongodb-org-shell
      - mongodb-org-tools 
    state: latest
    update_cache: true

Both modules support inline lists!

The second part of your question is how to integrate specific version numbers into the package lists. No problem - simply remove the state: latest (since using specific version numbers together with state: latest would raise errors) and add the version numbers to the package names using a preceding = like this:

- name: Install MongoDB
  yum:
    name:
      - mongodb-org-server=1:3.6.3-0centos1.1
      - mongodb-org-mongos=1:3.6.3-0centos1.1
      - mongodb-org-shell=1:3.6.3-0centos1.1
      - mongodb-org-tools=1:3.6.3-0centos1.1 
    update_cache: true

You could also optimize further and template the version numbers. In this case don't forget to add quotation marks :)

2 of 6
17

Some people have mentioned syntax that allows passing a list, but you don't need to special-case your code for apt or yum. Here is the command that uses the generic package manager module:

- name: Install packages
  become: yes
  package:
    name:
      - tmux
      - rsync
      - zsh
      - wget
    state: present

(Or state: latest.) This feature is only documented for Ansible 2.9, so it may be new.

🌐
Medium
medium.com › @fawazcp › how-to-install-multiple-packages-in-ansible-e639a7fa13c5
How to Install Multiple Packages in Ansible | by Fawaz C P | Medium
November 18, 2023 - cd /home/ansible/dev (directory we created in the Ansible lab setup) To see the examples of yum module you can get using the below command ... --- - name: I am going to install multi packages hosts: all tasks: - name: install 3 packages yum: - httpd - unzip - wget state: latest
Discussions

Installing multiple packages with yum
In case you Need the versions, you will need to quote each element. Otherwise your code is correct. „special-foo.bar“ More on reddit.com
🌐 r/ansible
4
1
November 24, 2020
Remotely install a software on multiple systems using ansible
Sounds like you first need to copy some files, so check out: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/copy_module.html Then install a package, check out: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/apt_module.html https://docs.ansible.com/ansible/latest/collections/ansible/builtin/dnf_module.html For something a bit more complete take a look here: https://serverfault.com/questions/736538/install-rpm-package-using-ansible#736545 Edit: I would also have a look at Jeff Geerlings material. His book got me started with ansible, and I think he gives it away now too! https://www.jeffgeerling.com/projects More on reddit.com
🌐 r/ansible
8
0
June 9, 2024
How to install multiple packages but have the name of the packages in vars/packages.yml
Don't do a loop (with_items is deprecated) on yum anyways, it's ineffecient. Put the list directly in the yum module and it'll run the installs as one step. More on reddit.com
🌐 r/ansible
10
6
January 27, 2019
Ansible download all files repo in Artifactory

You want the URI module if you're going to build a list https://docs.ansible.com/ansible/latest/modules/uri_module.html
And then, the https://www.jfrog.com/confluence/display/JFROG/Artifactory+REST+API#ArtifactoryRESTAPI-PatternSearch resource to register the json *files* list and with_items using the get_url module

Alternatively, and most likely faster, you could use the https://www.jfrog.com/confluence/display/JFROG/Artifactory+REST+API#ArtifactoryRESTAPI-RetrieveFolderorRepositoryArchive resource and the unarchive module https://docs.ansible.com/ansible/latest/modules/unarchive_module.html

More on reddit.com
🌐 r/ansible
7
3
March 4, 2020
People also ask

How do I install a package using the APT module in Ansible?
To install a package, use: ansible all -m apt -a 'name=package_name state=present' to install the desired package on all targeted hosts.
🌐
linuxbuz.com
linuxbuz.com › devops › ansible-apt-module-example
Ansible apt Module: Install Packages on Ubuntu/Debian
Is it possible to install multiple packages at once with the APT module?
Yes, you can install multiple packages by specifying them in a list: ansible all -m apt -a 'name=package1,package2 state=present'.
🌐
linuxbuz.com
linuxbuz.com › devops › ansible-apt-module-example
Ansible apt Module: Install Packages on Ubuntu/Debian
How can I install a package and ignore missing dependencies using the APT module?
You can add the force=yes parameter to ignore missing dependencies: ansible all -m apt -a 'name=package_name state=present force=yes'.
🌐
linuxbuz.com
linuxbuz.com › devops › ansible-apt-module-example
Ansible apt Module: Install Packages on Ubuntu/Debian
🌐
OneUptime
oneuptime.com › home › blog › how to use ansible loop to install multiple packages
How to Use Ansible loop to Install Multiple Packages
February 21, 2026 - # merged-lists.yml # Combines multiple package lists and installs everything in one loop - name: Install from multiple lists hosts: all become: true vars: base_packages: - curl - wget - vim monitoring_packages: - prometheus-node-exporter - collectd security_packages: - fail2ban - ufw tasks: - name: Install all packages from merged lists ansible.builtin.apt: name: "{{ item }}" state: present loop: "{{ (base_packages + monitoring_packages + security_packages) | flatten }}"
Top answer
1 of 2
1

My solution is to merge these into one play, as they do the same thing.

---
- name: php-fpm play
  hosts: aws
  become: true
  vars:
  - repo:
      Debian:
      - apt # already installed, but need something here
      RedHat:
      - epel-release
  - packages:
      Debian:
      - apache2
      #- nginx # cannot have 2 listening on port 80
      - php-fpm
      RedHat:
      - httpd
      #- nginx
      - php-fpm
  - services:
      Debian: apache2
      RedHat: httpd

  tasks:
     # TODO move update * task to different play

   - name: Install repo
     # Seperate package transaction for EPEL
     # so it is available in the next task
     package:
       name: "{{ repo[ansible_os_family] }}"

   - name: Install Web Server Packages
     # Keyed by OS family fact to also support RHEL and Debian
     package:
       name: "{{ packages[ansible_os_family] }}"
       state: latest

   - name: Web Service Start
     service:
       name: "{{ services[ansible_os_family] }}"
       state: restarted
       enabled: yes

Can't have multiple servers listening on ports 80 and 443. I commented out nginx, as a task was mislabeled "Apache Service Start". If you want one of these proxying for the other or something, you will need to deploy a config file to change the ports.

Used the package: action which delegates to actual package manager. Enables a package install task to run on different OSes. Can't do update_cache that way, but yum doesn't need it when adding repos like apt does.

Vars structure is dicts of OS family specific values. This enables the package and service names to be indexed by facts. OS family, so this also works on RHEL and Debian in addition to CentOS and Ubuntu.

Indentation was wrong. Modules parameters need to be indented a level below task level directives like name:.

Can't include_tasks an entire play, that only works with import_playbook. include_tasks is easier when you have roles, which have a tasks directory for such files. (Play level tasks are a thing, but I am in favor of roles doing everything.)


There still is more work to make this useful.

When you need to use template to install configuration, EL puts configs in /etc/httpd/, while Debian is in /etc/apache2/.

Plenty of web server roles are open sourced, to look at if you want ideas. Check Galaxy.

Consider moving your tasks to roles, enables reuse.

2 of 2
3

Its' better if you take a role as example, here you have the fixed code:

---

- hosts: aws
  remote_user: myuser
  become: true
  tasks:
  - name: Performing Tasks for CentOS
    include_tasks: centos.yml
    when: ansible_facts['distribution'] == 'CentOS'
  - name: Performing Tasks for Ubuntu
    include_tasks: ubuntu.yml
    when: ansible_facts['distribution'] == 'Ubuntu'

centos.yml tasks:

---

- name: installing httpd
  yum: pkg=httpd state=present

ubuntu.yml tasks:


- name: installing apache2
  apt: pkg=apache2 state=present

In the tasks files, you only need the tasks, without hosts,tasks and so on.

🌐
Ansible
docs.ansible.com › projects › ansible › latest › collections › ansible › builtin › dnf_module.html
ansible.builtin.dnf module – Manages packages with the dnf package manager — Ansible Community Documentation
- name: Install the latest version of Apache ansible.builtin.dnf: name: httpd state: latest - name: Install Apache >= 2.4 ansible.builtin.dnf: name: httpd >= 2.4 state: present - name: Install the latest version of Apache and MariaDB ansible.builtin.dnf: name: - httpd - mariadb-server state: latest - name: Remove the Apache package ansible.builtin.dnf: name: httpd state: absent - name: Install the latest version of Apache from the testing repo ansible.builtin.dnf: name: httpd enablerepo: testing state: present - name: Upgrade all packages ansible.builtin.dnf: name: "*" state: latest - name: Update the webserver, depending on which is installed on the system.
🌐
Spacelift
spacelift.io › blog › ansible-yum-module
Ansible Yum Module : Installing & Removing Packages
When your package has multiple ... yum module to install packages with conditionals, you can use the when clause to control when a task should be executed....
Published   October 17, 2025
Find elsewhere
🌐
Ansible
docs.ansible.com › projects › ansible › latest › collections › ansible › builtin › apt_module.html
ansible.builtin.apt module – Manages apt-packages — Ansible Community Documentation
- name: Install apache httpd (state=present is optional) ansible.builtin.apt: name: apache2 state: present - name: Update repositories cache and install "foo" package ansible.builtin.apt: name: foo update_cache: yes - name: Remove "foo" package ansible.builtin.apt: name: foo state: absent - name: Install the package "foo" ansible.builtin.apt: name: foo - name: Install a list of packages ansible.builtin.apt: pkg: - foo - foo-tools - name: Install the version '1.00' of package "foo" ansible.builtin.apt: name: foo=1.00 - name: Update the repository cache and update package "nginx" to latest versi
🌐
Ansible
docs.ansible.com › projects › ansible › latest › collections › ansible › builtin › package_module.html
ansible.builtin.package module – Generic OS package manager — Ansible Community Documentation
- name: Remove the apache package ansible.builtin.package: name: "{{ apache }}" state: absent - name: Install the latest version of Apache and MariaDB ansible.builtin.package: name: - httpd - mariadb-server state: latest - name: Use the dnf package manager to install httpd ansible.builtin.package: name: httpd state: present use: dnf
🌐
OneUptime
oneuptime.com › home › blog › how to install packages with the ansible apt module
How to Install Packages with the Ansible apt Module
February 21, 2026 - You can pass a list to install several packages in a single task. This is more efficient than writing separate tasks because Ansible batches them into a single apt-get call: # Install multiple packages in a single task - name: Install web server ...
🌐
LinuxBuz
linuxbuz.com › devops › ansible-apt-module-example
Ansible apt Module: Install Packages on Ubuntu/Debian
July 11, 2025 - Use this command to update the APT package cache on all remote servers. # ansible all -m apt -a "update_cache=yes" --become · To install multiple packages (e.g., Nginx, git, and curl), use the following command.
🌐
Red Hat
redhat.com › en › blog › software-packages-ansible
How to install software packages with an Ansible playbook
August 16, 2021 - However, in the interest of reusability, it’s better to put such instructions into an Ansible playbook, like this: --- - hosts: all tasks: - name: Make sure the current version of ‘sysstat’ is installed. dnf: name: sysstat state: latest · Save this playbook to a file called install_packages.yml, and then you can run it with the following command:
🌐
Reddit
reddit.com › r/ansible › installing multiple packages with yum
r/ansible on Reddit: Installing multiple packages with yum
November 24, 2020 -

Hi mates, I need to install several packages usign the yum module.

The documentation says:

- name: Install a list of packages (suitable replacement for 2.11 loop deprecation warning)
  yum:
    name:
      - nginx
      - postgresql
      - postgresql-server
    state: present

- name: Install a list of packages with a list variable
  yum:
    name: "{{ packages }}"
  vars:
    packages:
    - httpd
    - httpd-tools

So I did this playbook:

---
- hosts: all
  tasks:
    - name: Install required RAC packages
      yum:
        name:
          - binutils-2.23.52.0.1-12.el7
          - libSM-1.2.2-2.el7
          - bzip2-libs-1.0.6-13.el7
          - libstdc++-4.8.2-3.el7
          - compat-libcap1-1.10-3.el7
          - libstdc++-devel-4.8.2-3.el7
          - compat-libcap1-1.10-7.el7
          - libstdc++-devel-4.8.5-11.el7
          - compat-libstdc++-33-3.2.3-71.el7
          - libX11-1.6.0-2.1.el7
          - compat-libstdc++-33-3.2.3-72.el7
          - libXau-1.0.8-2.1.el7
          - cpp-4.8.5-11.el7
          - libXaw-1.0.12-5.el7
          - elfutils-libelf-0.163-3.el7
          - libxcb-1.9-5.el7
          - elfutils-libelf-devel-0.163-3.el7
          - libXi-1.7.2-1.el7
          - expect-5.45-14.el7
          - libXmu-1.1.2-2.el7
          - gcc-4.8.5-11.el7
          - libXpm-3.5.11-3.el7
          - gcc-c++-4.8.5-11.el7
          - libXt-1.1.4-6.1.el7
          - glibc-2.17-36.el7
          - libXtst-1.2.2-1.el7
          - glibc-devel-2.17-157.el7
          - make-3.82-19.el7
          - glibc-devel-2.17-36.el7
          - mpfr-3.1.1-4.el7
          - glibc-headers-2.17-157.el7
          - net-tools-2.0-0.17.20131004git.el7
          - gzip-1.5-8.el7
          - nfs-utils-1.3.0-0.21.el7
          - kernel-headers-3.10.0-514.el7
          - perl-Data-Dumper-2.145-3.el7
          - ksh-20120801-26.el7
          - psmisc x86_64 22.20-11.el7
          - libaio-0.3.109-9.el7
          - smartmontools-6.2-4.el7
          - libaio-devel-0.3.109-13.el7
          - sysstat-10.1.5-1.el7
          - libaio-devel-0.3.109-9.el7
          - unzip-6.0-16.el7
          - libgcc-4.8.2-3.el7
          - xorg-x11-xauth-1.0.9-1.el7
          - libICE-1.0.9-2.el7
          - xterm-295-3.el7
          - libmpc-1.0.1-3.el7zip-3.0-11.el7
        state: present

But I get this error:

TASK [Install required RAC packages] ************************************************************************************************************************* fatal: [127.0.0.1]: FAILED! => changed=false msg: It appears that a space separated string of packages was passed in as an argument. To operate on several packages, pass a comma separated string of packages or a list of packages.

If I write this list as "item1,item2,item3" or "item1, item2, item3" I get an error too... I'm really not understanding where I'm wrong...

Can you help me, please?

🌐
Ansible
docs.ansible.com › projects › ansible › latest › collections_guide › collections_installing.html
Installing collections — Ansible Community Documentation
By default, ansible-galaxy ignores pre-release versions. To install a pre-release version, you must use the == range identifier to require it explicitly. You can set up a requirements.yml file to install multiple collections in one command.
🌐
Ansible
docs.ansible.com › projects › ansible › latest › collections › ansible › windows › win_package_module.html
ansible.windows.win_package module – Installs/uninstalls an installable package — Ansible Community Documentation
- name: Install the Visual C thingy ansible.windows.win_package: path: http://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x64.exe product_id: '{CF2BEA3C-26EA-32F8-AA9B-331F7E34BA97}' arguments: /install /passive /norestart - name: Install Visual C thingy with list of arguments instead of a string ansible.windows.win_package: path: http://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x64.exe product_id: '{CF2BEA3C-26EA-32F8-AA9B-331F7E34BA97}' arguments: - /install - /passive - /norestart - name: Install M
🌐
Google Groups
groups.google.com › g › ansible-project › c › ASmB-5St1Fs
How to use pip module wiht multiple packages and versions
June 29, 2016 - pip: name={{ item }} state=present with_items: - <package> - <package> ... But how can I specify the version in a loop? Sorry, new at this... Many thanks ... Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message ...
🌐
Rclone
rclone.org › install
Install
February 18, 2026 - There are other make targets that can be used for more advanced builds, such as cross-compiling for all supported os/architectures, and packaging results into release artifacts. See Makefile and cross-compile.go for details. Another alternative method for source installation is to download the source, build and install rclone - all in one operation, as a regular Go package.
🌐
MangoHost
mangohost.net › mangohost blog › how to install and manage system packages in ansible playbooks
How to Install and Manage System Packages in Ansible Playbooks
July 31, 2025 - Ansible’s package management shines when integrated with other automation tools. Here are some killer combinations: ... - name: Setup Docker environment block: - name: Install Docker dependencies apt: name: - apt-transport-https - ca-certificates - curl - gnupg - lsb-release state: present - name: Add Docker repository shell: | curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null args: creates: /etc/apt/sources.list.d/docker.list - name: Install Docker apt: name: - docker-ce - docker-ce-cli - containerd.io state: present update_cache: yes
🌐
Medium
medium.com › cloudnloud › how-to-install-a-package-using-ansible-6840dbe96896
How to install a package through Ansible playbook? | by sangeetha arun | Cloudnloud Tech Community | Medium
September 4, 2023 - To see the examples of yum module you can get by using the command ansible-doc yum ... Scroll down to bottom to see the examples. ... After you’ve created the file, paste the script below into package1.yaml. --- name: I am going to install package hosts: all tasks: - name: Install package yum: name: unzip state: latest
🌐
Red Hat
redhat.com › en › services › training › ex200-red-hat-certified-system-administrator-rhcsa-exam
Red Hat Certified System Administrator exam | EX200
Install and update software packages from Red Hat Content Delivery Network, a remote repository, or from the local file system