<p>Is this what you're looking for?</p>

<pre><code>- hosts: all
  vars:
    bunch_of_specific_packages:
      - apache2
      - gcc
      - gedit
  tasks:
    - package:
        name: "{{ item }}"
      loop: "{{ bunch_of_specific_packages }}"
</code></pre>

CC BY-SA 4.0
2019-04-03T19:51:01.000Z
I think that's close. I would need to restructure it slightly so that the "task" is part of an "install packages" role, and then include that role and a machine-specific list of packages in each top level playbook. However, I'm starting to rethink doing this at all, since it makes it harder to then, say, configure each package in a sensible way.
Ryan O.
CC BY-SA 4.0
2019-04-03T20:18:29.687Z
On second thought, it would save me a lot of work when the default install is all I need. I could then create full roles for packages that require configuration after installation.
Ryan O.
CC BY-SA 4.0
2019-04-09T17:48:35.480Z
Having some globally-available packages is handy, but for things you don't need everywhere just embed those package installs in the roles that need them.  It might lead to some redundancy, but at least it will be clear which packages are needed by which roles.
chicks
CC BY-SA 4.0
2019-04-03T16:02:26.843Z
2019-04-03T16:02:26.843Z
Vladimir Botka
<p>Another way to do this would be to set a role variable in your host_vars file called "role" and assign the role to install that way.  You could also use the loop that Vladimir provided to install multiple roles.</p>

<pre><code>tasks:
  - name: "Install Apache"
    become: true
    package:
      name: apache2
      state: latest
    when: role == "apache"

  - name: "Install GCC"
    become: true
    package:
      name: gcc
      state: latest
    when: role == "gcc"
</code></pre>

<p>You could also use tags to control what gets run in your play:</p>

<pre><code>tasks:
  - name: "Install Apache"
    become: true
    package:
      name: apache2
      state: latest
    tags:
       - web
  - name: "Install GCC"
    become: true
    package:
      name: gcc
      state: latest
    tags:
       - gcc
</code></pre>

<p>And run your playbook setting the tags you require:</p>

<pre><code>ansible-playbook example.yml --tags "web,gcc"
</code></pre>

CC BY-SA 4.0
2019-04-24T09:53:54.443Z
2019-04-24T09:53:54.443Z
Daniel Flick
<p>I currently have a bunch of roles, like:</p>

<ul>
<li>apache2</li>
<li>gcc</li>
<li>gedit</li>
<li>...etc.</li>
</ul>

<p>For each of those, I have a task file that looks like this:</p>

<pre><code>---
- name: "Install {{ role_name }}"
  become: true
  package:
    name: "{{ role_name }}"
    state: present
</code></pre>

<p>Is there a way to abstract this to a higher level and have a single "Install package" role, and then somehow specify a bunch of specific packages to install per host in a variable or something?</p>

<ansible>
Getting rid of redundant Ansible roles
Ryan O.
# Getting rid of redundant Ansible roles

(Asked by: username_0 on 2019-04-03)

I currently have a bunch of roles, like:

apache2
gcc
gedit
...etc.

For each of those, I have a task file that looks like this:
---
- name: "Install {{ role_name }}"
  become: true
  package:
    name: "{{ role_name }}"
    state: present

Is there a way to abstract this to a higher level and have a single "Install package" role, and then somehow specify a bunch of specific packages to install per host in a variable or something?

**Tags:** ansible


---

## 2 answers

### Answer by username_1 on 2019-04-03. Score: 2 | Accepted answer

Is this what you're looking for?
- hosts: all
  vars:
    bunch_of_specific_packages:
      - apache2
      - gcc
      - gedit
  tasks:
    - package:
        name: "{{ item }}"
      loop: "{{ bunch_of_specific_packages }}"

> **Comments:**
> **username_0**: I think that's close. I would need to restructure it slightly so that the "task" is part of an "install packages" role, and then include that role and a machine-specific list of packages in each top level playbook. However, I'm starting to rethink doing this at all, since it makes it harder to then, say, configure each package in a sensible way.  
> **username_0**: On second thought, it would save me a lot of work when the default install is all I need. I could then create full roles for packages that require configuration after installation.  
> **username_2**: Having some globally-available packages is handy, but for things you don't need everywhere just embed those package installs in the roles that need them.  It might lead to some redundancy, but at least it will be clear which packages are needed by which roles.  

---

### Answer by username_3 on 2019-04-24. Score: 0

Another way to do this would be to set a role variable in your host_vars file called "role" and assign the role to install that way.  You could also use the loop that Vladimir provided to install multiple roles.
tasks:
  - name: "Install Apache"
    become: true
    package:
      name: apache2
      state: latest
    when: role == "apache"

  - name: "Install GCC"
    become: true
    package:
      name: gcc
      state: latest
    when: role == "gcc"

You could also use tags to control what gets run in your play:
tasks:
  - name: "Install Apache"
    become: true
    package:
      name: apache2
      state: latest
    tags:
       - web
  - name: "Install GCC"
    become: true
    package:
      name: gcc
      state: latest
    tags:
       - gcc

And run your playbook setting the tags you require:
ansible-playbook example.yml --tags "web,gcc"


---

